@xopcai/xopc 0.0.86 → 0.0.88

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 (658) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/adapters/cli-login.js +3 -3
  3. package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/delivery-chat-id.d.ts +1 -1
  7. package/dist/extensions/telegram/src/delivery-chat-id.js +1 -1
  8. package/dist/extensions/telegram/src/delivery-chat-id.js.map +1 -1
  9. package/dist/extensions/telegram/src/plugin.js +1 -1
  10. package/dist/extensions/telegram/src/routing-integration.js +3 -2
  11. package/dist/extensions/telegram/src/routing-integration.js.map +1 -1
  12. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  13. package/dist/extensions/telegram/xopc.extension.json +1 -1
  14. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +2 -2
  15. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -1
  16. package/dist/extensions/weixin/src/api/api.js +3 -3
  17. package/dist/extensions/weixin/src/api/api.js.map +1 -1
  18. package/dist/extensions/weixin/src/auth/accounts.js +12 -12
  19. package/dist/extensions/weixin/src/auth/accounts.js.map +1 -1
  20. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  21. package/dist/extensions/weixin/src/delivery-to.js +2 -2
  22. package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
  23. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  24. package/dist/extensions/weixin/src/messaging/debug-mode.js +5 -5
  25. package/dist/extensions/weixin/src/messaging/debug-mode.js.map +1 -1
  26. package/dist/extensions/weixin/src/messaging/inbound.js +11 -11
  27. package/dist/extensions/weixin/src/messaging/inbound.js.map +1 -1
  28. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  29. package/dist/extensions/weixin/src/plugin.js +1 -1
  30. package/dist/extensions/weixin/src/storage/sync-buf.js +4 -4
  31. package/dist/extensions/weixin/src/storage/sync-buf.js.map +1 -1
  32. package/dist/extensions/weixin/src/workflow-progress.d.ts +1 -1
  33. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  34. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -1
  35. package/dist/gateway/static/root/assets/agents-CRxETUZx.js +222 -0
  36. package/dist/gateway/static/root/assets/{apps-page-DrfytjOb.js → apps-page-wKWf3l57.js} +1 -1
  37. package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +1 -0
  38. package/dist/gateway/static/root/assets/{channels-status-swr-Bs5kMCMI.js → channels-status-swr-DIsl75Y3.js} +1 -1
  39. package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +1 -0
  40. package/dist/gateway/static/root/assets/{cron-api-BuVcZ5zR.js → cron-api-N9hvuRrn.js} +1 -1
  41. package/dist/gateway/static/root/assets/{cron-page-BMrloeFH.js → cron-page-tlNGNxhP.js} +1 -1
  42. package/dist/gateway/static/root/assets/{dist-CKU1OOTf.js → dist-CJwfHYvT.js} +1 -1
  43. package/dist/gateway/static/root/assets/{extension-debug-page-BdW_46sN.js → extension-debug-page-BVJohZoZ.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-page-DW47KI82.js → extension-page-BT2tmElC.js} +1 -1
  45. package/dist/gateway/static/root/assets/extension-settings-page-BSS47c2j.js +1 -0
  46. package/dist/gateway/static/root/assets/{fetch-B2MYHbWg.js → fetch-BaFNUtkE.js} +1 -1
  47. package/dist/gateway/static/root/assets/{field-primitives-DPG-oJmx.js → field-primitives-QwYEq6Hz.js} +1 -1
  48. package/dist/gateway/static/root/assets/{heartbeat-config-api-C8dNts9i.js → heartbeat-config-api-BVSidEDJ.js} +1 -1
  49. package/dist/gateway/static/root/assets/index-CqZzHNEg.css +1 -0
  50. package/dist/gateway/static/root/assets/{index-BmVYculr.js → index-qNrVJp-y.js} +97 -95
  51. package/dist/gateway/static/root/assets/{logs-page-sTsVWz0X.js → logs-page-DDonPVLn.js} +1 -1
  52. package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +1 -0
  53. package/dist/gateway/static/root/assets/{settings-form-section-DuvRQW--.js → settings-form-section-B8N3A3Zo.js} +1 -1
  54. package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +3 -0
  55. package/dist/gateway/static/root/assets/{share-preview-page-BtG2kLDh.js → share-preview-page-Q7KqkO-u.js} +1 -1
  56. package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +2 -0
  57. package/dist/gateway/static/root/assets/{theme-store-DryYl3qD.js → theme-store-BbRc5ugR.js} +1 -1
  58. package/dist/gateway/static/root/assets/url-D6jvVYIA.js +7 -0
  59. package/dist/gateway/static/root/assets/{utils-BY7bU1DT.js → utils-CxDGduqK.js} +1 -1
  60. package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +1 -0
  61. package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +27 -0
  62. package/dist/gateway/static/root/index.html +6 -5
  63. package/dist/package.js +1 -1
  64. package/dist/src/agent/agent-manager.js +7 -7
  65. package/dist/src/agent/agent-scope.d.ts +4 -0
  66. package/dist/src/agent/agent-scope.js +53 -10
  67. package/dist/src/agent/agent-scope.js.map +1 -1
  68. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +2 -1
  69. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  70. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  71. package/dist/src/agent/child-agent-factory.d.ts +15 -0
  72. package/dist/src/agent/child-agent-factory.js +35 -2
  73. package/dist/src/agent/child-agent-factory.js.map +1 -1
  74. package/dist/src/agent/client-error-format.d.ts +20 -0
  75. package/dist/src/agent/client-error-format.js +97 -0
  76. package/dist/src/agent/client-error-format.js.map +1 -0
  77. package/dist/src/agent/context/workspace-seed.js +2 -2
  78. package/dist/src/agent/embedded/run-turn.js +23 -4
  79. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  80. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -1
  81. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  82. package/dist/src/agent/embedded/tool-result-truncation.js +2 -1
  83. package/dist/src/agent/embedded/tool-result-truncation.js.map +1 -1
  84. package/dist/src/agent/fallback/candidates.js +2 -2
  85. package/dist/src/agent/fallback/candidates.js.map +1 -1
  86. package/dist/src/agent/goals/goal-locale.d.ts +1 -1
  87. package/dist/src/agent/goals/goal-run-store.js +4 -4
  88. package/dist/src/agent/goals/persistent-goal-apis.d.ts +0 -2
  89. package/dist/src/agent/goals/persistent-goal-service.js +1 -2
  90. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  91. package/dist/src/agent/goals/post-turn.js +2 -2
  92. package/dist/src/agent/image/generation/normalization.js +2 -12
  93. package/dist/src/agent/image/generation/normalization.js.map +1 -1
  94. package/dist/src/agent/image/generation/provider-registry.d.ts +4 -8
  95. package/dist/src/agent/image/generation/provider-registry.js.map +1 -1
  96. package/dist/src/agent/image/generation/runtime.d.ts +2 -2
  97. package/dist/src/agent/image/generation/runtime.js.map +1 -1
  98. package/dist/src/agent/image/generation/types.d.ts +0 -18
  99. package/dist/src/agent/image/image-helpers.js +6 -1
  100. package/dist/src/agent/image/image-helpers.js.map +1 -1
  101. package/dist/src/agent/image/index.d.ts +1 -1
  102. package/dist/src/agent/image/load-image-media.js +2 -2
  103. package/dist/src/agent/inbound/inbound-loop.d.ts +5 -0
  104. package/dist/src/agent/inbound/inbound-loop.js +41 -10
  105. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  106. package/dist/src/agent/inbound/turn-dispatcher.d.ts +4 -0
  107. package/dist/src/agent/inbound/turn-dispatcher.js +7 -5
  108. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  109. package/dist/src/agent/ipc/bus.js +1 -1
  110. package/dist/src/agent/ipc/inbox.js +2 -2
  111. package/dist/src/agent/ipc/socket.js +1 -1
  112. package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -1
  113. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  114. package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
  115. package/dist/src/agent/mcp/bundle-mcp-names.js.map +1 -1
  116. package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -1
  117. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  118. package/dist/src/agent/mcp/mcp-transport-config.js +2 -1
  119. package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
  120. package/dist/src/agent/mcp/mcp-transport.js +2 -1
  121. package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
  122. package/dist/src/agent/media-generation/runtime-shared.js +2 -9
  123. package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
  124. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  125. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  126. package/dist/src/agent/memory/dreaming/events.js +1 -1
  127. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  128. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  129. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  130. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  131. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  132. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  133. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  134. package/dist/src/agent/messaging/command-handler.d.ts +6 -0
  135. package/dist/src/agent/messaging/command-handler.js +5 -0
  136. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  137. package/dist/src/agent/models/manager.js +1 -1
  138. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
  139. package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
  140. package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
  141. package/dist/src/agent/prompt/safety.d.ts +0 -7
  142. package/dist/src/agent/prompt/safety.js +1 -20
  143. package/dist/src/agent/prompt/safety.js.map +1 -1
  144. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  145. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  146. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  147. package/dist/src/agent/sandbox/path-policy.js +2 -2
  148. package/dist/src/agent/service/build-direct-message-content.js +2 -2
  149. package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
  150. package/dist/src/agent/service/direct-turn-helpers.d.ts +3 -1
  151. package/dist/src/agent/service/direct-turn-helpers.js +6 -1
  152. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  153. package/dist/src/agent/service/process-direct-one-shot.d.ts +4 -0
  154. package/dist/src/agent/service/process-direct-one-shot.js +15 -2
  155. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  156. package/dist/src/agent/service/process-direct-streaming.d.ts +4 -0
  157. package/dist/src/agent/service/process-direct-streaming.js +53 -7
  158. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  159. package/dist/src/agent/service/webchat-tts.d.ts +1 -2
  160. package/dist/src/agent/service/webchat-tts.js +2 -2
  161. package/dist/src/agent/service/webchat-tts.js.map +1 -1
  162. package/dist/src/agent/service.d.ts +8 -0
  163. package/dist/src/agent/service.js +25 -5
  164. package/dist/src/agent/service.js.map +1 -1
  165. package/dist/src/agent/session/session-inspector.js +1 -1
  166. package/dist/src/agent/skills/config.js +1 -1
  167. package/dist/src/agent/skills/hub-hash.js +2 -2
  168. package/dist/src/agent/skills/hub-lock.js +1 -1
  169. package/dist/src/agent/skills/hub-pull.js +2 -2
  170. package/dist/src/agent/skills/index.js +1 -1
  171. package/dist/src/agent/skills/managed-store.js +1 -1
  172. package/dist/src/agent/skills/scanner.js +1 -1
  173. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  174. package/dist/src/agent/skills/skill-manager.js +1 -1
  175. package/dist/src/agent/tools/create-share-tool.js +27 -20
  176. package/dist/src/agent/tools/create-share-tool.js.map +1 -1
  177. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  178. package/dist/src/agent/tools/factory.js +2 -2
  179. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  180. package/dist/src/agent/tools/index.d.ts +0 -1
  181. package/dist/src/agent/tools/index.js +4 -5
  182. package/dist/src/agent/tools/send-media.js +1 -1
  183. package/dist/src/agent/tools/shell.js +0 -13
  184. package/dist/src/agent/tools/shell.js.map +1 -1
  185. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  186. package/dist/src/agent/tools/workflow-tool.js +70 -16
  187. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  188. package/dist/src/agent/tools/write.js +1 -1
  189. package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
  190. package/dist/src/agent/workflow/agent-progress.js +65 -0
  191. package/dist/src/agent/workflow/agent-progress.js.map +1 -0
  192. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
  193. package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
  194. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
  195. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
  196. package/dist/src/agent/workflow/builtins/debug-incident.js +14 -0
  197. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
  198. package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
  199. package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
  200. package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
  201. package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
  202. package/dist/src/agent/workflow/builtins/index.js +11 -1
  203. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  204. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
  205. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +14 -0
  206. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
  207. package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
  208. package/dist/src/agent/workflow/builtins/pr-review.js +14 -0
  209. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
  210. package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
  211. package/dist/src/agent/workflow/builtins/release-check.js +165 -0
  212. package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
  213. package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
  214. package/dist/src/agent/workflow/builtins/research.js +14 -0
  215. package/dist/src/agent/workflow/builtins/research.js.map +1 -1
  216. package/dist/src/agent/workflow/catalog.js +1 -1
  217. package/dist/src/agent/workflow/channel-capability.d.ts +3 -3
  218. package/dist/src/agent/workflow/index.d.ts +2 -1
  219. package/dist/src/agent/workflow/index.js +3 -2
  220. package/dist/src/agent/workflow/lint.d.ts +38 -0
  221. package/dist/src/agent/workflow/lint.js +74 -0
  222. package/dist/src/agent/workflow/lint.js.map +1 -0
  223. package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
  224. package/dist/src/agent/workflow/meta-locale.js +62 -0
  225. package/dist/src/agent/workflow/meta-locale.js.map +1 -0
  226. package/dist/src/agent/workflow/parser.js +7 -1
  227. package/dist/src/agent/workflow/parser.js.map +1 -1
  228. package/dist/src/agent/workflow/runtime.d.ts +4 -1
  229. package/dist/src/agent/workflow/runtime.js +88 -8
  230. package/dist/src/agent/workflow/runtime.js.map +1 -1
  231. package/dist/src/agent/workflow/snapshot.js +2 -12
  232. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  233. package/dist/src/agent/workflow/step-labels.d.ts +8 -0
  234. package/dist/src/agent/workflow/step-labels.js +48 -0
  235. package/dist/src/agent/workflow/step-labels.js.map +1 -0
  236. package/dist/src/agent/workflow/subagent-runner.js +46 -1
  237. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  238. package/dist/src/agent/workflow/types.d.ts +76 -1
  239. package/dist/src/auth/credentials.d.ts +5 -0
  240. package/dist/src/auth/credentials.js +12 -3
  241. package/dist/src/auth/credentials.js.map +1 -1
  242. package/dist/src/auth/profiles/store.js +1 -1
  243. package/dist/src/auth/sync-provider-auth.js +1 -1
  244. package/dist/src/browser/cache-dir-policy.js +1 -1
  245. package/dist/src/browser/cdp-local-launcher.js +2 -2
  246. package/dist/src/browser/index.js +4 -4
  247. package/dist/src/browser/manager.d.ts +1 -3
  248. package/dist/src/browser/manager.js +0 -6
  249. package/dist/src/browser/manager.js.map +1 -1
  250. package/dist/src/browser/providers/browser-ext-install.d.ts +4 -4
  251. package/dist/src/browser/providers/browser-ext-install.js +41 -88
  252. package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
  253. package/dist/src/browser/providers/cloakbrowser.d.ts +0 -5
  254. package/dist/src/browser/providers/cloakbrowser.js +6 -59
  255. package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
  256. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  257. package/dist/src/browser/stealth.js +1 -1
  258. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  259. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  260. package/dist/src/channels/attachments/voice-stt-webchat.js +10 -8
  261. package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
  262. package/dist/src/channels/outbound/persist-store.js +1 -1
  263. package/dist/src/channels/pairing/allow-from-file.js +9 -9
  264. package/dist/src/channels/pairing/allow-from-file.js.map +1 -1
  265. package/dist/src/channels/pairing/pairing-store.js +7 -7
  266. package/dist/src/channels/pairing/pairing-store.js.map +1 -1
  267. package/dist/src/chat-commands/builtins/config.js +2 -2
  268. package/dist/src/chat-commands/builtins/session.js +1 -1
  269. package/dist/src/chat-commands/builtins/session.js.map +1 -1
  270. package/dist/src/chat-commands/builtins/tts.js +2 -2
  271. package/dist/src/chat-commands/builtins/tts.js.map +1 -1
  272. package/dist/src/chat-commands/context.d.ts +3 -0
  273. package/dist/src/chat-commands/context.js +22 -4
  274. package/dist/src/chat-commands/context.js.map +1 -1
  275. package/dist/src/chat-commands/session-key.d.ts +4 -37
  276. package/dist/src/chat-commands/session-key.js +49 -85
  277. package/dist/src/chat-commands/session-key.js.map +1 -1
  278. package/dist/src/chat-commands/types.d.ts +2 -0
  279. package/dist/src/cli/commands/agent/interactive.js +2 -2
  280. package/dist/src/cli/commands/agent/interactive.js.map +1 -1
  281. package/dist/src/cli/commands/agent/sessions.js +2 -2
  282. package/dist/src/cli/commands/agent/sessions.js.map +1 -1
  283. package/dist/src/cli/commands/agent.js +4 -5
  284. package/dist/src/cli/commands/agent.js.map +1 -1
  285. package/dist/src/cli/commands/channels.js +1 -5
  286. package/dist/src/cli/commands/channels.js.map +1 -1
  287. package/dist/src/cli/commands/config.js +1 -1
  288. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  289. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  290. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  291. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  292. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  293. package/dist/src/cli/commands/extension-dev.js +1 -1
  294. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  295. package/dist/src/cli/commands/extension-pack.js +1 -1
  296. package/dist/src/cli/commands/gateway/lifecycle-core.js +1 -1
  297. package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
  298. package/dist/src/cli/commands/gateway/logs.d.ts +9 -0
  299. package/dist/src/cli/commands/gateway/logs.js +50 -17
  300. package/dist/src/cli/commands/gateway/logs.js.map +1 -1
  301. package/dist/src/cli/commands/image.js +23 -22
  302. package/dist/src/cli/commands/image.js.map +1 -1
  303. package/dist/src/cli/commands/init.js +4 -4
  304. package/dist/src/cli/commands/onboard.js +1 -1
  305. package/dist/src/cli/commands/session/utils.js +2 -2
  306. package/dist/src/cli/commands/session/utils.js.map +1 -1
  307. package/dist/src/cli/commands/update.js +26 -46
  308. package/dist/src/cli/commands/update.js.map +1 -1
  309. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  310. package/dist/src/cli/utils/session.d.ts +0 -5
  311. package/dist/src/cli/utils/session.js +1 -6
  312. package/dist/src/cli/utils/session.js.map +1 -1
  313. package/dist/src/commands/agents.config.js +1 -1
  314. package/dist/src/commands/agents.config.js.map +1 -1
  315. package/dist/src/config/agent-profile.js +6 -28
  316. package/dist/src/config/agent-profile.js.map +1 -1
  317. package/dist/src/config/agent-typed-models.d.ts +18 -0
  318. package/dist/src/config/agent-typed-models.js +53 -0
  319. package/dist/src/config/agent-typed-models.js.map +1 -0
  320. package/dist/src/config/gateway-bind.js +1 -1
  321. package/dist/src/config/index.js +6 -6
  322. package/dist/src/config/loader.js +2 -2
  323. package/dist/src/config/model-input.js +2 -5
  324. package/dist/src/config/model-input.js.map +1 -1
  325. package/dist/src/config/models-json.js +2 -2
  326. package/dist/src/config/paths-state.js +1 -1
  327. package/dist/src/config/profile.js +2 -2
  328. package/dist/src/config/schema.d.ts +253 -217
  329. package/dist/src/config/schema.js +91 -40
  330. package/dist/src/config/schema.js.map +1 -1
  331. package/dist/src/config/voice.d.ts +3 -28
  332. package/dist/src/config/voice.js +27 -261
  333. package/dist/src/config/voice.js.map +1 -1
  334. package/dist/src/config/workspace-path-helpers.d.ts +1 -2
  335. package/dist/src/config/workspace-path-helpers.js.map +1 -1
  336. package/dist/src/config/workspace-path.js +1 -1
  337. package/dist/src/cron/executor.js +2 -2
  338. package/dist/src/cron/persistence.js +1 -1
  339. package/dist/src/cron/run-log-store.js +1 -1
  340. package/dist/src/daemon/constants.js +1 -1
  341. package/dist/src/daemon/install-plan.js +27 -3
  342. package/dist/src/daemon/install-plan.js.map +1 -1
  343. package/dist/src/daemon/launchd.d.ts +8 -0
  344. package/dist/src/daemon/launchd.js +7 -14
  345. package/dist/src/daemon/launchd.js.map +1 -1
  346. package/dist/src/daemon/schtasks.d.ts +25 -0
  347. package/dist/src/daemon/schtasks.js +168 -48
  348. package/dist/src/daemon/schtasks.js.map +1 -1
  349. package/dist/src/daemon/service.js +5 -4
  350. package/dist/src/daemon/service.js.map +1 -1
  351. package/dist/src/daemon/systemd.d.ts +6 -0
  352. package/dist/src/daemon/systemd.js +20 -5
  353. package/dist/src/daemon/systemd.js.map +1 -1
  354. package/dist/src/extensions/activation-context.js +0 -1
  355. package/dist/src/extensions/activation-context.js.map +1 -1
  356. package/dist/src/extensions/bundle-mcp.js +1 -1
  357. package/dist/src/extensions/discover-extensions.js +1 -1
  358. package/dist/src/extensions/health.js +1 -1
  359. package/dist/src/extensions/loader.js +1 -1
  360. package/dist/src/extensions/lockfile.js +2 -2
  361. package/dist/src/extensions/normalize-manifest.js +0 -1
  362. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  363. package/dist/src/extensions/types/manifest.d.ts +0 -2
  364. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  365. package/dist/src/gateway/agent-builtin-tools.js +1 -0
  366. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  367. package/dist/src/gateway/agents-admin.d.ts +9 -0
  368. package/dist/src/gateway/agents-admin.js +28 -4
  369. package/dist/src/gateway/agents-admin.js.map +1 -1
  370. package/dist/src/gateway/config-tools-web.js +3 -2
  371. package/dist/src/gateway/config-tools-web.js.map +1 -1
  372. package/dist/src/gateway/file-path-classifier.js +2 -2
  373. package/dist/src/gateway/heartbeat/service.js +2 -2
  374. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  375. package/dist/src/gateway/hono/app.js +1 -1
  376. package/dist/src/gateway/hono/lib/agent-model.d.ts +25 -10
  377. package/dist/src/gateway/hono/lib/agent-model.js +60 -36
  378. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  379. package/dist/src/gateway/hono/lib/config-payload.js +29 -6
  380. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  381. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  382. package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
  383. package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
  384. package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
  385. package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
  386. package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
  387. package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
  388. package/dist/src/gateway/hono/lib/safe-voice-config.js +16 -54
  389. package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
  390. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  391. package/dist/src/gateway/hono/oauth.js +1 -1
  392. package/dist/src/gateway/hono/routes/agents.js +2 -2
  393. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  394. package/dist/src/gateway/hono/routes/config-patch/agents.js +25 -7
  395. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  396. package/dist/src/gateway/hono/routes/config-patch/channels.js +0 -11
  397. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  398. package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
  399. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  400. package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -3
  401. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  402. package/dist/src/gateway/hono/routes/config.js +59 -0
  403. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  404. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  405. package/dist/src/gateway/hono/routes/goals.js +1 -1
  406. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  407. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  408. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  409. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  410. package/dist/src/gateway/hono/routes/models.js +75 -12
  411. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  412. package/dist/src/gateway/hono/routes/sessions.js +28 -7
  413. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  414. package/dist/src/gateway/hono/routes/shares.js +15 -13
  415. package/dist/src/gateway/hono/routes/shares.js.map +1 -1
  416. package/dist/src/gateway/hono/routes/tunnel.js +1 -1
  417. package/dist/src/gateway/hono/routes/update.js +4 -2
  418. package/dist/src/gateway/hono/routes/update.js.map +1 -1
  419. package/dist/src/gateway/hono/routes/voice.js +75 -0
  420. package/dist/src/gateway/hono/routes/voice.js.map +1 -1
  421. package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
  422. package/dist/src/gateway/hono/routes/workflows.js +347 -0
  423. package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
  424. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  425. package/dist/src/gateway/hono/sse.js +16 -33
  426. package/dist/src/gateway/hono/sse.js.map +1 -1
  427. package/dist/src/gateway/lock.js +11 -11
  428. package/dist/src/gateway/lock.js.map +1 -1
  429. package/dist/src/gateway/ports.js +6 -6
  430. package/dist/src/gateway/ports.js.map +1 -1
  431. package/dist/src/gateway/resolve-webchat-session-key.d.ts +19 -0
  432. package/dist/src/gateway/resolve-webchat-session-key.js +46 -0
  433. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -0
  434. package/dist/src/gateway/service/agent-runner.js +2 -2
  435. package/dist/src/gateway/service/marketplace-service.js +2 -2
  436. package/dist/src/gateway/service/run-gateway-agent.js +9 -11
  437. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  438. package/dist/src/gateway/service/sessions-api.d.ts +3 -0
  439. package/dist/src/gateway/service/sessions-api.js +8 -0
  440. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  441. package/dist/src/gateway/service.d.ts +3 -2
  442. package/dist/src/gateway/service.js +9 -8
  443. package/dist/src/gateway/service.js.map +1 -1
  444. package/dist/src/gateway/session-reset-service.d.ts +20 -0
  445. package/dist/src/gateway/session-reset-service.js +54 -0
  446. package/dist/src/gateway/session-reset-service.js.map +1 -0
  447. package/dist/src/gateway/startup-readiness.d.ts +1 -1
  448. package/dist/src/gateway/startup-readiness.js +1 -0
  449. package/dist/src/gateway/startup-readiness.js.map +1 -1
  450. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  451. package/dist/src/heartbeat/index.js +1 -1
  452. package/dist/src/infra/gateway-processes.js +2 -2
  453. package/dist/src/infra/gateway-processes.js.map +1 -1
  454. package/dist/src/infra/restart.js +2 -2
  455. package/dist/src/infra/run-command.d.ts +16 -0
  456. package/dist/src/infra/run-command.js +67 -0
  457. package/dist/src/infra/run-command.js.map +1 -0
  458. package/dist/src/infra/update-check.js +1 -1
  459. package/dist/src/infra/update-global.d.ts +45 -0
  460. package/dist/src/infra/update-global.js +224 -0
  461. package/dist/src/infra/update-global.js.map +1 -0
  462. package/dist/src/infra/update-lock.js +3 -3
  463. package/dist/src/infra/update-runner.js +1 -1
  464. package/dist/src/infra/update-startup.js +2 -2
  465. package/dist/src/infra/write-file-atomic.js +2 -2
  466. package/dist/src/mcp/channel-shared.js +2 -1
  467. package/dist/src/mcp/channel-shared.js.map +1 -1
  468. package/dist/src/providers/auth-runtime/auth-profile-store.js +2 -2
  469. package/dist/src/providers/auth-runtime/auth-profile-store.js.map +1 -1
  470. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -12
  471. package/dist/src/providers/auth-runtime/resolve-auth.js.map +1 -1
  472. package/dist/src/providers/auth-runtime/types.d.ts +6 -12
  473. package/dist/src/providers/index.js +2 -2
  474. package/dist/src/providers/model-registry.js +1 -1
  475. package/dist/src/routing/agent-session-key.d.ts +58 -0
  476. package/dist/src/routing/agent-session-key.js +164 -0
  477. package/dist/src/routing/agent-session-key.js.map +1 -0
  478. package/dist/src/routing/index.d.ts +1 -1
  479. package/dist/src/routing/index.js +4 -2
  480. package/dist/src/routing/index.js.map +1 -1
  481. package/dist/src/routing/resolve-route.d.ts +15 -0
  482. package/dist/src/routing/resolve-route.js +41 -20
  483. package/dist/src/routing/resolve-route.js.map +1 -1
  484. package/dist/src/routing/resolve-tui-session-key.d.ts +25 -0
  485. package/dist/src/routing/resolve-tui-session-key.js +54 -0
  486. package/dist/src/routing/resolve-tui-session-key.js.map +1 -0
  487. package/dist/src/routing/session-key-utils.d.ts +24 -0
  488. package/dist/src/routing/session-key-utils.js +92 -0
  489. package/dist/src/routing/session-key-utils.js.map +1 -0
  490. package/dist/src/routing/session-key.d.ts +19 -49
  491. package/dist/src/routing/session-key.js +143 -116
  492. package/dist/src/routing/session-key.js.map +1 -1
  493. package/dist/src/session/config-store.js +2 -2
  494. package/dist/src/session/index.d.ts +6 -0
  495. package/dist/src/session/index.js +7 -1
  496. package/dist/src/session/init-session-turn.d.ts +30 -0
  497. package/dist/src/session/init-session-turn.js +102 -0
  498. package/dist/src/session/init-session-turn.js.map +1 -0
  499. package/dist/src/session/lifecycle-timestamps.d.ts +8 -0
  500. package/dist/src/session/lifecycle-timestamps.js +16 -0
  501. package/dist/src/session/lifecycle-timestamps.js.map +1 -0
  502. package/dist/src/session/manager.d.ts +7 -1
  503. package/dist/src/session/manager.js +8 -1
  504. package/dist/src/session/manager.js.map +1 -1
  505. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  506. package/dist/src/session/parity/sessions-json-file.js +1 -1
  507. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  508. package/dist/src/session/parity/transcript-paths.js +2 -2
  509. package/dist/src/session/parity/transcript-paths.js.map +1 -1
  510. package/dist/src/session/parity/xopc-session-disk-entry.d.ts +6 -0
  511. package/dist/src/session/reset-policy.d.ts +32 -0
  512. package/dist/src/session/reset-policy.js +65 -0
  513. package/dist/src/session/reset-policy.js.map +1 -0
  514. package/dist/src/session/reset-triggers.d.ts +20 -0
  515. package/dist/src/session/reset-triggers.js +63 -0
  516. package/dist/src/session/reset-triggers.js.map +1 -0
  517. package/dist/src/session/reset-type.d.ts +12 -0
  518. package/dist/src/session/reset-type.js +25 -0
  519. package/dist/src/session/reset-type.js.map +1 -0
  520. package/dist/src/session/resolve-session.d.ts +30 -0
  521. package/dist/src/session/resolve-session.js +93 -0
  522. package/dist/src/session/resolve-session.js.map +1 -0
  523. package/dist/src/session/search-index-cache.js +1 -1
  524. package/dist/src/session/search-index.js +1 -1
  525. package/dist/src/session/session-title.js +3 -2
  526. package/dist/src/session/session-title.js.map +1 -1
  527. package/dist/src/session/store.d.ts +11 -4
  528. package/dist/src/session/store.js +62 -11
  529. package/dist/src/session/store.js.map +1 -1
  530. package/dist/src/session/transcript-events.js +2 -1
  531. package/dist/src/session/transcript-events.js.map +1 -1
  532. package/dist/src/share/share-auto.js +2 -2
  533. package/dist/src/share/share-store.js +3 -3
  534. package/dist/src/share/share-thumbnail.js +2 -2
  535. package/dist/src/share/share-url.d.ts +33 -0
  536. package/dist/src/share/share-url.js +56 -14
  537. package/dist/src/share/share-url.js.map +1 -1
  538. package/dist/src/share/share-zip.js +1 -1
  539. package/dist/src/share/site-share-store.js +3 -3
  540. package/dist/src/share/site-static-serve.js +1 -1
  541. package/dist/src/tui/backends/embedded-backend.js +4 -9
  542. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  543. package/dist/src/tui/backends/gateway-sse-backend.js +1 -1
  544. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  545. package/dist/src/tui/clipboard-image.js +3 -3
  546. package/dist/src/tui/components/chat-log.js +3 -3
  547. package/dist/src/tui/components/chat-log.js.map +1 -1
  548. package/dist/src/tui/theme-manager.js +1 -1
  549. package/dist/src/tui/theme.d.ts +0 -2
  550. package/dist/src/tui/theme.js +1 -3
  551. package/dist/src/tui/theme.js.map +1 -1
  552. package/dist/src/tui/tui-agent-events.js +2 -1
  553. package/dist/src/tui/tui-agent-events.js.map +1 -1
  554. package/dist/src/tui/tui-commands.d.ts +3 -0
  555. package/dist/src/tui/tui-commands.js +45 -10
  556. package/dist/src/tui/tui-commands.js.map +1 -1
  557. package/dist/src/tui/tui-keybindings-file.js +2 -22
  558. package/dist/src/tui/tui-keybindings-file.js.map +1 -1
  559. package/dist/src/tui/tui-scoped-models.js +2 -2
  560. package/dist/src/tui/tui-session-actions.d.ts +28 -0
  561. package/dist/src/tui/tui-session-actions.js +88 -0
  562. package/dist/src/tui/tui-session-actions.js.map +1 -0
  563. package/dist/src/tui/tui-settings.js +1 -1
  564. package/dist/src/tui/tui.js +54 -49
  565. package/dist/src/tui/tui.js.map +1 -1
  566. package/dist/src/tunnel/frpc-binary.js +3 -3
  567. package/dist/src/tunnel/frpc-config.js +1 -1
  568. package/dist/src/tunnel/frpc-extract.js +1 -1
  569. package/dist/src/tunnel/tunnel-state.js +1 -1
  570. package/dist/src/utils/logger/audit.js +1 -1
  571. package/dist/src/utils/logger/log-store.js +1 -1
  572. package/dist/src/utils/logger/rotation.js +1 -1
  573. package/dist/src/utils/string-coerce.d.ts +2 -0
  574. package/dist/src/utils/string-coerce.js +10 -1
  575. package/dist/src/utils/string-coerce.js.map +1 -1
  576. package/dist/src/voice/metadata/builtin.d.ts +2 -0
  577. package/dist/src/voice/metadata/builtin.js +420 -0
  578. package/dist/src/voice/metadata/builtin.js.map +1 -0
  579. package/dist/src/voice/metadata/index.d.ts +4 -0
  580. package/dist/src/voice/metadata/index.js +3 -0
  581. package/dist/src/voice/metadata/registry.d.ts +5 -0
  582. package/dist/src/voice/metadata/registry.js +34 -0
  583. package/dist/src/voice/metadata/registry.js.map +1 -0
  584. package/dist/src/voice/metadata/types.d.ts +41 -0
  585. package/dist/src/voice/metadata/types.js +1 -0
  586. package/dist/src/voice/stt/config-slice.d.ts +2 -5
  587. package/dist/src/voice/stt/config-slice.js +5 -26
  588. package/dist/src/voice/stt/config-slice.js.map +1 -1
  589. package/dist/src/voice/stt/list-providers.d.ts +3 -3
  590. package/dist/src/voice/stt/list-providers.js +41 -6
  591. package/dist/src/voice/stt/list-providers.js.map +1 -1
  592. package/dist/src/voice/stt/types.d.ts +1 -18
  593. package/dist/src/voice/stt/types.js +4 -2
  594. package/dist/src/voice/stt/types.js.map +1 -1
  595. package/dist/src/voice/tts/audio.js +1 -1
  596. package/dist/src/voice/tts/config-slice.d.ts +3 -7
  597. package/dist/src/voice/tts/config-slice.js +7 -38
  598. package/dist/src/voice/tts/config-slice.js.map +1 -1
  599. package/dist/src/voice/tts/list-providers.d.ts +3 -3
  600. package/dist/src/voice/tts/list-providers.js +41 -6
  601. package/dist/src/voice/tts/list-providers.js.map +1 -1
  602. package/dist/src/voice/tts/merge-config.js +2 -48
  603. package/dist/src/voice/tts/merge-config.js.map +1 -1
  604. package/dist/src/voice/tts/providers/alibaba-speech.js +1 -1
  605. package/dist/src/voice/tts/providers/alibaba-speech.js.map +1 -1
  606. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  607. package/dist/src/voice/tts/types.d.ts +1 -29
  608. package/dist/src/voice/tts/types.js +19 -17
  609. package/dist/src/voice/tts/types.js.map +1 -1
  610. package/dist/src/workflows/domain/command.d.ts +18 -0
  611. package/dist/src/workflows/domain/command.js +1 -0
  612. package/dist/src/workflows/domain/definition.d.ts +62 -0
  613. package/dist/src/workflows/domain/definition.js +1 -0
  614. package/dist/src/workflows/domain/event.d.ts +67 -0
  615. package/dist/src/workflows/domain/event.js +1 -0
  616. package/dist/src/workflows/domain/index.d.ts +5 -0
  617. package/dist/src/workflows/domain/index.js +2 -0
  618. package/dist/src/workflows/domain/result.d.ts +65 -0
  619. package/dist/src/workflows/domain/result.js +1 -0
  620. package/dist/src/workflows/domain/run.d.ts +120 -0
  621. package/dist/src/workflows/domain/run.js +14 -0
  622. package/dist/src/workflows/domain/run.js.map +1 -0
  623. package/dist/src/workflows/engine/index.d.ts +2 -0
  624. package/dist/src/workflows/engine/index.js +3 -0
  625. package/dist/src/workflows/engine/projector.d.ts +3 -0
  626. package/dist/src/workflows/engine/projector.js +205 -0
  627. package/dist/src/workflows/engine/projector.js.map +1 -0
  628. package/dist/src/workflows/engine/workflow-engine.d.ts +31 -0
  629. package/dist/src/workflows/engine/workflow-engine.js +188 -0
  630. package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
  631. package/dist/src/workflows/index.d.ts +6 -0
  632. package/dist/src/workflows/index.js +11 -0
  633. package/dist/src/workflows/runtime/index.d.ts +1 -0
  634. package/dist/src/workflows/runtime/index.js +4 -0
  635. package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
  636. package/dist/src/workflows/runtime/script-runtime.js +3 -0
  637. package/dist/src/workflows/store/event-store.d.ts +17 -0
  638. package/dist/src/workflows/store/event-store.js +83 -0
  639. package/dist/src/workflows/store/event-store.js.map +1 -0
  640. package/dist/src/workflows/store/paths.d.ts +7 -0
  641. package/dist/src/workflows/store/paths.js +26 -0
  642. package/dist/src/workflows/store/paths.js.map +1 -0
  643. package/dist/src/workflows/store/run-store.d.ts +13 -0
  644. package/dist/src/workflows/store/run-store.js +68 -0
  645. package/dist/src/workflows/store/run-store.js.map +1 -0
  646. package/package.json +5 -8
  647. package/dist/gateway/static/root/assets/agents-mS3_HpRI.js +0 -222
  648. package/dist/gateway/static/root/assets/channels-settings-BG6b9KrW.js +0 -1
  649. package/dist/gateway/static/root/assets/extension-settings-page-B-W4x2xP.js +0 -1
  650. package/dist/gateway/static/root/assets/index-ew_2L2We.css +0 -1
  651. package/dist/gateway/static/root/assets/sessions-page-FaG_Vlkb.js +0 -1
  652. package/dist/gateway/static/root/assets/settings-page-Bet1OerL.js +0 -3
  653. package/dist/gateway/static/root/assets/skills-page-DhUO235y.js +0 -2
  654. package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +0 -3
  655. package/dist/gateway/static/root/assets/voice-api-key-field-CGEydndO.js +0 -1
  656. package/dist/src/agent/tools/browser-legacy-tools.d.ts +0 -17
  657. package/dist/src/agent/tools/browser-legacy-tools.js +0 -766
  658. package/dist/src/agent/tools/browser-legacy-tools.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
2
  import { channelToNpmTag } from "./update-channels.js";
3
- import { dirname, join } from "node:path";
4
3
  import { access, readFile } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  //#region src/infra/update-check.ts
7
7
  init_package_version();
@@ -0,0 +1,45 @@
1
+ import { type CommandRunner } from './run-command.js';
2
+ export declare const XOPC_PACKAGE_NAME = "@xopcai/xopc";
3
+ export type GlobalInstallManager = 'npm' | 'pnpm';
4
+ export type ResolvedGlobalInstallCommand = {
5
+ manager: GlobalInstallManager;
6
+ command: string;
7
+ };
8
+ export type GlobalInstallRunResult = {
9
+ exitCode: number;
10
+ stdout: string;
11
+ stderr: string;
12
+ packageManager: GlobalInstallManager;
13
+ usedFallback: boolean;
14
+ };
15
+ export declare function joinGlobalPackagePath(globalRoot: string): string;
16
+ export declare function resolveGlobalInstallCommand(manager: GlobalInstallManager, pkgRoot?: string | null): ResolvedGlobalInstallCommand;
17
+ export declare function createGlobalInstallEnv(env?: NodeJS.ProcessEnv): Promise<NodeJS.ProcessEnv | undefined>;
18
+ export declare function resolveGlobalInstallSpec(params: {
19
+ version: string;
20
+ env?: NodeJS.ProcessEnv;
21
+ }): string;
22
+ export declare function resolveGlobalRoot(managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand, runCommand: CommandRunner, timeoutMs: number, pkgRoot?: string | null): Promise<string | null>;
23
+ export declare function globalInstallArgs(managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand, spec: string, pkgRoot?: string | null): string[];
24
+ export declare function globalInstallFallbackArgs(managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand, spec: string, pkgRoot?: string | null): string[] | null;
25
+ export declare function detectGlobalInstallManagerForRoot(runCommand: CommandRunner, pkgRoot: string, timeoutMs: number): Promise<GlobalInstallManager | null>;
26
+ export declare function detectGlobalInstallManagerByPresence(runCommand: CommandRunner, timeoutMs: number): Promise<GlobalInstallManager | null>;
27
+ export declare function resolveGlobalManager(params: {
28
+ root: string | null;
29
+ timeoutMs?: number;
30
+ }): Promise<GlobalInstallManager>;
31
+ export declare function runGlobalPackageInstall(params: {
32
+ manager: GlobalInstallManager;
33
+ spec: string;
34
+ pkgRoot: string | null;
35
+ timeoutMs?: number;
36
+ /** Echo install output to the parent process (CLI interactive). */
37
+ echoToTerminal?: boolean;
38
+ }): Promise<GlobalInstallRunResult>;
39
+ export declare function formatGlobalInstallFailure(params: {
40
+ packageManager: GlobalInstallManager;
41
+ spec: string;
42
+ exitCode: number;
43
+ stderr: string;
44
+ usedFallback: boolean;
45
+ }): string;
@@ -0,0 +1,224 @@
1
+ import { createDefaultCommandRunner } from "./run-command.js";
2
+ import fs from "node:fs";
3
+ import fs$1 from "node:fs/promises";
4
+ import path from "node:path";
5
+ //#region src/infra/update-global.ts
6
+ const XOPC_PACKAGE_NAME = "@xopcai/xopc";
7
+ const COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT = "0";
8
+ const NPM_GLOBAL_INSTALL_QUIET_FLAGS = [
9
+ "--no-fund",
10
+ "--no-audit",
11
+ "--loglevel=error"
12
+ ];
13
+ const NPM_GLOBAL_INSTALL_OMIT_OPTIONAL_FLAGS = ["--omit=optional", ...NPM_GLOBAL_INSTALL_QUIET_FLAGS];
14
+ const GLOBAL_DETECT_TIMEOUT_MS = 15e3;
15
+ const GLOBAL_INSTALL_TIMEOUT_MS = 2700 * 1e3;
16
+ async function pathExists(targetPath) {
17
+ try {
18
+ await fs$1.access(targetPath);
19
+ return true;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+ async function tryRealpath(targetPath) {
25
+ try {
26
+ return await fs$1.realpath(targetPath);
27
+ } catch {
28
+ return path.resolve(targetPath);
29
+ }
30
+ }
31
+ function joinGlobalPackagePath(globalRoot) {
32
+ return path.join(globalRoot, XOPC_PACKAGE_NAME);
33
+ }
34
+ function inferNpmPrefixFromPackageRoot(pkgRoot) {
35
+ const trimmed = pkgRoot?.trim();
36
+ if (!trimmed) return null;
37
+ const normalized = path.resolve(trimmed);
38
+ const nodeModulesDir = path.dirname(normalized);
39
+ if (path.basename(nodeModulesDir) !== "node_modules") return null;
40
+ const parentDir = path.dirname(nodeModulesDir);
41
+ if (path.basename(parentDir) === "lib") return path.dirname(parentDir);
42
+ if (process.platform === "win32" && path.basename(parentDir).toLowerCase() === "npm") return parentDir;
43
+ return null;
44
+ }
45
+ function resolvePreferredNpmCommand(pkgRoot) {
46
+ const prefix = inferNpmPrefixFromPackageRoot(pkgRoot);
47
+ if (!prefix) return null;
48
+ const candidate = process.platform === "win32" ? path.join(prefix, "npm.cmd") : path.join(prefix, "bin", "npm");
49
+ return fs.existsSync(candidate) ? candidate : null;
50
+ }
51
+ function resolvePreferredGlobalManagerCommand(manager, pkgRoot) {
52
+ if (manager !== "npm") return manager;
53
+ return resolvePreferredNpmCommand(pkgRoot) ?? manager;
54
+ }
55
+ function resolveGlobalInstallCommand(manager, pkgRoot) {
56
+ return {
57
+ manager,
58
+ command: resolvePreferredGlobalManagerCommand(manager, pkgRoot)
59
+ };
60
+ }
61
+ function normalizeGlobalInstallCommand(managerOrCommand, pkgRoot) {
62
+ return typeof managerOrCommand === "string" ? resolveGlobalInstallCommand(managerOrCommand, pkgRoot) : managerOrCommand;
63
+ }
64
+ function applyWindowsPackageInstallEnv(env) {
65
+ if (process.platform !== "win32") return;
66
+ env.NPM_CONFIG_UPDATE_NOTIFIER = "false";
67
+ env.NPM_CONFIG_FUND = "false";
68
+ env.NPM_CONFIG_AUDIT = "false";
69
+ }
70
+ function applyCorepackDownloadPromptEnv(env) {
71
+ if (!env.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim()) env.COREPACK_ENABLE_DOWNLOAD_PROMPT = COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT;
72
+ }
73
+ async function createGlobalInstallEnv(env) {
74
+ const sourceEnv = env ?? process.env;
75
+ const hasCorepack = Boolean(sourceEnv.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim());
76
+ if (process.platform !== "win32" && hasCorepack) return env;
77
+ const merged = Object.fromEntries(Object.entries(sourceEnv).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)]));
78
+ applyWindowsPackageInstallEnv(merged);
79
+ applyCorepackDownloadPromptEnv(merged);
80
+ return merged;
81
+ }
82
+ function resolveGlobalInstallSpec(params) {
83
+ const override = params.env?.XOPC_UPDATE_PACKAGE_SPEC?.trim() || process.env.XOPC_UPDATE_PACKAGE_SPEC?.trim();
84
+ if (override) return override;
85
+ return `${XOPC_PACKAGE_NAME}@${params.version}`;
86
+ }
87
+ async function resolveGlobalRoot(managerOrCommand, runCommand, timeoutMs, pkgRoot) {
88
+ const res = await runCommand([
89
+ normalizeGlobalInstallCommand(managerOrCommand, pkgRoot).command,
90
+ "root",
91
+ "-g"
92
+ ], { timeoutMs }).catch(() => null);
93
+ if (!res || res.code !== 0) return null;
94
+ return res.stdout.trim() || null;
95
+ }
96
+ function globalInstallArgs(managerOrCommand, spec, pkgRoot) {
97
+ const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);
98
+ if (resolved.manager === "pnpm") return [
99
+ resolved.command,
100
+ "add",
101
+ "-g",
102
+ spec
103
+ ];
104
+ return [
105
+ resolved.command,
106
+ "install",
107
+ "-g",
108
+ spec,
109
+ ...NPM_GLOBAL_INSTALL_QUIET_FLAGS
110
+ ];
111
+ }
112
+ function globalInstallFallbackArgs(managerOrCommand, spec, pkgRoot) {
113
+ const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);
114
+ if (resolved.manager !== "npm") return null;
115
+ return [
116
+ resolved.command,
117
+ "install",
118
+ "-g",
119
+ spec,
120
+ ...NPM_GLOBAL_INSTALL_OMIT_OPTIONAL_FLAGS
121
+ ];
122
+ }
123
+ async function detectGlobalInstallManagerForRoot(runCommand, pkgRoot, timeoutMs) {
124
+ const pkgReal = await tryRealpath(pkgRoot);
125
+ for (const { manager, argv } of [{
126
+ manager: "npm",
127
+ argv: [
128
+ "npm",
129
+ "root",
130
+ "-g"
131
+ ]
132
+ }, {
133
+ manager: "pnpm",
134
+ argv: [
135
+ "pnpm",
136
+ "root",
137
+ "-g"
138
+ ]
139
+ }]) {
140
+ const res = await runCommand(argv, { timeoutMs }).catch(() => null);
141
+ if (!res || res.code !== 0) continue;
142
+ const globalRoot = res.stdout.trim();
143
+ if (!globalRoot) continue;
144
+ const expectedReal = await tryRealpath(joinGlobalPackagePath(await tryRealpath(globalRoot)));
145
+ if (path.resolve(expectedReal) === path.resolve(pkgReal)) return manager;
146
+ }
147
+ if (resolvePreferredNpmCommand(pkgRoot)) return "npm";
148
+ return null;
149
+ }
150
+ async function detectGlobalInstallManagerByPresence(runCommand, timeoutMs) {
151
+ for (const manager of ["npm", "pnpm"]) {
152
+ const root = await resolveGlobalRoot(manager, runCommand, timeoutMs);
153
+ if (!root) continue;
154
+ if (await pathExists(joinGlobalPackagePath(root))) return manager;
155
+ }
156
+ return null;
157
+ }
158
+ async function resolveGlobalManager(params) {
159
+ const runCommand = createDefaultCommandRunner();
160
+ const timeoutMs = params.timeoutMs ?? GLOBAL_DETECT_TIMEOUT_MS;
161
+ if (params.root) {
162
+ const detected = await detectGlobalInstallManagerForRoot(runCommand, params.root, timeoutMs);
163
+ if (detected) return detected;
164
+ }
165
+ return await detectGlobalInstallManagerByPresence(runCommand, timeoutMs) ?? "npm";
166
+ }
167
+ function tailOutput(text, max = 4e3) {
168
+ const t = text.trim();
169
+ if (t.length <= max) return t;
170
+ return t.slice(-max);
171
+ }
172
+ async function runGlobalPackageInstall(params) {
173
+ const timeoutMs = params.timeoutMs ?? GLOBAL_INSTALL_TIMEOUT_MS;
174
+ const runCommand = createDefaultCommandRunner();
175
+ const installEnv = await createGlobalInstallEnv();
176
+ const runStep = async (argv) => {
177
+ const result = await runCommand(argv, {
178
+ timeoutMs,
179
+ env: installEnv
180
+ });
181
+ if (params.echoToTerminal) {
182
+ if (result.stdout) process.stdout.write(result.stdout);
183
+ if (result.stderr) process.stderr.write(result.stderr);
184
+ }
185
+ return result;
186
+ };
187
+ const primary = await runStep(globalInstallArgs(params.manager, params.spec, params.pkgRoot));
188
+ if (primary.code === 0) return {
189
+ exitCode: 0,
190
+ stdout: primary.stdout,
191
+ stderr: primary.stderr,
192
+ packageManager: params.manager,
193
+ usedFallback: false
194
+ };
195
+ const fallbackArgv = globalInstallFallbackArgs(params.manager, params.spec, params.pkgRoot);
196
+ if (!fallbackArgv) return {
197
+ exitCode: primary.code ?? 1,
198
+ stdout: primary.stdout,
199
+ stderr: primary.stderr,
200
+ packageManager: params.manager,
201
+ usedFallback: false
202
+ };
203
+ const fallback = await runStep(fallbackArgv);
204
+ return {
205
+ exitCode: fallback.code ?? 1,
206
+ stdout: [primary.stdout, fallback.stdout].filter(Boolean).join("\n"),
207
+ stderr: [primary.stderr, fallback.stderr].filter(Boolean).join("\n"),
208
+ packageManager: params.manager,
209
+ usedFallback: true
210
+ };
211
+ }
212
+ function formatGlobalInstallFailure(params) {
213
+ const tail = tailOutput(params.stderr);
214
+ return [
215
+ `Global install via ${params.packageManager} failed (exit ${params.exitCode}).`,
216
+ params.usedFallback ? "Retried with --omit=optional." : null,
217
+ `Try manually: ${params.packageManager} install -g ${params.spec}`,
218
+ tail ? `Install output:\n${tail}` : null
219
+ ].filter(Boolean).join("\n");
220
+ }
221
+ //#endregion
222
+ export { XOPC_PACKAGE_NAME, createGlobalInstallEnv, detectGlobalInstallManagerByPresence, detectGlobalInstallManagerForRoot, formatGlobalInstallFailure, globalInstallArgs, globalInstallFallbackArgs, joinGlobalPackagePath, resolveGlobalInstallCommand, resolveGlobalInstallSpec, resolveGlobalManager, resolveGlobalRoot, runGlobalPackageInstall };
223
+
224
+ //# sourceMappingURL=update-global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-global.js","names":["fs","fsSync"],"sources":["../../../src/infra/update-global.ts"],"sourcesContent":["// src/infra/update-global.ts — global npm/pnpm install detection and commands (OpenClaw-aligned)\n\nimport fsSync from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport {\n createDefaultCommandRunner,\n type CommandRunner,\n type CommandRunResult,\n} from './run-command.js';\n\nexport const XOPC_PACKAGE_NAME = '@xopcai/xopc';\n\nexport type GlobalInstallManager = 'npm' | 'pnpm';\n\nexport type ResolvedGlobalInstallCommand = {\n manager: GlobalInstallManager;\n command: string;\n};\n\nconst COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT = '0';\nconst NPM_GLOBAL_INSTALL_QUIET_FLAGS = ['--no-fund', '--no-audit', '--loglevel=error'] as const;\nconst NPM_GLOBAL_INSTALL_OMIT_OPTIONAL_FLAGS = [\n '--omit=optional',\n ...NPM_GLOBAL_INSTALL_QUIET_FLAGS,\n] as const;\n\nconst GLOBAL_DETECT_TIMEOUT_MS = 15_000;\nconst GLOBAL_INSTALL_TIMEOUT_MS = 45 * 60 * 1000;\n\nexport type GlobalInstallRunResult = {\n exitCode: number;\n stdout: string;\n stderr: string;\n packageManager: GlobalInstallManager;\n usedFallback: boolean;\n};\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await fs.access(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function tryRealpath(targetPath: string): Promise<string> {\n try {\n return await fs.realpath(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n}\n\nexport function joinGlobalPackagePath(globalRoot: string): string {\n return path.join(globalRoot, XOPC_PACKAGE_NAME);\n}\n\nfunction inferNpmPrefixFromPackageRoot(pkgRoot?: string | null): string | null {\n const trimmed = pkgRoot?.trim();\n if (!trimmed) return null;\n const normalized = path.resolve(trimmed);\n const nodeModulesDir = path.dirname(normalized);\n if (path.basename(nodeModulesDir) !== 'node_modules') return null;\n const parentDir = path.dirname(nodeModulesDir);\n if (path.basename(parentDir) === 'lib') {\n return path.dirname(parentDir);\n }\n if (process.platform === 'win32' && path.basename(parentDir).toLowerCase() === 'npm') {\n return parentDir;\n }\n return null;\n}\n\nfunction resolvePreferredNpmCommand(pkgRoot?: string | null): string | null {\n const prefix = inferNpmPrefixFromPackageRoot(pkgRoot);\n if (!prefix) return null;\n const candidate =\n process.platform === 'win32' ? path.join(prefix, 'npm.cmd') : path.join(prefix, 'bin', 'npm');\n return fsSync.existsSync(candidate) ? candidate : null;\n}\n\nfunction resolvePreferredGlobalManagerCommand(\n manager: GlobalInstallManager,\n pkgRoot?: string | null,\n): string {\n if (manager !== 'npm') return manager;\n return resolvePreferredNpmCommand(pkgRoot) ?? manager;\n}\n\nexport function resolveGlobalInstallCommand(\n manager: GlobalInstallManager,\n pkgRoot?: string | null,\n): ResolvedGlobalInstallCommand {\n return {\n manager,\n command: resolvePreferredGlobalManagerCommand(manager, pkgRoot),\n };\n}\n\nfunction normalizeGlobalInstallCommand(\n managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand,\n pkgRoot?: string | null,\n): ResolvedGlobalInstallCommand {\n return typeof managerOrCommand === 'string'\n ? resolveGlobalInstallCommand(managerOrCommand, pkgRoot)\n : managerOrCommand;\n}\n\nfunction applyWindowsPackageInstallEnv(env: Record<string, string>): void {\n if (process.platform !== 'win32') return;\n env.NPM_CONFIG_UPDATE_NOTIFIER = 'false';\n env.NPM_CONFIG_FUND = 'false';\n env.NPM_CONFIG_AUDIT = 'false';\n}\n\nfunction applyCorepackDownloadPromptEnv(env: Record<string, string>): void {\n if (!env.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim()) {\n env.COREPACK_ENABLE_DOWNLOAD_PROMPT = COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT;\n }\n}\n\nexport async function createGlobalInstallEnv(\n env?: NodeJS.ProcessEnv,\n): Promise<NodeJS.ProcessEnv | undefined> {\n const sourceEnv = env ?? process.env;\n const hasCorepack = Boolean(sourceEnv.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim());\n if (process.platform !== 'win32' && hasCorepack) {\n return env;\n }\n const merged = Object.fromEntries(\n Object.entries(sourceEnv)\n .filter(([, value]) => value != null)\n .map(([key, value]) => [key, String(value)]),\n ) as Record<string, string>;\n applyWindowsPackageInstallEnv(merged);\n applyCorepackDownloadPromptEnv(merged);\n return merged;\n}\n\nexport function resolveGlobalInstallSpec(params: {\n version: string;\n env?: NodeJS.ProcessEnv;\n}): string {\n const override =\n params.env?.XOPC_UPDATE_PACKAGE_SPEC?.trim() || process.env.XOPC_UPDATE_PACKAGE_SPEC?.trim();\n if (override) return override;\n return `${XOPC_PACKAGE_NAME}@${params.version}`;\n}\n\nexport async function resolveGlobalRoot(\n managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand,\n runCommand: CommandRunner,\n timeoutMs: number,\n pkgRoot?: string | null,\n): Promise<string | null> {\n const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);\n const argv = [resolved.command, 'root', '-g'];\n const res = await runCommand(argv, { timeoutMs }).catch(() => null);\n if (!res || res.code !== 0) return null;\n const root = res.stdout.trim();\n return root || null;\n}\n\nexport function globalInstallArgs(\n managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand,\n spec: string,\n pkgRoot?: string | null,\n): string[] {\n const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);\n if (resolved.manager === 'pnpm') {\n return [resolved.command, 'add', '-g', spec];\n }\n return [resolved.command, 'install', '-g', spec, ...NPM_GLOBAL_INSTALL_QUIET_FLAGS];\n}\n\nexport function globalInstallFallbackArgs(\n managerOrCommand: GlobalInstallManager | ResolvedGlobalInstallCommand,\n spec: string,\n pkgRoot?: string | null,\n): string[] | null {\n const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);\n if (resolved.manager !== 'npm') return null;\n return [resolved.command, 'install', '-g', spec, ...NPM_GLOBAL_INSTALL_OMIT_OPTIONAL_FLAGS];\n}\n\nexport async function detectGlobalInstallManagerForRoot(\n runCommand: CommandRunner,\n pkgRoot: string,\n timeoutMs: number,\n): Promise<GlobalInstallManager | null> {\n const pkgReal = await tryRealpath(pkgRoot);\n\n const candidates: Array<{ manager: GlobalInstallManager; argv: string[] }> = [\n { manager: 'npm', argv: ['npm', 'root', '-g'] },\n { manager: 'pnpm', argv: ['pnpm', 'root', '-g'] },\n ];\n\n for (const { manager, argv } of candidates) {\n const res = await runCommand(argv, { timeoutMs }).catch(() => null);\n if (!res || res.code !== 0) continue;\n const globalRoot = res.stdout.trim();\n if (!globalRoot) continue;\n const globalReal = await tryRealpath(globalRoot);\n const expected = joinGlobalPackagePath(globalReal);\n const expectedReal = await tryRealpath(expected);\n if (path.resolve(expectedReal) === path.resolve(pkgReal)) {\n return manager;\n }\n }\n\n if (resolvePreferredNpmCommand(pkgRoot)) {\n return 'npm';\n }\n\n return null;\n}\n\nexport async function detectGlobalInstallManagerByPresence(\n runCommand: CommandRunner,\n timeoutMs: number,\n): Promise<GlobalInstallManager | null> {\n for (const manager of ['npm', 'pnpm'] as const) {\n const root = await resolveGlobalRoot(manager, runCommand, timeoutMs);\n if (!root) continue;\n if (await pathExists(joinGlobalPackagePath(root))) {\n return manager;\n }\n }\n return null;\n}\n\nexport async function resolveGlobalManager(params: {\n root: string | null;\n timeoutMs?: number;\n}): Promise<GlobalInstallManager> {\n const runCommand = createDefaultCommandRunner();\n const timeoutMs = params.timeoutMs ?? GLOBAL_DETECT_TIMEOUT_MS;\n\n if (params.root) {\n const detected = await detectGlobalInstallManagerForRoot(runCommand, params.root, timeoutMs);\n if (detected) return detected;\n }\n\n const byPresence = await detectGlobalInstallManagerByPresence(runCommand, timeoutMs);\n return byPresence ?? 'npm';\n}\n\nfunction tailOutput(text: string, max = 4000): string {\n const t = text.trim();\n if (t.length <= max) return t;\n return t.slice(-max);\n}\n\nexport async function runGlobalPackageInstall(params: {\n manager: GlobalInstallManager;\n spec: string;\n pkgRoot: string | null;\n timeoutMs?: number;\n /** Echo install output to the parent process (CLI interactive). */\n echoToTerminal?: boolean;\n}): Promise<GlobalInstallRunResult> {\n const timeoutMs = params.timeoutMs ?? GLOBAL_INSTALL_TIMEOUT_MS;\n const runCommand = createDefaultCommandRunner();\n const installEnv = await createGlobalInstallEnv();\n\n const runStep = async (argv: string[]): Promise<CommandRunResult> => {\n const result = await runCommand(argv, { timeoutMs, env: installEnv });\n if (params.echoToTerminal) {\n if (result.stdout) process.stdout.write(result.stdout);\n if (result.stderr) process.stderr.write(result.stderr);\n }\n return result;\n };\n\n const primaryArgv = globalInstallArgs(params.manager, params.spec, params.pkgRoot);\n const primary = await runStep(primaryArgv);\n if (primary.code === 0) {\n return {\n exitCode: 0,\n stdout: primary.stdout,\n stderr: primary.stderr,\n packageManager: params.manager,\n usedFallback: false,\n };\n }\n\n const fallbackArgv = globalInstallFallbackArgs(params.manager, params.spec, params.pkgRoot);\n if (!fallbackArgv) {\n return {\n exitCode: primary.code ?? 1,\n stdout: primary.stdout,\n stderr: primary.stderr,\n packageManager: params.manager,\n usedFallback: false,\n };\n }\n\n const fallback = await runStep(fallbackArgv);\n return {\n exitCode: fallback.code ?? 1,\n stdout: [primary.stdout, fallback.stdout].filter(Boolean).join('\\n'),\n stderr: [primary.stderr, fallback.stderr].filter(Boolean).join('\\n'),\n packageManager: params.manager,\n usedFallback: true,\n };\n}\n\nexport function formatGlobalInstallFailure(params: {\n packageManager: GlobalInstallManager;\n spec: string;\n exitCode: number;\n stderr: string;\n usedFallback: boolean;\n}): string {\n const tail = tailOutput(params.stderr);\n const parts = [\n `Global install via ${params.packageManager} failed (exit ${params.exitCode}).`,\n params.usedFallback ? 'Retried with --omit=optional.' : null,\n `Try manually: ${params.packageManager} install -g ${params.spec}`,\n tail ? `Install output:\\n${tail}` : null,\n ].filter(Boolean);\n return parts.join('\\n');\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { init_paths_state, resolveUpdateLockPath } from "../config/paths-state.js";
1
+ import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
- import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
5
- import { dirname } from "node:path";
4
+ import { init_paths_state, resolveUpdateLockPath } from "../config/paths-state.js";
6
5
  import { mkdir, readFile, unlink } from "node:fs/promises";
6
+ import { dirname } from "node:path";
7
7
  //#region src/infra/update-lock.ts
8
8
  init_write_file_atomic();
9
9
  init_paths_state();
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
- import { join } from "node:path";
4
3
  import { access, readdir, unlink } from "node:fs/promises";
4
+ import { join } from "node:path";
5
5
  import { spawn } from "node:child_process";
6
6
  //#region src/infra/update-runner.ts
7
7
  init_logger();
@@ -1,8 +1,8 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
- import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-state.js";
2
+ import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
3
3
  import { createLogger } from "../utils/logger/index.js";
4
4
  import { init_logger } from "../utils/logger.js";
5
- import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
5
+ import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-state.js";
6
6
  import { acquireUpdateLock } from "./update-lock.js";
7
7
  import { normalizeUpdateChannel } from "./update-channels.js";
8
8
  import { compareSemver, detectInstallKind, resolveNpmChannelTag, resolvePackageRoot } from "./update-check.js";
@@ -1,8 +1,8 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import path from "node:path";
3
- import { chmodSync, closeSync, copyFileSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
2
  import { randomUUID } from "node:crypto";
3
+ import { chmodSync, closeSync, copyFileSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync } from "node:fs";
5
4
  import { chmod, copyFile, mkdir, open, rename, rm } from "node:fs/promises";
5
+ import path from "node:path";
6
6
  //#region src/infra/write-file-atomic.ts
7
7
  /**
8
8
  * Durable single-file writes: temp file → fsync → rename to target.
@@ -1,6 +1,7 @@
1
- import { normalizeOptionalString } from "../utils/string-coerce.js";
1
+ import { init_string_coerce, normalizeOptionalString } from "../utils/string-coerce.js";
2
2
  import { z } from "zod";
3
3
  //#region src/mcp/channel-shared.ts
4
+ init_string_coerce();
4
5
  function normalizeMessageChannel(value) {
5
6
  return value?.trim() || void 0;
6
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"channel-shared.js","names":["toText"],"sources":["../../../src/mcp/channel-shared.ts"],"sourcesContent":["import { z } from 'zod';\nimport { normalizeOptionalString as toText } from '../utils/string-coerce.js';\n\nfunction normalizeMessageChannel(value: string | undefined): string | undefined {\n return value?.trim() || undefined;\n}\n\nexport type ClaudeChannelMode = \"off\" | \"on\" | \"auto\";\n\nexport type ConversationDescriptor = {\n sessionKey: string;\n channel: string;\n to: string;\n accountId?: string;\n threadId?: string | number;\n label?: string;\n displayName?: string;\n derivedTitle?: string;\n lastMessagePreview?: string;\n updatedAt?: number | null;\n};\n\nexport type SessionRow = {\n key: string;\n channel?: string;\n lastChannel?: string;\n lastTo?: string;\n lastAccountId?: string;\n lastThreadId?: string | number;\n deliveryContext?: {\n channel?: string;\n to?: string;\n accountId?: string;\n threadId?: string | number;\n };\n origin?: {\n provider?: string;\n accountId?: string;\n threadId?: string | number;\n };\n label?: string;\n displayName?: string;\n derivedTitle?: string;\n lastMessagePreview?: string;\n updatedAt?: number | null;\n};\n\nexport type SessionListResult = {\n sessions?: SessionRow[];\n};\n\nexport type ChatHistoryResult = {\n messages?: Array<{ id?: string; role?: string; content?: unknown; [key: string]: unknown }>;\n};\n\nexport type SessionMessagePayload = {\n sessionKey?: string;\n messageId?: string;\n messageSeq?: number;\n message?: { role?: string; content?: unknown; [key: string]: unknown };\n lastChannel?: string;\n lastTo?: string;\n lastAccountId?: string;\n lastThreadId?: string | number;\n [key: string]: unknown;\n};\n\nexport type ApprovalKind = \"exec\" | \"plugin\";\nexport type ApprovalDecision = \"allow-once\" | \"allow-always\" | \"deny\";\n\nexport type PendingApproval = {\n kind: ApprovalKind;\n id: string;\n request?: Record<string, unknown>;\n createdAtMs?: number;\n expiresAtMs?: number;\n};\n\nexport type QueueEvent =\n | {\n cursor: number;\n type: \"message\";\n sessionKey: string;\n conversation?: ConversationDescriptor;\n messageId?: string;\n messageSeq?: number;\n role?: string;\n text?: string;\n raw: SessionMessagePayload;\n }\n | {\n cursor: number;\n type: \"claude_permission_request\";\n requestId: string;\n toolName: string;\n description: string;\n inputPreview: string;\n }\n | {\n cursor: number;\n type: \"exec_approval_requested\" | \"exec_approval_resolved\";\n raw: Record<string, unknown>;\n }\n | {\n cursor: number;\n type: \"plugin_approval_requested\" | \"plugin_approval_resolved\";\n raw: Record<string, unknown>;\n };\n\nexport type ClaudePermissionRequest = {\n toolName: string;\n description: string;\n inputPreview: string;\n};\n\nexport type WaitFilter = {\n afterCursor: number;\n sessionKey?: string;\n};\n\nexport const ClaudePermissionRequestSchema = z.object({\n method: z.literal(\"notifications/claude/channel/permission_request\"),\n params: z.object({\n request_id: z.string(),\n tool_name: z.string(),\n description: z.string(),\n input_preview: z.string(),\n }),\n});\n\nexport { toText };\n\nexport function resolveMessageId(entry: Record<string, unknown>): string | undefined {\n return (\n toText(entry.id) ??\n (entry.__openclaw && typeof entry.__openclaw === \"object\"\n ? toText((entry.__openclaw as { id?: unknown }).id)\n : undefined)\n );\n}\n\nexport function summarizeResult(\n label: string,\n count: number,\n): { content: Array<{ type: \"text\"; text: string }> } {\n return {\n content: [{ type: \"text\", text: `${label}: ${count}` }],\n };\n}\n\nexport function resolveConversationChannel(row: SessionRow): string | undefined {\n return normalizeMessageChannel(\n toText(row.deliveryContext?.channel) ??\n toText(row.lastChannel) ??\n toText(row.channel) ??\n toText(row.origin?.provider),\n );\n}\n\nexport function toConversation(row: SessionRow): ConversationDescriptor | null {\n const channel = resolveConversationChannel(row);\n const to = toText(row.deliveryContext?.to) ?? toText(row.lastTo);\n if (!channel || !to) {\n return null;\n }\n return {\n sessionKey: row.key,\n channel,\n to,\n accountId:\n toText(row.deliveryContext?.accountId) ??\n toText(row.lastAccountId) ??\n toText(row.origin?.accountId),\n threadId: row.deliveryContext?.threadId ?? row.lastThreadId ?? row.origin?.threadId,\n label: toText(row.label),\n displayName: toText(row.displayName),\n derivedTitle: toText(row.derivedTitle),\n lastMessagePreview: toText(row.lastMessagePreview),\n updatedAt: typeof row.updatedAt === \"number\" ? row.updatedAt : null,\n };\n}\n\nexport function matchEventFilter(event: QueueEvent, filter: WaitFilter): boolean {\n if (event.cursor <= filter.afterCursor) {\n return false;\n }\n if (!filter.sessionKey) {\n return true;\n }\n return \"sessionKey\" in event && event.sessionKey === filter.sessionKey;\n}\n\nexport function extractAttachmentsFromMessage(message: unknown): unknown[] {\n if (!message || typeof message !== \"object\") {\n return [];\n }\n const content = (message as { content?: unknown }).content;\n if (!Array.isArray(content)) {\n return [];\n }\n return content.filter((entry) => {\n if (!entry || typeof entry !== \"object\") {\n return false;\n }\n return toText((entry as { type?: unknown }).type) !== \"text\";\n });\n}\n\nexport function normalizeApprovalId(value: unknown): string | undefined {\n const id = toText(value);\n return id ? id.trim() : undefined;\n}\n"],"mappings":";;;AAGA,SAAS,wBAAwB,OAA+C;AAC9E,QAAO,OAAO,MAAM,IAAI,KAAA;;AAoH1B,MAAa,gCAAgC,EAAE,OAAO;CACpD,QAAQ,EAAE,QAAQ,kDAAkD;CACpE,QAAQ,EAAE,OAAO;EACf,YAAY,EAAE,QAAQ;EACtB,WAAW,EAAE,QAAQ;EACrB,aAAa,EAAE,QAAQ;EACvB,eAAe,EAAE,QAAQ;EAC1B,CAAC;CACH,CAAC;AAIF,SAAgB,iBAAiB,OAAoD;AACnF,QACEA,wBAAO,MAAM,GAAG,KACf,MAAM,cAAc,OAAO,MAAM,eAAe,WAC7CA,wBAAQ,MAAM,WAAgC,GAAG,GACjD,KAAA;;AAIR,SAAgB,gBACd,OACA,OACoD;AACpD,QAAO,EACL,SAAS,CAAC;EAAE,MAAM;EAAQ,MAAM,GAAG,MAAM,IAAI;EAAS,CAAC,EACxD;;AAGH,SAAgB,2BAA2B,KAAqC;AAC9E,QAAO,wBACLA,wBAAO,IAAI,iBAAiB,QAAQ,IAClCA,wBAAO,IAAI,YAAY,IACvBA,wBAAO,IAAI,QAAQ,IACnBA,wBAAO,IAAI,QAAQ,SAAS,CAC/B;;AAGH,SAAgB,eAAe,KAAgD;CAC7E,MAAM,UAAU,2BAA2B,IAAI;CAC/C,MAAM,KAAKA,wBAAO,IAAI,iBAAiB,GAAG,IAAIA,wBAAO,IAAI,OAAO;AAChE,KAAI,CAAC,WAAW,CAAC,GACf,QAAO;AAET,QAAO;EACL,YAAY,IAAI;EAChB;EACA;EACA,WACEA,wBAAO,IAAI,iBAAiB,UAAU,IACtCA,wBAAO,IAAI,cAAc,IACzBA,wBAAO,IAAI,QAAQ,UAAU;EAC/B,UAAU,IAAI,iBAAiB,YAAY,IAAI,gBAAgB,IAAI,QAAQ;EAC3E,OAAOA,wBAAO,IAAI,MAAM;EACxB,aAAaA,wBAAO,IAAI,YAAY;EACpC,cAAcA,wBAAO,IAAI,aAAa;EACtC,oBAAoBA,wBAAO,IAAI,mBAAmB;EAClD,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;EAChE;;AAGH,SAAgB,iBAAiB,OAAmB,QAA6B;AAC/E,KAAI,MAAM,UAAU,OAAO,YACzB,QAAO;AAET,KAAI,CAAC,OAAO,WACV,QAAO;AAET,QAAO,gBAAgB,SAAS,MAAM,eAAe,OAAO;;AAG9D,SAAgB,8BAA8B,SAA6B;AACzE,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO,EAAE;CAEX,MAAM,UAAW,QAAkC;AACnD,KAAI,CAAC,MAAM,QAAQ,QAAQ,CACzB,QAAO,EAAE;AAEX,QAAO,QAAQ,QAAQ,UAAU;AAC/B,MAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAET,SAAOA,wBAAQ,MAA6B,KAAK,KAAK;GACtD;;AAGJ,SAAgB,oBAAoB,OAAoC;CACtE,MAAM,KAAKA,wBAAO,MAAM;AACxB,QAAO,KAAK,GAAG,MAAM,GAAG,KAAA"}
1
+ {"version":3,"file":"channel-shared.js","names":["toText"],"sources":["../../../src/mcp/channel-shared.ts"],"sourcesContent":["import { z } from 'zod';\nimport { normalizeOptionalString as toText } from '../utils/string-coerce.js';\n\nfunction normalizeMessageChannel(value: string | undefined): string | undefined {\n return value?.trim() || undefined;\n}\n\nexport type ClaudeChannelMode = \"off\" | \"on\" | \"auto\";\n\nexport type ConversationDescriptor = {\n sessionKey: string;\n channel: string;\n to: string;\n accountId?: string;\n threadId?: string | number;\n label?: string;\n displayName?: string;\n derivedTitle?: string;\n lastMessagePreview?: string;\n updatedAt?: number | null;\n};\n\nexport type SessionRow = {\n key: string;\n channel?: string;\n lastChannel?: string;\n lastTo?: string;\n lastAccountId?: string;\n lastThreadId?: string | number;\n deliveryContext?: {\n channel?: string;\n to?: string;\n accountId?: string;\n threadId?: string | number;\n };\n origin?: {\n provider?: string;\n accountId?: string;\n threadId?: string | number;\n };\n label?: string;\n displayName?: string;\n derivedTitle?: string;\n lastMessagePreview?: string;\n updatedAt?: number | null;\n};\n\nexport type SessionListResult = {\n sessions?: SessionRow[];\n};\n\nexport type ChatHistoryResult = {\n messages?: Array<{ id?: string; role?: string; content?: unknown; [key: string]: unknown }>;\n};\n\nexport type SessionMessagePayload = {\n sessionKey?: string;\n messageId?: string;\n messageSeq?: number;\n message?: { role?: string; content?: unknown; [key: string]: unknown };\n lastChannel?: string;\n lastTo?: string;\n lastAccountId?: string;\n lastThreadId?: string | number;\n [key: string]: unknown;\n};\n\nexport type ApprovalKind = \"exec\" | \"plugin\";\nexport type ApprovalDecision = \"allow-once\" | \"allow-always\" | \"deny\";\n\nexport type PendingApproval = {\n kind: ApprovalKind;\n id: string;\n request?: Record<string, unknown>;\n createdAtMs?: number;\n expiresAtMs?: number;\n};\n\nexport type QueueEvent =\n | {\n cursor: number;\n type: \"message\";\n sessionKey: string;\n conversation?: ConversationDescriptor;\n messageId?: string;\n messageSeq?: number;\n role?: string;\n text?: string;\n raw: SessionMessagePayload;\n }\n | {\n cursor: number;\n type: \"claude_permission_request\";\n requestId: string;\n toolName: string;\n description: string;\n inputPreview: string;\n }\n | {\n cursor: number;\n type: \"exec_approval_requested\" | \"exec_approval_resolved\";\n raw: Record<string, unknown>;\n }\n | {\n cursor: number;\n type: \"plugin_approval_requested\" | \"plugin_approval_resolved\";\n raw: Record<string, unknown>;\n };\n\nexport type ClaudePermissionRequest = {\n toolName: string;\n description: string;\n inputPreview: string;\n};\n\nexport type WaitFilter = {\n afterCursor: number;\n sessionKey?: string;\n};\n\nexport const ClaudePermissionRequestSchema = z.object({\n method: z.literal(\"notifications/claude/channel/permission_request\"),\n params: z.object({\n request_id: z.string(),\n tool_name: z.string(),\n description: z.string(),\n input_preview: z.string(),\n }),\n});\n\nexport { toText };\n\nexport function resolveMessageId(entry: Record<string, unknown>): string | undefined {\n return (\n toText(entry.id) ??\n (entry.__openclaw && typeof entry.__openclaw === \"object\"\n ? toText((entry.__openclaw as { id?: unknown }).id)\n : undefined)\n );\n}\n\nexport function summarizeResult(\n label: string,\n count: number,\n): { content: Array<{ type: \"text\"; text: string }> } {\n return {\n content: [{ type: \"text\", text: `${label}: ${count}` }],\n };\n}\n\nexport function resolveConversationChannel(row: SessionRow): string | undefined {\n return normalizeMessageChannel(\n toText(row.deliveryContext?.channel) ??\n toText(row.lastChannel) ??\n toText(row.channel) ??\n toText(row.origin?.provider),\n );\n}\n\nexport function toConversation(row: SessionRow): ConversationDescriptor | null {\n const channel = resolveConversationChannel(row);\n const to = toText(row.deliveryContext?.to) ?? toText(row.lastTo);\n if (!channel || !to) {\n return null;\n }\n return {\n sessionKey: row.key,\n channel,\n to,\n accountId:\n toText(row.deliveryContext?.accountId) ??\n toText(row.lastAccountId) ??\n toText(row.origin?.accountId),\n threadId: row.deliveryContext?.threadId ?? row.lastThreadId ?? row.origin?.threadId,\n label: toText(row.label),\n displayName: toText(row.displayName),\n derivedTitle: toText(row.derivedTitle),\n lastMessagePreview: toText(row.lastMessagePreview),\n updatedAt: typeof row.updatedAt === \"number\" ? row.updatedAt : null,\n };\n}\n\nexport function matchEventFilter(event: QueueEvent, filter: WaitFilter): boolean {\n if (event.cursor <= filter.afterCursor) {\n return false;\n }\n if (!filter.sessionKey) {\n return true;\n }\n return \"sessionKey\" in event && event.sessionKey === filter.sessionKey;\n}\n\nexport function extractAttachmentsFromMessage(message: unknown): unknown[] {\n if (!message || typeof message !== \"object\") {\n return [];\n }\n const content = (message as { content?: unknown }).content;\n if (!Array.isArray(content)) {\n return [];\n }\n return content.filter((entry) => {\n if (!entry || typeof entry !== \"object\") {\n return false;\n }\n return toText((entry as { type?: unknown }).type) !== \"text\";\n });\n}\n\nexport function normalizeApprovalId(value: unknown): string | undefined {\n const id = toText(value);\n return id ? id.trim() : undefined;\n}\n"],"mappings":";;;oBAC8E;AAE9E,SAAS,wBAAwB,OAA+C;AAC9E,QAAO,OAAO,MAAM,IAAI,KAAA;;AAoH1B,MAAa,gCAAgC,EAAE,OAAO;CACpD,QAAQ,EAAE,QAAQ,kDAAkD;CACpE,QAAQ,EAAE,OAAO;EACf,YAAY,EAAE,QAAQ;EACtB,WAAW,EAAE,QAAQ;EACrB,aAAa,EAAE,QAAQ;EACvB,eAAe,EAAE,QAAQ;EAC1B,CAAC;CACH,CAAC;AAIF,SAAgB,iBAAiB,OAAoD;AACnF,QACEA,wBAAO,MAAM,GAAG,KACf,MAAM,cAAc,OAAO,MAAM,eAAe,WAC7CA,wBAAQ,MAAM,WAAgC,GAAG,GACjD,KAAA;;AAIR,SAAgB,gBACd,OACA,OACoD;AACpD,QAAO,EACL,SAAS,CAAC;EAAE,MAAM;EAAQ,MAAM,GAAG,MAAM,IAAI;EAAS,CAAC,EACxD;;AAGH,SAAgB,2BAA2B,KAAqC;AAC9E,QAAO,wBACLA,wBAAO,IAAI,iBAAiB,QAAQ,IAClCA,wBAAO,IAAI,YAAY,IACvBA,wBAAO,IAAI,QAAQ,IACnBA,wBAAO,IAAI,QAAQ,SAAS,CAC/B;;AAGH,SAAgB,eAAe,KAAgD;CAC7E,MAAM,UAAU,2BAA2B,IAAI;CAC/C,MAAM,KAAKA,wBAAO,IAAI,iBAAiB,GAAG,IAAIA,wBAAO,IAAI,OAAO;AAChE,KAAI,CAAC,WAAW,CAAC,GACf,QAAO;AAET,QAAO;EACL,YAAY,IAAI;EAChB;EACA;EACA,WACEA,wBAAO,IAAI,iBAAiB,UAAU,IACtCA,wBAAO,IAAI,cAAc,IACzBA,wBAAO,IAAI,QAAQ,UAAU;EAC/B,UAAU,IAAI,iBAAiB,YAAY,IAAI,gBAAgB,IAAI,QAAQ;EAC3E,OAAOA,wBAAO,IAAI,MAAM;EACxB,aAAaA,wBAAO,IAAI,YAAY;EACpC,cAAcA,wBAAO,IAAI,aAAa;EACtC,oBAAoBA,wBAAO,IAAI,mBAAmB;EAClD,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;EAChE;;AAGH,SAAgB,iBAAiB,OAAmB,QAA6B;AAC/E,KAAI,MAAM,UAAU,OAAO,YACzB,QAAO;AAET,KAAI,CAAC,OAAO,WACV,QAAO;AAET,QAAO,gBAAgB,SAAS,MAAM,eAAe,OAAO;;AAG9D,SAAgB,8BAA8B,SAA6B;AACzE,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO,EAAE;CAEX,MAAM,UAAW,QAAkC;AACnD,KAAI,CAAC,MAAM,QAAQ,QAAQ,CACzB,QAAO,EAAE;AAEX,QAAO,QAAQ,QAAQ,UAAU;AAC/B,MAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAET,SAAOA,wBAAQ,MAA6B,KAAK,KAAK;GACtD;;AAGJ,SAAgB,oBAAoB,OAAoC;CACtE,MAAM,KAAKA,wBAAO,MAAM;AACxB,QAAO,KAAK,GAAG,MAAM,GAAG,KAAA"}
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { dirname, join } from "node:path";
4
3
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
5
  //#region src/providers/auth-runtime/auth-profile-store.ts
6
6
  /**
7
7
  * {@link AuthProfileStore} implementations.
@@ -206,7 +206,7 @@ function ensureDiskAuthProfileStore(agentDir) {
206
206
  * store or the default store.
207
207
  */
208
208
  function listProfilesForProvider(store, providerId) {
209
- return (store ?? getDefaultAuthProfileStore()).list?.(providerId) ?? [];
209
+ return (store ?? getDefaultAuthProfileStore()).list(providerId);
210
210
  }
211
211
  //#endregion
212
212
  export { DiskAuthProfileStore, NoopAuthProfileStore, ensureDiskAuthProfileStore, getDefaultAuthProfileStore, listProfilesForProvider, setDefaultAuthProfileStore };
@@ -1 +1 @@
1
- {"version":3,"file":"auth-profile-store.js","names":[],"sources":["../../../../src/providers/auth-runtime/auth-profile-store.ts"],"sourcesContent":["/**\n * {@link AuthProfileStore} implementations.\n *\n * - {@link NoopAuthProfileStore}: returns nothing; used by tests and as a safe\n * fallback when no agent context is available.\n * - {@link DiskAuthProfileStore}: persists per-agent profiles under\n * `<stateDir>/agents/<agentId>/auth-profiles.json` with a lazy in-memory\n * cache and atomic writes. Used by the gateway and CLI to host OAuth\n * tokens (Codex / Anthropic) without leaking them through env vars.\n *\n * Capability providers stay synchronous: `getApiKeySync` / `hasCredentialSync`\n * read the cached snapshot. Async members (`save`, `refresh`) are only used\n * by vendor-specific code that explicitly opts in to OAuth flows.\n */\n\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { createLogger } from '../../utils/logger.js';\nimport type { AuthProfile, AuthProfileStore } from './types.js';\n\nconst log = createLogger('AuthProfileStore');\n\nconst STORE_FILENAME = 'auth-profiles.json';\n\nexport class NoopAuthProfileStore implements AuthProfileStore {\n getApiKeySync(): string | undefined {\n return undefined;\n }\n hasCredentialSync(): boolean {\n return false;\n }\n list(): AuthProfile[] {\n return [];\n }\n get(): AuthProfile | undefined {\n return undefined;\n }\n async save(): Promise<void> {\n /* no-op */\n }\n async refresh(profile: AuthProfile): Promise<AuthProfile> {\n return profile;\n }\n}\n\ntype DiskFile = {\n /** Schema version; bumped if we ever change the on-disk shape. */\n version: 1;\n profiles: AuthProfile[];\n};\n\nfunction emptyFile(): DiskFile {\n return { version: 1, profiles: [] };\n}\n\nfunction isDiskFile(v: unknown): v is DiskFile {\n if (!v || typeof v !== 'object') return false;\n const o = v as Record<string, unknown>;\n return o.version === 1 && Array.isArray(o.profiles);\n}\n\n/**\n * Persistent per-agent credential store.\n *\n * File layout (`<stateDir>/agents/<agentId>/auth-profiles.json`):\n *\n * ```json\n * {\n * \"version\": 1,\n * \"profiles\": [\n * { \"provider\": \"openai\", \"profileId\": \"default\", \"mode\": \"api-key\", \"apiKey\": \"sk-...\" },\n * { \"provider\": \"openai\", \"profileId\": \"codex\", \"mode\": \"oauth\",\n * \"oauthAccessToken\": \"...\", \"oauthRefreshToken\": \"...\", \"expiresAt\": 1714000000000 }\n * ]\n * }\n * ```\n *\n * - Constructor is non-blocking; the first read triggers a sync load.\n * - Writes go through a temp file + `renameSync` so partial writes never\n * leave the JSON corrupted.\n */\nexport class DiskAuthProfileStore implements AuthProfileStore {\n private readonly path: string;\n private cache: DiskFile | undefined;\n private writeChain: Promise<void> = Promise.resolve();\n\n constructor(filePath: string) {\n this.path = filePath;\n }\n\n /** Absolute path to the backing JSON file. */\n get filePath(): string {\n return this.path;\n }\n\n // --- Sync read API ------------------------------------------------------\n\n getApiKeySync(providerId: string, profile?: string): string | undefined {\n const p = this.findProfile(providerId, profile);\n if (!p) return undefined;\n if (typeof p.apiKey === 'string' && p.apiKey.length > 0) return p.apiKey;\n if (typeof p.oauthAccessToken === 'string' && p.oauthAccessToken.length > 0) {\n return p.oauthAccessToken;\n }\n return undefined;\n }\n\n hasCredentialSync(providerId: string, profile?: string): boolean {\n return Boolean(this.getApiKeySync(providerId, profile));\n }\n\n list(providerId: string): AuthProfile[] {\n const file = this.ensureLoaded();\n return file.profiles\n .filter((p) => p.provider === providerId)\n .map((p) => ({ ...p }));\n }\n\n get(providerId: string, profileId?: string): AuthProfile | undefined {\n const p = this.findProfile(providerId, profileId);\n return p ? { ...p } : undefined;\n }\n\n // --- Async write API ----------------------------------------------------\n\n /**\n * Persist a profile. Uses a serial write chain so concurrent saves cannot\n * race each other on the JSON document.\n */\n save(profile: AuthProfile): Promise<void> {\n const next = this.writeChain.then(() => {\n const file = this.ensureLoaded();\n const idx = file.profiles.findIndex(\n (p) => p.provider === profile.provider && p.profileId === profile.profileId,\n );\n if (idx >= 0) {\n file.profiles[idx] = { ...profile };\n } else {\n file.profiles.push({ ...profile });\n }\n // Only one default per provider.\n if (profile.default) {\n for (const p of file.profiles) {\n if (\n p.provider === profile.provider &&\n p.profileId !== profile.profileId &&\n p.default\n ) {\n p.default = false;\n }\n }\n }\n this.persist(file);\n });\n // Swallow rejections in the chain so a single bad write doesn't poison\n // every subsequent save attempt.\n this.writeChain = next.catch(() => undefined);\n return next;\n }\n\n /**\n * Default `refresh()` is a no-op. Vendor-specific OAuth refresh logic\n * (Codex / Anthropic) lives in `src/providers/auth-runtime/oauth.ts` and\n * calls `save()` here once it has a fresh token.\n */\n async refresh(profile: AuthProfile): Promise<AuthProfile> {\n return profile;\n }\n\n // --- Internals ----------------------------------------------------------\n\n private ensureLoaded(): DiskFile {\n if (this.cache) return this.cache;\n if (!existsSync(this.path)) {\n this.cache = emptyFile();\n return this.cache;\n }\n try {\n const raw = readFileSync(this.path, 'utf8');\n const parsed = JSON.parse(raw);\n if (isDiskFile(parsed)) {\n this.cache = { version: 1, profiles: parsed.profiles.filter(isAuthProfileLike) };\n } else {\n log.warn(\n { path: this.path, phase: 'load' },\n 'auth-profiles.json has unexpected shape; resetting to empty (file is preserved on disk)',\n );\n this.cache = emptyFile();\n }\n } catch (err) {\n log.warn(\n { err, path: this.path, phase: 'load' },\n `Failed to read auth-profiles.json: ${err instanceof Error ? err.message : String(err)}`,\n );\n this.cache = emptyFile();\n }\n return this.cache;\n }\n\n private findProfile(providerId: string, profileId?: string): AuthProfile | undefined {\n const file = this.ensureLoaded();\n const matches = file.profiles.filter((p) => p.provider === providerId);\n if (matches.length === 0) return undefined;\n const wanted = profileId?.trim();\n if (wanted) {\n return matches.find((p) => p.profileId === wanted);\n }\n return matches.find((p) => p.default) ?? matches.find((p) => p.profileId === 'default') ?? matches[0];\n }\n\n private persist(file: DiskFile): void {\n mkdirSync(dirname(this.path), { recursive: true });\n const tmp = `${this.path}.tmp-${process.pid}-${Date.now()}`;\n writeFileSync(tmp, JSON.stringify(file, null, 2), { encoding: 'utf8', mode: 0o600 });\n renameSync(tmp, this.path);\n this.cache = file;\n }\n}\n\nfunction isAuthProfileLike(v: unknown): v is AuthProfile {\n if (!v || typeof v !== 'object') return false;\n const o = v as Record<string, unknown>;\n return typeof o.provider === 'string' && typeof o.profileId === 'string' && typeof o.mode === 'string';\n}\n\n// --- Default store registry ------------------------------------------------\n\nlet defaultStore: AuthProfileStore = new NoopAuthProfileStore();\nconst diskStores = new Map<string, DiskAuthProfileStore>();\n\nexport function getDefaultAuthProfileStore(): AuthProfileStore {\n return defaultStore;\n}\n\n/**\n * Override the default store. Returns a function that restores the previous\n * store; tests typically call it in `afterEach`.\n */\nexport function setDefaultAuthProfileStore(store: AuthProfileStore): () => void {\n const prev = defaultStore;\n defaultStore = store;\n return () => {\n defaultStore = prev;\n };\n}\n\n/**\n * Get (or create) a {@link DiskAuthProfileStore} for the given agent\n * directory. Same `agentDir` always returns the same store instance so the\n * in-memory cache stays consistent within one process.\n */\nexport function ensureDiskAuthProfileStore(agentDir: string): DiskAuthProfileStore {\n const key = agentDir;\n let store = diskStores.get(key);\n if (!store) {\n store = new DiskAuthProfileStore(join(agentDir, STORE_FILENAME));\n diskStores.set(key, store);\n }\n return store;\n}\n\n/**\n * Convenience: list every profile for a provider via either an explicit\n * store or the default store.\n */\nexport function listProfilesForProvider(\n store: AuthProfileStore | undefined,\n providerId: string,\n): AuthProfile[] {\n const s = store ?? getDefaultAuthProfileStore();\n return s.list?.(providerId) ?? [];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"auth-profile-store.js","names":[],"sources":["../../../../src/providers/auth-runtime/auth-profile-store.ts"],"sourcesContent":["/**\n * {@link AuthProfileStore} implementations.\n *\n * - {@link NoopAuthProfileStore}: returns nothing; used by tests and as a safe\n * fallback when no agent context is available.\n * - {@link DiskAuthProfileStore}: persists per-agent profiles under\n * `<stateDir>/agents/<agentId>/auth-profiles.json` with a lazy in-memory\n * cache and atomic writes. Used by the gateway and CLI to host OAuth\n * tokens (Codex / Anthropic) without leaking them through env vars.\n *\n * Capability providers stay synchronous: `getApiKeySync` / `hasCredentialSync`\n * read the cached snapshot. Async members (`save`, `refresh`) are only used\n * by vendor-specific code that explicitly opts in to OAuth flows.\n */\n\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { createLogger } from '../../utils/logger.js';\nimport type { AuthProfile, AuthProfileStore } from './types.js';\n\nconst log = createLogger('AuthProfileStore');\n\nconst STORE_FILENAME = 'auth-profiles.json';\n\nexport class NoopAuthProfileStore implements AuthProfileStore {\n getApiKeySync(): string | undefined {\n return undefined;\n }\n hasCredentialSync(): boolean {\n return false;\n }\n list(): AuthProfile[] {\n return [];\n }\n get(): AuthProfile | undefined {\n return undefined;\n }\n async save(): Promise<void> {\n /* no-op */\n }\n async refresh(profile: AuthProfile): Promise<AuthProfile> {\n return profile;\n }\n}\n\ntype DiskFile = {\n /** Schema version; bumped if we ever change the on-disk shape. */\n version: 1;\n profiles: AuthProfile[];\n};\n\nfunction emptyFile(): DiskFile {\n return { version: 1, profiles: [] };\n}\n\nfunction isDiskFile(v: unknown): v is DiskFile {\n if (!v || typeof v !== 'object') return false;\n const o = v as Record<string, unknown>;\n return o.version === 1 && Array.isArray(o.profiles);\n}\n\n/**\n * Persistent per-agent credential store.\n *\n * File layout (`<stateDir>/agents/<agentId>/auth-profiles.json`):\n *\n * ```json\n * {\n * \"version\": 1,\n * \"profiles\": [\n * { \"provider\": \"openai\", \"profileId\": \"default\", \"mode\": \"api-key\", \"apiKey\": \"sk-...\" },\n * { \"provider\": \"openai\", \"profileId\": \"codex\", \"mode\": \"oauth\",\n * \"oauthAccessToken\": \"...\", \"oauthRefreshToken\": \"...\", \"expiresAt\": 1714000000000 }\n * ]\n * }\n * ```\n *\n * - Constructor is non-blocking; the first read triggers a sync load.\n * - Writes go through a temp file + `renameSync` so partial writes never\n * leave the JSON corrupted.\n */\nexport class DiskAuthProfileStore implements AuthProfileStore {\n private readonly path: string;\n private cache: DiskFile | undefined;\n private writeChain: Promise<void> = Promise.resolve();\n\n constructor(filePath: string) {\n this.path = filePath;\n }\n\n /** Absolute path to the backing JSON file. */\n get filePath(): string {\n return this.path;\n }\n\n // --- Sync read API ------------------------------------------------------\n\n getApiKeySync(providerId: string, profile?: string): string | undefined {\n const p = this.findProfile(providerId, profile);\n if (!p) return undefined;\n if (typeof p.apiKey === 'string' && p.apiKey.length > 0) return p.apiKey;\n if (typeof p.oauthAccessToken === 'string' && p.oauthAccessToken.length > 0) {\n return p.oauthAccessToken;\n }\n return undefined;\n }\n\n hasCredentialSync(providerId: string, profile?: string): boolean {\n return Boolean(this.getApiKeySync(providerId, profile));\n }\n\n list(providerId: string): AuthProfile[] {\n const file = this.ensureLoaded();\n return file.profiles\n .filter((p) => p.provider === providerId)\n .map((p) => ({ ...p }));\n }\n\n get(providerId: string, profileId?: string): AuthProfile | undefined {\n const p = this.findProfile(providerId, profileId);\n return p ? { ...p } : undefined;\n }\n\n // --- Async write API ----------------------------------------------------\n\n /**\n * Persist a profile. Uses a serial write chain so concurrent saves cannot\n * race each other on the JSON document.\n */\n save(profile: AuthProfile): Promise<void> {\n const next = this.writeChain.then(() => {\n const file = this.ensureLoaded();\n const idx = file.profiles.findIndex(\n (p) => p.provider === profile.provider && p.profileId === profile.profileId,\n );\n if (idx >= 0) {\n file.profiles[idx] = { ...profile };\n } else {\n file.profiles.push({ ...profile });\n }\n // Only one default per provider.\n if (profile.default) {\n for (const p of file.profiles) {\n if (\n p.provider === profile.provider &&\n p.profileId !== profile.profileId &&\n p.default\n ) {\n p.default = false;\n }\n }\n }\n this.persist(file);\n });\n // Swallow rejections in the chain so a single bad write doesn't poison\n // every subsequent save attempt.\n this.writeChain = next.catch(() => undefined);\n return next;\n }\n\n /**\n * Default `refresh()` is a no-op. Vendor-specific OAuth refresh logic\n * (Codex / Anthropic) lives in `src/providers/auth-runtime/oauth.ts` and\n * calls `save()` here once it has a fresh token.\n */\n async refresh(profile: AuthProfile): Promise<AuthProfile> {\n return profile;\n }\n\n // --- Internals ----------------------------------------------------------\n\n private ensureLoaded(): DiskFile {\n if (this.cache) return this.cache;\n if (!existsSync(this.path)) {\n this.cache = emptyFile();\n return this.cache;\n }\n try {\n const raw = readFileSync(this.path, 'utf8');\n const parsed = JSON.parse(raw);\n if (isDiskFile(parsed)) {\n this.cache = { version: 1, profiles: parsed.profiles.filter(isAuthProfileLike) };\n } else {\n log.warn(\n { path: this.path, phase: 'load' },\n 'auth-profiles.json has unexpected shape; resetting to empty (file is preserved on disk)',\n );\n this.cache = emptyFile();\n }\n } catch (err) {\n log.warn(\n { err, path: this.path, phase: 'load' },\n `Failed to read auth-profiles.json: ${err instanceof Error ? err.message : String(err)}`,\n );\n this.cache = emptyFile();\n }\n return this.cache;\n }\n\n private findProfile(providerId: string, profileId?: string): AuthProfile | undefined {\n const file = this.ensureLoaded();\n const matches = file.profiles.filter((p) => p.provider === providerId);\n if (matches.length === 0) return undefined;\n const wanted = profileId?.trim();\n if (wanted) {\n return matches.find((p) => p.profileId === wanted);\n }\n return matches.find((p) => p.default) ?? matches.find((p) => p.profileId === 'default') ?? matches[0];\n }\n\n private persist(file: DiskFile): void {\n mkdirSync(dirname(this.path), { recursive: true });\n const tmp = `${this.path}.tmp-${process.pid}-${Date.now()}`;\n writeFileSync(tmp, JSON.stringify(file, null, 2), { encoding: 'utf8', mode: 0o600 });\n renameSync(tmp, this.path);\n this.cache = file;\n }\n}\n\nfunction isAuthProfileLike(v: unknown): v is AuthProfile {\n if (!v || typeof v !== 'object') return false;\n const o = v as Record<string, unknown>;\n return typeof o.provider === 'string' && typeof o.profileId === 'string' && typeof o.mode === 'string';\n}\n\n// --- Default store registry ------------------------------------------------\n\nlet defaultStore: AuthProfileStore = new NoopAuthProfileStore();\nconst diskStores = new Map<string, DiskAuthProfileStore>();\n\nexport function getDefaultAuthProfileStore(): AuthProfileStore {\n return defaultStore;\n}\n\n/**\n * Override the default store. Returns a function that restores the previous\n * store; tests typically call it in `afterEach`.\n */\nexport function setDefaultAuthProfileStore(store: AuthProfileStore): () => void {\n const prev = defaultStore;\n defaultStore = store;\n return () => {\n defaultStore = prev;\n };\n}\n\n/**\n * Get (or create) a {@link DiskAuthProfileStore} for the given agent\n * directory. Same `agentDir` always returns the same store instance so the\n * in-memory cache stays consistent within one process.\n */\nexport function ensureDiskAuthProfileStore(agentDir: string): DiskAuthProfileStore {\n const key = agentDir;\n let store = diskStores.get(key);\n if (!store) {\n store = new DiskAuthProfileStore(join(agentDir, STORE_FILENAME));\n diskStores.set(key, store);\n }\n return store;\n}\n\n/**\n * Convenience: list every profile for a provider via either an explicit\n * store or the default store.\n */\nexport function listProfilesForProvider(\n store: AuthProfileStore | undefined,\n providerId: string,\n): AuthProfile[] {\n const s = store ?? getDefaultAuthProfileStore();\n return s.list(providerId);\n}\n"],"mappings":"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"}
@@ -43,22 +43,11 @@ function resolveAuthProfileForProvider(options) {
43
43
  };
44
44
  }
45
45
  function pickProfile(store, providerId, profileName) {
46
- if (typeof store.get === "function") try {
47
- return store.get(providerId, profileName);
48
- } catch {}
49
- let key;
50
46
  try {
51
- key = store.getApiKeySync(providerId, profileName);
47
+ return store.get(providerId, profileName);
52
48
  } catch {
53
49
  return;
54
50
  }
55
- if (!key) return void 0;
56
- return {
57
- provider: providerId,
58
- profileId: profileName ?? "default",
59
- mode: "api-key",
60
- apiKey: key
61
- };
62
51
  }
63
52
  function readCfgApiKey(cfg, providerId) {
64
53
  const providers = cfg?.providers;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-auth.js","names":[],"sources":["../../../../src/providers/auth-runtime/resolve-auth.ts"],"sourcesContent":["/**\n * Higher-level auth resolution that returns the *full* profile context, not\n * just the API key. Vendors that support multiple auth modes (e.g. OpenAI\n * api-key + Codex OAuth + Azure api-key) call this to pick the right\n * branch.\n *\n * Resolution order matches `resolveApiKeyForProvider`:\n * 1. AuthProfileStore (per-agent profile — may be OAuth)\n * 2. cfg.providers.<id>.apiKey\n * 3. PROVIDER_ENV_MAP[providerId] env vars\n *\n * Returns:\n * - `mode: 'oauth' | 'azure-key' | 'api-key'`\n * - `apiKey` (or OAuth access token) if found\n * - `profileId` when the credential came from the store\n */\n\nimport { getApiKeyFromEnv } from '../env-keys.js';\nimport { getDefaultAuthProfileStore } from './auth-profile-store.js';\nimport type { AuthProfile, ProviderAuthMode, ResolveApiKeyOptions } from './types.js';\n\nexport interface ProviderAuthResolution {\n apiKey?: string;\n mode: ProviderAuthMode;\n profileId?: string;\n /** Source bucket: 'store' | 'config' | 'env' | 'none'. */\n source: 'store' | 'config' | 'env' | 'none';\n /** Vendor metadata copied from the matched profile (azure resource etc.). */\n meta?: Record<string, unknown>;\n}\n\nexport function resolveAuthProfileForProvider(\n options: ResolveApiKeyOptions,\n): ProviderAuthResolution {\n const { providerId } = options;\n if (!providerId) {\n return { apiKey: undefined, mode: 'api-key', source: 'none' };\n }\n\n // 1. Profile store\n const store = options.store ?? getDefaultAuthProfileStore();\n const profile = pickProfile(store, providerId, options.profileName);\n if (profile) {\n const key =\n (typeof profile.apiKey === 'string' && profile.apiKey.length > 0 ? profile.apiKey : undefined) ??\n (typeof profile.oauthAccessToken === 'string' && profile.oauthAccessToken.length > 0\n ? profile.oauthAccessToken\n : undefined);\n if (key) {\n return {\n apiKey: key,\n mode: profile.mode,\n profileId: profile.profileId,\n source: 'store',\n meta: profile.meta,\n };\n }\n }\n\n // 2. cfg.providers.<id>.apiKey\n const cfgKey = readCfgApiKey(options.cfg, providerId);\n if (cfgKey) {\n const azure = readCfgAzureMeta(options.cfg, providerId);\n return {\n apiKey: cfgKey,\n mode: azure ? 'azure-key' : 'api-key',\n source: 'config',\n meta: azure,\n };\n }\n\n // 3. env\n const envKey = options.envReader\n ? readFromCustomEnv(options.envReader, providerId)\n : getApiKeyFromEnv(providerId);\n if (envKey) {\n return { apiKey: envKey, mode: 'api-key', source: 'env' };\n }\n\n return { apiKey: undefined, mode: 'api-key', source: 'none' };\n}\n\nfunction pickProfile(\n store: { get?(p: string, id?: string): AuthProfile | undefined; getApiKeySync(p: string, id?: string): string | undefined },\n providerId: string,\n profileName?: string,\n): AuthProfile | undefined {\n if (typeof store.get === 'function') {\n try {\n return store.get(providerId, profileName);\n } catch {\n // fall through to legacy lookup\n }\n }\n // Legacy-only stores that just have getApiKeySync — synthesize a minimal\n // profile so callers can still branch on `mode === 'api-key'`.\n let key: string | undefined;\n try {\n key = store.getApiKeySync(providerId, profileName);\n } catch {\n return undefined;\n }\n if (!key) return undefined;\n return {\n provider: providerId,\n profileId: profileName ?? 'default',\n mode: 'api-key',\n apiKey: key,\n };\n}\n\nfunction readCfgApiKey(cfg: ResolveApiKeyOptions['cfg'], providerId: string): string | undefined {\n const providers = (cfg as unknown as { providers?: Record<string, unknown> } | undefined)?.providers;\n if (!providers || typeof providers !== 'object') return undefined;\n const entry = (providers as Record<string, unknown>)[providerId];\n if (!entry || typeof entry !== 'object') return undefined;\n const apiKey = (entry as Record<string, unknown>).apiKey;\n return typeof apiKey === 'string' && apiKey.length > 0 ? apiKey : undefined;\n}\n\nfunction readCfgAzureMeta(\n cfg: ResolveApiKeyOptions['cfg'],\n providerId: string,\n): Record<string, unknown> | undefined {\n const providers = (cfg as unknown as { providers?: Record<string, unknown> } | undefined)?.providers;\n if (!providers || typeof providers !== 'object') return undefined;\n const entry = (providers as Record<string, unknown>)[providerId];\n if (!entry || typeof entry !== 'object') return undefined;\n const azure = (entry as Record<string, unknown>).azure;\n return azure && typeof azure === 'object' ? (azure as Record<string, unknown>) : undefined;\n}\n\nfunction readFromCustomEnv(\n reader: (name: string) => string | undefined,\n providerId: string,\n): string | undefined {\n const fallbackName = providerId.toUpperCase().replace(/-/g, '_') + '_API_KEY';\n const v = reader(fallbackName);\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n"],"mappings":";;;eAiBkD;AAclD,SAAgB,8BACd,SACwB;CACxB,MAAM,EAAE,eAAe;AACvB,KAAI,CAAC,WACH,QAAO;EAAE,QAAQ,KAAA;EAAW,MAAM;EAAW,QAAQ;EAAQ;CAK/D,MAAM,UAAU,YADF,QAAQ,SAAS,4BAA4B,EACxB,YAAY,QAAQ,YAAY;AACnE,KAAI,SAAS;EACX,MAAM,OACH,OAAO,QAAQ,WAAW,YAAY,QAAQ,OAAO,SAAS,IAAI,QAAQ,SAAS,KAAA,OACnF,OAAO,QAAQ,qBAAqB,YAAY,QAAQ,iBAAiB,SAAS,IAC/E,QAAQ,mBACR,KAAA;AACN,MAAI,IACF,QAAO;GACL,QAAQ;GACR,MAAM,QAAQ;GACd,WAAW,QAAQ;GACnB,QAAQ;GACR,MAAM,QAAQ;GACf;;CAKL,MAAM,SAAS,cAAc,QAAQ,KAAK,WAAW;AACrD,KAAI,QAAQ;EACV,MAAM,QAAQ,iBAAiB,QAAQ,KAAK,WAAW;AACvD,SAAO;GACL,QAAQ;GACR,MAAM,QAAQ,cAAc;GAC5B,QAAQ;GACR,MAAM;GACP;;CAIH,MAAM,SAAS,QAAQ,YACnB,kBAAkB,QAAQ,WAAW,WAAW,GAChD,iBAAiB,WAAW;AAChC,KAAI,OACF,QAAO;EAAE,QAAQ;EAAQ,MAAM;EAAW,QAAQ;EAAO;AAG3D,QAAO;EAAE,QAAQ,KAAA;EAAW,MAAM;EAAW,QAAQ;EAAQ;;AAG/D,SAAS,YACP,OACA,YACA,aACyB;AACzB,KAAI,OAAO,MAAM,QAAQ,WACvB,KAAI;AACF,SAAO,MAAM,IAAI,YAAY,YAAY;SACnC;CAMV,IAAI;AACJ,KAAI;AACF,QAAM,MAAM,cAAc,YAAY,YAAY;SAC5C;AACN;;AAEF,KAAI,CAAC,IAAK,QAAO,KAAA;AACjB,QAAO;EACL,UAAU;EACV,WAAW,eAAe;EAC1B,MAAM;EACN,QAAQ;EACT;;AAGH,SAAS,cAAc,KAAkC,YAAwC;CAC/F,MAAM,YAAa,KAAwE;AAC3F,KAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO,KAAA;CACxD,MAAM,QAAS,UAAsC;AACrD,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,KAAA;CAChD,MAAM,SAAU,MAAkC;AAClD,QAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS,KAAA;;AAGpE,SAAS,iBACP,KACA,YACqC;CACrC,MAAM,YAAa,KAAwE;AAC3F,KAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO,KAAA;CACxD,MAAM,QAAS,UAAsC;AACrD,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,KAAA;CAChD,MAAM,QAAS,MAAkC;AACjD,QAAO,SAAS,OAAO,UAAU,WAAY,QAAoC,KAAA;;AAGnF,SAAS,kBACP,QACA,YACoB;CAEpB,MAAM,IAAI,OADW,WAAW,aAAa,CAAC,QAAQ,MAAM,IAAI,GAAG,WACrC;AAC9B,QAAO,OAAO,MAAM,YAAY,EAAE,SAAS,IAAI,IAAI,KAAA"}
1
+ {"version":3,"file":"resolve-auth.js","names":[],"sources":["../../../../src/providers/auth-runtime/resolve-auth.ts"],"sourcesContent":["/**\n * Higher-level auth resolution that returns the *full* profile context, not\n * just the API key. Vendors that support multiple auth modes (e.g. OpenAI\n * api-key + Codex OAuth + Azure api-key) call this to pick the right\n * branch.\n *\n * Resolution order matches `resolveApiKeyForProvider`:\n * 1. AuthProfileStore (per-agent profile — may be OAuth)\n * 2. cfg.providers.<id>.apiKey\n * 3. PROVIDER_ENV_MAP[providerId] env vars\n *\n * Returns:\n * - `mode: 'oauth' | 'azure-key' | 'api-key'`\n * - `apiKey` (or OAuth access token) if found\n * - `profileId` when the credential came from the store\n */\n\nimport { getApiKeyFromEnv } from '../env-keys.js';\nimport { getDefaultAuthProfileStore } from './auth-profile-store.js';\nimport type { AuthProfile, AuthProfileStore, ProviderAuthMode, ResolveApiKeyOptions } from './types.js';\n\nexport interface ProviderAuthResolution {\n apiKey?: string;\n mode: ProviderAuthMode;\n profileId?: string;\n /** Source bucket: 'store' | 'config' | 'env' | 'none'. */\n source: 'store' | 'config' | 'env' | 'none';\n /** Vendor metadata copied from the matched profile (azure resource etc.). */\n meta?: Record<string, unknown>;\n}\n\nexport function resolveAuthProfileForProvider(\n options: ResolveApiKeyOptions,\n): ProviderAuthResolution {\n const { providerId } = options;\n if (!providerId) {\n return { apiKey: undefined, mode: 'api-key', source: 'none' };\n }\n\n // 1. Profile store\n const store = options.store ?? getDefaultAuthProfileStore();\n const profile = pickProfile(store, providerId, options.profileName);\n if (profile) {\n const key =\n (typeof profile.apiKey === 'string' && profile.apiKey.length > 0 ? profile.apiKey : undefined) ??\n (typeof profile.oauthAccessToken === 'string' && profile.oauthAccessToken.length > 0\n ? profile.oauthAccessToken\n : undefined);\n if (key) {\n return {\n apiKey: key,\n mode: profile.mode,\n profileId: profile.profileId,\n source: 'store',\n meta: profile.meta,\n };\n }\n }\n\n // 2. cfg.providers.<id>.apiKey\n const cfgKey = readCfgApiKey(options.cfg, providerId);\n if (cfgKey) {\n const azure = readCfgAzureMeta(options.cfg, providerId);\n return {\n apiKey: cfgKey,\n mode: azure ? 'azure-key' : 'api-key',\n source: 'config',\n meta: azure,\n };\n }\n\n // 3. env\n const envKey = options.envReader\n ? readFromCustomEnv(options.envReader, providerId)\n : getApiKeyFromEnv(providerId);\n if (envKey) {\n return { apiKey: envKey, mode: 'api-key', source: 'env' };\n }\n\n return { apiKey: undefined, mode: 'api-key', source: 'none' };\n}\n\nfunction pickProfile(\n store: AuthProfileStore,\n providerId: string,\n profileName?: string,\n): AuthProfile | undefined {\n try {\n return store.get(providerId, profileName);\n } catch {\n return undefined;\n }\n}\n\nfunction readCfgApiKey(cfg: ResolveApiKeyOptions['cfg'], providerId: string): string | undefined {\n const providers = (cfg as unknown as { providers?: Record<string, unknown> } | undefined)?.providers;\n if (!providers || typeof providers !== 'object') return undefined;\n const entry = (providers as Record<string, unknown>)[providerId];\n if (!entry || typeof entry !== 'object') return undefined;\n const apiKey = (entry as Record<string, unknown>).apiKey;\n return typeof apiKey === 'string' && apiKey.length > 0 ? apiKey : undefined;\n}\n\nfunction readCfgAzureMeta(\n cfg: ResolveApiKeyOptions['cfg'],\n providerId: string,\n): Record<string, unknown> | undefined {\n const providers = (cfg as unknown as { providers?: Record<string, unknown> } | undefined)?.providers;\n if (!providers || typeof providers !== 'object') return undefined;\n const entry = (providers as Record<string, unknown>)[providerId];\n if (!entry || typeof entry !== 'object') return undefined;\n const azure = (entry as Record<string, unknown>).azure;\n return azure && typeof azure === 'object' ? (azure as Record<string, unknown>) : undefined;\n}\n\nfunction readFromCustomEnv(\n reader: (name: string) => string | undefined,\n providerId: string,\n): string | undefined {\n const fallbackName = providerId.toUpperCase().replace(/-/g, '_') + '_API_KEY';\n const v = reader(fallbackName);\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n"],"mappings":";;;eAiBkD;AAclD,SAAgB,8BACd,SACwB;CACxB,MAAM,EAAE,eAAe;AACvB,KAAI,CAAC,WACH,QAAO;EAAE,QAAQ,KAAA;EAAW,MAAM;EAAW,QAAQ;EAAQ;CAK/D,MAAM,UAAU,YADF,QAAQ,SAAS,4BAA4B,EACxB,YAAY,QAAQ,YAAY;AACnE,KAAI,SAAS;EACX,MAAM,OACH,OAAO,QAAQ,WAAW,YAAY,QAAQ,OAAO,SAAS,IAAI,QAAQ,SAAS,KAAA,OACnF,OAAO,QAAQ,qBAAqB,YAAY,QAAQ,iBAAiB,SAAS,IAC/E,QAAQ,mBACR,KAAA;AACN,MAAI,IACF,QAAO;GACL,QAAQ;GACR,MAAM,QAAQ;GACd,WAAW,QAAQ;GACnB,QAAQ;GACR,MAAM,QAAQ;GACf;;CAKL,MAAM,SAAS,cAAc,QAAQ,KAAK,WAAW;AACrD,KAAI,QAAQ;EACV,MAAM,QAAQ,iBAAiB,QAAQ,KAAK,WAAW;AACvD,SAAO;GACL,QAAQ;GACR,MAAM,QAAQ,cAAc;GAC5B,QAAQ;GACR,MAAM;GACP;;CAIH,MAAM,SAAS,QAAQ,YACnB,kBAAkB,QAAQ,WAAW,WAAW,GAChD,iBAAiB,WAAW;AAChC,KAAI,OACF,QAAO;EAAE,QAAQ;EAAQ,MAAM;EAAW,QAAQ;EAAO;AAG3D,QAAO;EAAE,QAAQ,KAAA;EAAW,MAAM;EAAW,QAAQ;EAAQ;;AAG/D,SAAS,YACP,OACA,YACA,aACyB;AACzB,KAAI;AACF,SAAO,MAAM,IAAI,YAAY,YAAY;SACnC;AACN;;;AAIJ,SAAS,cAAc,KAAkC,YAAwC;CAC/F,MAAM,YAAa,KAAwE;AAC3F,KAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO,KAAA;CACxD,MAAM,QAAS,UAAsC;AACrD,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,KAAA;CAChD,MAAM,SAAU,MAAkC;AAClD,QAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS,KAAA;;AAGpE,SAAS,iBACP,KACA,YACqC;CACrC,MAAM,YAAa,KAAwE;AAC3F,KAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO,KAAA;CACxD,MAAM,QAAS,UAAsC;AACrD,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,KAAA;CAChD,MAAM,QAAS,MAAkC;AACjD,QAAO,SAAS,OAAO,UAAU,WAAY,QAAoC,KAAA;;AAGnF,SAAS,kBACP,QACA,YACoB;CAEpB,MAAM,IAAI,OADW,WAAW,aAAa,CAAC,QAAQ,MAAM,IAAI,GAAG,WACrC;AAC9B,QAAO,OAAO,MAAM,YAAY,EAAE,SAAS,IAAI,IAAI,KAAA"}
@@ -3,11 +3,6 @@
3
3
  * (image / audio / video). Decoupled from the LLM-side
4
4
  * `src/auth/credentials.ts` so capability providers do not need to
5
5
  * `await` for every isConfigured() call.
6
- *
7
- * Step 4 expands {@link AuthProfileStore} from a simple key lookup into a
8
- * full per-agent profile store that can hold OAuth tokens and refresh them
9
- * on demand, while keeping every existing sync caller working (legacy
10
- * methods remain on the interface).
11
6
  */
12
7
  import type { Config } from '../../config/schema.js';
13
8
  export interface ResolveApiKeyOptions {
@@ -58,20 +53,19 @@ export interface AuthProfile {
58
53
  *
59
54
  * Sync members ({@link getApiKeySync}, {@link hasCredentialSync}) keep
60
55
  * `resolveApiKeyForProvider` synchronous so capability providers and tool
61
- * default-model resolution stay non-blocking. Async members
62
- * ({@link list}, {@link get}, {@link save}, {@link refresh}) are used by
63
- * vendor-specific code (Codex / Anthropic OAuth) and the gateway settings
64
- * UI.
56
+ * default-model resolution stay non-blocking. {@link get} / {@link list} are
57
+ * required so OAuth-aware callers can branch on `mode` without falling back
58
+ * to the sync getters.
65
59
  */
66
60
  export interface AuthProfileStore {
67
61
  /** Synchronous lookup; returns undefined when no profile is loaded. */
68
62
  getApiKeySync(providerId: string, profile?: string): string | undefined;
69
63
  /** Synchronous "do we have any usable credential" check. */
70
64
  hasCredentialSync(providerId: string, profile?: string): boolean;
71
- /** All profiles for a provider (Step 4 stores can return multiple). */
72
- list?(providerId: string): AuthProfile[];
65
+ /** All profiles for a provider. */
66
+ list(providerId: string): AuthProfile[];
73
67
  /** Single profile; defaults to `default: true` then "default" id. */
74
- get?(providerId: string, profileId?: string): AuthProfile | undefined;
68
+ get(providerId: string, profileId?: string): AuthProfile | undefined;
75
69
  /** Persist a profile; replaces any existing record with the same id. */
76
70
  save?(profile: AuthProfile): Promise<void>;
77
71
  /** Refresh OAuth access token; idempotent if still fresh. */
@@ -1,8 +1,8 @@
1
1
  import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
- import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
3
2
  import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
4
- import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
5
3
  import { CredentialResolver, hasCredentials, init_credentials, resolveApiKey } from "../auth/credentials.js";
4
+ import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
5
+ import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
6
6
  import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
7
7
  import { getModel, getModels, getProviders } from "@earendil-works/pi-ai";
8
8
  //#region src/providers/index.ts
@@ -1,10 +1,10 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
+ import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
4
5
  import { resolveModelsJsonPath } from "../config/paths.js";
5
6
  import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
6
7
  import { getDefaultModelValues, init_models_json, validateModelsConfig } from "../config/models-json.js";
7
- import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
8
8
  import { existsSync, readFileSync } from "fs";
9
9
  import { getModels, getProviders } from "@earendil-works/pi-ai";
10
10
  //#region src/providers/model-registry.ts