@xopcai/xopc 0.0.6 → 0.0.11

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 (412) hide show
  1. package/dist/extensions/weixin/src/api/api.js +1 -1
  2. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  3. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  4. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  5. package/dist/gateway/static/root/assets/{agents-B6s2BvpH.js → agents-BdC4Y-HX.js} +2 -2
  6. package/dist/gateway/static/root/assets/agents-BdC4Y-HX.js.map +1 -0
  7. package/dist/gateway/static/root/assets/{apps-page-BtsZ5ZPx.js → apps-page-C-oaSHkm.js} +2 -2
  8. package/dist/gateway/static/root/assets/{apps-page-BtsZ5ZPx.js.map → apps-page-C-oaSHkm.js.map} +1 -1
  9. package/dist/gateway/static/root/assets/attachment-load-BDDlItdE.js +1 -0
  10. package/dist/gateway/static/root/assets/{channels-settings-BUfWBEVU.js → channels-settings-BqEUppPO.js} +2 -2
  11. package/dist/gateway/static/root/assets/{channels-settings-BUfWBEVU.js.map → channels-settings-BqEUppPO.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{chat-agents-api-BR30M2YQ.js → chat-agents-api-BhqjQ7iL.js} +2 -2
  13. package/dist/gateway/static/root/assets/{chat-agents-api-BR30M2YQ.js.map → chat-agents-api-BhqjQ7iL.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{cron-page-CMTx0Mjz.js → cron-page-Cli49RKR.js} +2 -2
  15. package/dist/gateway/static/root/assets/{cron-page-CMTx0Mjz.js.map → cron-page-Cli49RKR.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{cron-utils-BJma9IcD.js → cron-utils-Dkj-Ldpf.js} +2 -2
  17. package/dist/gateway/static/root/assets/{cron-utils-BJma9IcD.js.map → cron-utils-Dkj-Ldpf.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/electron-env-BDtJw9AY.js +2 -0
  19. package/dist/gateway/static/root/assets/electron-env-BDtJw9AY.js.map +1 -0
  20. package/dist/gateway/static/root/assets/{extension-debug-page-BCVoNSo6.js → extension-debug-page-BMcZlaxF.js} +2 -2
  21. package/dist/gateway/static/root/assets/{extension-debug-page-BCVoNSo6.js.map → extension-debug-page-BMcZlaxF.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{extension-iframe-host-PWB-Pw2d.js → extension-iframe-host-D5HEF0KR.js} +2 -2
  23. package/dist/gateway/static/root/assets/{extension-iframe-host-PWB-Pw2d.js.map → extension-iframe-host-D5HEF0KR.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{extension-page-D2tTklsD.js → extension-page-CXdCSSPl.js} +2 -2
  25. package/dist/gateway/static/root/assets/{extension-page-D2tTklsD.js.map → extension-page-CXdCSSPl.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-provider-BpHodVRj.js → extension-provider-DZCZgQE2.js} +2 -2
  27. package/dist/gateway/static/root/assets/{extension-provider-BpHodVRj.js.map → extension-provider-DZCZgQE2.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-settings-page-BEu6Xw1Z.js → extension-settings-page-CX6STpx3.js} +2 -2
  29. package/dist/gateway/static/root/assets/{extension-settings-page-BEu6Xw1Z.js.map → extension-settings-page-CX6STpx3.js.map} +1 -1
  30. package/dist/gateway/static/root/assets/{gateway-config-swr-C7ZFPhNj.js → gateway-config-swr-Cph02QZn.js} +2 -2
  31. package/dist/gateway/static/root/assets/{gateway-config-swr-C7ZFPhNj.js.map → gateway-config-swr-Cph02QZn.js.map} +1 -1
  32. package/dist/gateway/static/root/assets/index-Bty3m0mS.css +2 -0
  33. package/dist/gateway/static/root/assets/index-iTUyfzNr.js +16 -0
  34. package/dist/gateway/static/root/assets/index-iTUyfzNr.js.map +1 -0
  35. package/dist/gateway/static/root/assets/{logs-page-BpsxYdcL.js → logs-page-B9O5l3I8.js} +2 -2
  36. package/dist/gateway/static/root/assets/{logs-page-BpsxYdcL.js.map → logs-page-B9O5l3I8.js.map} +1 -1
  37. package/dist/gateway/static/root/assets/{model-selector-BiiDq8Pk.js → model-selector-BLiY_O25.js} +2 -2
  38. package/dist/gateway/static/root/assets/{model-selector-BiiDq8Pk.js.map → model-selector-BLiY_O25.js.map} +1 -1
  39. package/dist/gateway/static/root/assets/navigation-DB9S-C6S.js +2 -0
  40. package/dist/gateway/static/root/assets/navigation-DB9S-C6S.js.map +1 -0
  41. package/dist/gateway/static/root/assets/page-header-store-BFpnFTed.js +2 -0
  42. package/dist/gateway/static/root/assets/{page-header-store-HcRZK5CZ.js.map → page-header-store-BFpnFTed.js.map} +1 -1
  43. package/dist/gateway/static/root/assets/{session-api-DxNaAkmX.js → session-api-DEhQXWJg.js} +2 -2
  44. package/dist/gateway/static/root/assets/{session-api-DxNaAkmX.js.map → session-api-DEhQXWJg.js.map} +1 -1
  45. package/dist/gateway/static/root/assets/{session-working-directory-control-CDH-Wk4E.js → session-working-directory-control-DKOtWs3-.js} +3 -3
  46. package/dist/gateway/static/root/assets/{session-working-directory-control-CDH-Wk4E.js.map → session-working-directory-control-DKOtWs3-.js.map} +1 -1
  47. package/dist/gateway/static/root/assets/{sessions-page-5PK75r1n.js → sessions-page-BYlWP1ep.js} +2 -2
  48. package/dist/gateway/static/root/assets/{sessions-page-5PK75r1n.js.map → sessions-page-BYlWP1ep.js.map} +1 -1
  49. package/dist/gateway/static/root/assets/settings-page-oCnIavdg.js +2 -0
  50. package/dist/gateway/static/root/assets/settings-page-oCnIavdg.js.map +1 -0
  51. package/dist/gateway/static/root/assets/{skill-api-CxbNlOD_.js → skill-api-DWrn8Az0.js} +2 -2
  52. package/dist/gateway/static/root/assets/{skill-api-CxbNlOD_.js.map → skill-api-DWrn8Az0.js.map} +1 -1
  53. package/dist/gateway/static/root/assets/{skills-page-Dd8ZzYJb.js → skills-page-C59WQpM1.js} +2 -2
  54. package/dist/gateway/static/root/assets/{skills-page-Dd8ZzYJb.js.map → skills-page-C59WQpM1.js.map} +1 -1
  55. package/dist/gateway/static/root/assets/{theme-store-CPTH77BE.js → theme-store-CywXkKml.js} +2 -2
  56. package/dist/gateway/static/root/assets/{theme-store-CPTH77BE.js.map → theme-store-CywXkKml.js.map} +1 -1
  57. package/dist/gateway/static/root/assets/url-D7yWllI8.js +2 -0
  58. package/dist/gateway/static/root/assets/url-D7yWllI8.js.map +1 -0
  59. package/dist/gateway/static/root/assets/{useTranslation-BEUWOMuh.js → useTranslation-CACj0DBJ.js} +2 -2
  60. package/dist/gateway/static/root/assets/{useTranslation-BEUWOMuh.js.map → useTranslation-CACj0DBJ.js.map} +1 -1
  61. package/dist/gateway/static/root/index.html +16 -16
  62. package/dist/package.js +1 -1
  63. package/dist/src/agent/agent-manager.d.ts +1 -0
  64. package/dist/src/agent/agent-manager.js +17 -9
  65. package/dist/src/agent/agent-manager.js.map +1 -1
  66. package/dist/src/agent/background-review/run-background-review.js +2 -0
  67. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  68. package/dist/src/agent/child-agent-factory.js +2 -0
  69. package/dist/src/agent/child-agent-factory.js.map +1 -1
  70. package/dist/src/agent/context/expand-at-file-mentions.d.ts +4 -0
  71. package/dist/src/agent/context/expand-at-file-mentions.js +69 -0
  72. package/dist/src/agent/context/expand-at-file-mentions.js.map +1 -0
  73. package/dist/src/agent/context/workspace-seed.js +1 -1
  74. package/dist/src/agent/image/index.d.ts +0 -1
  75. package/dist/src/agent/image/index.js +1 -2
  76. package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
  77. package/dist/src/agent/ipc/inbox.js +1 -1
  78. package/dist/src/agent/ipc/socket.js +1 -1
  79. package/dist/src/agent/memory/compaction.d.ts +1 -1
  80. package/dist/src/agent/memory/compaction.js +38 -11
  81. package/dist/src/agent/memory/compaction.js.map +1 -1
  82. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  83. package/dist/src/agent/messaging/command-handler.d.ts +13 -0
  84. package/dist/src/agent/messaging/command-handler.js +14 -2
  85. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  86. package/dist/src/agent/orchestration/agent-orchestrator.js +6 -1
  87. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  88. package/dist/src/agent/service.d.ts +16 -1
  89. package/dist/src/agent/service.js +175 -17
  90. package/dist/src/agent/service.js.map +1 -1
  91. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  92. package/dist/src/agent/skills/hub-hash.js +1 -1
  93. package/dist/src/agent/skills/hub-pull.js +1 -1
  94. package/dist/src/agent/skills/scanner.js +1 -1
  95. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  96. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  97. package/dist/src/agent/tools/browser/tools.js +2 -2
  98. package/dist/src/agent/tools/browser/tools.js.map +1 -1
  99. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  100. package/dist/src/agent/tools/image-tool.js +2 -2
  101. package/dist/src/agent/tools/image-tool.js.map +1 -1
  102. package/dist/src/agent/tools/index.d.ts +1 -1
  103. package/dist/src/agent/tools/index.js +2 -2
  104. package/dist/src/agent/tools/read.d.ts +0 -2
  105. package/dist/src/agent/tools/read.js +1 -3
  106. package/dist/src/agent/tools/read.js.map +1 -1
  107. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  108. package/dist/src/agent/tools/write.js +1 -1
  109. package/dist/src/auth/credentials.js +2 -2
  110. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  111. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  112. package/dist/src/channels/index.d.ts +1 -1
  113. package/dist/src/channels/index.js +2 -2
  114. package/dist/src/channels/pipeline.d.ts +8 -1
  115. package/dist/src/channels/pipeline.js +49 -4
  116. package/dist/src/channels/pipeline.js.map +1 -1
  117. package/dist/src/channels/plugin-types.d.ts +14 -0
  118. package/dist/src/chat-commands/builtins/config.d.ts +4 -0
  119. package/dist/src/chat-commands/builtins/config.js +197 -0
  120. package/dist/src/chat-commands/builtins/config.js.map +1 -0
  121. package/dist/src/chat-commands/builtins/context.d.ts +4 -0
  122. package/dist/src/chat-commands/builtins/context.js +44 -0
  123. package/dist/src/chat-commands/builtins/context.js.map +1 -0
  124. package/dist/src/chat-commands/builtins/session.js +111 -0
  125. package/dist/src/chat-commands/builtins/session.js.map +1 -1
  126. package/dist/src/chat-commands/builtins/thinking.js +49 -21
  127. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  128. package/dist/src/chat-commands/config-paths.d.ts +10 -0
  129. package/dist/src/chat-commands/config-paths.js +45 -0
  130. package/dist/src/chat-commands/config-paths.js.map +1 -0
  131. package/dist/src/chat-commands/config-value.d.ts +12 -0
  132. package/dist/src/chat-commands/config-value.js +53 -0
  133. package/dist/src/chat-commands/config-value.js.map +1 -0
  134. package/dist/src/chat-commands/context.d.ts +24 -1
  135. package/dist/src/chat-commands/context.js +41 -0
  136. package/dist/src/chat-commands/context.js.map +1 -1
  137. package/dist/src/chat-commands/index.d.ts +2 -0
  138. package/dist/src/chat-commands/index.js +5 -1
  139. package/dist/src/chat-commands/index.js.map +1 -1
  140. package/dist/src/chat-commands/types.d.ts +33 -1
  141. package/dist/src/cli/commands/agent/interactive.js +1 -1
  142. package/dist/src/cli/commands/agent/interactive.js.map +1 -1
  143. package/dist/src/cli/commands/agent.js +21 -9
  144. package/dist/src/cli/commands/agent.js.map +1 -1
  145. package/dist/src/cli/commands/auth.js.map +1 -1
  146. package/dist/src/cli/commands/doctor/checks/channel-config.d.ts +2 -0
  147. package/dist/src/cli/commands/doctor/checks/channel-config.js +113 -0
  148. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -0
  149. package/dist/src/cli/commands/doctor/checks/channel-plugins.d.ts +2 -0
  150. package/dist/src/cli/commands/doctor/checks/channel-plugins.js +47 -0
  151. package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -0
  152. package/dist/src/cli/commands/doctor/checks/config-health.d.ts +2 -0
  153. package/dist/src/cli/commands/doctor/checks/config-health.js +82 -0
  154. package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -0
  155. package/dist/src/cli/commands/doctor/checks/cron-health.d.ts +2 -0
  156. package/dist/src/cli/commands/doctor/checks/cron-health.js +116 -0
  157. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -0
  158. package/dist/src/cli/commands/doctor/checks/gateway-health.d.ts +2 -0
  159. package/dist/src/cli/commands/doctor/checks/gateway-health.js +64 -0
  160. package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -0
  161. package/dist/src/cli/commands/doctor/checks/gateway-service.d.ts +2 -0
  162. package/dist/src/cli/commands/doctor/checks/gateway-service.js +64 -0
  163. package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -0
  164. package/dist/src/cli/commands/doctor/checks/node-version.d.ts +2 -0
  165. package/dist/src/cli/commands/doctor/checks/node-version.js +33 -0
  166. package/dist/src/cli/commands/doctor/checks/node-version.js.map +1 -0
  167. package/dist/src/cli/commands/doctor/checks/provider-auth.d.ts +2 -0
  168. package/dist/src/cli/commands/doctor/checks/provider-auth.js +91 -0
  169. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -0
  170. package/dist/src/cli/commands/doctor/checks/security-audit.d.ts +2 -0
  171. package/dist/src/cli/commands/doctor/checks/security-audit.js +85 -0
  172. package/dist/src/cli/commands/doctor/checks/security-audit.js.map +1 -0
  173. package/dist/src/cli/commands/doctor/checks/session-integrity.d.ts +2 -0
  174. package/dist/src/cli/commands/doctor/checks/session-integrity.js +118 -0
  175. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -0
  176. package/dist/src/cli/commands/doctor/checks/state-integrity.d.ts +2 -0
  177. package/dist/src/cli/commands/doctor/checks/state-integrity.js +99 -0
  178. package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -0
  179. package/dist/src/cli/commands/doctor/checks/version-check.d.ts +2 -0
  180. package/dist/src/cli/commands/doctor/checks/version-check.js +71 -0
  181. package/dist/src/cli/commands/doctor/checks/version-check.js.map +1 -0
  182. package/dist/src/cli/commands/doctor/checks/workspace-status.d.ts +2 -0
  183. package/dist/src/cli/commands/doctor/checks/workspace-status.js +73 -0
  184. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -0
  185. package/dist/src/cli/commands/doctor/flow.d.ts +9 -0
  186. package/dist/src/cli/commands/doctor/flow.js +51 -0
  187. package/dist/src/cli/commands/doctor/flow.js.map +1 -0
  188. package/dist/src/cli/commands/doctor/format.d.ts +6 -0
  189. package/dist/src/cli/commands/doctor/format.js +61 -0
  190. package/dist/src/cli/commands/doctor/format.js.map +1 -0
  191. package/dist/src/cli/commands/doctor/index.js +44 -0
  192. package/dist/src/cli/commands/doctor/index.js.map +1 -0
  193. package/dist/src/cli/commands/doctor/types.d.ts +20 -0
  194. package/dist/src/cli/commands/doctor/types.js +1 -0
  195. package/dist/src/cli/commands/extension.js +10 -0
  196. package/dist/src/cli/commands/extension.js.map +1 -1
  197. package/dist/src/cli/commands/init.js +1 -2
  198. package/dist/src/cli/commands/init.js.map +1 -1
  199. package/dist/src/cli/commands/session/utils.js.map +1 -1
  200. package/dist/src/cli/commands/update.d.ts +1 -0
  201. package/dist/src/cli/commands/update.js +171 -0
  202. package/dist/src/cli/commands/update.js.map +1 -0
  203. package/dist/src/cli/index.d.ts +2 -2
  204. package/dist/src/cli/index.js +4 -2
  205. package/dist/src/cli/index.js.map +1 -1
  206. package/dist/src/cli/utils/init-workspace.js +1 -1
  207. package/dist/src/config/index.d.ts +1 -0
  208. package/dist/src/config/index.js +4 -3
  209. package/dist/src/config/index.js.map +1 -1
  210. package/dist/src/config/loader.js +1 -1
  211. package/dist/src/config/models-json.d.ts +15 -15
  212. package/dist/src/config/paths.js.map +1 -1
  213. package/dist/src/config/profile.js +1 -1
  214. package/dist/src/config/runtime-overrides.d.ts +8 -0
  215. package/dist/src/config/runtime-overrides.js +40 -0
  216. package/dist/src/config/runtime-overrides.js.map +1 -0
  217. package/dist/src/config/schema.d.ts +34 -104
  218. package/dist/src/config/schema.js +18 -39
  219. package/dist/src/config/schema.js.map +1 -1
  220. package/dist/src/cron/persistence.js +1 -1
  221. package/dist/src/cron/run-log-store.js +1 -1
  222. package/dist/src/daemon/launchd.js +2 -2
  223. package/dist/src/daemon/launchd.js.map +1 -1
  224. package/dist/src/daemon/systemd.js +2 -2
  225. package/dist/src/daemon/systemd.js.map +1 -1
  226. package/dist/src/extensions/health.js +1 -1
  227. package/dist/src/extensions/loader.d.ts +1 -1
  228. package/dist/src/extensions/loader.js +5 -8
  229. package/dist/src/extensions/loader.js.map +1 -1
  230. package/dist/src/extensions/lockfile.js +1 -1
  231. package/dist/src/extensions/sdk/index.js +6 -1
  232. package/dist/src/extensions/sdk/index.js.map +1 -0
  233. package/dist/src/gateway/agents-admin.js +1 -1
  234. package/dist/src/gateway/agents-admin.js.map +1 -1
  235. package/dist/src/gateway/hono/lib/static-ui.js +1 -1
  236. package/dist/src/gateway/hono/oauth.js +1 -1
  237. package/dist/src/gateway/hono/routes/config.js +1 -1
  238. package/dist/src/gateway/hono/routes/doctor.d.ts +3 -0
  239. package/dist/src/gateway/hono/routes/doctor.js +35 -0
  240. package/dist/src/gateway/hono/routes/doctor.js.map +1 -0
  241. package/dist/src/gateway/hono/routes/index.js +4 -0
  242. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  243. package/dist/src/gateway/hono/routes/models.js +64 -11
  244. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  245. package/dist/src/gateway/hono/routes/public-gateway.js +10 -0
  246. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  247. package/dist/src/gateway/hono/routes/update.d.ts +3 -0
  248. package/dist/src/gateway/hono/routes/update.js +141 -0
  249. package/dist/src/gateway/hono/routes/update.js.map +1 -0
  250. package/dist/src/gateway/hono/routes/workspace.js +82 -2
  251. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  252. package/dist/src/gateway/lock.js +1 -1
  253. package/dist/src/gateway/ports.js +98 -3
  254. package/dist/src/gateway/ports.js.map +1 -1
  255. package/dist/src/gateway/service.d.ts +1 -4
  256. package/dist/src/gateway/service.js +13 -20
  257. package/dist/src/gateway/service.js.map +1 -1
  258. package/dist/src/gateway/workspace-fs-file-list.d.ts +5 -0
  259. package/dist/src/gateway/workspace-fs-file-list.js +56 -0
  260. package/dist/src/gateway/workspace-fs-file-list.js.map +1 -0
  261. package/dist/src/gateway/workspace-heartbeat-path.js +1 -1
  262. package/dist/src/gateway/workspace-ripgrep.d.ts +5 -0
  263. package/dist/src/gateway/workspace-ripgrep.js +88 -4
  264. package/dist/src/gateway/workspace-ripgrep.js.map +1 -1
  265. package/dist/src/infra/update-channels.d.ts +14 -0
  266. package/dist/src/infra/update-channels.js +30 -0
  267. package/dist/src/infra/update-channels.js.map +1 -0
  268. package/dist/src/infra/update-check.d.ts +53 -0
  269. package/dist/src/infra/update-check.js +155 -0
  270. package/dist/src/infra/update-check.js.map +1 -0
  271. package/dist/src/infra/update-runner.d.ts +18 -0
  272. package/dist/src/infra/update-runner.js +112 -0
  273. package/dist/src/infra/update-runner.js.map +1 -0
  274. package/dist/src/infra/update-startup.d.ts +20 -0
  275. package/dist/src/infra/update-startup.js +246 -0
  276. package/dist/src/infra/update-startup.js.map +1 -0
  277. package/dist/src/providers/extension-stream-bridge.d.ts +3 -0
  278. package/dist/src/providers/extension-stream-bridge.js +239 -0
  279. package/dist/src/providers/extension-stream-bridge.js.map +1 -0
  280. package/dist/src/providers/index.d.ts +7 -2
  281. package/dist/src/providers/index.js +77 -14
  282. package/dist/src/providers/index.js.map +1 -1
  283. package/dist/src/providers/model-registry.js +1 -1
  284. package/dist/src/providers/plugin-registry.js +92 -87
  285. package/dist/src/providers/plugin-registry.js.map +1 -1
  286. package/dist/src/routing/bindings.js +1 -1
  287. package/dist/src/routing/index.d.ts +1 -1
  288. package/dist/src/routing/index.js +2 -2
  289. package/dist/src/routing/index.js.map +1 -1
  290. package/dist/src/routing/resolve-route.js +1 -1
  291. package/dist/src/routing/session-key.d.ts +0 -5
  292. package/dist/src/routing/session-key.js +1 -27
  293. package/dist/src/routing/session-key.js.map +1 -1
  294. package/dist/src/session/chat-export.d.ts +5 -0
  295. package/dist/src/session/chat-export.js +35 -0
  296. package/dist/src/session/chat-export.js.map +1 -0
  297. package/dist/src/session/config-store.js +1 -1
  298. package/dist/src/session/manager.d.ts +1 -1
  299. package/dist/src/session/manager.js +2 -2
  300. package/dist/src/session/manager.js.map +1 -1
  301. package/dist/src/session/store.d.ts +1 -1
  302. package/dist/src/session/store.js +3 -7
  303. package/dist/src/session/store.js.map +1 -1
  304. package/dist/src/session/types.d.ts +0 -10
  305. package/dist/src/session/types.js.map +1 -1
  306. package/dist/src/utils/logger/audit.js +1 -1
  307. package/dist/src/utils/logger/log-store.js +1 -1
  308. package/dist/src/utils/logger/rotation.js +1 -1
  309. package/dist/src/voice/tts/audio.js +1 -1
  310. package/package.json +2 -2
  311. package/dist/gateway/static/root/assets/agents-B6s2BvpH.js.map +0 -1
  312. package/dist/gateway/static/root/assets/attachment-load-6pRlDPZ8.js +0 -1
  313. package/dist/gateway/static/root/assets/index-DBZ5eXW5.js +0 -16
  314. package/dist/gateway/static/root/assets/index-DBZ5eXW5.js.map +0 -1
  315. package/dist/gateway/static/root/assets/index-KsVMH-Jo.css +0 -2
  316. package/dist/gateway/static/root/assets/navigation-BpLKd2Ca.js +0 -2
  317. package/dist/gateway/static/root/assets/navigation-BpLKd2Ca.js.map +0 -1
  318. package/dist/gateway/static/root/assets/page-header-store-HcRZK5CZ.js +0 -2
  319. package/dist/gateway/static/root/assets/preference-select-fields-B4AJBqUY.js +0 -2
  320. package/dist/gateway/static/root/assets/preference-select-fields-B4AJBqUY.js.map +0 -1
  321. package/dist/gateway/static/root/assets/settings-page-BvSj0JqX.js +0 -2
  322. package/dist/gateway/static/root/assets/settings-page-BvSj0JqX.js.map +0 -1
  323. package/dist/gateway/static/root/assets/url-QmwQTJ-j.js +0 -2
  324. package/dist/gateway/static/root/assets/url-QmwQTJ-j.js.map +0 -1
  325. package/dist/src/acp/commands.d.ts +0 -11
  326. package/dist/src/acp/commands.js +0 -17
  327. package/dist/src/acp/commands.js.map +0 -1
  328. package/dist/src/acp/control-plane/identity-reconcile.d.ts +0 -36
  329. package/dist/src/acp/control-plane/identity-reconcile.js +0 -124
  330. package/dist/src/acp/control-plane/identity-reconcile.js.map +0 -1
  331. package/dist/src/acp/control-plane/index.d.ts +0 -10
  332. package/dist/src/acp/control-plane/index.js +0 -6
  333. package/dist/src/acp/control-plane/manager.d.ts +0 -86
  334. package/dist/src/acp/control-plane/manager.js +0 -502
  335. package/dist/src/acp/control-plane/manager.js.map +0 -1
  336. package/dist/src/acp/control-plane/manager.types.d.ts +0 -125
  337. package/dist/src/acp/control-plane/manager.types.js +0 -14
  338. package/dist/src/acp/control-plane/manager.types.js.map +0 -1
  339. package/dist/src/acp/control-plane/manager.utils.d.ts +0 -29
  340. package/dist/src/acp/control-plane/manager.utils.js +0 -46
  341. package/dist/src/acp/control-plane/manager.utils.js.map +0 -1
  342. package/dist/src/acp/control-plane/runtime-cache-manager.d.ts +0 -49
  343. package/dist/src/acp/control-plane/runtime-cache-manager.js +0 -155
  344. package/dist/src/acp/control-plane/runtime-cache-manager.js.map +0 -1
  345. package/dist/src/acp/control-plane/runtime-cache.d.ts +0 -45
  346. package/dist/src/acp/control-plane/runtime-cache.js +0 -58
  347. package/dist/src/acp/control-plane/runtime-cache.js.map +0 -1
  348. package/dist/src/acp/control-plane/runtime-options.d.ts +0 -30
  349. package/dist/src/acp/control-plane/runtime-options.js +0 -92
  350. package/dist/src/acp/control-plane/runtime-options.js.map +0 -1
  351. package/dist/src/acp/control-plane/session-actor-queue.d.ts +0 -22
  352. package/dist/src/acp/control-plane/session-actor-queue.js +0 -70
  353. package/dist/src/acp/control-plane/session-actor-queue.js.map +0 -1
  354. package/dist/src/acp/control-plane/session-lifecycle-manager.d.ts +0 -59
  355. package/dist/src/acp/control-plane/session-lifecycle-manager.js +0 -209
  356. package/dist/src/acp/control-plane/session-lifecycle-manager.js.map +0 -1
  357. package/dist/src/acp/control-plane/session-store.d.ts +0 -39
  358. package/dist/src/acp/control-plane/session-store.js +0 -149
  359. package/dist/src/acp/control-plane/session-store.js.map +0 -1
  360. package/dist/src/acp/control-plane/turn-manager.d.ts +0 -40
  361. package/dist/src/acp/control-plane/turn-manager.js +0 -134
  362. package/dist/src/acp/control-plane/turn-manager.js.map +0 -1
  363. package/dist/src/acp/event-mapper.d.ts +0 -48
  364. package/dist/src/acp/event-mapper.js +0 -94
  365. package/dist/src/acp/event-mapper.js.map +0 -1
  366. package/dist/src/acp/index.d.ts +0 -10
  367. package/dist/src/acp/index.js +0 -5
  368. package/dist/src/acp/meta.d.ts +0 -15
  369. package/dist/src/acp/meta.js +0 -36
  370. package/dist/src/acp/meta.js.map +0 -1
  371. package/dist/src/acp/routing-integration.d.ts +0 -37
  372. package/dist/src/acp/routing-integration.js +0 -58
  373. package/dist/src/acp/routing-integration.js.map +0 -1
  374. package/dist/src/acp/runtime/backends/index.d.ts +0 -4
  375. package/dist/src/acp/runtime/backends/index.js +0 -2
  376. package/dist/src/acp/runtime/backends/local.d.ts +0 -136
  377. package/dist/src/acp/runtime/backends/local.js +0 -603
  378. package/dist/src/acp/runtime/backends/local.js.map +0 -1
  379. package/dist/src/acp/runtime/error-text.d.ts +0 -16
  380. package/dist/src/acp/runtime/error-text.js +0 -40
  381. package/dist/src/acp/runtime/error-text.js.map +0 -1
  382. package/dist/src/acp/runtime/errors.d.ts +0 -31
  383. package/dist/src/acp/runtime/errors.js +0 -47
  384. package/dist/src/acp/runtime/errors.js.map +0 -1
  385. package/dist/src/acp/runtime/index.d.ts +0 -7
  386. package/dist/src/acp/runtime/index.js +0 -4
  387. package/dist/src/acp/runtime/registry.d.ts +0 -35
  388. package/dist/src/acp/runtime/registry.js +0 -85
  389. package/dist/src/acp/runtime/registry.js.map +0 -1
  390. package/dist/src/acp/runtime/session-identity.d.ts +0 -35
  391. package/dist/src/acp/runtime/session-identity.js +0 -134
  392. package/dist/src/acp/runtime/session-identity.js.map +0 -1
  393. package/dist/src/acp/runtime/types.d.ts +0 -214
  394. package/dist/src/acp/secret-file.d.ts +0 -7
  395. package/dist/src/acp/secret-file.js +0 -19
  396. package/dist/src/acp/secret-file.js.map +0 -1
  397. package/dist/src/acp/server.d.ts +0 -48
  398. package/dist/src/acp/server.js +0 -300
  399. package/dist/src/acp/server.js.map +0 -1
  400. package/dist/src/acp/session.d.ts +0 -29
  401. package/dist/src/acp/session.js +0 -30
  402. package/dist/src/acp/session.js.map +0 -1
  403. package/dist/src/acp/types.d.ts +0 -39
  404. package/dist/src/acp/types.js +0 -13
  405. package/dist/src/acp/types.js.map +0 -1
  406. package/dist/src/agent/image/describe-images.d.ts +0 -18
  407. package/dist/src/agent/image/describe-images.js +0 -19
  408. package/dist/src/agent/image/describe-images.js.map +0 -1
  409. package/dist/src/cli/commands/acp.d.ts +0 -4
  410. package/dist/src/cli/commands/acp.js +0 -200
  411. package/dist/src/cli/commands/acp.js.map +0 -1
  412. /package/dist/src/{acp/runtime/types.js → cli/commands/doctor/index.d.ts} +0 -0
@@ -0,0 +1,53 @@
1
+ import { type UpdateChannel } from './update-channels.js';
2
+ export type InstallKind = 'git' | 'package' | 'unknown';
3
+ export type NpmTagResult = {
4
+ tag: string;
5
+ version: string | null;
6
+ error?: string;
7
+ };
8
+ export type UpdateCheckResult = {
9
+ installKind: InstallKind;
10
+ root: string | null;
11
+ };
12
+ export type UpdateAvailable = {
13
+ currentVersion: string;
14
+ latestVersion: string;
15
+ channel: string;
16
+ };
17
+ /**
18
+ * Fetch the version published under a specific npm dist-tag.
19
+ * Uses the abbreviated packument endpoint: `GET /<pkg>/<tag>`.
20
+ */
21
+ export declare function fetchNpmTagVersion(params: {
22
+ tag: string;
23
+ timeoutMs?: number;
24
+ }): Promise<NpmTagResult>;
25
+ /**
26
+ * Resolve the best version for the given update channel.
27
+ * For beta channel: if the beta tag version is older than latest, return latest instead.
28
+ */
29
+ export declare function resolveNpmChannelTag(params: {
30
+ channel: UpdateChannel;
31
+ timeoutMs?: number;
32
+ }): Promise<{
33
+ tag: string;
34
+ version: string | null;
35
+ }>;
36
+ /**
37
+ * Compare two semver strings. Returns:
38
+ * -1 if a < b, 0 if equal, 1 if a > b, null if either is unparseable.
39
+ * Prerelease versions are considered older than the same version without prerelease.
40
+ */
41
+ export declare function compareSemver(a: string | null, b: string | null): number | null;
42
+ /**
43
+ * Detect whether the current process is running from a git checkout or npm-installed package.
44
+ * Checks for `.git` directory in the package root.
45
+ */
46
+ export declare function detectInstallKind(packageRoot: string): Promise<InstallKind>;
47
+ /**
48
+ * Resolve the xopc package root directory.
49
+ * Walks up from this file to find package.json with name @xopcai/xopc.
50
+ */
51
+ export declare function resolvePackageRoot(): Promise<string | null>;
52
+ /** Get the current running version from package.json. */
53
+ export declare function getCurrentVersion(): string;
@@ -0,0 +1,155 @@
1
+ import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
+ import { channelToNpmTag } from "./update-channels.js";
3
+ import { dirname, join } from "node:path";
4
+ import { access, readFile } from "node:fs/promises";
5
+ import { fileURLToPath } from "node:url";
6
+ //#region src/infra/update-check.ts
7
+ init_package_version();
8
+ const REGISTRY_BASE = "https://registry.npmjs.org";
9
+ const PACKAGE_NAME = "@xopcai/xopc";
10
+ const REGISTRY_TIMEOUT_MS = 3500;
11
+ /**
12
+ * Fetch the version published under a specific npm dist-tag.
13
+ * Uses the abbreviated packument endpoint: `GET /<pkg>/<tag>`.
14
+ */
15
+ async function fetchNpmTagVersion(params) {
16
+ const timeoutMs = params.timeoutMs ?? REGISTRY_TIMEOUT_MS;
17
+ const url = `${REGISTRY_BASE}/${encodeURIComponent(PACKAGE_NAME).replace("%40", "@")}/${encodeURIComponent(params.tag)}`;
18
+ try {
19
+ const response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
20
+ if (!response.ok) return {
21
+ tag: params.tag,
22
+ version: null,
23
+ error: `HTTP ${response.status}`
24
+ };
25
+ const json = await response.json();
26
+ const version = typeof json?.version === "string" ? json.version : null;
27
+ return {
28
+ tag: params.tag,
29
+ version
30
+ };
31
+ } catch (err) {
32
+ return {
33
+ tag: params.tag,
34
+ version: null,
35
+ error: String(err)
36
+ };
37
+ }
38
+ }
39
+ /**
40
+ * Resolve the best version for the given update channel.
41
+ * For beta channel: if the beta tag version is older than latest, return latest instead.
42
+ */
43
+ async function resolveNpmChannelTag(params) {
44
+ const channelTag = channelToNpmTag(params.channel);
45
+ const channelResult = await fetchNpmTagVersion({
46
+ tag: channelTag,
47
+ timeoutMs: params.timeoutMs
48
+ });
49
+ if (params.channel !== "beta") return {
50
+ tag: channelTag,
51
+ version: channelResult.version
52
+ };
53
+ const latestResult = await fetchNpmTagVersion({
54
+ tag: "latest",
55
+ timeoutMs: params.timeoutMs
56
+ });
57
+ if (!latestResult.version) return {
58
+ tag: channelTag,
59
+ version: channelResult.version
60
+ };
61
+ if (!channelResult.version) return {
62
+ tag: "latest",
63
+ version: latestResult.version
64
+ };
65
+ const comparison = compareSemver(channelResult.version, latestResult.version);
66
+ if (comparison !== null && comparison < 0) return {
67
+ tag: "latest",
68
+ version: latestResult.version
69
+ };
70
+ return {
71
+ tag: channelTag,
72
+ version: channelResult.version
73
+ };
74
+ }
75
+ /**
76
+ * Parse a version string into comparable numeric parts.
77
+ * Handles formats like "1.2.3", "1.2.3-beta.1".
78
+ * Returns null for unparseable strings.
79
+ */
80
+ function parseSemverParts(version) {
81
+ const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/.exec(version.trim());
82
+ if (!match) return null;
83
+ return {
84
+ major: parseInt(match[1], 10),
85
+ minor: parseInt(match[2], 10),
86
+ patch: parseInt(match[3], 10),
87
+ prerelease: match[4] ?? null
88
+ };
89
+ }
90
+ /**
91
+ * Compare two semver strings. Returns:
92
+ * -1 if a < b, 0 if equal, 1 if a > b, null if either is unparseable.
93
+ * Prerelease versions are considered older than the same version without prerelease.
94
+ */
95
+ function compareSemver(a, b) {
96
+ if (!a || !b) return null;
97
+ const parsedA = parseSemverParts(a);
98
+ const parsedB = parseSemverParts(b);
99
+ if (!parsedA || !parsedB) return null;
100
+ for (const field of [
101
+ "major",
102
+ "minor",
103
+ "patch"
104
+ ]) if (parsedA[field] !== parsedB[field]) return parsedA[field] < parsedB[field] ? -1 : 1;
105
+ if (parsedA.prerelease === null && parsedB.prerelease === null) return 0;
106
+ if (parsedA.prerelease !== null && parsedB.prerelease === null) return -1;
107
+ if (parsedA.prerelease === null && parsedB.prerelease !== null) return 1;
108
+ if (parsedA.prerelease < parsedB.prerelease) return -1;
109
+ if (parsedA.prerelease > parsedB.prerelease) return 1;
110
+ return 0;
111
+ }
112
+ /**
113
+ * Detect whether the current process is running from a git checkout or npm-installed package.
114
+ * Checks for `.git` directory in the package root.
115
+ */
116
+ async function detectInstallKind(packageRoot) {
117
+ try {
118
+ await access(join(packageRoot, ".git"));
119
+ return "git";
120
+ } catch {
121
+ try {
122
+ await access(join(packageRoot, "package.json"));
123
+ return "package";
124
+ } catch {
125
+ return "unknown";
126
+ }
127
+ }
128
+ }
129
+ /**
130
+ * Resolve the xopc package root directory.
131
+ * Walks up from this file to find package.json with name @xopcai/xopc.
132
+ */
133
+ async function resolvePackageRoot() {
134
+ let current = dirname(fileURLToPath(import.meta.url));
135
+ for (let depth = 0; depth < 20; depth++) {
136
+ const pkgPath = join(current, "package.json");
137
+ try {
138
+ const raw = await readFile(pkgPath, "utf-8");
139
+ const parsed = JSON.parse(raw);
140
+ if (typeof parsed.name === "string" && parsed.name === PACKAGE_NAME) return current;
141
+ } catch {}
142
+ const parent = dirname(current);
143
+ if (parent === current) return null;
144
+ current = parent;
145
+ }
146
+ return null;
147
+ }
148
+ /** Get the current running version from package.json. */
149
+ function getCurrentVersion() {
150
+ return PACKAGE_VERSION;
151
+ }
152
+ //#endregion
153
+ export { compareSemver, detectInstallKind, fetchNpmTagVersion, getCurrentVersion, resolveNpmChannelTag, resolvePackageRoot };
154
+
155
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","names":[],"sources":["../../../src/infra/update-check.ts"],"sourcesContent":["// src/infra/update-check.ts\n\nimport { access, readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { PACKAGE_VERSION } from '../package-version.js';\n\nimport { channelToNpmTag, type UpdateChannel } from './update-channels.js';\n\n// --- Types ---\n\nexport type InstallKind = 'git' | 'package' | 'unknown';\n\nexport type NpmTagResult = {\n tag: string;\n version: string | null;\n error?: string;\n};\n\nexport type UpdateCheckResult = {\n installKind: InstallKind;\n root: string | null;\n};\n\nexport type UpdateAvailable = {\n currentVersion: string;\n latestVersion: string;\n channel: string;\n};\n\n// --- npm Registry ---\n\nconst REGISTRY_BASE = 'https://registry.npmjs.org';\nconst PACKAGE_NAME = '@xopcai/xopc';\nconst REGISTRY_TIMEOUT_MS = 3500;\n\n/**\n * Fetch the version published under a specific npm dist-tag.\n * Uses the abbreviated packument endpoint: `GET /<pkg>/<tag>`.\n */\nexport async function fetchNpmTagVersion(params: {\n tag: string;\n timeoutMs?: number;\n}): Promise<NpmTagResult> {\n const timeoutMs = params.timeoutMs ?? REGISTRY_TIMEOUT_MS;\n const encodedName = encodeURIComponent(PACKAGE_NAME).replace('%40', '@');\n const url = `${REGISTRY_BASE}/${encodedName}/${encodeURIComponent(params.tag)}`;\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!response.ok) {\n return { tag: params.tag, version: null, error: `HTTP ${response.status}` };\n }\n const json = (await response.json()) as { version?: unknown };\n const version = typeof json?.version === 'string' ? json.version : null;\n return { tag: params.tag, version };\n } catch (err) {\n return { tag: params.tag, version: null, error: String(err) };\n }\n}\n\n/**\n * Resolve the best version for the given update channel.\n * For beta channel: if the beta tag version is older than latest, return latest instead.\n */\nexport async function resolveNpmChannelTag(params: {\n channel: UpdateChannel;\n timeoutMs?: number;\n}): Promise<{ tag: string; version: string | null }> {\n const channelTag = channelToNpmTag(params.channel);\n const channelResult = await fetchNpmTagVersion({ tag: channelTag, timeoutMs: params.timeoutMs });\n\n if (params.channel !== 'beta') {\n return { tag: channelTag, version: channelResult.version };\n }\n\n // For beta: also check latest, return whichever is newer\n const latestResult = await fetchNpmTagVersion({ tag: 'latest', timeoutMs: params.timeoutMs });\n if (!latestResult.version) {\n return { tag: channelTag, version: channelResult.version };\n }\n if (!channelResult.version) {\n return { tag: 'latest', version: latestResult.version };\n }\n const comparison = compareSemver(channelResult.version, latestResult.version);\n if (comparison !== null && comparison < 0) {\n return { tag: 'latest', version: latestResult.version };\n }\n return { tag: channelTag, version: channelResult.version };\n}\n\n// --- Semver comparison ---\n\n/**\n * Parse a version string into comparable numeric parts.\n * Handles formats like \"1.2.3\", \"1.2.3-beta.1\".\n * Returns null for unparseable strings.\n */\nfunction parseSemverParts(\n version: string,\n): { major: number; minor: number; patch: number; prerelease: string | null } | null {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-(.+))?$/.exec(version.trim());\n if (!match) return null;\n return {\n major: parseInt(match[1], 10),\n minor: parseInt(match[2], 10),\n patch: parseInt(match[3], 10),\n prerelease: match[4] ?? null,\n };\n}\n\n/**\n * Compare two semver strings. Returns:\n * -1 if a < b, 0 if equal, 1 if a > b, null if either is unparseable.\n * Prerelease versions are considered older than the same version without prerelease.\n */\nexport function compareSemver(a: string | null, b: string | null): number | null {\n if (!a || !b) return null;\n const parsedA = parseSemverParts(a);\n const parsedB = parseSemverParts(b);\n if (!parsedA || !parsedB) return null;\n\n for (const field of ['major', 'minor', 'patch'] as const) {\n if (parsedA[field] !== parsedB[field]) {\n return parsedA[field] < parsedB[field] ? -1 : 1;\n }\n }\n\n // Both have same major.minor.patch — compare prerelease\n if (parsedA.prerelease === null && parsedB.prerelease === null) return 0;\n if (parsedA.prerelease !== null && parsedB.prerelease === null) return -1; // pre < release\n if (parsedA.prerelease === null && parsedB.prerelease !== null) return 1;\n\n // Both have prerelease — lexicographic fallback\n if (parsedA.prerelease! < parsedB.prerelease!) return -1;\n if (parsedA.prerelease! > parsedB.prerelease!) return 1;\n return 0;\n}\n\n// --- Install kind detection ---\n\n/**\n * Detect whether the current process is running from a git checkout or npm-installed package.\n * Checks for `.git` directory in the package root.\n */\nexport async function detectInstallKind(packageRoot: string): Promise<InstallKind> {\n try {\n await access(join(packageRoot, '.git'));\n return 'git';\n } catch {\n // No .git directory — likely installed via npm\n try {\n await access(join(packageRoot, 'package.json'));\n return 'package';\n } catch {\n return 'unknown';\n }\n }\n}\n\n/**\n * Resolve the xopc package root directory.\n * Walks up from this file to find package.json with name @xopcai/xopc.\n */\nexport async function resolvePackageRoot(): Promise<string | null> {\n let current = dirname(fileURLToPath(import.meta.url));\n for (let depth = 0; depth < 20; depth++) {\n const pkgPath = join(current, 'package.json');\n try {\n const raw = await readFile(pkgPath, 'utf-8');\n const parsed = JSON.parse(raw) as { name?: unknown };\n if (typeof parsed.name === 'string' && parsed.name === PACKAGE_NAME) {\n return current;\n }\n } catch {\n // continue\n }\n const parent = dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n return null;\n}\n\n/** Get the current running version from package.json. */\nexport function getCurrentVersion(): string {\n return PACKAGE_VERSION;\n}\n"],"mappings":";;;;;;sBAMwD;AA2BxD,MAAM,gBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,sBAAsB;;;;;AAM5B,eAAsB,mBAAmB,QAGf;CACxB,MAAM,YAAY,OAAO,aAAa;CAEtC,MAAM,MAAM,GAAG,cAAc,GADT,mBAAmB,aAAa,CAAC,QAAQ,OAAO,IAAI,CAC5B,GAAG,mBAAmB,OAAO,IAAI;AAC7E,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,KAAK,EAChC,QAAQ,YAAY,QAAQ,UAAU,EACvC,CAAC;AACF,MAAI,CAAC,SAAS,GACZ,QAAO;GAAE,KAAK,OAAO;GAAK,SAAS;GAAM,OAAO,QAAQ,SAAS;GAAU;EAE7E,MAAM,OAAQ,MAAM,SAAS,MAAM;EACnC,MAAM,UAAU,OAAO,MAAM,YAAY,WAAW,KAAK,UAAU;AACnE,SAAO;GAAE,KAAK,OAAO;GAAK;GAAS;UAC5B,KAAK;AACZ,SAAO;GAAE,KAAK,OAAO;GAAK,SAAS;GAAM,OAAO,OAAO,IAAI;GAAE;;;;;;;AAQjE,eAAsB,qBAAqB,QAGU;CACnD,MAAM,aAAa,gBAAgB,OAAO,QAAQ;CAClD,MAAM,gBAAgB,MAAM,mBAAmB;EAAE,KAAK;EAAY,WAAW,OAAO;EAAW,CAAC;AAEhG,KAAI,OAAO,YAAY,OACrB,QAAO;EAAE,KAAK;EAAY,SAAS,cAAc;EAAS;CAI5D,MAAM,eAAe,MAAM,mBAAmB;EAAE,KAAK;EAAU,WAAW,OAAO;EAAW,CAAC;AAC7F,KAAI,CAAC,aAAa,QAChB,QAAO;EAAE,KAAK;EAAY,SAAS,cAAc;EAAS;AAE5D,KAAI,CAAC,cAAc,QACjB,QAAO;EAAE,KAAK;EAAU,SAAS,aAAa;EAAS;CAEzD,MAAM,aAAa,cAAc,cAAc,SAAS,aAAa,QAAQ;AAC7E,KAAI,eAAe,QAAQ,aAAa,EACtC,QAAO;EAAE,KAAK;EAAU,SAAS,aAAa;EAAS;AAEzD,QAAO;EAAE,KAAK;EAAY,SAAS,cAAc;EAAS;;;;;;;AAU5D,SAAS,iBACP,SACmF;CACnF,MAAM,QAAQ,oCAAoC,KAAK,QAAQ,MAAM,CAAC;AACtE,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EACL,OAAO,SAAS,MAAM,IAAI,GAAG;EAC7B,OAAO,SAAS,MAAM,IAAI,GAAG;EAC7B,OAAO,SAAS,MAAM,IAAI,GAAG;EAC7B,YAAY,MAAM,MAAM;EACzB;;;;;;;AAQH,SAAgB,cAAc,GAAkB,GAAiC;AAC/E,KAAI,CAAC,KAAK,CAAC,EAAG,QAAO;CACrB,MAAM,UAAU,iBAAiB,EAAE;CACnC,MAAM,UAAU,iBAAiB,EAAE;AACnC,KAAI,CAAC,WAAW,CAAC,QAAS,QAAO;AAEjC,MAAK,MAAM,SAAS;EAAC;EAAS;EAAS;EAAQ,CAC7C,KAAI,QAAQ,WAAW,QAAQ,OAC7B,QAAO,QAAQ,SAAS,QAAQ,SAAS,KAAK;AAKlD,KAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAM,QAAO;AACvE,KAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAM,QAAO;AACvE,KAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAM,QAAO;AAGvE,KAAI,QAAQ,aAAc,QAAQ,WAAa,QAAO;AACtD,KAAI,QAAQ,aAAc,QAAQ,WAAa,QAAO;AACtD,QAAO;;;;;;AAST,eAAsB,kBAAkB,aAA2C;AACjF,KAAI;AACF,QAAM,OAAO,KAAK,aAAa,OAAO,CAAC;AACvC,SAAO;SACD;AAEN,MAAI;AACF,SAAM,OAAO,KAAK,aAAa,eAAe,CAAC;AAC/C,UAAO;UACD;AACN,UAAO;;;;;;;;AASb,eAAsB,qBAA6C;CACjE,IAAI,UAAU,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AACrD,MAAK,IAAI,QAAQ,GAAG,QAAQ,IAAI,SAAS;EACvC,MAAM,UAAU,KAAK,SAAS,eAAe;AAC7C,MAAI;GACF,MAAM,MAAM,MAAM,SAAS,SAAS,QAAQ;GAC5C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,OAAI,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,aACrD,QAAO;UAEH;EAGR,MAAM,SAAS,QAAQ,QAAQ;AAC/B,MAAI,WAAW,QAAS,QAAO;AAC/B,YAAU;;AAEZ,QAAO;;;AAIT,SAAgB,oBAA4B;AAC1C,QAAO"}
@@ -0,0 +1,18 @@
1
+ import type { UpdateChannel } from './update-channels.js';
2
+ export type AutoUpdateResult = {
3
+ ok: boolean;
4
+ exitCode: number | null;
5
+ reason?: string;
6
+ stdout?: string;
7
+ stderr?: string;
8
+ };
9
+ /**
10
+ * Spawn a child process to execute `xopc update --yes --channel <channel> --json`.
11
+ * Uses the current runtime (process.execPath) and entry point (process.argv[1]) to
12
+ * ensure the correct Node.js version and binary path are used.
13
+ */
14
+ export declare function runAutoUpdateCommand(params: {
15
+ channel: UpdateChannel;
16
+ root?: string | null;
17
+ timeoutMs?: number;
18
+ }): Promise<AutoUpdateResult>;
@@ -0,0 +1,112 @@
1
+ import { join } from "node:path";
2
+ import { access } from "node:fs/promises";
3
+ import { spawn } from "node:child_process";
4
+ //#region src/infra/update-runner.ts
5
+ const AUTO_UPDATE_TIMEOUT_MS = 2700 * 1e3;
6
+ /**
7
+ * Spawn a child process to execute `xopc update --yes --channel <channel> --json`.
8
+ * Uses the current runtime (process.execPath) and entry point (process.argv[1]) to
9
+ * ensure the correct Node.js version and binary path are used.
10
+ */
11
+ async function runAutoUpdateCommand(params) {
12
+ const timeoutMs = params.timeoutMs ?? AUTO_UPDATE_TIMEOUT_MS;
13
+ const argv = await resolveUpdateCommandArgv([
14
+ "update",
15
+ "--yes",
16
+ "--channel",
17
+ params.channel,
18
+ "--json"
19
+ ], params.root ?? null);
20
+ return new Promise((resolve) => {
21
+ const child = spawn(argv[0], argv.slice(1), {
22
+ env: {
23
+ ...process.env,
24
+ XOPC_AUTO_UPDATE: "1"
25
+ },
26
+ stdio: [
27
+ "ignore",
28
+ "pipe",
29
+ "pipe"
30
+ ],
31
+ detached: false
32
+ });
33
+ let stdout = "";
34
+ let stderr = "";
35
+ const timeoutId = setTimeout(() => {
36
+ child.kill("SIGTERM");
37
+ }, timeoutMs);
38
+ const finish = (result) => {
39
+ clearTimeout(timeoutId);
40
+ resolve(result);
41
+ };
42
+ child.stdout?.on("data", (chunk) => {
43
+ stdout += chunk.toString();
44
+ if (stdout.length > 64e3) stdout = stdout.slice(-32e3);
45
+ });
46
+ child.stderr?.on("data", (chunk) => {
47
+ stderr += chunk.toString();
48
+ if (stderr.length > 64e3) stderr = stderr.slice(-32e3);
49
+ });
50
+ child.on("error", (err) => {
51
+ finish({
52
+ ok: false,
53
+ exitCode: null,
54
+ reason: String(err),
55
+ stdout,
56
+ stderr
57
+ });
58
+ });
59
+ child.on("exit", (code, signal) => {
60
+ if (signal === "SIGTERM" || code === 143) {
61
+ finish({
62
+ ok: false,
63
+ exitCode: code,
64
+ reason: "timeout",
65
+ stdout,
66
+ stderr
67
+ });
68
+ return;
69
+ }
70
+ finish({
71
+ ok: code === 0,
72
+ exitCode: code,
73
+ reason: code === 0 ? void 0 : "non-zero-exit",
74
+ stdout,
75
+ stderr
76
+ });
77
+ });
78
+ });
79
+ }
80
+ /**
81
+ * Resolve the argv array for spawning the update command.
82
+ *
83
+ * Priority:
84
+ * 1. process.execPath + process.argv[1] (current runtime + entry point)
85
+ * 2. process.execPath + known dist entry points in root
86
+ * 3. Fallback to bare `xopc` (assumes global install)
87
+ */
88
+ async function resolveUpdateCommandArgv(baseArgs, root) {
89
+ const execPath = process.execPath?.trim();
90
+ const argv1 = process.argv[1]?.trim();
91
+ if (execPath && argv1) return [
92
+ execPath,
93
+ argv1,
94
+ ...baseArgs
95
+ ];
96
+ if (execPath && root) {
97
+ const candidates = [join(root, "dist/src/cli/index.js"), join(root, "dist/index.js")];
98
+ for (const candidate of candidates) try {
99
+ await access(candidate);
100
+ return [
101
+ execPath,
102
+ candidate,
103
+ ...baseArgs
104
+ ];
105
+ } catch {}
106
+ }
107
+ return ["xopc", ...baseArgs];
108
+ }
109
+ //#endregion
110
+ export { runAutoUpdateCommand };
111
+
112
+ //# sourceMappingURL=update-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-runner.js","names":[],"sources":["../../../src/infra/update-runner.ts"],"sourcesContent":["// src/infra/update-runner.ts\n\nimport { spawn } from 'node:child_process';\nimport { access } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport type { UpdateChannel } from './update-channels.js';\n\nconst AUTO_UPDATE_TIMEOUT_MS = 45 * 60 * 1000; // 45 minutes\n\nexport type AutoUpdateResult = {\n ok: boolean;\n exitCode: number | null;\n reason?: string;\n stdout?: string;\n stderr?: string;\n};\n\n/**\n * Spawn a child process to execute `xopc update --yes --channel <channel> --json`.\n * Uses the current runtime (process.execPath) and entry point (process.argv[1]) to\n * ensure the correct Node.js version and binary path are used.\n */\nexport async function runAutoUpdateCommand(params: {\n channel: UpdateChannel;\n root?: string | null;\n timeoutMs?: number;\n}): Promise<AutoUpdateResult> {\n const timeoutMs = params.timeoutMs ?? AUTO_UPDATE_TIMEOUT_MS;\n const baseArgs = ['update', '--yes', '--channel', params.channel, '--json'];\n\n const argv = await resolveUpdateCommandArgv(baseArgs, params.root ?? null);\n\n return new Promise<AutoUpdateResult>((resolve) => {\n const child = spawn(argv[0], argv.slice(1), {\n env: {\n ...process.env,\n XOPC_AUTO_UPDATE: '1',\n },\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: false,\n });\n\n let stdout = '';\n let stderr = '';\n\n const timeoutId = setTimeout(() => {\n child.kill('SIGTERM');\n }, timeoutMs);\n\n const finish = (result: AutoUpdateResult) => {\n clearTimeout(timeoutId);\n resolve(result);\n };\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString();\n if (stdout.length > 64_000) stdout = stdout.slice(-32_000);\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n if (stderr.length > 64_000) stderr = stderr.slice(-32_000);\n });\n\n child.on('error', (err) => {\n finish({ ok: false, exitCode: null, reason: String(err), stdout, stderr });\n });\n\n child.on('exit', (code, signal) => {\n if (signal === 'SIGTERM' || code === 143) {\n finish({ ok: false, exitCode: code, reason: 'timeout', stdout, stderr });\n return;\n }\n finish({\n ok: code === 0,\n exitCode: code,\n reason: code === 0 ? undefined : 'non-zero-exit',\n stdout,\n stderr,\n });\n });\n });\n}\n\n/**\n * Resolve the argv array for spawning the update command.\n *\n * Priority:\n * 1. process.execPath + process.argv[1] (current runtime + entry point)\n * 2. process.execPath + known dist entry points in root\n * 3. Fallback to bare `xopc` (assumes global install)\n */\nasync function resolveUpdateCommandArgv(\n baseArgs: string[],\n root: string | null,\n): Promise<string[]> {\n const execPath = process.execPath?.trim();\n const argv1 = process.argv[1]?.trim();\n\n // Best case: we know both the runtime and the entry point\n if (execPath && argv1) {\n return [execPath, argv1, ...baseArgs];\n }\n\n // Try known entry points in the package root\n if (execPath && root) {\n const candidates = [join(root, 'dist/src/cli/index.js'), join(root, 'dist/index.js')];\n for (const candidate of candidates) {\n try {\n await access(candidate);\n return [execPath, candidate, ...baseArgs];\n } catch {\n // try next\n }\n }\n }\n\n // Fallback: rely on global PATH\n return ['xopc', ...baseArgs];\n}\n"],"mappings":";;;;AAQA,MAAM,yBAAyB,OAAU;;;;;;AAezC,eAAsB,qBAAqB,QAIb;CAC5B,MAAM,YAAY,OAAO,aAAa;CAGtC,MAAM,OAAO,MAAM,yBAFF;EAAC;EAAU;EAAS;EAAa,OAAO;EAAS;EAAS,EAErB,OAAO,QAAQ,KAAK;AAE1E,QAAO,IAAI,SAA2B,YAAY;EAChD,MAAM,QAAQ,MAAM,KAAK,IAAI,KAAK,MAAM,EAAE,EAAE;GAC1C,KAAK;IACH,GAAG,QAAQ;IACX,kBAAkB;IACnB;GACD,OAAO;IAAC;IAAU;IAAQ;IAAO;GACjC,UAAU;GACX,CAAC;EAEF,IAAI,SAAS;EACb,IAAI,SAAS;EAEb,MAAM,YAAY,iBAAiB;AACjC,SAAM,KAAK,UAAU;KACpB,UAAU;EAEb,MAAM,UAAU,WAA6B;AAC3C,gBAAa,UAAU;AACvB,WAAQ,OAAO;;AAGjB,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU,MAAM,UAAU;AAC1B,OAAI,OAAO,SAAS,KAAQ,UAAS,OAAO,MAAM,MAAQ;IAC1D;AACF,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU,MAAM,UAAU;AAC1B,OAAI,OAAO,SAAS,KAAQ,UAAS,OAAO,MAAM,MAAQ;IAC1D;AAEF,QAAM,GAAG,UAAU,QAAQ;AACzB,UAAO;IAAE,IAAI;IAAO,UAAU;IAAM,QAAQ,OAAO,IAAI;IAAE;IAAQ;IAAQ,CAAC;IAC1E;AAEF,QAAM,GAAG,SAAS,MAAM,WAAW;AACjC,OAAI,WAAW,aAAa,SAAS,KAAK;AACxC,WAAO;KAAE,IAAI;KAAO,UAAU;KAAM,QAAQ;KAAW;KAAQ;KAAQ,CAAC;AACxE;;AAEF,UAAO;IACL,IAAI,SAAS;IACb,UAAU;IACV,QAAQ,SAAS,IAAI,KAAA,IAAY;IACjC;IACA;IACD,CAAC;IACF;GACF;;;;;;;;;;AAWJ,eAAe,yBACb,UACA,MACmB;CACnB,MAAM,WAAW,QAAQ,UAAU,MAAM;CACzC,MAAM,QAAQ,QAAQ,KAAK,IAAI,MAAM;AAGrC,KAAI,YAAY,MACd,QAAO;EAAC;EAAU;EAAO,GAAG;EAAS;AAIvC,KAAI,YAAY,MAAM;EACpB,MAAM,aAAa,CAAC,KAAK,MAAM,wBAAwB,EAAE,KAAK,MAAM,gBAAgB,CAAC;AACrF,OAAK,MAAM,aAAa,WACtB,KAAI;AACF,SAAM,OAAO,UAAU;AACvB,UAAO;IAAC;IAAU;IAAW,GAAG;IAAS;UACnC;;AAOZ,QAAO,CAAC,QAAQ,GAAG,SAAS"}
@@ -0,0 +1,20 @@
1
+ import type { Config } from '../config/schema.js';
2
+ import { type UpdateAvailable } from './update-check.js';
3
+ /** Get the cached update-available state (populated after startup check). */
4
+ export declare function getUpdateAvailable(): UpdateAvailable | null;
5
+ /**
6
+ * Main startup update check. Called once when the gateway starts (or on demand).
7
+ */
8
+ export declare function runGatewayUpdateCheck(params: {
9
+ config: Config;
10
+ onUpdateAvailableChange?: (update: UpdateAvailable | null) => void;
11
+ /** When true, bypass checkOnStart/auto-disabled early exit and throttle (for POST /api/update/check). */
12
+ force?: boolean;
13
+ }): Promise<void>;
14
+ /**
15
+ * Schedule periodic update checks. Returns a cleanup function to stop the timer.
16
+ */
17
+ export declare function scheduleGatewayUpdateCheck(params: {
18
+ config: Config;
19
+ onUpdateAvailableChange?: (update: UpdateAvailable | null) => void;
20
+ }): () => void;
@@ -0,0 +1,246 @@
1
+ import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
+ import { createLogger } from "../utils/logger/index.js";
3
+ import { init_logger } from "../utils/logger.js";
4
+ import { resolveStateDir } from "../config/paths-state.js";
5
+ import { init_paths } from "../config/paths.js";
6
+ import { normalizeUpdateChannel } from "./update-channels.js";
7
+ import { compareSemver, detectInstallKind, resolveNpmChannelTag, resolvePackageRoot } from "./update-check.js";
8
+ import { dirname, join } from "node:path";
9
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
10
+ import { createHash, randomUUID } from "node:crypto";
11
+ //#region src/infra/update-startup.ts
12
+ init_paths();
13
+ init_package_version();
14
+ init_logger();
15
+ const log = createLogger("UpdateCheck");
16
+ const UPDATE_CHECK_FILENAME = "update-check.json";
17
+ const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
18
+ const ONE_HOUR_MS = 3600 * 1e3;
19
+ let updateAvailableCache = null;
20
+ /** Get the cached update-available state (populated after startup check). */
21
+ function getUpdateAvailable() {
22
+ return updateAvailableCache;
23
+ }
24
+ async function readState(statePath) {
25
+ try {
26
+ const raw = await readFile(statePath, "utf-8");
27
+ const parsed = JSON.parse(raw);
28
+ return parsed && typeof parsed === "object" ? parsed : {};
29
+ } catch {
30
+ return {};
31
+ }
32
+ }
33
+ async function writeState(statePath, state) {
34
+ await mkdir(dirname(statePath), { recursive: true });
35
+ await writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
36
+ }
37
+ function resolveCheckIntervalMs(config) {
38
+ const auto = config.update?.auto;
39
+ if (!auto?.enabled) return CHECK_INTERVAL_MS;
40
+ if ((normalizeUpdateChannel(config.update?.channel) ?? "stable") === "beta") {
41
+ const hours = auto.betaCheckIntervalHours ?? 1;
42
+ return Math.max(ONE_HOUR_MS / 4, Math.floor(hours * ONE_HOUR_MS));
43
+ }
44
+ return ONE_HOUR_MS;
45
+ }
46
+ /**
47
+ * Compute a deterministic delay for stable auto-update rollout,
48
+ * based on a per-installation hash to spread updates over time.
49
+ */
50
+ function resolveStableJitterMs(installId, version, tag, jitterWindowMs) {
51
+ if (jitterWindowMs <= 0) return 0;
52
+ return createHash("sha256").update(`${installId}:${version}:${tag}`).digest().readUInt32BE(0) % (Math.floor(jitterWindowMs) + 1);
53
+ }
54
+ /**
55
+ * Main startup update check. Called once when the gateway starts (or on demand).
56
+ */
57
+ async function runGatewayUpdateCheck(params) {
58
+ const { config, force } = params;
59
+ const autoEnabled = config.update?.auto?.enabled ?? false;
60
+ const shouldCheckHints = config.update?.checkOnStart !== false;
61
+ if (!force && !shouldCheckHints && !autoEnabled) return;
62
+ const statePath = join(resolveStateDir(), UPDATE_CHECK_FILENAME);
63
+ const state = await readState(statePath);
64
+ const now = Date.now();
65
+ const lastCheckedAt = state.lastCheckedAt ? Date.parse(state.lastCheckedAt) : null;
66
+ if (state.lastAvailableVersion && (shouldCheckHints || force)) {
67
+ const comparison = compareSemver(PACKAGE_VERSION, state.lastAvailableVersion);
68
+ if (comparison !== null && comparison < 0) {
69
+ const cached = {
70
+ currentVersion: PACKAGE_VERSION,
71
+ latestVersion: state.lastAvailableVersion,
72
+ channel: state.lastAvailableTag ?? "latest"
73
+ };
74
+ updateAvailableCache = cached;
75
+ params.onUpdateAvailableChange?.(cached);
76
+ }
77
+ }
78
+ const checkIntervalMs = resolveCheckIntervalMs(config);
79
+ const shouldBypassThrottleForVersion = state.lastCheckPackageVersion === void 0 || state.lastCheckPackageVersion !== PACKAGE_VERSION;
80
+ if (!force && !shouldBypassThrottleForVersion && lastCheckedAt && Number.isFinite(lastCheckedAt) && now - lastCheckedAt < checkIntervalMs) return;
81
+ const root = await resolvePackageRoot();
82
+ let installKind = "unknown";
83
+ if (root) {
84
+ installKind = await detectInstallKind(root);
85
+ if (installKind === "git") log.info("Update check: git checkout (hint-only; use git pull to update, no auto npm install)");
86
+ }
87
+ const channel = normalizeUpdateChannel(config.update?.channel) ?? "stable";
88
+ const resolved = await resolveNpmChannelTag({
89
+ channel,
90
+ timeoutMs: 2500
91
+ });
92
+ const nextState = {
93
+ ...state,
94
+ lastCheckedAt: new Date(now).toISOString()
95
+ };
96
+ if (!resolved.version) {
97
+ nextState.lastCheckPackageVersion = PACKAGE_VERSION;
98
+ await writeState(statePath, nextState);
99
+ return;
100
+ }
101
+ const comparison = compareSemver(PACKAGE_VERSION, resolved.version);
102
+ if (comparison !== null && comparison < 0) {
103
+ const updateInfo = {
104
+ currentVersion: PACKAGE_VERSION,
105
+ latestVersion: resolved.version,
106
+ channel: resolved.tag
107
+ };
108
+ if (shouldCheckHints || force) {
109
+ updateAvailableCache = updateInfo;
110
+ params.onUpdateAvailableChange?.(updateInfo);
111
+ }
112
+ nextState.lastAvailableVersion = resolved.version;
113
+ nextState.lastAvailableTag = resolved.tag;
114
+ const shouldNotify = state.lastNotifiedVersion !== resolved.version || state.lastNotifiedTag !== resolved.tag;
115
+ if ((shouldCheckHints || force) && shouldNotify) {
116
+ log.info({
117
+ currentVersion: PACKAGE_VERSION,
118
+ latestVersion: resolved.version,
119
+ tag: resolved.tag
120
+ }, `Update available (${resolved.tag}): v${resolved.version} (current v${PACKAGE_VERSION}). Run: xopc update`);
121
+ nextState.lastNotifiedVersion = resolved.version;
122
+ nextState.lastNotifiedTag = resolved.tag;
123
+ }
124
+ if (autoEnabled && (channel === "stable" || channel === "beta") && installKind !== "git") await handleAutoUpdate({
125
+ channel,
126
+ version: resolved.version,
127
+ tag: resolved.tag,
128
+ state,
129
+ nextState,
130
+ now,
131
+ root,
132
+ config
133
+ });
134
+ } else {
135
+ delete nextState.lastAvailableVersion;
136
+ delete nextState.lastAvailableTag;
137
+ updateAvailableCache = null;
138
+ params.onUpdateAvailableChange?.(null);
139
+ }
140
+ nextState.lastCheckPackageVersion = PACKAGE_VERSION;
141
+ await writeState(statePath, nextState);
142
+ }
143
+ async function handleAutoUpdate(params) {
144
+ const { channel, version, tag, state, nextState, now, root, config } = params;
145
+ const auto = config.update?.auto;
146
+ if (!auto) return;
147
+ const stableDelayHours = auto.stableDelayHours ?? 6;
148
+ const stableJitterHours = auto.stableJitterHours ?? 12;
149
+ const betaCheckIntervalHours = auto.betaCheckIntervalHours ?? 1;
150
+ const attemptIntervalMs = channel === "beta" ? Math.max(ONE_HOUR_MS / 4, Math.floor(betaCheckIntervalHours * ONE_HOUR_MS)) : ONE_HOUR_MS;
151
+ const lastAttemptAt = state.autoLastAttemptAt ? Date.parse(state.autoLastAttemptAt) : null;
152
+ if (state.autoLastAttemptVersion === version && lastAttemptAt !== null && Number.isFinite(lastAttemptAt) && now - lastAttemptAt < attemptIntervalMs) {
153
+ log.info({
154
+ version,
155
+ tag
156
+ }, "Auto-update deferred: recent attempt exists");
157
+ return;
158
+ }
159
+ if (channel === "stable") {
160
+ if (!nextState.autoInstallId) nextState.autoInstallId = state.autoInstallId?.trim() || randomUUID();
161
+ if (state.autoFirstSeenVersion !== version || state.autoFirstSeenTag !== tag) {
162
+ nextState.autoFirstSeenVersion = version;
163
+ nextState.autoFirstSeenTag = tag;
164
+ nextState.autoFirstSeenAt = new Date(now).toISOString();
165
+ } else nextState.autoFirstSeenAt = state.autoFirstSeenAt;
166
+ const firstSeenMs = nextState.autoFirstSeenAt ? Date.parse(nextState.autoFirstSeenAt) : now;
167
+ const baseDelayMs = Math.max(0, stableDelayHours) * ONE_HOUR_MS;
168
+ const jitterWindowMs = Math.max(0, stableJitterHours) * ONE_HOUR_MS;
169
+ const jitterMs = resolveStableJitterMs(nextState.autoInstallId, version, tag, jitterWindowMs);
170
+ const applyAfterMs = firstSeenMs + baseDelayMs + jitterMs;
171
+ if (now < applyAfterMs) {
172
+ log.info({
173
+ version,
174
+ tag,
175
+ applyAfter: new Date(applyAfterMs).toISOString()
176
+ }, "Auto-update deferred: stable rollout window not yet due");
177
+ return;
178
+ }
179
+ }
180
+ nextState.autoLastAttemptVersion = version;
181
+ nextState.autoLastAttemptAt = new Date(now).toISOString();
182
+ log.info({
183
+ channel,
184
+ version,
185
+ tag
186
+ }, "Starting auto-update");
187
+ try {
188
+ const { runAutoUpdateCommand } = await import("./update-runner.js");
189
+ const result = await runAutoUpdateCommand({
190
+ channel,
191
+ root
192
+ });
193
+ if (result.ok) {
194
+ nextState.autoLastSuccessVersion = version;
195
+ nextState.autoLastSuccessAt = new Date(now).toISOString();
196
+ log.info({
197
+ channel,
198
+ version,
199
+ tag
200
+ }, "Auto-update applied successfully");
201
+ } else log.warn({
202
+ channel,
203
+ version,
204
+ tag,
205
+ exitCode: result.exitCode,
206
+ reason: result.reason
207
+ }, `Auto-update attempt failed: ${result.reason ?? `exit ${result.exitCode}`}`);
208
+ } catch (err) {
209
+ log.error({
210
+ err,
211
+ channel,
212
+ version
213
+ }, "Auto-update command threw");
214
+ }
215
+ }
216
+ /**
217
+ * Schedule periodic update checks. Returns a cleanup function to stop the timer.
218
+ */
219
+ function scheduleGatewayUpdateCheck(params) {
220
+ let stopped = false;
221
+ let timer = null;
222
+ const tick = async () => {
223
+ if (stopped) return;
224
+ try {
225
+ await runGatewayUpdateCheck(params);
226
+ } catch (err) {
227
+ log.warn({ err }, "Periodic update check failed");
228
+ }
229
+ if (!stopped) {
230
+ const intervalMs = resolveCheckIntervalMs(params.config);
231
+ timer = setTimeout(() => void tick(), intervalMs);
232
+ }
233
+ };
234
+ timer = setTimeout(() => void tick(), 5e3);
235
+ return () => {
236
+ stopped = true;
237
+ if (timer) {
238
+ clearTimeout(timer);
239
+ timer = null;
240
+ }
241
+ };
242
+ }
243
+ //#endregion
244
+ export { getUpdateAvailable, runGatewayUpdateCheck, scheduleGatewayUpdateCheck };
245
+
246
+ //# sourceMappingURL=update-startup.js.map