@xopcai/xopc 0.0.88 → 0.0.90

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 (275) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +8 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +222 -0
  6. package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +1 -0
  7. package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +1 -0
  8. package/dist/gateway/static/root/assets/{channels-status-swr-DIsl75Y3.js → channels-status-swr-BrtH2VzC.js} +1 -1
  9. package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +1 -0
  10. package/dist/gateway/static/root/assets/cron-api-CyqbgfHM.js +1 -0
  11. package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +2 -0
  12. package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +1 -0
  13. package/dist/gateway/static/root/assets/dist-BpAiK86n.js +1 -0
  14. package/dist/gateway/static/root/assets/{extension-debug-page-BVJohZoZ.js → extension-debug-page-D6Ak0STa.js} +1 -1
  15. package/dist/gateway/static/root/assets/{extension-page-BT2tmElC.js → extension-page-Q0P3d6DW.js} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-settings-page-BSS47c2j.js → extension-settings-page-CL55LwU_.js} +1 -1
  17. package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +1 -0
  18. package/dist/gateway/static/root/assets/{fetch-BaFNUtkE.js → fetch-Dqa9iTWl.js} +1 -1
  19. package/dist/gateway/static/root/assets/{field-primitives-QwYEq6Hz.js → field-primitives-HUR6JElP.js} +1 -1
  20. package/dist/gateway/static/root/assets/{heartbeat-config-api-BVSidEDJ.js → heartbeat-config-api-DusckjUX.js} +1 -1
  21. package/dist/gateway/static/root/assets/{index-qNrVJp-y.js → index-BYcGfwcE.js} +97 -97
  22. package/dist/gateway/static/root/assets/index-V7MQ7834.css +1 -0
  23. package/dist/gateway/static/root/assets/{logs-page-DDonPVLn.js → logs-page-_HcZ2fgK.js} +1 -1
  24. package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +1 -0
  25. package/dist/gateway/static/root/assets/{settings-form-section-B8N3A3Zo.js → settings-form-section-a0qGVOlr.js} +1 -1
  26. package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +3 -0
  27. package/dist/gateway/static/root/assets/{share-preview-page-Q7KqkO-u.js → share-preview-page-DExl7CJy.js} +1 -1
  28. package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +2 -0
  29. package/dist/gateway/static/root/assets/{theme-store-BbRc5ugR.js → theme-store-C0Ehmdo5.js} +1 -1
  30. package/dist/gateway/static/root/assets/url-fxyYANfA.js +3 -0
  31. package/dist/gateway/static/root/assets/{utils-CxDGduqK.js → utils-DRQryzdn.js} +1 -1
  32. package/dist/gateway/static/root/assets/voice-api-key-field-D0viACE2.js +1 -0
  33. package/dist/gateway/static/root/assets/workflow-page.utils-DnG8JBhV.js +1 -0
  34. package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +27 -0
  35. package/dist/gateway/static/root/index.html +7 -6
  36. package/dist/package.js +1 -1
  37. package/dist/src/agent/agent-manager.d.ts +2 -0
  38. package/dist/src/agent/agent-manager.js +1 -0
  39. package/dist/src/agent/agent-manager.js.map +1 -1
  40. package/dist/src/agent/service.js +2 -1
  41. package/dist/src/agent/service.js.map +1 -1
  42. package/dist/src/agent/service.types.d.ts +3 -1
  43. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +20 -18
  44. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  45. package/dist/src/agent/tools/cronjob-tool.d.ts +6 -0
  46. package/dist/src/agent/tools/cronjob-tool.js +76 -10
  47. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  48. package/dist/src/agent/tools/edit.d.ts +5 -1
  49. package/dist/src/agent/tools/edit.js +7 -5
  50. package/dist/src/agent/tools/edit.js.map +1 -1
  51. package/dist/src/agent/tools/factory.d.ts +3 -0
  52. package/dist/src/agent/tools/factory.js +4 -25
  53. package/dist/src/agent/tools/factory.js.map +1 -1
  54. package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
  55. package/dist/src/agent/tools/workflow-tool.js +60 -260
  56. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  57. package/dist/src/agent/tools/write.d.ts +5 -1
  58. package/dist/src/agent/tools/write.js +7 -5
  59. package/dist/src/agent/tools/write.js.map +1 -1
  60. package/dist/src/agent/workflow/agent-progress.js +2 -0
  61. package/dist/src/agent/workflow/agent-progress.js.map +1 -1
  62. package/dist/src/agent/workflow/builtins/client-proposal.d.ts +12 -0
  63. package/dist/src/agent/workflow/builtins/client-proposal.js +155 -0
  64. package/dist/src/agent/workflow/builtins/client-proposal.js.map +1 -0
  65. package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +12 -0
  66. package/dist/src/agent/workflow/builtins/competitor-scan.js +150 -0
  67. package/dist/src/agent/workflow/builtins/competitor-scan.js.map +1 -0
  68. package/dist/src/agent/workflow/builtins/content-draft.d.ts +13 -0
  69. package/dist/src/agent/workflow/builtins/content-draft.js +146 -0
  70. package/dist/src/agent/workflow/builtins/content-draft.js.map +1 -0
  71. package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +11 -0
  72. package/dist/src/agent/workflow/builtins/content-repurpose.js +137 -0
  73. package/dist/src/agent/workflow/builtins/content-repurpose.js.map +1 -0
  74. package/dist/src/agent/workflow/builtins/decision-compare.d.ts +13 -0
  75. package/dist/src/agent/workflow/builtins/decision-compare.js +173 -0
  76. package/dist/src/agent/workflow/builtins/decision-compare.js.map +1 -0
  77. package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +11 -0
  78. package/dist/src/agent/workflow/builtins/inbox-triage.js +148 -0
  79. package/dist/src/agent/workflow/builtins/inbox-triage.js.map +1 -0
  80. package/dist/src/agent/workflow/builtins/index.d.ts +10 -1
  81. package/dist/src/agent/workflow/builtins/index.js +46 -1
  82. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  83. package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +12 -0
  84. package/dist/src/agent/workflow/builtins/meeting-prep.js +144 -0
  85. package/dist/src/agent/workflow/builtins/meeting-prep.js.map +1 -0
  86. package/dist/src/agent/workflow/builtins/offer-design.d.ts +12 -0
  87. package/dist/src/agent/workflow/builtins/offer-design.js +161 -0
  88. package/dist/src/agent/workflow/builtins/offer-design.js.map +1 -0
  89. package/dist/src/agent/workflow/builtins/weekly-review.d.ts +12 -0
  90. package/dist/src/agent/workflow/builtins/weekly-review.js +131 -0
  91. package/dist/src/agent/workflow/builtins/weekly-review.js.map +1 -0
  92. package/dist/src/agent/workflow/step-labels.js +2 -2
  93. package/dist/src/agent/workflow/step-labels.js.map +1 -1
  94. package/dist/src/agent/workflow/subagent-runner.js +3 -1
  95. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  96. package/dist/src/agent/workflow/types.d.ts +4 -0
  97. package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
  98. package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
  99. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
  100. package/dist/src/auth/credentials.d.ts +14 -2
  101. package/dist/src/auth/credentials.js +38 -13
  102. package/dist/src/auth/credentials.js.map +1 -1
  103. package/dist/src/auth/oauth/types.d.ts +16 -0
  104. package/dist/src/chat-commands/agent-edit.d.ts +4 -0
  105. package/dist/src/chat-commands/agent-edit.js +136 -0
  106. package/dist/src/chat-commands/agent-edit.js.map +1 -0
  107. package/dist/src/chat-commands/index.d.ts +1 -0
  108. package/dist/src/chat-commands/index.js +3 -1
  109. package/dist/src/chat-commands/index.js.map +1 -1
  110. package/dist/src/cli/bin.js +2 -0
  111. package/dist/src/cli/bin.js.map +1 -1
  112. package/dist/src/cli/commands/auth.js +6 -0
  113. package/dist/src/cli/commands/auth.js.map +1 -1
  114. package/dist/src/cli/commands/cron.js +42 -3
  115. package/dist/src/cli/commands/cron.js.map +1 -1
  116. package/dist/src/cli/commands/doctor/checks/session-integrity.js +79 -56
  117. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  118. package/dist/src/cli/commands/onboard/model.js +6 -0
  119. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  120. package/dist/src/cli/commands/update.js +86 -79
  121. package/dist/src/cli/commands/update.js.map +1 -1
  122. package/dist/src/commands/agents.config.d.ts +3 -2
  123. package/dist/src/commands/agents.config.js +5 -2
  124. package/dist/src/commands/agents.config.js.map +1 -1
  125. package/dist/src/config/agent-typed-models.d.ts +2 -7
  126. package/dist/src/config/agent-typed-models.js +3 -14
  127. package/dist/src/config/agent-typed-models.js.map +1 -1
  128. package/dist/src/config/localized-text.d.ts +6 -0
  129. package/dist/src/config/localized-text.js +42 -0
  130. package/dist/src/config/localized-text.js.map +1 -0
  131. package/dist/src/config/models-json.d.ts +6 -6
  132. package/dist/src/config/schema.d.ts +6 -21
  133. package/dist/src/config/schema.js +4 -4
  134. package/dist/src/config/schema.js.map +1 -1
  135. package/dist/src/cron/executor.d.ts +4 -0
  136. package/dist/src/cron/executor.js +169 -5
  137. package/dist/src/cron/executor.js.map +1 -1
  138. package/dist/src/cron/job-content.js +2 -1
  139. package/dist/src/cron/job-content.js.map +1 -1
  140. package/dist/src/cron/types.d.ts +28 -1
  141. package/dist/src/cron/validation.d.ts +80 -0
  142. package/dist/src/cron/validation.js +30 -4
  143. package/dist/src/cron/validation.js.map +1 -1
  144. package/dist/src/cron/workflow-run-completion.d.ts +23 -0
  145. package/dist/src/cron/workflow-run-completion.js +72 -0
  146. package/dist/src/cron/workflow-run-completion.js.map +1 -0
  147. package/dist/src/extensions/update.d.ts +51 -0
  148. package/dist/src/extensions/update.js +260 -0
  149. package/dist/src/extensions/update.js.map +1 -0
  150. package/dist/src/gateway/agents-admin.d.ts +15 -8
  151. package/dist/src/gateway/agents-admin.js +77 -28
  152. package/dist/src/gateway/agents-admin.js.map +1 -1
  153. package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
  154. package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
  155. package/dist/src/gateway/heartbeat/service.js +1 -1
  156. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -0
  157. package/dist/src/gateway/hono/lib/config-payload.js +2 -1
  158. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  159. package/dist/src/gateway/hono/middleware/auth.d.ts +2 -0
  160. package/dist/src/gateway/hono/middleware/auth.js +12 -7
  161. package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
  162. package/dist/src/gateway/hono/oauth-async.js +40 -15
  163. package/dist/src/gateway/hono/oauth-async.js.map +1 -1
  164. package/dist/src/gateway/hono/oauth.js +31 -6
  165. package/dist/src/gateway/hono/oauth.js.map +1 -1
  166. package/dist/src/gateway/hono/routes/agents.js +55 -12
  167. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  168. package/dist/src/gateway/hono/routes/config-patch/agents.js +1 -1
  169. package/dist/src/gateway/hono/routes/models.js +11 -5
  170. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  171. package/dist/src/gateway/hono/routes/update.js +55 -107
  172. package/dist/src/gateway/hono/routes/update.js.map +1 -1
  173. package/dist/src/gateway/hono/routes/workflows.js +72 -191
  174. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  175. package/dist/src/gateway/server.js +2 -0
  176. package/dist/src/gateway/server.js.map +1 -1
  177. package/dist/src/gateway/service.d.ts +5 -0
  178. package/dist/src/gateway/service.js +24 -3
  179. package/dist/src/gateway/service.js.map +1 -1
  180. package/dist/src/heartbeat/index.js +1 -1
  181. package/dist/src/infra/brew.d.ts +4 -0
  182. package/dist/src/infra/brew.js +20 -0
  183. package/dist/src/infra/brew.js.map +1 -0
  184. package/dist/src/infra/package-json.d.ts +2 -0
  185. package/dist/src/infra/package-json.js +23 -0
  186. package/dist/src/infra/package-json.js.map +1 -0
  187. package/dist/src/infra/package-update-steps.d.ts +35 -0
  188. package/dist/src/infra/package-update-steps.js +304 -0
  189. package/dist/src/infra/package-update-steps.js.map +1 -0
  190. package/dist/src/infra/path-env.d.ts +11 -0
  191. package/dist/src/infra/path-env.js +90 -0
  192. package/dist/src/infra/path-env.js.map +1 -0
  193. package/dist/src/infra/path-prepend.d.ts +7 -0
  194. package/dist/src/infra/path-prepend.js +44 -0
  195. package/dist/src/infra/path-prepend.js.map +1 -0
  196. package/dist/src/infra/stable-node-path.d.ts +2 -0
  197. package/dist/src/infra/stable-node-path.js +28 -0
  198. package/dist/src/infra/stable-node-path.js.map +1 -0
  199. package/dist/src/infra/update-global.d.ts +30 -23
  200. package/dist/src/infra/update-global.js +113 -64
  201. package/dist/src/infra/update-global.js.map +1 -1
  202. package/dist/src/infra/update-log.d.ts +1 -0
  203. package/dist/src/infra/update-log.js +12 -0
  204. package/dist/src/infra/update-log.js.map +1 -0
  205. package/dist/src/infra/update-restart.d.ts +20 -0
  206. package/dist/src/infra/update-restart.js +165 -0
  207. package/dist/src/infra/update-restart.js.map +1 -0
  208. package/dist/src/infra/update-runner.d.ts +89 -1
  209. package/dist/src/infra/update-runner.js +604 -173
  210. package/dist/src/infra/update-runner.js.map +1 -1
  211. package/dist/src/infra/update-startup.d.ts +3 -0
  212. package/dist/src/infra/update-startup.js +8 -4
  213. package/dist/src/infra/update-startup.js.map +1 -1
  214. package/dist/src/providers/index.d.ts +8 -0
  215. package/dist/src/providers/index.js +51 -12
  216. package/dist/src/providers/index.js.map +1 -1
  217. package/dist/src/routing/resolve-route.d.ts +3 -1
  218. package/dist/src/routing/resolve-route.js.map +1 -1
  219. package/dist/src/session/store.d.ts +5 -3
  220. package/dist/src/session/store.js +66 -20
  221. package/dist/src/session/store.js.map +1 -1
  222. package/dist/src/share/site-share-config.d.ts +3 -2
  223. package/dist/src/share/site-share-config.js.map +1 -1
  224. package/dist/src/utils/logger/stats.d.ts +1 -1
  225. package/dist/src/workflows/domain/command.d.ts +2 -1
  226. package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
  227. package/dist/src/workflows/domain/definition-utils.js +50 -0
  228. package/dist/src/workflows/domain/definition-utils.js.map +1 -0
  229. package/dist/src/workflows/domain/event.d.ts +3 -0
  230. package/dist/src/workflows/domain/index.d.ts +2 -0
  231. package/dist/src/workflows/domain/index.js +3 -1
  232. package/dist/src/workflows/domain/run.d.ts +60 -0
  233. package/dist/src/workflows/domain/run.js.map +1 -1
  234. package/dist/src/workflows/domain/validation.d.ts +19 -0
  235. package/dist/src/workflows/domain/validation.js +66 -0
  236. package/dist/src/workflows/domain/validation.js.map +1 -0
  237. package/dist/src/workflows/engine/projector.js +17 -0
  238. package/dist/src/workflows/engine/projector.js.map +1 -1
  239. package/dist/src/workflows/engine/workflow-engine.d.ts +2 -1
  240. package/dist/src/workflows/engine/workflow-engine.js +128 -0
  241. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  242. package/dist/src/workflows/index.d.ts +4 -0
  243. package/dist/src/workflows/index.js +9 -2
  244. package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
  245. package/dist/src/workflows/service/run-view-to-snapshot.js +63 -0
  246. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
  247. package/dist/src/workflows/service/workflow-run-service.d.ts +37 -0
  248. package/dist/src/workflows/service/workflow-run-service.js +282 -0
  249. package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
  250. package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
  251. package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
  252. package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
  253. package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
  254. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
  255. package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
  256. package/dist/src/workflows/service/workflow-session-key.js +21 -0
  257. package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
  258. package/dist/src/workflows/store/run-store.js +1 -0
  259. package/dist/src/workflows/store/run-store.js.map +1 -1
  260. package/package.json +1 -1
  261. package/dist/gateway/static/root/assets/agents-CRxETUZx.js +0 -222
  262. package/dist/gateway/static/root/assets/apps-page-wKWf3l57.js +0 -1
  263. package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +0 -1
  264. package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +0 -1
  265. package/dist/gateway/static/root/assets/cron-api-N9hvuRrn.js +0 -1
  266. package/dist/gateway/static/root/assets/cron-dreaming-jobs-DueM3rBz.js +0 -2
  267. package/dist/gateway/static/root/assets/cron-page-tlNGNxhP.js +0 -1
  268. package/dist/gateway/static/root/assets/dist-CJwfHYvT.js +0 -1
  269. package/dist/gateway/static/root/assets/index-CqZzHNEg.css +0 -1
  270. package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +0 -1
  271. package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +0 -3
  272. package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +0 -2
  273. package/dist/gateway/static/root/assets/url-D6jvVYIA.js +0 -7
  274. package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +0 -1
  275. package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +0 -27
@@ -1,192 +1,623 @@
1
- import { createLogger } from "../utils/logger/index.js";
2
- import { init_logger } from "../utils/logger.js";
3
- import { access, readdir, unlink } from "node:fs/promises";
4
- import { join } from "node:path";
5
- import { spawn } from "node:child_process";
1
+ import { runPostUpdateExtensionSync } from "../extensions/update.js";
2
+ import "./update-channels.js";
3
+ import { compareSemver, resolveNpmChannelTag } from "./update-check.js";
4
+ import { readPackageName, readPackageVersion } from "./package-json.js";
5
+ import { createDefaultCommandRunner, runCommandWithTimeout } from "./run-command.js";
6
+ import { XOPC_PACKAGE_NAME, cleanupGlobalRenameDirs, createGlobalInstallEnv, detectGlobalInstallManagerForRoot, resolveGlobalInstallSpec, resolveGlobalInstallTarget } from "./update-global.js";
7
+ import { runGlobalPackageUpdateSteps } from "./package-update-steps.js";
8
+ import { resolveStableNodePath } from "./stable-node-path.js";
9
+ import { trimLogTail } from "./update-log.js";
10
+ import { maybeRestartGatewayAfterUpdate } from "./update-restart.js";
11
+ import fs from "node:fs/promises";
12
+ import path from "node:path";
6
13
  //#region src/infra/update-runner.ts
7
- init_logger();
8
- const log = createLogger("UpdateRunner");
9
- const AUTO_UPDATE_TIMEOUT_MS = 2700 * 1e3;
10
- function createLineEmitter(onProgress) {
11
- let bufOut = "";
12
- let bufErr = "";
13
- const flush = (buf, source) => {
14
- const parts = buf.split("\n");
15
- const rest = parts.pop() ?? "";
16
- for (const line of parts) if (line.length) onProgress?.(line, source);
17
- return rest;
14
+ const DEFAULT_TIMEOUT_MS = 2700 * 1e3;
15
+ const MAX_LOG_CHARS = 8e3;
16
+ const CORE_PACKAGE_NAMES = new Set([XOPC_PACKAGE_NAME]);
17
+ function normalizeDir(value) {
18
+ if (!value) return null;
19
+ const trimmed = value.trim();
20
+ return trimmed ? path.resolve(trimmed) : null;
21
+ }
22
+ function resolveNodeModulesBinPackageRoot(argv1) {
23
+ const normalized = path.resolve(argv1);
24
+ const parts = normalized.split(path.sep);
25
+ const binIndex = parts.lastIndexOf(".bin");
26
+ if (binIndex <= 0 || parts[binIndex - 1] !== "node_modules") return null;
27
+ return path.join(parts.slice(0, binIndex).join(path.sep), path.basename(normalized));
28
+ }
29
+ function buildStartDirs(opts) {
30
+ const dirs = [];
31
+ const cwd = normalizeDir(opts.cwd);
32
+ if (cwd) dirs.push(cwd);
33
+ const argv1 = normalizeDir(opts.argv1);
34
+ if (argv1) {
35
+ dirs.push(path.dirname(argv1));
36
+ const packageRoot = resolveNodeModulesBinPackageRoot(argv1);
37
+ if (packageRoot) dirs.push(packageRoot);
38
+ }
39
+ const proc = normalizeDir(process.cwd());
40
+ if (proc) dirs.push(proc);
41
+ return Array.from(new Set(dirs));
42
+ }
43
+ async function resolveComparablePath(target) {
44
+ return fs.realpath(target).catch(() => path.resolve(target));
45
+ }
46
+ async function pathsReferToSameLocation(left, right) {
47
+ return await resolveComparablePath(left) === await resolveComparablePath(right);
48
+ }
49
+ async function looksLikeGitCheckout(root) {
50
+ try {
51
+ await fs.access(path.join(root, ".git"));
52
+ return true;
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+ async function resolveGitRoot(runCommand, candidates, timeoutMs) {
58
+ for (const dir of candidates) {
59
+ const res = await runCommand([
60
+ "git",
61
+ "-C",
62
+ dir,
63
+ "rev-parse",
64
+ "--show-toplevel"
65
+ ], { timeoutMs }).catch(() => null);
66
+ if (!res || res.code !== 0) continue;
67
+ const root = res.stdout.trim();
68
+ if (root) return root;
69
+ }
70
+ return null;
71
+ }
72
+ async function findPackageRoot(candidates) {
73
+ for (const dir of candidates) {
74
+ let current = dir;
75
+ for (let i = 0; i < 12; i += 1) {
76
+ const pkgPath = path.join(current, "package.json");
77
+ try {
78
+ const raw = await fs.readFile(pkgPath, "utf-8");
79
+ const name = JSON.parse(raw)?.name?.trim();
80
+ if (name && CORE_PACKAGE_NAMES.has(name)) return current;
81
+ } catch {}
82
+ const parent = path.dirname(current);
83
+ if (parent === current) break;
84
+ current = parent;
85
+ }
86
+ }
87
+ return null;
88
+ }
89
+ function mergeCommandEnvironments(baseEnv, overrideEnv) {
90
+ if (!baseEnv) return overrideEnv;
91
+ if (!overrideEnv) return baseEnv;
92
+ return {
93
+ ...baseEnv,
94
+ ...overrideEnv
18
95
  };
96
+ }
97
+ async function buildUpdateCommandRunner() {
98
+ const defaultCommandEnv = await createGlobalInstallEnv();
19
99
  return {
20
- pushStdout(chunk) {
21
- bufOut += chunk;
22
- bufOut = flush(bufOut, "stdout");
23
- },
24
- pushStderr(chunk) {
25
- bufErr += chunk;
26
- bufErr = flush(bufErr, "stderr");
27
- },
28
- flushEnd() {
29
- if (bufOut.length) onProgress?.(bufOut, "stdout");
30
- if (bufErr.length) onProgress?.(bufErr, "stderr");
100
+ defaultCommandEnv,
101
+ runCommand: async (argv, options) => {
102
+ const res = await runCommandWithTimeout(argv, {
103
+ ...options,
104
+ env: mergeCommandEnvironments(defaultCommandEnv, options.env)
105
+ });
106
+ return {
107
+ stdout: res.stdout,
108
+ stderr: res.stderr,
109
+ code: res.code
110
+ };
31
111
  }
32
112
  };
33
113
  }
34
- async function spawnUpdateCommand(params) {
35
- const timeoutMs = params.timeoutMs ?? AUTO_UPDATE_TIMEOUT_MS;
36
- const argv = await resolveUpdateCommandArgv([
37
- "update",
38
- "--yes",
39
- "--channel",
40
- params.channel,
41
- "--json"
42
- ], params.root ?? null);
43
- return new Promise((resolve) => {
44
- const child = spawn(argv[0], argv.slice(1), {
45
- env: {
46
- ...process.env,
47
- XOPC_AUTO_UPDATE: "1"
48
- },
49
- stdio: [
50
- "ignore",
51
- "pipe",
52
- "pipe"
53
- ],
54
- detached: false
114
+ async function runStep(opts) {
115
+ const { runCommand, name, argv, cwd, timeoutMs, env, progress, stepIndex, totalSteps } = opts;
116
+ const command = argv.join(" ");
117
+ const stepInfo = {
118
+ name,
119
+ command,
120
+ index: stepIndex,
121
+ total: totalSteps
122
+ };
123
+ progress?.onStepStart?.(stepInfo);
124
+ const started = Date.now();
125
+ const result = await runCommand(argv, {
126
+ cwd,
127
+ timeoutMs,
128
+ env
129
+ });
130
+ const durationMs = Date.now() - started;
131
+ const stderrTail = trimLogTail(result.stderr, MAX_LOG_CHARS);
132
+ progress?.onStepComplete?.({
133
+ ...stepInfo,
134
+ durationMs,
135
+ exitCode: result.code,
136
+ stderrTail
137
+ });
138
+ return {
139
+ name,
140
+ command,
141
+ cwd,
142
+ durationMs,
143
+ exitCode: result.code,
144
+ stdoutTail: trimLogTail(result.stdout, MAX_LOG_CHARS),
145
+ stderrTail
146
+ };
147
+ }
148
+ function toUpdateStepResult(step) {
149
+ return {
150
+ name: step.name,
151
+ command: step.command,
152
+ cwd: step.cwd,
153
+ durationMs: step.durationMs,
154
+ exitCode: step.exitCode,
155
+ stdoutTail: step.stdoutTail,
156
+ stderrTail: step.stderrTail
157
+ };
158
+ }
159
+ async function resolveUpdateInstallSurface(opts = {}) {
160
+ const { runCommand } = await buildUpdateCommandRunner();
161
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
162
+ const candidates = buildStartDirs(opts);
163
+ const pkgRoot = await findPackageRoot(candidates);
164
+ let gitRoot = await resolveGitRoot(runCommand, candidates, timeoutMs);
165
+ if (gitRoot && pkgRoot && !await pathsReferToSameLocation(gitRoot, pkgRoot)) gitRoot = null;
166
+ if (gitRoot && !pkgRoot) return {
167
+ kind: "missing",
168
+ mode: "unknown",
169
+ root: gitRoot
170
+ };
171
+ if (gitRoot && pkgRoot && await pathsReferToSameLocation(gitRoot, pkgRoot)) return {
172
+ kind: "git",
173
+ mode: "git",
174
+ root: gitRoot,
175
+ packageRoot: pkgRoot
176
+ };
177
+ if (!pkgRoot) return {
178
+ kind: "missing",
179
+ mode: "unknown"
180
+ };
181
+ const globalManager = await detectGlobalInstallManagerForRoot(runCommand, pkgRoot, timeoutMs);
182
+ if (globalManager) return {
183
+ kind: "global",
184
+ mode: globalManager,
185
+ root: pkgRoot,
186
+ packageRoot: pkgRoot
187
+ };
188
+ return {
189
+ kind: "package-root",
190
+ mode: "unknown",
191
+ root: pkgRoot,
192
+ packageRoot: pkgRoot
193
+ };
194
+ }
195
+ async function runGitUpdate(params) {
196
+ const startedAt = Date.now();
197
+ const steps = [];
198
+ const { gitRoot, runCommand, timeoutMs, progress, defaultCommandEnv } = params;
199
+ const totalSteps = 7;
200
+ let stepIndex = 0;
201
+ const step = (name, argv, cwd, env) => runStep({
202
+ runCommand,
203
+ name,
204
+ argv,
205
+ cwd,
206
+ timeoutMs,
207
+ env,
208
+ progress,
209
+ stepIndex: stepIndex++,
210
+ totalSteps
211
+ });
212
+ const beforeSha = (await runCommand([
213
+ "git",
214
+ "-C",
215
+ gitRoot,
216
+ "rev-parse",
217
+ "HEAD"
218
+ ], {
219
+ cwd: gitRoot,
220
+ timeoutMs
221
+ })).stdout.trim() || null;
222
+ const beforeVersion = await readPackageVersion(gitRoot);
223
+ const statusCheck = await step("clean check", [
224
+ "git",
225
+ "-C",
226
+ gitRoot,
227
+ "status",
228
+ "--porcelain"
229
+ ], gitRoot);
230
+ steps.push(statusCheck);
231
+ if (statusCheck.stdoutTail?.trim()) return {
232
+ status: "skipped",
233
+ mode: "git",
234
+ root: gitRoot,
235
+ reason: "dirty",
236
+ before: {
237
+ sha: beforeSha,
238
+ version: beforeVersion
239
+ },
240
+ steps,
241
+ durationMs: Date.now() - startedAt
242
+ };
243
+ const fetchStep = await step("git fetch", [
244
+ "git",
245
+ "-C",
246
+ gitRoot,
247
+ "fetch",
248
+ "--all",
249
+ "--prune",
250
+ "--tags"
251
+ ], gitRoot);
252
+ steps.push(fetchStep);
253
+ if (fetchStep.exitCode !== 0) return {
254
+ status: "error",
255
+ mode: "git",
256
+ root: gitRoot,
257
+ reason: "fetch-failed",
258
+ before: {
259
+ sha: beforeSha,
260
+ version: beforeVersion
261
+ },
262
+ steps,
263
+ durationMs: Date.now() - startedAt
264
+ };
265
+ const upstreamStep = await step("upstream check", [
266
+ "git",
267
+ "-C",
268
+ gitRoot,
269
+ "rev-parse",
270
+ "--abbrev-ref",
271
+ "--symbolic-full-name",
272
+ "@{upstream}"
273
+ ], gitRoot);
274
+ steps.push(upstreamStep);
275
+ if (upstreamStep.exitCode !== 0) return {
276
+ status: "skipped",
277
+ mode: "git",
278
+ root: gitRoot,
279
+ reason: "no-upstream",
280
+ before: {
281
+ sha: beforeSha,
282
+ version: beforeVersion
283
+ },
284
+ steps,
285
+ durationMs: Date.now() - startedAt
286
+ };
287
+ const rebaseStep = await step("git rebase", [
288
+ "git",
289
+ "-C",
290
+ gitRoot,
291
+ "rebase",
292
+ "@{upstream}"
293
+ ], gitRoot);
294
+ steps.push(rebaseStep);
295
+ if (rebaseStep.exitCode !== 0) return {
296
+ status: "error",
297
+ mode: "git",
298
+ root: gitRoot,
299
+ reason: "rebase-failed",
300
+ before: {
301
+ sha: beforeSha,
302
+ version: beforeVersion
303
+ },
304
+ steps,
305
+ durationMs: Date.now() - startedAt
306
+ };
307
+ const depsStep = await step("deps install", ["pnpm", "install"], gitRoot, defaultCommandEnv);
308
+ steps.push(depsStep);
309
+ if (depsStep.exitCode !== 0) return {
310
+ status: "error",
311
+ mode: "git",
312
+ root: gitRoot,
313
+ reason: "deps-install-failed",
314
+ before: {
315
+ sha: beforeSha,
316
+ version: beforeVersion
317
+ },
318
+ steps,
319
+ durationMs: Date.now() - startedAt
320
+ };
321
+ const buildStep = await step("build", [
322
+ "pnpm",
323
+ "run",
324
+ "build"
325
+ ], gitRoot, defaultCommandEnv);
326
+ steps.push(buildStep);
327
+ if (buildStep.exitCode !== 0) return {
328
+ status: "error",
329
+ mode: "git",
330
+ root: gitRoot,
331
+ reason: "build-failed",
332
+ before: {
333
+ sha: beforeSha,
334
+ version: beforeVersion
335
+ },
336
+ steps,
337
+ durationMs: Date.now() - startedAt
338
+ };
339
+ const doctorEntry = path.join(gitRoot, "dist/src/cli/bin.js");
340
+ if (await fs.stat(doctorEntry).then(() => true).catch(() => false)) {
341
+ const doctorStep = await step("xopc doctor", [
342
+ await resolveStableNodePath(process.execPath),
343
+ doctorEntry,
344
+ "doctor",
345
+ "--fix"
346
+ ], gitRoot, {
347
+ ...defaultCommandEnv,
348
+ XOPC_UPDATE_IN_PROGRESS: "1"
55
349
  });
56
- let stdout = "";
57
- let stderr = "";
58
- let stdoutTruncated = false;
59
- let stderrTruncated = false;
60
- const lineEmitter = createLineEmitter(params.onProgress);
61
- const timeoutId = setTimeout(() => {
62
- child.kill("SIGTERM");
63
- }, timeoutMs);
64
- const finish = (result) => {
65
- clearTimeout(timeoutId);
66
- lineEmitter.flushEnd();
67
- resolve(result);
350
+ steps.push(doctorStep);
351
+ if (doctorStep.exitCode !== 0) return {
352
+ status: "error",
353
+ mode: "git",
354
+ root: gitRoot,
355
+ reason: "doctor-failed",
356
+ before: {
357
+ sha: beforeSha,
358
+ version: beforeVersion
359
+ },
360
+ steps,
361
+ durationMs: Date.now() - startedAt
68
362
  };
69
- child.stdout?.on("data", (chunk) => {
70
- const text = chunk.toString();
71
- stdout += text;
72
- lineEmitter.pushStdout(text);
73
- if (stdout.length > 64e3) {
74
- if (!stdoutTruncated) {
75
- log.warn("Update command stdout exceeded 64KB; truncating");
76
- stdoutTruncated = true;
77
- }
78
- stdout = stdout.slice(-32e3);
79
- }
80
- });
81
- child.stderr?.on("data", (chunk) => {
82
- const text = chunk.toString();
83
- stderr += text;
84
- lineEmitter.pushStderr(text);
85
- if (stderr.length > 64e3) {
86
- if (!stderrTruncated) {
87
- log.warn("Update command stderr exceeded 64KB; truncating");
88
- stderrTruncated = true;
89
- }
90
- stderr = stderr.slice(-32e3);
91
- }
92
- });
93
- child.on("error", (err) => {
94
- log.error({ err }, `Update subprocess spawn error: ${err.message}`);
95
- finish({
96
- ok: false,
97
- exitCode: null,
98
- reason: err.message,
99
- stdout,
100
- stderr
101
- });
102
- });
103
- child.on("exit", (code, signal) => {
104
- if (signal === "SIGTERM" || code === 143) {
105
- log.warn({
106
- code,
107
- signal
108
- }, "Update subprocess timed out; attempting lock file cleanup");
109
- cleanupNpmLockFiles(params.root).catch((cleanupErr) => {
110
- log.warn({ err: cleanupErr }, "Failed to clean npm lock files after timeout");
111
- });
112
- finish({
113
- ok: false,
114
- exitCode: code,
115
- reason: "timeout",
116
- stdout,
117
- stderr
118
- });
119
- return;
120
- }
121
- finish({
122
- ok: code === 0,
123
- exitCode: code,
124
- reason: code === 0 ? void 0 : "non-zero-exit",
125
- stdout,
126
- stderr
363
+ }
364
+ const afterShaStep = await step("git rev-parse HEAD (after)", [
365
+ "git",
366
+ "-C",
367
+ gitRoot,
368
+ "rev-parse",
369
+ "HEAD"
370
+ ], gitRoot);
371
+ steps.push(afterShaStep);
372
+ const afterVersion = await readPackageVersion(gitRoot);
373
+ return {
374
+ status: "ok",
375
+ mode: "git",
376
+ root: gitRoot,
377
+ before: {
378
+ sha: beforeSha,
379
+ version: beforeVersion
380
+ },
381
+ after: {
382
+ sha: afterShaStep.stdoutTail?.trim() ?? null,
383
+ version: afterVersion
384
+ },
385
+ steps,
386
+ durationMs: Date.now() - startedAt
387
+ };
388
+ }
389
+ async function runGlobalUpdate(params) {
390
+ const startedAt = Date.now();
391
+ const beforeVersion = await readPackageVersion(params.pkgRoot);
392
+ const resolved = await resolveNpmChannelTag({
393
+ channel: params.channel,
394
+ timeoutMs: 1e4
395
+ });
396
+ if (!resolved.version) return {
397
+ status: "error",
398
+ mode: params.globalManager,
399
+ root: params.pkgRoot,
400
+ reason: "registry-unreachable",
401
+ before: { version: beforeVersion },
402
+ steps: [],
403
+ durationMs: Date.now() - startedAt
404
+ };
405
+ const comparison = compareSemver(beforeVersion ?? "0.0.0", resolved.version);
406
+ if (comparison !== null && comparison >= 0) return {
407
+ status: "skipped",
408
+ mode: params.globalManager,
409
+ root: params.pkgRoot,
410
+ reason: "up-to-date",
411
+ before: { version: beforeVersion },
412
+ after: { version: beforeVersion },
413
+ steps: [],
414
+ durationMs: Date.now() - startedAt
415
+ };
416
+ const installTarget = await resolveGlobalInstallTarget({
417
+ manager: params.globalManager,
418
+ runCommand: params.runCommand,
419
+ timeoutMs: params.timeoutMs,
420
+ pkgRoot: params.pkgRoot
421
+ });
422
+ const packageName = await readPackageName(params.pkgRoot) ?? "@xopcai/xopc";
423
+ if (installTarget.globalRoot) await cleanupGlobalRenameDirs({
424
+ globalRoot: installTarget.globalRoot,
425
+ packageName
426
+ });
427
+ const spec = resolveGlobalInstallSpec({
428
+ version: resolved.version,
429
+ env: params.defaultCommandEnv
430
+ });
431
+ let stepIndex = 0;
432
+ const packageUpdate = await runGlobalPackageUpdateSteps({
433
+ installTarget,
434
+ installSpec: spec,
435
+ packageName,
436
+ packageRoot: params.pkgRoot,
437
+ runCommand: params.runCommand,
438
+ timeoutMs: params.timeoutMs,
439
+ ...params.defaultCommandEnv === void 0 ? {} : { env: params.defaultCommandEnv },
440
+ installCwd: params.pkgRoot,
441
+ runStep: async (stepParams) => {
442
+ const result = await runStep({
443
+ runCommand: params.runCommand,
444
+ name: stepParams.name,
445
+ argv: stepParams.argv,
446
+ cwd: stepParams.cwd ?? params.pkgRoot,
447
+ timeoutMs: stepParams.timeoutMs,
448
+ env: stepParams.env,
449
+ progress: params.progress,
450
+ stepIndex: stepIndex++,
451
+ totalSteps: 3
127
452
  });
453
+ return {
454
+ name: result.name,
455
+ command: result.command,
456
+ cwd: result.cwd,
457
+ durationMs: result.durationMs,
458
+ exitCode: result.exitCode,
459
+ stdoutTail: result.stdoutTail,
460
+ stderrTail: result.stderrTail
461
+ };
462
+ }
463
+ });
464
+ const steps = packageUpdate.steps.map(toUpdateStepResult);
465
+ return {
466
+ status: packageUpdate.failedStep ? "error" : "ok",
467
+ mode: params.globalManager,
468
+ root: packageUpdate.verifiedPackageRoot ?? params.pkgRoot,
469
+ reason: packageUpdate.failedStep ? "global-install-failed" : void 0,
470
+ before: { version: beforeVersion },
471
+ after: { version: packageUpdate.afterVersion },
472
+ steps,
473
+ durationMs: Date.now() - startedAt
474
+ };
475
+ }
476
+ async function runGatewayUpdate(opts = {}) {
477
+ const startedAt = Date.now();
478
+ const { defaultCommandEnv, runCommand } = await buildUpdateCommandRunner();
479
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
480
+ const channel = opts.channel ?? "stable";
481
+ const candidates = buildStartDirs(opts);
482
+ const pkgRoot = await findPackageRoot(candidates);
483
+ let gitRoot = await resolveGitRoot(runCommand, candidates, timeoutMs);
484
+ if (!gitRoot && pkgRoot) {
485
+ const cwdRoot = normalizeDir(opts.cwd);
486
+ if (cwdRoot && await pathsReferToSameLocation(cwdRoot, pkgRoot) && await looksLikeGitCheckout(cwdRoot)) gitRoot = await resolveComparablePath(cwdRoot);
487
+ }
488
+ if (gitRoot && pkgRoot && !await pathsReferToSameLocation(gitRoot, pkgRoot)) gitRoot = null;
489
+ if (gitRoot && pkgRoot && await pathsReferToSameLocation(gitRoot, pkgRoot)) return runGitUpdate({
490
+ gitRoot,
491
+ runCommand,
492
+ timeoutMs,
493
+ progress: opts.progress,
494
+ defaultCommandEnv
495
+ });
496
+ if (!pkgRoot) return {
497
+ status: "error",
498
+ mode: "unknown",
499
+ reason: "not-xopc-root",
500
+ steps: [],
501
+ durationMs: Date.now() - startedAt
502
+ };
503
+ const globalManager = await detectGlobalInstallManagerForRoot(runCommand, pkgRoot, timeoutMs);
504
+ if (globalManager) return runGlobalUpdate({
505
+ pkgRoot,
506
+ globalManager,
507
+ channel,
508
+ runCommand,
509
+ timeoutMs,
510
+ defaultCommandEnv,
511
+ progress: opts.progress
512
+ });
513
+ return {
514
+ status: "skipped",
515
+ mode: "unknown",
516
+ root: pkgRoot,
517
+ reason: "not-global-install",
518
+ before: { version: await readPackageVersion(pkgRoot) },
519
+ steps: [],
520
+ durationMs: Date.now() - startedAt
521
+ };
522
+ }
523
+ async function runGatewayUpdateWithPostSteps(opts = {}) {
524
+ const channel = opts.channel ?? "stable";
525
+ const result = await runGatewayUpdate(opts);
526
+ if (result.status !== "ok") return result;
527
+ const postUpdate = {};
528
+ if (!opts.skipExtensionSync) {
529
+ const extensions = await runPostUpdateExtensionSync({
530
+ channel,
531
+ timeoutMs: opts.timeoutMs
128
532
  });
533
+ postUpdate.extensions = extensions;
534
+ if (extensions.status === "error") return {
535
+ ...result,
536
+ status: "error",
537
+ reason: "post-update-extensions",
538
+ postUpdate
539
+ };
540
+ }
541
+ postUpdate.restart = await maybeRestartGatewayAfterUpdate({
542
+ shouldRestart: opts.shouldRestart,
543
+ expectedVersion: result.after?.version ?? void 0,
544
+ triggerInProcessRestart: opts.triggerInProcessRestart
129
545
  });
546
+ return {
547
+ ...result,
548
+ postUpdate
549
+ };
550
+ }
551
+ function formatUpdateApiResult(result, channel) {
552
+ if (result.status === "skipped" && result.reason === "up-to-date") return {
553
+ status: "up-to-date",
554
+ currentVersion: result.before?.version ?? null,
555
+ latestVersion: result.before?.version ?? null,
556
+ channel,
557
+ mode: result.mode
558
+ };
559
+ if (result.status === "ok") return {
560
+ status: "ok",
561
+ previousVersion: result.before?.version ?? null,
562
+ installedVersion: result.after?.version ?? null,
563
+ channel,
564
+ mode: result.mode,
565
+ steps: result.steps.length,
566
+ postUpdate: result.postUpdate ?? void 0
567
+ };
568
+ const failed = result.steps.find((step) => step.exitCode !== 0);
569
+ return {
570
+ status: "error",
571
+ reason: result.reason ?? "update-failed",
572
+ mode: result.mode,
573
+ message: failed?.stderrTail ?? failed?.stdoutTail ?? result.reason,
574
+ stderrTail: failed?.stderrTail ?? void 0
575
+ };
130
576
  }
131
577
  async function runAutoUpdateCommand(params) {
132
- return spawnUpdateCommand(params);
578
+ const result = await runGatewayUpdateWithPostSteps({
579
+ channel: params.channel,
580
+ cwd: params.root ?? void 0,
581
+ argv1: process.argv[1],
582
+ timeoutMs: params.timeoutMs,
583
+ triggerInProcessRestart: params.triggerInProcessRestart
584
+ });
585
+ const payload = formatUpdateApiResult(result, params.channel);
586
+ const stdout = JSON.stringify(payload);
587
+ return {
588
+ ok: result.status === "ok" || result.status === "skipped" && result.reason === "up-to-date",
589
+ exitCode: result.status === "error" ? 1 : 0,
590
+ reason: result.reason,
591
+ stdout,
592
+ stderr: result.steps.find((s) => s.exitCode !== 0)?.stderrTail ?? void 0,
593
+ result
594
+ };
133
595
  }
134
596
  async function runAutoUpdateCommandWithProgress(params) {
135
- return spawnUpdateCommand(params);
136
- }
137
- async function cleanupNpmLockFiles(root) {
138
- if (!root) return;
139
- let entries;
140
- try {
141
- entries = await readdir(root);
142
- } catch {
143
- return;
144
- }
145
- for (const entry of entries) if (entry.startsWith(".package-lock")) try {
146
- await unlink(join(root, entry));
147
- } catch {}
148
- }
149
- /**
150
- * Resolve the argv array for spawning the update command.
151
- *
152
- * Priority:
153
- * 1. process.execPath + process.argv[1] (current runtime + entry point)
154
- * 2. process.execPath + known dist entry points in root
155
- * 3. Fallback to bare `xopc` (assumes global install)
156
- */
157
- async function resolveUpdateCommandArgv(baseArgs, root) {
158
- const execPath = process.execPath?.trim();
159
- const argv1 = process.argv[1]?.trim();
160
- if (execPath && argv1) return [
161
- execPath,
162
- argv1,
163
- ...baseArgs
164
- ];
165
- if (execPath && root) {
166
- const candidates = [join(root, "dist/src/cli/bin.js"), join(root, "dist/index.js")];
167
- for (const candidate of candidates) try {
168
- await access(candidate);
169
- return [
170
- execPath,
171
- candidate,
172
- ...baseArgs
173
- ];
174
- } catch {}
175
- }
176
- log.warn("Falling back to bare `xopc` command — version mismatch possible");
177
- try {
178
- const { execSync } = await import("node:child_process");
179
- const whichResult = execSync(process.platform === "win32" ? "where xopc" : "which xopc", {
180
- encoding: "utf-8",
181
- timeout: 3e3
182
- }).trim();
183
- if (whichResult) log.info({ resolvedPath: whichResult.split(/\r?\n/)[0]?.trim() }, "Resolved xopc via PATH");
184
- } catch {
185
- log.warn("Could not resolve `xopc` in PATH; update command may fail");
186
- }
187
- return ["xopc", ...baseArgs];
597
+ const result = await runGatewayUpdateWithPostSteps({
598
+ channel: params.channel,
599
+ cwd: params.root ?? void 0,
600
+ argv1: process.argv[1],
601
+ timeoutMs: params.timeoutMs,
602
+ triggerInProcessRestart: params.triggerInProcessRestart,
603
+ progress: {
604
+ onStepStart: (step) => void params.onProgress?.(`[${step.index + 1}/${step.total}] ${step.name}`, "stdout"),
605
+ onStepComplete: (step) => {
606
+ if (step.exitCode !== 0 && step.stderrTail) params.onProgress?.(step.stderrTail, "stderr");
607
+ }
608
+ }
609
+ });
610
+ const payload = formatUpdateApiResult(result, params.channel);
611
+ return {
612
+ ok: result.status === "ok" || result.status === "skipped" && result.reason === "up-to-date",
613
+ exitCode: result.status === "error" ? 1 : 0,
614
+ reason: result.reason,
615
+ stdout: JSON.stringify(payload),
616
+ stderr: result.steps.find((s) => s.exitCode !== 0)?.stderrTail ?? void 0,
617
+ result
618
+ };
188
619
  }
189
620
  //#endregion
190
- export { runAutoUpdateCommand, runAutoUpdateCommandWithProgress };
621
+ export { createDefaultCommandRunner, formatUpdateApiResult, resolveUpdateInstallSurface, runAutoUpdateCommand, runAutoUpdateCommandWithProgress, runGatewayUpdate, runGatewayUpdateWithPostSteps };
191
622
 
192
623
  //# sourceMappingURL=update-runner.js.map