@xopcai/xopc 0.0.90 → 0.0.92

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 (365) hide show
  1. package/README.md +36 -12
  2. package/README.zh-CN.md +36 -12
  3. package/dist/browser-ext/manifest.json +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/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/extensions/weixin/src/api/api.js +2 -2
  11. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  12. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  13. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  15. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  17. package/dist/extensions/weixin/src/plugin.js +1 -1
  18. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  19. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  20. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +41 -0
  21. package/dist/gateway/static/root/assets/agents-uwPn7ZW9.js +222 -0
  22. package/dist/gateway/static/root/assets/apps-page-CWKdhSPU.js +1 -0
  23. package/dist/gateway/static/root/assets/{attachment-preview-renderer-CpyoFbs4.js → attachment-preview-renderer-DBAxQXb-.js} +2 -2
  24. package/dist/gateway/static/root/assets/{attachment-process-heavy-CqVriadb.js → attachment-process-heavy-Csq3TrrP.js} +4 -4
  25. package/dist/gateway/static/root/assets/channels-settings-hEhW7Mbk.js +1 -0
  26. package/dist/gateway/static/root/assets/{channels-status-swr-BrtH2VzC.js → channels-status-swr-XzddfJW2.js} +1 -1
  27. package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +1 -0
  28. package/dist/gateway/static/root/assets/{cron-api-CyqbgfHM.js → cron-api--I8LJ44S.js} +1 -1
  29. package/dist/gateway/static/root/assets/cron-page-B0kvgZGR.js +1 -0
  30. package/dist/gateway/static/root/assets/dist-CYgHMQO0.js +1 -0
  31. package/dist/gateway/static/root/assets/{extension-debug-page-D6Ak0STa.js → extension-debug-page-6cRP0nA9.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-Q0P3d6DW.js → extension-page-DpwIkspI.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-CL55LwU_.js → extension-settings-page-DYbnQUxH.js} +1 -1
  34. package/dist/gateway/static/root/assets/{fetch-Dqa9iTWl.js → fetch-DTN0w7rV.js} +1 -1
  35. package/dist/gateway/static/root/assets/{field-primitives-HUR6JElP.js → field-primitives-CslW6HwD.js} +1 -1
  36. package/dist/gateway/static/root/assets/heartbeat-config-api-2UiKevxG.js +1 -0
  37. package/dist/gateway/static/root/assets/index-BUKUv7QW.css +1 -0
  38. package/dist/gateway/static/root/assets/{index-BYcGfwcE.js → index-DnevRVa6.js} +63 -59
  39. package/dist/gateway/static/root/assets/logs-page-sOP4TXJ4.js +1 -0
  40. package/dist/gateway/static/root/assets/note-detail-page-B91pLkEI.css +1 -0
  41. package/dist/gateway/static/root/assets/note-detail-page-DvW2qg4i.js +179 -0
  42. package/dist/gateway/static/root/assets/note-time-BEiibLJv.js +1 -0
  43. package/dist/gateway/static/root/assets/notes-page-BFQaquHU.js +1 -0
  44. package/dist/gateway/static/root/assets/{pdf-BnEvgIXZ.js → pdf-epILhEOn.js} +1 -1
  45. package/dist/gateway/static/root/assets/preload-helper-zJ_50EbN.js +1 -0
  46. package/dist/gateway/static/root/assets/sessions-page-CptjDKAX.js +1 -0
  47. package/dist/gateway/static/root/assets/settings-advanced-gate-BctKqHcf.js +2 -0
  48. package/dist/gateway/static/root/assets/{settings-form-section-a0qGVOlr.js → settings-form-section-QJh5ruel.js} +1 -1
  49. package/dist/gateway/static/root/assets/settings-page-V3p-hISB.js +2 -0
  50. package/dist/gateway/static/root/assets/share-preview-page-DBsvvbmD.js +2 -0
  51. package/dist/gateway/static/root/assets/skills-page-q2zPUJAR.js +2 -0
  52. package/dist/gateway/static/root/assets/{theme-store-C0Ehmdo5.js → theme-store-ht5iswWS.js} +1 -1
  53. package/dist/gateway/static/root/assets/toast-z0toXu32.js +1 -0
  54. package/dist/gateway/static/root/assets/url-CWWpfkq1.js +3 -0
  55. package/dist/gateway/static/root/assets/{utils-DRQryzdn.js → utils-DhPv9xoB.js} +1 -1
  56. package/dist/gateway/static/root/assets/vendor-codemirror-DYoKfS8f.js +45 -0
  57. package/dist/gateway/static/root/assets/voice-api-key-field-DLSKUipa.js +1 -0
  58. package/dist/gateway/static/root/assets/{workflow-page.utils-DnG8JBhV.js → workflow-page.utils-CJqnPWkW.js} +1 -1
  59. package/dist/gateway/static/root/assets/workflows-page-DRRQ1A0l.js +27 -0
  60. package/dist/gateway/static/root/index.html +10 -8
  61. package/dist/package.js +1 -1
  62. package/dist/src/agent/agent-manager.js +7 -7
  63. package/dist/src/agent/agent-scope.js +1 -1
  64. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  65. package/dist/src/agent/context/workspace-seed.js +2 -2
  66. package/dist/src/agent/goals/goal-run-store.js +4 -4
  67. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  68. package/dist/src/agent/goals/post-turn.js +2 -2
  69. package/dist/src/agent/image/load-image-media.js +2 -2
  70. package/dist/src/agent/ipc/bus.js +1 -1
  71. package/dist/src/agent/ipc/inbox.js +2 -2
  72. package/dist/src/agent/ipc/socket.js +1 -1
  73. package/dist/src/agent/mcp/bundle-mcp-config.d.ts +2 -9
  74. package/dist/src/agent/mcp/bundle-mcp-config.js +10 -34
  75. package/dist/src/agent/mcp/bundle-mcp-config.js.map +1 -1
  76. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  77. package/dist/src/agent/mcp/bundle-mcp-policy.js +2 -2
  78. package/dist/src/agent/mcp/bundle-mcp-policy.js.map +1 -1
  79. package/dist/src/agent/mcp/bundle-mcp-runtime.js +5 -5
  80. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  81. package/dist/src/agent/mcp/index.js +2 -2
  82. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  83. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  84. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  85. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  86. package/dist/src/agent/memory/dreaming/events.js +1 -1
  87. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  88. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  89. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  90. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  91. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  92. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  93. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  94. package/dist/src/agent/models/manager.js +1 -1
  95. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  96. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  97. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  98. package/dist/src/agent/sandbox/path-policy.js +2 -2
  99. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  100. package/dist/src/agent/service.js +4 -4
  101. package/dist/src/agent/session/session-inspector.js +1 -1
  102. package/dist/src/agent/skills/config.js +1 -1
  103. package/dist/src/agent/skills/hub-hash.js +2 -2
  104. package/dist/src/agent/skills/hub-lock.js +1 -1
  105. package/dist/src/agent/skills/hub-pull.js +2 -2
  106. package/dist/src/agent/skills/index.js +1 -1
  107. package/dist/src/agent/skills/managed-store.js +1 -1
  108. package/dist/src/agent/skills/scanner.js +1 -1
  109. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  110. package/dist/src/agent/skills/skill-manager.js +1 -1
  111. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  112. package/dist/src/agent/tools/factory.js +1 -1
  113. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  114. package/dist/src/agent/tools/send-media.js +1 -1
  115. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  116. package/dist/src/agent/tools/workflow-tool.js +1 -1
  117. package/dist/src/agent/tools/write.js +1 -1
  118. package/dist/src/agent/workflow/catalog.js +1 -1
  119. package/dist/src/auth/credentials.js +3 -3
  120. package/dist/src/auth/profiles/store.js +1 -1
  121. package/dist/src/auth/sync-provider-auth.js +1 -1
  122. package/dist/src/browser/cache-dir-policy.js +1 -1
  123. package/dist/src/browser/cdp-local-launcher.js +2 -2
  124. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  125. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  126. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  127. package/dist/src/browser/stealth.js +1 -1
  128. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  129. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  130. package/dist/src/channels/outbound/persist-store.js +1 -1
  131. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  132. package/dist/src/channels/pairing/pairing-store.js +2 -2
  133. package/dist/src/chat-commands/agent-edit.js +2 -2
  134. package/dist/src/chat-commands/builtins/config.js +2 -2
  135. package/dist/src/chat-commands/context.js +1 -1
  136. package/dist/src/cli/command-catalog.js +0 -4
  137. package/dist/src/cli/command-catalog.js.map +1 -1
  138. package/dist/src/cli/command-loaders.js +1 -2
  139. package/dist/src/cli/command-loaders.js.map +1 -1
  140. package/dist/src/cli/command-manifest.js +0 -4
  141. package/dist/src/cli/command-manifest.js.map +1 -1
  142. package/dist/src/cli/commands/config.js +1 -1
  143. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  144. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  145. package/dist/src/cli/commands/doctor/checks/session-integrity.js +2 -2
  146. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  147. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  148. package/dist/src/cli/commands/extension-dev.js +1 -1
  149. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  150. package/dist/src/cli/commands/extension-pack.js +1 -1
  151. package/dist/src/cli/commands/gateway/logs.js +1 -1
  152. package/dist/src/cli/commands/image.js +1 -1
  153. package/dist/src/cli/commands/init.js +4 -4
  154. package/dist/src/cli/commands/onboard.js +1 -1
  155. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  156. package/dist/src/commands/agents.config.js +1 -1
  157. package/dist/src/config/agent-profile.js +1 -1
  158. package/dist/src/config/gateway-bind.js +1 -1
  159. package/dist/src/config/index.d.ts +0 -1
  160. package/dist/src/config/index.js +6 -7
  161. package/dist/src/config/index.js.map +1 -1
  162. package/dist/src/config/loader.js +2 -2
  163. package/dist/src/config/models-json.js +2 -2
  164. package/dist/src/config/paths-state.js +1 -1
  165. package/dist/src/config/profile.js +2 -2
  166. package/dist/src/config/schema.d.ts +36 -6
  167. package/dist/src/config/schema.js +13 -11
  168. package/dist/src/config/schema.js.map +1 -1
  169. package/dist/src/config/workspace-path.js +1 -1
  170. package/dist/src/connectors/builtin-catalog.d.ts +2 -0
  171. package/dist/src/connectors/builtin-catalog.js +152 -0
  172. package/dist/src/connectors/builtin-catalog.js.map +1 -0
  173. package/dist/src/connectors/catalog.d.ts +5 -0
  174. package/dist/src/connectors/catalog.js +13 -0
  175. package/dist/src/connectors/catalog.js.map +1 -0
  176. package/dist/src/connectors/health.d.ts +3 -0
  177. package/dist/src/connectors/health.js +61 -0
  178. package/dist/src/connectors/health.js.map +1 -0
  179. package/dist/src/connectors/install.d.ts +5 -0
  180. package/dist/src/connectors/install.js +46 -0
  181. package/dist/src/connectors/install.js.map +1 -0
  182. package/dist/src/connectors/instances.d.ts +4 -0
  183. package/dist/src/connectors/instances.js +43 -0
  184. package/dist/src/connectors/instances.js.map +1 -0
  185. package/dist/src/connectors/materialize.d.ts +9 -0
  186. package/dist/src/connectors/materialize.js +76 -0
  187. package/dist/src/connectors/materialize.js.map +1 -0
  188. package/dist/src/connectors/oauth.d.ts +22 -0
  189. package/dist/src/connectors/oauth.js +99 -0
  190. package/dist/src/connectors/oauth.js.map +1 -0
  191. package/dist/src/connectors/providers.d.ts +9 -0
  192. package/dist/src/connectors/providers.js +20 -0
  193. package/dist/src/connectors/providers.js.map +1 -0
  194. package/dist/src/connectors/secret-store.d.ts +7 -0
  195. package/dist/src/connectors/secret-store.js +47 -0
  196. package/dist/src/connectors/secret-store.js.map +1 -0
  197. package/dist/src/connectors/types.d.ts +102 -0
  198. package/dist/src/connectors/types.js +1 -0
  199. package/dist/src/connectors/usage.d.ts +6 -0
  200. package/dist/src/connectors/usage.js +63 -0
  201. package/dist/src/connectors/usage.js.map +1 -0
  202. package/dist/src/cron/executor.js +2 -2
  203. package/dist/src/cron/persistence.js +1 -1
  204. package/dist/src/cron/run-log-store.js +1 -1
  205. package/dist/src/daemon/constants.js +1 -1
  206. package/dist/src/daemon/install-plan.js +2 -2
  207. package/dist/src/daemon/launchd.js +2 -2
  208. package/dist/src/daemon/schtasks.js +2 -2
  209. package/dist/src/daemon/systemd.js +2 -2
  210. package/dist/src/extensions/bundle-mcp.js +1 -1
  211. package/dist/src/extensions/discover-extensions.js +1 -1
  212. package/dist/src/extensions/health.js +1 -1
  213. package/dist/src/extensions/loader.js +1 -1
  214. package/dist/src/extensions/lockfile.js +2 -2
  215. package/dist/src/extensions/update.js +1 -1
  216. package/dist/src/gateway/agents-admin.js +3 -3
  217. package/dist/src/gateway/file-path-classifier.js +2 -2
  218. package/dist/src/gateway/heartbeat/service.js +1 -1
  219. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  220. package/dist/src/gateway/hono/lib/config-payload.js +2 -1
  221. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  222. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  223. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  224. package/dist/src/gateway/hono/middleware/auth.js +1 -2
  225. package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
  226. package/dist/src/gateway/hono/oauth.js +1 -1
  227. package/dist/src/gateway/hono/routes/agents.js +1 -1
  228. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  229. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +2 -2
  230. package/dist/src/gateway/hono/routes/config-patch/gateway.js +12 -0
  231. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  232. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  233. package/dist/src/gateway/hono/routes/connectors.d.ts +3 -0
  234. package/dist/src/gateway/hono/routes/connectors.js +177 -0
  235. package/dist/src/gateway/hono/routes/connectors.js.map +1 -0
  236. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  237. package/dist/src/gateway/hono/routes/home.d.ts +12 -0
  238. package/dist/src/gateway/hono/routes/home.js +50 -0
  239. package/dist/src/gateway/hono/routes/home.js.map +1 -0
  240. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  241. package/dist/src/gateway/hono/routes/lazy-bundles.js +20 -4
  242. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  243. package/dist/src/gateway/hono/routes/models.js +1 -1
  244. package/dist/src/gateway/hono/routes/notes.d.ts +3 -0
  245. package/dist/src/gateway/hono/routes/notes.js +305 -0
  246. package/dist/src/gateway/hono/routes/notes.js.map +1 -0
  247. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  248. package/dist/src/gateway/hono/routes/shares.js +1 -1
  249. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  250. package/dist/src/gateway/lock.js +3 -3
  251. package/dist/src/gateway/ports.js +1 -1
  252. package/dist/src/gateway/service/agent-runner.js +2 -2
  253. package/dist/src/gateway/service/marketplace-service.js +2 -2
  254. package/dist/src/gateway/service.d.ts +3 -0
  255. package/dist/src/gateway/service.js +11 -1
  256. package/dist/src/gateway/service.js.map +1 -1
  257. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  258. package/dist/src/gateway/workspace-ripgrep.d.ts +6 -0
  259. package/dist/src/gateway/workspace-ripgrep.js +62 -11
  260. package/dist/src/gateway/workspace-ripgrep.js.map +1 -1
  261. package/dist/src/heartbeat/index.js +1 -1
  262. package/dist/src/infra/brew.js +1 -1
  263. package/dist/src/infra/package-json.js +1 -1
  264. package/dist/src/infra/package-update-steps.js +1 -1
  265. package/dist/src/infra/path-env.js +2 -2
  266. package/dist/src/infra/restart.js +2 -2
  267. package/dist/src/infra/stable-node-path.js +1 -1
  268. package/dist/src/infra/update-check.js +1 -1
  269. package/dist/src/infra/update-global.js +1 -1
  270. package/dist/src/infra/update-lock.js +3 -3
  271. package/dist/src/infra/update-runner.js +1 -1
  272. package/dist/src/infra/update-startup.js +2 -2
  273. package/dist/src/infra/write-file-atomic.js +2 -2
  274. package/dist/src/mcp/channel-bridge.js +1 -1
  275. package/dist/src/mcp/channel-bridge.js.map +1 -1
  276. package/dist/src/notes/attachment-ref.d.ts +9 -0
  277. package/dist/src/notes/attachment-ref.js +27 -0
  278. package/dist/src/notes/attachment-ref.js.map +1 -0
  279. package/dist/src/notes/index.d.ts +4 -0
  280. package/dist/src/notes/index.js +4 -0
  281. package/dist/src/notes/note-attachment-sync.d.ts +7 -0
  282. package/dist/src/notes/note-attachment-sync.js +46 -0
  283. package/dist/src/notes/note-attachment-sync.js.map +1 -0
  284. package/dist/src/notes/note-index-meta.d.ts +14 -0
  285. package/dist/src/notes/note-index-meta.js +87 -0
  286. package/dist/src/notes/note-index-meta.js.map +1 -0
  287. package/dist/src/notes/paths.d.ts +5 -0
  288. package/dist/src/notes/paths.js +23 -0
  289. package/dist/src/notes/paths.js.map +1 -0
  290. package/dist/src/notes/service.d.ts +53 -0
  291. package/dist/src/notes/service.js +373 -0
  292. package/dist/src/notes/service.js.map +1 -0
  293. package/dist/src/notes/store.d.ts +34 -0
  294. package/dist/src/notes/store.js +342 -0
  295. package/dist/src/notes/store.js.map +1 -0
  296. package/dist/src/notes/types.d.ts +199 -0
  297. package/dist/src/notes/types.js +1 -0
  298. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  299. package/dist/src/providers/index.js +2 -2
  300. package/dist/src/providers/model-registry.js +1 -1
  301. package/dist/src/session/config-store.js +2 -2
  302. package/dist/src/session/init-session-turn.js +2 -2
  303. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  304. package/dist/src/session/parity/sessions-json-file.js +1 -1
  305. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  306. package/dist/src/session/parity/transcript-paths.js +1 -1
  307. package/dist/src/session/resolve-session.js +4 -4
  308. package/dist/src/session/search-index-cache.js +1 -1
  309. package/dist/src/session/search-index.js +1 -1
  310. package/dist/src/session/session-title.js +2 -2
  311. package/dist/src/session/store.d.ts +2 -0
  312. package/dist/src/session/store.js +27 -7
  313. package/dist/src/session/store.js.map +1 -1
  314. package/dist/src/share/share-auto.js +2 -2
  315. package/dist/src/share/share-store.js +3 -3
  316. package/dist/src/share/share-thumbnail.js +2 -2
  317. package/dist/src/share/share-zip.js +1 -1
  318. package/dist/src/share/site-share-store.js +3 -3
  319. package/dist/src/share/site-static-serve.js +1 -1
  320. package/dist/src/tui/clipboard-image.js +3 -3
  321. package/dist/src/tui/theme-manager.js +1 -1
  322. package/dist/src/tui/tui-keybindings-file.js +1 -1
  323. package/dist/src/tui/tui-scoped-models.js +2 -2
  324. package/dist/src/tui/tui-settings.js +1 -1
  325. package/dist/src/tui/tui.js +3 -3
  326. package/dist/src/tunnel/frpc-binary.js +3 -3
  327. package/dist/src/tunnel/frpc-config.js +1 -1
  328. package/dist/src/tunnel/frpc-extract.js +1 -1
  329. package/dist/src/tunnel/tunnel-state.js +1 -1
  330. package/dist/src/utils/logger/audit.js +1 -1
  331. package/dist/src/utils/logger/log-store.js +1 -1
  332. package/dist/src/utils/logger/rotation.js +1 -1
  333. package/dist/src/voice/tts/audio.js +1 -1
  334. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  335. package/dist/src/workflows/store/event-store.js +1 -1
  336. package/dist/src/workflows/store/run-store.js +1 -1
  337. package/package.json +1 -1
  338. package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +0 -222
  339. package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +0 -1
  340. package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +0 -1
  341. package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +0 -2
  342. package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +0 -1
  343. package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +0 -45
  344. package/dist/gateway/static/root/assets/dist-BpAiK86n.js +0 -1
  345. package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +0 -1
  346. package/dist/gateway/static/root/assets/heartbeat-config-api-DusckjUX.js +0 -1
  347. package/dist/gateway/static/root/assets/index-V7MQ7834.css +0 -1
  348. package/dist/gateway/static/root/assets/logs-page-_HcZ2fgK.js +0 -1
  349. package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +0 -1
  350. package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +0 -3
  351. package/dist/gateway/static/root/assets/share-preview-page-DExl7CJy.js +0 -2
  352. package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +0 -2
  353. package/dist/gateway/static/root/assets/url-fxyYANfA.js +0 -3
  354. package/dist/gateway/static/root/assets/vendor-codemirror-D0yxdRpg.js +0 -58
  355. package/dist/gateway/static/root/assets/voice-api-key-field-D0viACE2.js +0 -1
  356. package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +0 -27
  357. package/dist/src/cli/commands/mcp.d.ts +0 -4
  358. package/dist/src/cli/commands/mcp.js +0 -85
  359. package/dist/src/cli/commands/mcp.js.map +0 -1
  360. package/dist/src/config/mcp-config.d.ts +0 -34
  361. package/dist/src/config/mcp-config.js +0 -116
  362. package/dist/src/config/mcp-config.js.map +0 -1
  363. package/dist/src/gateway/hono/routes/mcp.d.ts +0 -3
  364. package/dist/src/gateway/hono/routes/mcp.js +0 -99
  365. package/dist/src/gateway/hono/routes/mcp.js.map +0 -1
@@ -0,0 +1,13 @@
1
+ import { listConnectorProviderDefinitions, listConnectorProviders } from "./providers.js";
2
+ //#region src/connectors/catalog.ts
3
+ const CONNECTOR_BY_ID = new Map(listConnectorProviderDefinitions().map((connector) => [connector.id, connector]));
4
+ function listConnectorCatalog() {
5
+ return listConnectorProviderDefinitions().sort((left, right) => left.displayName.localeCompare(right.displayName));
6
+ }
7
+ function getConnectorDefinition(connectorId) {
8
+ return CONNECTOR_BY_ID.get(connectorId);
9
+ }
10
+ //#endregion
11
+ export { getConnectorDefinition, listConnectorCatalog, listConnectorProviders };
12
+
13
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","names":[],"sources":["../../../src/connectors/catalog.ts"],"sourcesContent":["import { listConnectorProviderDefinitions, listConnectorProviders } from './providers.js';\nimport type { ConnectorDefinition } from './types.js';\n\nconst CONNECTOR_BY_ID = new Map(listConnectorProviderDefinitions().map((connector) => [connector.id, connector]));\n\nexport function listConnectorCatalog(): ConnectorDefinition[] {\n return listConnectorProviderDefinitions().sort((left, right) => left.displayName.localeCompare(right.displayName));\n}\n\nexport function getConnectorDefinition(connectorId: string): ConnectorDefinition | undefined {\n return CONNECTOR_BY_ID.get(connectorId);\n}\n\nexport { listConnectorProviders };\n"],"mappings":";;AAGA,MAAM,kBAAkB,IAAI,IAAI,kCAAkC,CAAC,KAAK,cAAc,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC;AAEjH,SAAgB,uBAA8C;AAC5D,QAAO,kCAAkC,CAAC,MAAM,MAAM,UAAU,KAAK,YAAY,cAAc,MAAM,YAAY,CAAC;;AAGpH,SAAgB,uBAAuB,aAAsD;AAC3F,QAAO,gBAAgB,IAAI,YAAY"}
@@ -0,0 +1,3 @@
1
+ import type { Config } from '../config/schema.js';
2
+ import type { ConnectorHealthResult } from './types.js';
3
+ export declare function testConnectorInstance(config: Config, serverId: string): Promise<ConnectorHealthResult>;
@@ -0,0 +1,61 @@
1
+ import { getConnectorInstance } from "./instances.js";
2
+ import { createBundleMcpToolRuntime, mapBundleMcpToolsForGateway } from "../agent/mcp/bundle-mcp-materialize.js";
3
+ import { getWorkspacePath } from "../config/workspace-path-helpers.js";
4
+ //#region src/connectors/health.ts
5
+ function classifyConnectorHealthError(error) {
6
+ const message = error instanceof Error ? error.message : String(error);
7
+ if (/timed out|timeout/i.test(message)) return "timeout";
8
+ if (/ECONN|ENOTFOUND|network|fetch failed/i.test(message)) return "network_failed";
9
+ if (/missing|required|credential|api key|token/i.test(message)) return "missing_secret";
10
+ if (/tools|listTools/i.test(message)) return "tools_list_failed";
11
+ if (/spawn|command|start|connect/i.test(message)) return "startup_failed";
12
+ return "unknown_error";
13
+ }
14
+ function healthActionForStatus(status) {
15
+ if (status === "missing_secret") return "Reconnect the connector and provide the required secret.";
16
+ if (status === "timeout" || status === "network_failed") return "Check network access and retry the connector health check.";
17
+ if (status === "startup_failed") return "Verify the connector runtime dependency is installed and reachable.";
18
+ }
19
+ async function testConnectorInstance(config, serverId) {
20
+ if (!getConnectorInstance(config, serverId)) return {
21
+ serverId,
22
+ ok: false,
23
+ status: "server_not_found",
24
+ toolCount: 0,
25
+ tools: [],
26
+ error: `Connector instance not found: ${serverId}`
27
+ };
28
+ const workspaceDir = getWorkspacePath(config) || "./workspace";
29
+ let runtime;
30
+ try {
31
+ runtime = await createBundleMcpToolRuntime({
32
+ workspaceDir,
33
+ cfg: config
34
+ });
35
+ const tools = mapBundleMcpToolsForGateway(runtime.tools, serverId);
36
+ return {
37
+ serverId,
38
+ ok: true,
39
+ status: "ok",
40
+ toolCount: tools.length,
41
+ tools
42
+ };
43
+ } catch (error) {
44
+ const status = classifyConnectorHealthError(error);
45
+ return {
46
+ serverId,
47
+ ok: false,
48
+ status,
49
+ toolCount: 0,
50
+ tools: [],
51
+ error: error instanceof Error ? error.message : String(error),
52
+ action: healthActionForStatus(status)
53
+ };
54
+ } finally {
55
+ await runtime?.dispose();
56
+ }
57
+ }
58
+ //#endregion
59
+ export { testConnectorInstance };
60
+
61
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","names":[],"sources":["../../../src/connectors/health.ts"],"sourcesContent":["import { getWorkspacePath } from '../config/workspace-path-helpers.js';\nimport {\n createBundleMcpToolRuntime,\n mapBundleMcpToolsForGateway,\n} from '../agent/mcp/bundle-mcp-materialize.js';\nimport type { Config } from '../config/schema.js';\nimport { getConnectorInstance } from './instances.js';\nimport type { ConnectorHealthResult, ConnectorHealthStatus } from './types.js';\n\nfunction classifyConnectorHealthError(error: unknown): ConnectorHealthStatus {\n const message = error instanceof Error ? error.message : String(error);\n if (/timed out|timeout/i.test(message)) {\n return 'timeout';\n }\n if (/ECONN|ENOTFOUND|network|fetch failed/i.test(message)) {\n return 'network_failed';\n }\n if (/missing|required|credential|api key|token/i.test(message)) {\n return 'missing_secret';\n }\n if (/tools|listTools/i.test(message)) {\n return 'tools_list_failed';\n }\n if (/spawn|command|start|connect/i.test(message)) {\n return 'startup_failed';\n }\n return 'unknown_error';\n}\n\nfunction healthActionForStatus(status: ConnectorHealthStatus): string | undefined {\n if (status === 'missing_secret') {\n return 'Reconnect the connector and provide the required secret.';\n }\n if (status === 'timeout' || status === 'network_failed') {\n return 'Check network access and retry the connector health check.';\n }\n if (status === 'startup_failed') {\n return 'Verify the connector runtime dependency is installed and reachable.';\n }\n return undefined;\n}\n\nexport async function testConnectorInstance(config: Config, serverId: string): Promise<ConnectorHealthResult> {\n const instance = getConnectorInstance(config, serverId);\n if (!instance) {\n return {\n serverId,\n ok: false,\n status: 'server_not_found',\n toolCount: 0,\n tools: [],\n error: `Connector instance not found: ${serverId}`,\n };\n }\n\n const workspaceDir = getWorkspacePath(config) || './workspace';\n let runtime: Awaited<ReturnType<typeof createBundleMcpToolRuntime>> | undefined;\n try {\n runtime = await createBundleMcpToolRuntime({\n workspaceDir,\n cfg: config,\n });\n const tools = mapBundleMcpToolsForGateway(runtime.tools, serverId);\n return {\n serverId,\n ok: true,\n status: 'ok',\n toolCount: tools.length,\n tools,\n };\n } catch (error) {\n const status = classifyConnectorHealthError(error);\n return {\n serverId,\n ok: false,\n status,\n toolCount: 0,\n tools: [],\n error: error instanceof Error ? error.message : String(error),\n action: healthActionForStatus(status),\n };\n } finally {\n await runtime?.dispose();\n }\n}\n"],"mappings":";;;;AASA,SAAS,6BAA6B,OAAuC;CAC3E,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,KAAI,qBAAqB,KAAK,QAAQ,CACpC,QAAO;AAET,KAAI,wCAAwC,KAAK,QAAQ,CACvD,QAAO;AAET,KAAI,6CAA6C,KAAK,QAAQ,CAC5D,QAAO;AAET,KAAI,mBAAmB,KAAK,QAAQ,CAClC,QAAO;AAET,KAAI,+BAA+B,KAAK,QAAQ,CAC9C,QAAO;AAET,QAAO;;AAGT,SAAS,sBAAsB,QAAmD;AAChF,KAAI,WAAW,iBACb,QAAO;AAET,KAAI,WAAW,aAAa,WAAW,iBACrC,QAAO;AAET,KAAI,WAAW,iBACb,QAAO;;AAKX,eAAsB,sBAAsB,QAAgB,UAAkD;AAE5G,KAAI,CADa,qBAAqB,QAAQ,SACjC,CACX,QAAO;EACL;EACA,IAAI;EACJ,QAAQ;EACR,WAAW;EACX,OAAO,EAAE;EACT,OAAO,iCAAiC;EACzC;CAGH,MAAM,eAAe,iBAAiB,OAAO,IAAI;CACjD,IAAI;AACJ,KAAI;AACF,YAAU,MAAM,2BAA2B;GACzC;GACA,KAAK;GACN,CAAC;EACF,MAAM,QAAQ,4BAA4B,QAAQ,OAAO,SAAS;AAClE,SAAO;GACL;GACA,IAAI;GACJ,QAAQ;GACR,WAAW,MAAM;GACjB;GACD;UACM,OAAO;EACd,MAAM,SAAS,6BAA6B,MAAM;AAClD,SAAO;GACL;GACA,IAAI;GACJ;GACA,WAAW;GACX,OAAO,EAAE;GACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAC7D,QAAQ,sBAAsB,OAAO;GACtC;WACO;AACR,QAAM,SAAS,SAAS"}
@@ -0,0 +1,5 @@
1
+ import { CredentialResolver } from '../auth/credentials.js';
2
+ import type { Config } from '../config/schema.js';
3
+ import type { ConnectorInstallInput, ConnectorInstance } from './types.js';
4
+ export declare function installConnector(config: Config, connectorId: string, input: ConnectorInstallInput, resolver?: CredentialResolver): Promise<ConnectorInstance>;
5
+ export declare function uninstallConnector(config: Config, instanceId: string): ConnectorInstance;
@@ -0,0 +1,46 @@
1
+ import { CredentialResolver, init_credentials } from "../auth/credentials.js";
2
+ import { getConnectorDefinition } from "./catalog.js";
3
+ import { saveConnectorSecrets } from "./secret-store.js";
4
+ import { isManagedConnectorServer, materializeConnectorMcpServer } from "./materialize.js";
5
+ import { appendConnectorAuditRecord } from "./usage.js";
6
+ import { listConnectorInstances } from "./instances.js";
7
+ import { assertConnectorOAuthReady } from "./oauth.js";
8
+ //#region src/connectors/install.ts
9
+ init_credentials();
10
+ async function installConnector(config, connectorId, input, resolver = new CredentialResolver()) {
11
+ const definition = getConnectorDefinition(connectorId);
12
+ if (!definition) throw new Error(`Unknown connector: ${connectorId}`);
13
+ const { serverId, server } = materializeConnectorMcpServer(definition, input);
14
+ const existingServer = config.mcp?.servers?.[serverId];
15
+ if (existingServer && !isManagedConnectorServer(existingServer)) throw new Error(`MCP server "${serverId}" already exists and is not managed by Connectors.`);
16
+ await assertConnectorOAuthReady(definition, resolver);
17
+ await saveConnectorSecrets(definition, input, resolver);
18
+ config.mcp = config.mcp ?? {};
19
+ config.mcp.servers = {
20
+ ...config.mcp.servers ?? {},
21
+ [serverId]: server
22
+ };
23
+ const instance = listConnectorInstances(config).find((candidate) => candidate.instanceId === serverId);
24
+ if (!instance) throw new Error(`Connector "${connectorId}" was installed but could not be resolved.`);
25
+ appendConnectorAuditRecord(config, serverId, { action: "installed" });
26
+ return instance;
27
+ }
28
+ function uninstallConnector(config, instanceId) {
29
+ const server = config.mcp?.servers?.[instanceId];
30
+ if (!server) throw new Error(`Connector instance not found: ${instanceId}`);
31
+ if (!isManagedConnectorServer(server)) throw new Error(`MCP server "${instanceId}" is not managed by Connectors.`);
32
+ const instance = listConnectorInstances(config).find((candidate) => candidate.instanceId === instanceId);
33
+ if (!instance) throw new Error(`Connector instance not found: ${instanceId}`);
34
+ appendConnectorAuditRecord(config, instanceId, { action: "removed" });
35
+ const nextServers = { ...config.mcp?.servers ?? {} };
36
+ delete nextServers[instanceId];
37
+ config.mcp = {
38
+ ...config.mcp ?? {},
39
+ servers: nextServers
40
+ };
41
+ return instance;
42
+ }
43
+ //#endregion
44
+ export { installConnector, uninstallConnector };
45
+
46
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","names":[],"sources":["../../../src/connectors/install.ts"],"sourcesContent":["import { CredentialResolver } from '../auth/credentials.js';\nimport type { Config } from '../config/schema.js';\nimport { getConnectorDefinition } from './catalog.js';\nimport { listConnectorInstances } from './instances.js';\nimport { isManagedConnectorServer, materializeConnectorMcpServer } from './materialize.js';\nimport { assertConnectorOAuthReady } from './oauth.js';\nimport { saveConnectorSecrets } from './secret-store.js';\nimport { appendConnectorAuditRecord } from './usage.js';\nimport type { ConnectorInstallInput, ConnectorInstance } from './types.js';\n\nexport async function installConnector(\n config: Config,\n connectorId: string,\n input: ConnectorInstallInput,\n resolver = new CredentialResolver(),\n): Promise<ConnectorInstance> {\n const definition = getConnectorDefinition(connectorId);\n if (!definition) {\n throw new Error(`Unknown connector: ${connectorId}`);\n }\n\n const { serverId, server } = materializeConnectorMcpServer(definition, input);\n const existingServer = config.mcp?.servers?.[serverId];\n if (existingServer && !isManagedConnectorServer(existingServer)) {\n throw new Error(`MCP server \"${serverId}\" already exists and is not managed by Connectors.`);\n }\n\n await assertConnectorOAuthReady(definition, resolver);\n await saveConnectorSecrets(definition, input, resolver);\n\n config.mcp = config.mcp ?? {};\n config.mcp.servers = {\n ...(config.mcp.servers ?? {}),\n [serverId]: server,\n };\n\n const instance = listConnectorInstances(config).find((candidate) => candidate.instanceId === serverId);\n if (!instance) {\n throw new Error(`Connector \"${connectorId}\" was installed but could not be resolved.`);\n }\n appendConnectorAuditRecord(config, serverId, { action: 'installed' });\n return instance;\n}\n\nexport function uninstallConnector(config: Config, instanceId: string): ConnectorInstance {\n const server = config.mcp?.servers?.[instanceId];\n if (!server) {\n throw new Error(`Connector instance not found: ${instanceId}`);\n }\n if (!isManagedConnectorServer(server)) {\n throw new Error(`MCP server \"${instanceId}\" is not managed by Connectors.`);\n }\n\n const instance = listConnectorInstances(config).find((candidate) => candidate.instanceId === instanceId);\n if (!instance) {\n throw new Error(`Connector instance not found: ${instanceId}`);\n }\n appendConnectorAuditRecord(config, instanceId, { action: 'removed' });\n\n const nextServers = { ...(config.mcp?.servers ?? {}) };\n delete nextServers[instanceId];\n config.mcp = {\n ...(config.mcp ?? {}),\n servers: nextServers,\n };\n return instance;\n}\n"],"mappings":";;;;;;;;kBAA4D;AAU5D,eAAsB,iBACpB,QACA,aACA,OACA,WAAW,IAAI,oBAAoB,EACP;CAC5B,MAAM,aAAa,uBAAuB,YAAY;AACtD,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,sBAAsB,cAAc;CAGtD,MAAM,EAAE,UAAU,WAAW,8BAA8B,YAAY,MAAM;CAC7E,MAAM,iBAAiB,OAAO,KAAK,UAAU;AAC7C,KAAI,kBAAkB,CAAC,yBAAyB,eAAe,CAC7D,OAAM,IAAI,MAAM,eAAe,SAAS,oDAAoD;AAG9F,OAAM,0BAA0B,YAAY,SAAS;AACrD,OAAM,qBAAqB,YAAY,OAAO,SAAS;AAEvD,QAAO,MAAM,OAAO,OAAO,EAAE;AAC7B,QAAO,IAAI,UAAU;EACnB,GAAI,OAAO,IAAI,WAAW,EAAE;GAC3B,WAAW;EACb;CAED,MAAM,WAAW,uBAAuB,OAAO,CAAC,MAAM,cAAc,UAAU,eAAe,SAAS;AACtG,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,cAAc,YAAY,4CAA4C;AAExF,4BAA2B,QAAQ,UAAU,EAAE,QAAQ,aAAa,CAAC;AACrE,QAAO;;AAGT,SAAgB,mBAAmB,QAAgB,YAAuC;CACxF,MAAM,SAAS,OAAO,KAAK,UAAU;AACrC,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,iCAAiC,aAAa;AAEhE,KAAI,CAAC,yBAAyB,OAAO,CACnC,OAAM,IAAI,MAAM,eAAe,WAAW,iCAAiC;CAG7E,MAAM,WAAW,uBAAuB,OAAO,CAAC,MAAM,cAAc,UAAU,eAAe,WAAW;AACxG,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,iCAAiC,aAAa;AAEhE,4BAA2B,QAAQ,YAAY,EAAE,QAAQ,WAAW,CAAC;CAErE,MAAM,cAAc,EAAE,GAAI,OAAO,KAAK,WAAW,EAAE,EAAG;AACtD,QAAO,YAAY;AACnB,QAAO,MAAM;EACX,GAAI,OAAO,OAAO,EAAE;EACpB,SAAS;EACV;AACD,QAAO"}
@@ -0,0 +1,4 @@
1
+ import type { Config } from '../config/schema.js';
2
+ import type { ConnectorInstance } from './types.js';
3
+ export declare function listConnectorInstances(config: Config): ConnectorInstance[];
4
+ export declare function getConnectorInstance(config: Config, instanceId: string): ConnectorInstance | undefined;
@@ -0,0 +1,43 @@
1
+ import { getConnectorDefinition } from "./catalog.js";
2
+ import { isManagedConnectorServer } from "./materialize.js";
3
+ import { getConnectorAuditFromMarker, getConnectorUsageFromMarker } from "./usage.js";
4
+ //#region src/connectors/instances.ts
5
+ function secretStatusForServer(server) {
6
+ const marker = server.xopcConnector;
7
+ const definition = marker?.connectorId ? getConnectorDefinition(marker.connectorId) : void 0;
8
+ const env = server.env && typeof server.env === "object" && !Array.isArray(server.env) ? server.env : {};
9
+ const status = {};
10
+ for (const secret of definition?.setup.secrets ?? []) {
11
+ const value = env[secret.key];
12
+ status[secret.key] = Boolean(value && typeof value === "object" && !Array.isArray(value) && "xopcSecretRef" in value);
13
+ }
14
+ return status;
15
+ }
16
+ function listConnectorInstances(config) {
17
+ const servers = config.mcp?.servers ?? {};
18
+ return Object.entries(servers).flatMap(([serverId, server]) => {
19
+ if (!isManagedConnectorServer(server)) return [];
20
+ const connectorId = server.xopcConnector.connectorId;
21
+ return [{
22
+ instanceId: serverId,
23
+ connectorId,
24
+ displayName: getConnectorDefinition(connectorId)?.displayName ?? connectorId,
25
+ enabled: true,
26
+ status: "installed",
27
+ secretStatus: secretStatusForServer(server),
28
+ materialized: {
29
+ type: "mcp",
30
+ serverId
31
+ },
32
+ usage: getConnectorUsageFromMarker(server.xopcConnector),
33
+ audit: getConnectorAuditFromMarker(server.xopcConnector)
34
+ }];
35
+ }).sort((left, right) => left.displayName.localeCompare(right.displayName));
36
+ }
37
+ function getConnectorInstance(config, instanceId) {
38
+ return listConnectorInstances(config).find((instance) => instance.instanceId === instanceId);
39
+ }
40
+ //#endregion
41
+ export { getConnectorInstance, listConnectorInstances };
42
+
43
+ //# sourceMappingURL=instances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instances.js","names":[],"sources":["../../../src/connectors/instances.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { getConnectorDefinition } from './catalog.js';\nimport { isManagedConnectorServer } from './materialize.js';\nimport { getConnectorAuditFromMarker, getConnectorUsageFromMarker } from './usage.js';\nimport type { ConnectorInstance } from './types.js';\n\nfunction secretStatusForServer(server: Record<string, unknown>): Record<string, boolean> {\n const marker = server.xopcConnector as { connectorId?: string } | undefined;\n const definition = marker?.connectorId ? getConnectorDefinition(marker.connectorId) : undefined;\n const env = server.env && typeof server.env === 'object' && !Array.isArray(server.env)\n ? (server.env as Record<string, unknown>)\n : {};\n const status: Record<string, boolean> = {};\n for (const secret of definition?.setup.secrets ?? []) {\n const value = env[secret.key];\n status[secret.key] = Boolean(\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n 'xopcSecretRef' in value,\n );\n }\n return status;\n}\n\nexport function listConnectorInstances(config: Config): ConnectorInstance[] {\n const servers = config.mcp?.servers ?? {};\n return Object.entries(servers)\n .flatMap(([serverId, server]) => {\n if (!isManagedConnectorServer(server)) {\n return [];\n }\n const connectorId = server.xopcConnector.connectorId;\n const definition = getConnectorDefinition(connectorId);\n return [\n {\n instanceId: serverId,\n connectorId,\n displayName: definition?.displayName ?? connectorId,\n enabled: true,\n status: 'installed' as const,\n secretStatus: secretStatusForServer(server),\n materialized: {\n type: 'mcp' as const,\n serverId,\n },\n usage: getConnectorUsageFromMarker(server.xopcConnector),\n audit: getConnectorAuditFromMarker(server.xopcConnector),\n },\n ];\n })\n .sort((left, right) => left.displayName.localeCompare(right.displayName));\n}\n\nexport function getConnectorInstance(config: Config, instanceId: string): ConnectorInstance | undefined {\n return listConnectorInstances(config).find((instance) => instance.instanceId === instanceId);\n}\n"],"mappings":";;;;AAMA,SAAS,sBAAsB,QAA0D;CACvF,MAAM,SAAS,OAAO;CACtB,MAAM,aAAa,QAAQ,cAAc,uBAAuB,OAAO,YAAY,GAAG,KAAA;CACtF,MAAM,MAAM,OAAO,OAAO,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,OAAO,IAAI,GACjF,OAAO,MACR,EAAE;CACN,MAAM,SAAkC,EAAE;AAC1C,MAAK,MAAM,UAAU,YAAY,MAAM,WAAW,EAAE,EAAE;EACpD,MAAM,QAAQ,IAAI,OAAO;AACzB,SAAO,OAAO,OAAO,QACnB,SACE,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,MAAM,IACrB,mBAAmB,MACtB;;AAEH,QAAO;;AAGT,SAAgB,uBAAuB,QAAqC;CAC1E,MAAM,UAAU,OAAO,KAAK,WAAW,EAAE;AACzC,QAAO,OAAO,QAAQ,QAAQ,CAC3B,SAAS,CAAC,UAAU,YAAY;AAC/B,MAAI,CAAC,yBAAyB,OAAO,CACnC,QAAO,EAAE;EAEX,MAAM,cAAc,OAAO,cAAc;AAEzC,SAAO,CACL;GACE,YAAY;GACZ;GACA,aALe,uBAAuB,YAKf,EAAE,eAAe;GACxC,SAAS;GACT,QAAQ;GACR,cAAc,sBAAsB,OAAO;GAC3C,cAAc;IACZ,MAAM;IACN;IACD;GACD,OAAO,4BAA4B,OAAO,cAAc;GACxD,OAAO,4BAA4B,OAAO,cAAc;GACzD,CACF;GACD,CACD,MAAM,MAAM,UAAU,KAAK,YAAY,cAAc,MAAM,YAAY,CAAC;;AAG7E,SAAgB,qBAAqB,QAAgB,YAAmD;AACtG,QAAO,uBAAuB,OAAO,CAAC,MAAM,aAAa,SAAS,eAAe,WAAW"}
@@ -0,0 +1,9 @@
1
+ import type { ConnectorDefinition, ConnectorInstallInput, ManagedConnectorMarker } from './types.js';
2
+ export declare function assertValidConnectorServerId(serverId: string): void;
3
+ export declare function materializeConnectorMcpServer(definition: ConnectorDefinition, input: ConnectorInstallInput): {
4
+ serverId: string;
5
+ server: Record<string, unknown>;
6
+ };
7
+ export declare function isManagedConnectorServer(server: unknown): server is Record<string, unknown> & {
8
+ xopcConnector: ManagedConnectorMarker;
9
+ };
@@ -0,0 +1,76 @@
1
+ import { McpServerSchema, init_schema } from "../config/schema.js";
2
+ import { createConnectorSecretReference } from "./secret-store.js";
3
+ //#region src/connectors/materialize.ts
4
+ init_schema();
5
+ const SERVER_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
6
+ const TEMPLATE_PATTERN = /^\{\{(secrets|config)\.([A-Za-z0-9_.-]+)\}\}$/;
7
+ function assertValidConnectorServerId(serverId) {
8
+ if (!SERVER_ID_PATTERN.test(serverId)) throw new Error("Connector server name must start with a lowercase letter and only contain lowercase letters, numbers, dashes, and underscores.");
9
+ }
10
+ function readInputValue(definition, input, scope, key) {
11
+ if (scope === "secrets") return createConnectorSecretReference(definition.id, key);
12
+ return input.config?.[key];
13
+ }
14
+ function resolveTemplateValue(value, definition, input) {
15
+ if (typeof value !== "string") return value;
16
+ const match = TEMPLATE_PATTERN.exec(value.trim());
17
+ if (!match) return value;
18
+ return readInputValue(definition, input, match[1], match[2]);
19
+ }
20
+ function materializeTemplate(value, definition, input) {
21
+ const resolved = resolveTemplateValue(value, definition, input);
22
+ if (Array.isArray(resolved)) return resolved.map((item) => materializeTemplate(item, definition, input));
23
+ if (resolved && typeof resolved === "object") {
24
+ const output = {};
25
+ for (const [key, child] of Object.entries(resolved)) {
26
+ const materializedChild = materializeTemplate(child, definition, input);
27
+ if (materializedChild !== void 0) output[key] = materializedChild;
28
+ }
29
+ return output;
30
+ }
31
+ return resolved;
32
+ }
33
+ function assertRequiredInputs(definition, input) {
34
+ for (const secret of definition.setup.secrets ?? []) {
35
+ const value = input.secrets?.[secret.key];
36
+ if (secret.required && (typeof value !== "string" || value.trim().length === 0)) throw new Error(`Missing required secret: ${secret.key}`);
37
+ }
38
+ for (const field of definition.setup.config ?? []) {
39
+ const value = input.config?.[field.key];
40
+ if (field.required && (value === void 0 || value === null || value === "")) throw new Error(`Missing required config: ${field.key}`);
41
+ }
42
+ }
43
+ function materializeConnectorMcpServer(definition, input) {
44
+ assertRequiredInputs(definition, input);
45
+ if (definition.runtime.type !== "mcp") throw new Error(`Unsupported connector runtime: ${definition.runtime.type}`);
46
+ const rawServerId = materializeTemplate(definition.runtime.serverId, definition, input);
47
+ if (typeof rawServerId !== "string") throw new Error("Connector server name must be a string.");
48
+ const serverId = rawServerId.trim();
49
+ assertValidConnectorServerId(serverId);
50
+ const rawServer = materializeTemplate(definition.runtime.serverTemplate, definition, input);
51
+ if (!rawServer || typeof rawServer !== "object" || Array.isArray(rawServer)) throw new Error("Connector MCP server template must resolve to a JSON object.");
52
+ const marker = {
53
+ managed: true,
54
+ connectorId: definition.id,
55
+ version: definition.version
56
+ };
57
+ const server = {
58
+ ...rawServer,
59
+ xopcConnector: marker
60
+ };
61
+ const parsed = McpServerSchema.safeParse(server);
62
+ if (!parsed.success) throw new Error(parsed.error.issues[0]?.message ?? "Invalid MCP server config.");
63
+ return {
64
+ serverId,
65
+ server
66
+ };
67
+ }
68
+ function isManagedConnectorServer(server) {
69
+ if (!server || typeof server !== "object" || Array.isArray(server)) return false;
70
+ const marker = server.xopcConnector;
71
+ return Boolean(marker && typeof marker === "object" && !Array.isArray(marker) && marker.managed === true && typeof marker.connectorId === "string");
72
+ }
73
+ //#endregion
74
+ export { assertValidConnectorServerId, isManagedConnectorServer, materializeConnectorMcpServer };
75
+
76
+ //# sourceMappingURL=materialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materialize.js","names":[],"sources":["../../../src/connectors/materialize.ts"],"sourcesContent":["import { McpServerSchema } from '../config/schema.js';\nimport { createConnectorSecretReference } from './secret-store.js';\nimport type { ConnectorDefinition, ConnectorInstallInput, ManagedConnectorMarker } from './types.js';\n\nconst SERVER_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\nconst TEMPLATE_PATTERN = /^\\{\\{(secrets|config)\\.([A-Za-z0-9_.-]+)\\}\\}$/;\n\nexport function assertValidConnectorServerId(serverId: string): void {\n if (!SERVER_ID_PATTERN.test(serverId)) {\n throw new Error('Connector server name must start with a lowercase letter and only contain lowercase letters, numbers, dashes, and underscores.');\n }\n}\n\nfunction readInputValue(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n scope: 'secrets' | 'config',\n key: string,\n): unknown {\n if (scope === 'secrets') {\n return createConnectorSecretReference(definition.id, key);\n }\n return input.config?.[key];\n}\n\nfunction resolveTemplateValue(value: unknown, definition: ConnectorDefinition, input: ConnectorInstallInput): unknown {\n if (typeof value !== 'string') {\n return value;\n }\n const match = TEMPLATE_PATTERN.exec(value.trim());\n if (!match) {\n return value;\n }\n return readInputValue(definition, input, match[1] as 'secrets' | 'config', match[2]);\n}\n\nfunction materializeTemplate(value: unknown, definition: ConnectorDefinition, input: ConnectorInstallInput): unknown {\n const resolved = resolveTemplateValue(value, definition, input);\n if (Array.isArray(resolved)) {\n return resolved.map((item) => materializeTemplate(item, definition, input));\n }\n if (resolved && typeof resolved === 'object') {\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(resolved as Record<string, unknown>)) {\n const materializedChild = materializeTemplate(child, definition, input);\n if (materializedChild !== undefined) {\n output[key] = materializedChild;\n }\n }\n return output;\n }\n return resolved;\n}\n\nfunction assertRequiredInputs(definition: ConnectorDefinition, input: ConnectorInstallInput): void {\n for (const secret of definition.setup.secrets ?? []) {\n const value = input.secrets?.[secret.key];\n if (secret.required && (typeof value !== 'string' || value.trim().length === 0)) {\n throw new Error(`Missing required secret: ${secret.key}`);\n }\n }\n for (const field of definition.setup.config ?? []) {\n const value = input.config?.[field.key];\n if (field.required && (value === undefined || value === null || value === '')) {\n throw new Error(`Missing required config: ${field.key}`);\n }\n }\n}\n\nexport function materializeConnectorMcpServer(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n): { serverId: string; server: Record<string, unknown> } {\n assertRequiredInputs(definition, input);\n if (definition.runtime.type !== 'mcp') {\n throw new Error(`Unsupported connector runtime: ${definition.runtime.type}`);\n }\n\n const rawServerId = materializeTemplate(definition.runtime.serverId, definition, input);\n if (typeof rawServerId !== 'string') {\n throw new Error('Connector server name must be a string.');\n }\n const serverId = rawServerId.trim();\n assertValidConnectorServerId(serverId);\n\n const rawServer = materializeTemplate(definition.runtime.serverTemplate, definition, input);\n if (!rawServer || typeof rawServer !== 'object' || Array.isArray(rawServer)) {\n throw new Error('Connector MCP server template must resolve to a JSON object.');\n }\n\n const marker: ManagedConnectorMarker = {\n managed: true,\n connectorId: definition.id,\n version: definition.version,\n };\n const server = {\n ...(rawServer as Record<string, unknown>),\n xopcConnector: marker,\n };\n const parsed = McpServerSchema.safeParse(server);\n if (!parsed.success) {\n throw new Error(parsed.error.issues[0]?.message ?? 'Invalid MCP server config.');\n }\n return { serverId, server };\n}\n\nexport function isManagedConnectorServer(server: unknown): server is Record<string, unknown> & { xopcConnector: ManagedConnectorMarker } {\n if (!server || typeof server !== 'object' || Array.isArray(server)) {\n return false;\n }\n const marker = (server as Record<string, unknown>).xopcConnector;\n return Boolean(\n marker &&\n typeof marker === 'object' &&\n !Array.isArray(marker) &&\n (marker as Record<string, unknown>).managed === true &&\n typeof (marker as Record<string, unknown>).connectorId === 'string',\n );\n}\n"],"mappings":";;;aAAsD;AAItD,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB;AAEzB,SAAgB,6BAA6B,UAAwB;AACnE,KAAI,CAAC,kBAAkB,KAAK,SAAS,CACnC,OAAM,IAAI,MAAM,iIAAiI;;AAIrJ,SAAS,eACP,YACA,OACA,OACA,KACS;AACT,KAAI,UAAU,UACZ,QAAO,+BAA+B,WAAW,IAAI,IAAI;AAE3D,QAAO,MAAM,SAAS;;AAGxB,SAAS,qBAAqB,OAAgB,YAAiC,OAAuC;AACpH,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,QAAQ,iBAAiB,KAAK,MAAM,MAAM,CAAC;AACjD,KAAI,CAAC,MACH,QAAO;AAET,QAAO,eAAe,YAAY,OAAO,MAAM,IAA4B,MAAM,GAAG;;AAGtF,SAAS,oBAAoB,OAAgB,YAAiC,OAAuC;CACnH,MAAM,WAAW,qBAAqB,OAAO,YAAY,MAAM;AAC/D,KAAI,MAAM,QAAQ,SAAS,CACzB,QAAO,SAAS,KAAK,SAAS,oBAAoB,MAAM,YAAY,MAAM,CAAC;AAE7E,KAAI,YAAY,OAAO,aAAa,UAAU;EAC5C,MAAM,SAAkC,EAAE;AAC1C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAoC,EAAE;GAC9E,MAAM,oBAAoB,oBAAoB,OAAO,YAAY,MAAM;AACvE,OAAI,sBAAsB,KAAA,EACxB,QAAO,OAAO;;AAGlB,SAAO;;AAET,QAAO;;AAGT,SAAS,qBAAqB,YAAiC,OAAoC;AACjG,MAAK,MAAM,UAAU,WAAW,MAAM,WAAW,EAAE,EAAE;EACnD,MAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,MAAI,OAAO,aAAa,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,WAAW,GAC3E,OAAM,IAAI,MAAM,4BAA4B,OAAO,MAAM;;AAG7D,MAAK,MAAM,SAAS,WAAW,MAAM,UAAU,EAAE,EAAE;EACjD,MAAM,QAAQ,MAAM,SAAS,MAAM;AACnC,MAAI,MAAM,aAAa,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,IACxE,OAAM,IAAI,MAAM,4BAA4B,MAAM,MAAM;;;AAK9D,SAAgB,8BACd,YACA,OACuD;AACvD,sBAAqB,YAAY,MAAM;AACvC,KAAI,WAAW,QAAQ,SAAS,MAC9B,OAAM,IAAI,MAAM,kCAAkC,WAAW,QAAQ,OAAO;CAG9E,MAAM,cAAc,oBAAoB,WAAW,QAAQ,UAAU,YAAY,MAAM;AACvF,KAAI,OAAO,gBAAgB,SACzB,OAAM,IAAI,MAAM,0CAA0C;CAE5D,MAAM,WAAW,YAAY,MAAM;AACnC,8BAA6B,SAAS;CAEtC,MAAM,YAAY,oBAAoB,WAAW,QAAQ,gBAAgB,YAAY,MAAM;AAC3F,KAAI,CAAC,aAAa,OAAO,cAAc,YAAY,MAAM,QAAQ,UAAU,CACzE,OAAM,IAAI,MAAM,+DAA+D;CAGjF,MAAM,SAAiC;EACrC,SAAS;EACT,aAAa,WAAW;EACxB,SAAS,WAAW;EACrB;CACD,MAAM,SAAS;EACb,GAAI;EACJ,eAAe;EAChB;CACD,MAAM,SAAS,gBAAgB,UAAU,OAAO;AAChD,KAAI,CAAC,OAAO,QACV,OAAM,IAAI,MAAM,OAAO,MAAM,OAAO,IAAI,WAAW,6BAA6B;AAElF,QAAO;EAAE;EAAU;EAAQ;;AAG7B,SAAgB,yBAAyB,QAAgG;AACvI,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAChE,QAAO;CAET,MAAM,SAAU,OAAmC;AACnD,QAAO,QACL,UACE,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,OAAO,IACrB,OAAmC,YAAY,QAChD,OAAQ,OAAmC,gBAAgB,SAC9D"}
@@ -0,0 +1,22 @@
1
+ import { CredentialResolver } from '../auth/credentials.js';
2
+ import type { ConnectorDefinition } from './types.js';
3
+ export type ConnectorOAuthStartResult = {
4
+ connectorId: string;
5
+ provider: 'github';
6
+ deviceCode: string;
7
+ userCode: string;
8
+ verificationUri: string;
9
+ expiresInSeconds: number;
10
+ intervalSeconds: number;
11
+ };
12
+ export type ConnectorOAuthCompleteResult = {
13
+ connectorId: string;
14
+ provider: 'github';
15
+ connected: true;
16
+ };
17
+ export declare function githubConnectorOAuthCredentialProviderId(definition: ConnectorDefinition): string;
18
+ export declare function assertConnectorOAuthReady(definition: ConnectorDefinition, resolver?: CredentialResolver): Promise<void>;
19
+ export declare function startConnectorOAuth(definition: ConnectorDefinition): Promise<ConnectorOAuthStartResult>;
20
+ export declare function completeConnectorOAuth(definition: ConnectorDefinition, params: {
21
+ deviceCode: string;
22
+ }, resolver?: CredentialResolver): Promise<ConnectorOAuthCompleteResult>;
@@ -0,0 +1,99 @@
1
+ import { CredentialResolver, init_credentials } from "../auth/credentials.js";
2
+ import { connectorSecretProviderId } from "./secret-store.js";
3
+ //#region src/connectors/oauth.ts
4
+ init_credentials();
5
+ const GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
6
+ const GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
7
+ const GITHUB_OAUTH_FIELD_KEY = "GITHUB_PERSONAL_ACCESS_TOKEN";
8
+ const DEFAULT_GITHUB_SCOPES = [
9
+ "repo",
10
+ "read:user",
11
+ "read:org"
12
+ ];
13
+ function githubOAuthClientId() {
14
+ const clientId = process.env.XOPC_GITHUB_OAUTH_CLIENT_ID?.trim() ?? "";
15
+ if (!clientId) throw new Error("GitHub OAuth is not configured. Set XOPC_GITHUB_OAUTH_CLIENT_ID to enable GitHub Connect.");
16
+ return clientId;
17
+ }
18
+ function assertConnectorSupportsOAuth(definition) {
19
+ if (definition.auth.mode !== "oauth" || !definition.capabilities.includes("auth.oauth")) throw new Error(`Connector "${definition.id}" does not support OAuth.`);
20
+ if (definition.id !== "github") throw new Error(`OAuth provider is not implemented for connector: ${definition.id}`);
21
+ }
22
+ async function readJsonResponse(response, context) {
23
+ const data = await response.json().catch(async () => ({ error_description: await response.text() }));
24
+ if (!response.ok) {
25
+ const errorData = data;
26
+ throw new Error(`${context}: ${errorData.error_description ?? errorData.error ?? response.statusText}`);
27
+ }
28
+ return data;
29
+ }
30
+ function githubConnectorOAuthCredentialProviderId(definition) {
31
+ return connectorSecretProviderId(definition.id, GITHUB_OAUTH_FIELD_KEY);
32
+ }
33
+ async function assertConnectorOAuthReady(definition, resolver = new CredentialResolver()) {
34
+ if (definition.auth.mode !== "oauth") return;
35
+ assertConnectorSupportsOAuth(definition);
36
+ if (!(await resolver.loadOAuthToken(githubConnectorOAuthCredentialProviderId(definition)))?.access) throw new Error(`Connect ${definition.displayName} with OAuth before installing this connector.`);
37
+ }
38
+ async function startConnectorOAuth(definition) {
39
+ assertConnectorSupportsOAuth(definition);
40
+ const clientId = githubOAuthClientId();
41
+ const data = await readJsonResponse(await fetch(GITHUB_DEVICE_CODE_URL, {
42
+ method: "POST",
43
+ headers: {
44
+ Accept: "application/json",
45
+ "Content-Type": "application/json"
46
+ },
47
+ body: JSON.stringify({
48
+ client_id: clientId,
49
+ scope: DEFAULT_GITHUB_SCOPES.join(" ")
50
+ })
51
+ }), "GitHub device authorization failed");
52
+ return {
53
+ connectorId: definition.id,
54
+ provider: "github",
55
+ deviceCode: data.device_code,
56
+ userCode: data.user_code,
57
+ verificationUri: data.verification_uri,
58
+ expiresInSeconds: data.expires_in,
59
+ intervalSeconds: data.interval ?? 5
60
+ };
61
+ }
62
+ async function completeConnectorOAuth(definition, params, resolver = new CredentialResolver()) {
63
+ assertConnectorSupportsOAuth(definition);
64
+ const deviceCode = params.deviceCode.trim();
65
+ if (!deviceCode) throw new Error("Missing GitHub OAuth device code.");
66
+ const data = await readJsonResponse(await fetch(GITHUB_ACCESS_TOKEN_URL, {
67
+ method: "POST",
68
+ headers: {
69
+ Accept: "application/json",
70
+ "Content-Type": "application/json"
71
+ },
72
+ body: JSON.stringify({
73
+ client_id: githubOAuthClientId(),
74
+ device_code: deviceCode,
75
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code"
76
+ })
77
+ }), "GitHub token exchange failed");
78
+ if (data.error) {
79
+ if (data.error === "authorization_pending") throw new Error("GitHub authorization is still pending. Complete the browser step and try again.");
80
+ if (data.error === "slow_down") throw new Error("GitHub asked us to slow down. Wait a few seconds and try again.");
81
+ throw new Error(data.error_description ?? data.error);
82
+ }
83
+ if (!data.access_token) throw new Error("GitHub token exchange did not return an access token.");
84
+ await resolver.saveOAuthToken(githubConnectorOAuthCredentialProviderId(definition), {
85
+ access: data.access_token,
86
+ refresh: "",
87
+ scope: data.scope?.split(/\s+/).filter(Boolean),
88
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
89
+ });
90
+ return {
91
+ connectorId: definition.id,
92
+ provider: "github",
93
+ connected: true
94
+ };
95
+ }
96
+ //#endregion
97
+ export { assertConnectorOAuthReady, completeConnectorOAuth, githubConnectorOAuthCredentialProviderId, startConnectorOAuth };
98
+
99
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","names":[],"sources":["../../../src/connectors/oauth.ts"],"sourcesContent":["import { CredentialResolver } from '../auth/credentials.js';\nimport { connectorSecretProviderId } from './secret-store.js';\nimport type { ConnectorDefinition } from './types.js';\n\nexport type ConnectorOAuthStartResult = {\n connectorId: string;\n provider: 'github';\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresInSeconds: number;\n intervalSeconds: number;\n};\n\nexport type ConnectorOAuthCompleteResult = {\n connectorId: string;\n provider: 'github';\n connected: true;\n};\n\ntype GitHubDeviceCodeResponse = {\n device_code: string;\n user_code: string;\n verification_uri: string;\n expires_in: number;\n interval?: number;\n};\n\ntype GitHubTokenResponse = {\n access_token?: string;\n token_type?: string;\n scope?: string;\n error?: string;\n error_description?: string;\n interval?: number;\n};\n\nconst GITHUB_DEVICE_CODE_URL = 'https://github.com/login/device/code';\nconst GITHUB_ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token';\nconst GITHUB_OAUTH_FIELD_KEY = 'GITHUB_PERSONAL_ACCESS_TOKEN';\nconst DEFAULT_GITHUB_SCOPES = ['repo', 'read:user', 'read:org'];\n\nfunction githubOAuthClientId(): string {\n const clientId = process.env.XOPC_GITHUB_OAUTH_CLIENT_ID?.trim() ?? '';\n if (!clientId) {\n throw new Error('GitHub OAuth is not configured. Set XOPC_GITHUB_OAUTH_CLIENT_ID to enable GitHub Connect.');\n }\n return clientId;\n}\n\nfunction assertConnectorSupportsOAuth(definition: ConnectorDefinition): void {\n if (definition.auth.mode !== 'oauth' || !definition.capabilities.includes('auth.oauth')) {\n throw new Error(`Connector \"${definition.id}\" does not support OAuth.`);\n }\n if (definition.id !== 'github') {\n throw new Error(`OAuth provider is not implemented for connector: ${definition.id}`);\n }\n}\n\nasync function readJsonResponse<T>(response: Response, context: string): Promise<T> {\n const data = await response.json().catch(async () => ({ error_description: await response.text() }));\n if (!response.ok) {\n const errorData = data as { error_description?: string; error?: string };\n throw new Error(`${context}: ${errorData.error_description ?? errorData.error ?? response.statusText}`);\n }\n return data as T;\n}\n\nexport function githubConnectorOAuthCredentialProviderId(definition: ConnectorDefinition): string {\n return connectorSecretProviderId(definition.id, GITHUB_OAUTH_FIELD_KEY);\n}\n\nexport async function assertConnectorOAuthReady(\n definition: ConnectorDefinition,\n resolver = new CredentialResolver(),\n): Promise<void> {\n if (definition.auth.mode !== 'oauth') {\n return;\n }\n assertConnectorSupportsOAuth(definition);\n const token = await resolver.loadOAuthToken(githubConnectorOAuthCredentialProviderId(definition));\n if (!token?.access) {\n throw new Error(`Connect ${definition.displayName} with OAuth before installing this connector.`);\n }\n}\n\nexport async function startConnectorOAuth(definition: ConnectorDefinition): Promise<ConnectorOAuthStartResult> {\n assertConnectorSupportsOAuth(definition);\n const clientId = githubOAuthClientId();\n const response = await fetch(GITHUB_DEVICE_CODE_URL, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n client_id: clientId,\n scope: DEFAULT_GITHUB_SCOPES.join(' '),\n }),\n });\n const data = await readJsonResponse<GitHubDeviceCodeResponse>(response, 'GitHub device authorization failed');\n return {\n connectorId: definition.id,\n provider: 'github',\n deviceCode: data.device_code,\n userCode: data.user_code,\n verificationUri: data.verification_uri,\n expiresInSeconds: data.expires_in,\n intervalSeconds: data.interval ?? 5,\n };\n}\n\nexport async function completeConnectorOAuth(\n definition: ConnectorDefinition,\n params: { deviceCode: string },\n resolver = new CredentialResolver(),\n): Promise<ConnectorOAuthCompleteResult> {\n assertConnectorSupportsOAuth(definition);\n const deviceCode = params.deviceCode.trim();\n if (!deviceCode) {\n throw new Error('Missing GitHub OAuth device code.');\n }\n\n const response = await fetch(GITHUB_ACCESS_TOKEN_URL, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n client_id: githubOAuthClientId(),\n device_code: deviceCode,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n }),\n });\n const data = await readJsonResponse<GitHubTokenResponse>(response, 'GitHub token exchange failed');\n if (data.error) {\n if (data.error === 'authorization_pending') {\n throw new Error('GitHub authorization is still pending. Complete the browser step and try again.');\n }\n if (data.error === 'slow_down') {\n throw new Error('GitHub asked us to slow down. Wait a few seconds and try again.');\n }\n throw new Error(data.error_description ?? data.error);\n }\n if (!data.access_token) {\n throw new Error('GitHub token exchange did not return an access token.');\n }\n\n await resolver.saveOAuthToken(githubConnectorOAuthCredentialProviderId(definition), {\n access: data.access_token,\n refresh: '',\n scope: data.scope?.split(/\\s+/).filter(Boolean),\n createdAt: new Date().toISOString(),\n });\n return {\n connectorId: definition.id,\n provider: 'github',\n connected: true,\n };\n}\n"],"mappings":";;;kBAA4D;AAqC5D,MAAM,yBAAyB;AAC/B,MAAM,0BAA0B;AAChC,MAAM,yBAAyB;AAC/B,MAAM,wBAAwB;CAAC;CAAQ;CAAa;CAAW;AAE/D,SAAS,sBAA8B;CACrC,MAAM,WAAW,QAAQ,IAAI,6BAA6B,MAAM,IAAI;AACpE,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,4FAA4F;AAE9G,QAAO;;AAGT,SAAS,6BAA6B,YAAuC;AAC3E,KAAI,WAAW,KAAK,SAAS,WAAW,CAAC,WAAW,aAAa,SAAS,aAAa,CACrF,OAAM,IAAI,MAAM,cAAc,WAAW,GAAG,2BAA2B;AAEzE,KAAI,WAAW,OAAO,SACpB,OAAM,IAAI,MAAM,oDAAoD,WAAW,KAAK;;AAIxF,eAAe,iBAAoB,UAAoB,SAA6B;CAClF,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,MAAM,aAAa,EAAE,mBAAmB,MAAM,SAAS,MAAM,EAAE,EAAE;AACpG,KAAI,CAAC,SAAS,IAAI;EAChB,MAAM,YAAY;AAClB,QAAM,IAAI,MAAM,GAAG,QAAQ,IAAI,UAAU,qBAAqB,UAAU,SAAS,SAAS,aAAa;;AAEzG,QAAO;;AAGT,SAAgB,yCAAyC,YAAyC;AAChG,QAAO,0BAA0B,WAAW,IAAI,uBAAuB;;AAGzE,eAAsB,0BACpB,YACA,WAAW,IAAI,oBAAoB,EACpB;AACf,KAAI,WAAW,KAAK,SAAS,QAC3B;AAEF,8BAA6B,WAAW;AAExC,KAAI,EAAC,MADe,SAAS,eAAe,yCAAyC,WAAW,CAAC,GACrF,OACV,OAAM,IAAI,MAAM,WAAW,WAAW,YAAY,+CAA+C;;AAIrG,eAAsB,oBAAoB,YAAqE;AAC7G,8BAA6B,WAAW;CACxC,MAAM,WAAW,qBAAqB;CAYtC,MAAM,OAAO,MAAM,iBAA2C,MAXvC,MAAM,wBAAwB;EACnD,QAAQ;EACR,SAAS;GACP,QAAQ;GACR,gBAAgB;GACjB;EACD,MAAM,KAAK,UAAU;GACnB,WAAW;GACX,OAAO,sBAAsB,KAAK,IAAI;GACvC,CAAC;EACH,CAAC,EACsE,qCAAqC;AAC7G,QAAO;EACL,aAAa,WAAW;EACxB,UAAU;EACV,YAAY,KAAK;EACjB,UAAU,KAAK;EACf,iBAAiB,KAAK;EACtB,kBAAkB,KAAK;EACvB,iBAAiB,KAAK,YAAY;EACnC;;AAGH,eAAsB,uBACpB,YACA,QACA,WAAW,IAAI,oBAAoB,EACI;AACvC,8BAA6B,WAAW;CACxC,MAAM,aAAa,OAAO,WAAW,MAAM;AAC3C,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,oCAAoC;CAetD,MAAM,OAAO,MAAM,iBAAsC,MAZlC,MAAM,yBAAyB;EACpD,QAAQ;EACR,SAAS;GACP,QAAQ;GACR,gBAAgB;GACjB;EACD,MAAM,KAAK,UAAU;GACnB,WAAW,qBAAqB;GAChC,aAAa;GACb,YAAY;GACb,CAAC;EACH,CAAC,EACiE,+BAA+B;AAClG,KAAI,KAAK,OAAO;AACd,MAAI,KAAK,UAAU,wBACjB,OAAM,IAAI,MAAM,kFAAkF;AAEpG,MAAI,KAAK,UAAU,YACjB,OAAM,IAAI,MAAM,kEAAkE;AAEpF,QAAM,IAAI,MAAM,KAAK,qBAAqB,KAAK,MAAM;;AAEvD,KAAI,CAAC,KAAK,aACR,OAAM,IAAI,MAAM,wDAAwD;AAG1E,OAAM,SAAS,eAAe,yCAAyC,WAAW,EAAE;EAClF,QAAQ,KAAK;EACb,SAAS;EACT,OAAO,KAAK,OAAO,MAAM,MAAM,CAAC,OAAO,QAAQ;EAC/C,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC,CAAC;AACF,QAAO;EACL,aAAa,WAAW;EACxB,UAAU;EACV,WAAW;EACZ"}
@@ -0,0 +1,9 @@
1
+ import type { ConnectorDefinition } from './types.js';
2
+ export type ConnectorProvider = {
3
+ id: string;
4
+ displayName: string;
5
+ listConnectors(): readonly ConnectorDefinition[];
6
+ };
7
+ export declare const builtinConnectorProvider: ConnectorProvider;
8
+ export declare function listConnectorProviders(): ConnectorProvider[];
9
+ export declare function listConnectorProviderDefinitions(): ConnectorDefinition[];
@@ -0,0 +1,20 @@
1
+ import { BUILTIN_CONNECTORS } from "./builtin-catalog.js";
2
+ //#region src/connectors/providers.ts
3
+ const builtinConnectorProvider = {
4
+ id: "builtin",
5
+ displayName: "Built-in connectors",
6
+ listConnectors() {
7
+ return BUILTIN_CONNECTORS;
8
+ }
9
+ };
10
+ const CONNECTOR_PROVIDERS = [builtinConnectorProvider];
11
+ function listConnectorProviders() {
12
+ return [...CONNECTOR_PROVIDERS];
13
+ }
14
+ function listConnectorProviderDefinitions() {
15
+ return CONNECTOR_PROVIDERS.flatMap((provider) => provider.listConnectors());
16
+ }
17
+ //#endregion
18
+ export { builtinConnectorProvider, listConnectorProviderDefinitions, listConnectorProviders };
19
+
20
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","names":[],"sources":["../../../src/connectors/providers.ts"],"sourcesContent":["import { BUILTIN_CONNECTORS } from './builtin-catalog.js';\nimport type { ConnectorDefinition } from './types.js';\n\nexport type ConnectorProvider = {\n id: string;\n displayName: string;\n listConnectors(): readonly ConnectorDefinition[];\n};\n\nexport const builtinConnectorProvider: ConnectorProvider = {\n id: 'builtin',\n displayName: 'Built-in connectors',\n listConnectors() {\n return BUILTIN_CONNECTORS;\n },\n};\n\nconst CONNECTOR_PROVIDERS: readonly ConnectorProvider[] = [builtinConnectorProvider];\n\nexport function listConnectorProviders(): ConnectorProvider[] {\n return [...CONNECTOR_PROVIDERS];\n}\n\nexport function listConnectorProviderDefinitions(): ConnectorDefinition[] {\n return CONNECTOR_PROVIDERS.flatMap((provider) => provider.listConnectors());\n}\n"],"mappings":";;AASA,MAAa,2BAA8C;CACzD,IAAI;CACJ,aAAa;CACb,iBAAiB;AACf,SAAO;;CAEV;AAED,MAAM,sBAAoD,CAAC,yBAAyB;AAEpF,SAAgB,yBAA8C;AAC5D,QAAO,CAAC,GAAG,oBAAoB;;AAGjC,SAAgB,mCAA0D;AACxE,QAAO,oBAAoB,SAAS,aAAa,SAAS,gBAAgB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { CredentialResolver } from '../auth/credentials.js';
2
+ import type { ConnectorDefinition, ConnectorInstallInput, ConnectorSecretReference } from './types.js';
3
+ export declare function connectorSecretProviderId(connectorId: string, fieldKey: string): string;
4
+ export declare function createConnectorSecretReference(connectorId: string, fieldKey: string): ConnectorSecretReference;
5
+ export declare function isConnectorSecretReference(value: unknown): value is ConnectorSecretReference;
6
+ export declare function saveConnectorSecrets(definition: ConnectorDefinition, input: ConnectorInstallInput, resolver?: CredentialResolver): Promise<void>;
7
+ export declare function resolveConnectorSecretReferences(value: unknown, resolver?: CredentialResolver): Promise<unknown>;
@@ -0,0 +1,47 @@
1
+ import { CredentialResolver, init_credentials } from "../auth/credentials.js";
2
+ //#region src/connectors/secret-store.ts
3
+ init_credentials();
4
+ function normalizeSecretSegment(value) {
5
+ return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
6
+ }
7
+ function connectorSecretProviderId(connectorId, fieldKey) {
8
+ return `connector-${normalizeSecretSegment(connectorId)}-${normalizeSecretSegment(fieldKey)}`;
9
+ }
10
+ function createConnectorSecretReference(connectorId, fieldKey) {
11
+ return { xopcSecretRef: {
12
+ provider: connectorSecretProviderId(connectorId, fieldKey),
13
+ fieldKey
14
+ } };
15
+ }
16
+ function isConnectorSecretReference(value) {
17
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
18
+ const ref = value.xopcSecretRef;
19
+ return Boolean(ref && typeof ref === "object" && !Array.isArray(ref) && typeof ref.provider === "string" && typeof ref.fieldKey === "string");
20
+ }
21
+ async function saveConnectorSecrets(definition, input, resolver = new CredentialResolver()) {
22
+ for (const secret of definition.setup.secrets ?? []) {
23
+ const rawValue = input.secrets?.[secret.key];
24
+ if (typeof rawValue !== "string" || rawValue.trim().length === 0) continue;
25
+ await resolver.saveApiKey(connectorSecretProviderId(definition.id, secret.key), rawValue.trim(), { profileName: "default" });
26
+ }
27
+ }
28
+ async function resolveSecretReference(reference, resolver) {
29
+ return await resolver.resolveApiKey(reference.xopcSecretRef.provider) ?? void 0;
30
+ }
31
+ async function resolveConnectorSecretReferences(value, resolver = new CredentialResolver()) {
32
+ if (isConnectorSecretReference(value)) return resolveSecretReference(value, resolver);
33
+ if (Array.isArray(value)) return (await Promise.all(value.map((item) => resolveConnectorSecretReferences(item, resolver)))).filter((item) => item !== void 0);
34
+ if (value && typeof value === "object") {
35
+ const output = {};
36
+ for (const [key, child] of Object.entries(value)) {
37
+ const resolved = await resolveConnectorSecretReferences(child, resolver);
38
+ if (resolved !== void 0) output[key] = resolved;
39
+ }
40
+ return output;
41
+ }
42
+ return value;
43
+ }
44
+ //#endregion
45
+ export { connectorSecretProviderId, createConnectorSecretReference, isConnectorSecretReference, resolveConnectorSecretReferences, saveConnectorSecrets };
46
+
47
+ //# sourceMappingURL=secret-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-store.js","names":[],"sources":["../../../src/connectors/secret-store.ts"],"sourcesContent":["import { CredentialResolver } from '../auth/credentials.js';\nimport type { ConnectorDefinition, ConnectorInstallInput, ConnectorSecretReference } from './types.js';\n\nfunction normalizeSecretSegment(value: string): string {\n return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '');\n}\n\nexport function connectorSecretProviderId(connectorId: string, fieldKey: string): string {\n const normalizedConnectorId = normalizeSecretSegment(connectorId);\n const normalizedFieldKey = normalizeSecretSegment(fieldKey);\n return `connector-${normalizedConnectorId}-${normalizedFieldKey}`;\n}\n\nexport function createConnectorSecretReference(connectorId: string, fieldKey: string): ConnectorSecretReference {\n return {\n xopcSecretRef: {\n provider: connectorSecretProviderId(connectorId, fieldKey),\n fieldKey,\n },\n };\n}\n\nexport function isConnectorSecretReference(value: unknown): value is ConnectorSecretReference {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const ref = (value as Record<string, unknown>).xopcSecretRef;\n return Boolean(\n ref &&\n typeof ref === 'object' &&\n !Array.isArray(ref) &&\n typeof (ref as Record<string, unknown>).provider === 'string' &&\n typeof (ref as Record<string, unknown>).fieldKey === 'string',\n );\n}\n\nexport async function saveConnectorSecrets(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n resolver = new CredentialResolver(),\n): Promise<void> {\n for (const secret of definition.setup.secrets ?? []) {\n const rawValue = input.secrets?.[secret.key];\n if (typeof rawValue !== 'string' || rawValue.trim().length === 0) {\n continue;\n }\n await resolver.saveApiKey(connectorSecretProviderId(definition.id, secret.key), rawValue.trim(), {\n profileName: 'default',\n });\n }\n}\n\nasync function resolveSecretReference(\n reference: ConnectorSecretReference,\n resolver: CredentialResolver,\n): Promise<string | undefined> {\n const value = await resolver.resolveApiKey(reference.xopcSecretRef.provider);\n return value ?? undefined;\n}\n\nexport async function resolveConnectorSecretReferences(\n value: unknown,\n resolver = new CredentialResolver(),\n): Promise<unknown> {\n if (isConnectorSecretReference(value)) {\n return resolveSecretReference(value, resolver);\n }\n if (Array.isArray(value)) {\n const items = await Promise.all(value.map((item) => resolveConnectorSecretReferences(item, resolver)));\n return items.filter((item) => item !== undefined);\n }\n if (value && typeof value === 'object') {\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n const resolved = await resolveConnectorSecretReferences(child, resolver);\n if (resolved !== undefined) {\n output[key] = resolved;\n }\n }\n return output;\n }\n return value;\n}\n"],"mappings":";;kBAA4D;AAG5D,SAAS,uBAAuB,OAAuB;AACrD,QAAO,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,iBAAiB,IAAI,CAAC,QAAQ,YAAY,GAAG;;AAGzF,SAAgB,0BAA0B,aAAqB,UAA0B;AAGvF,QAAO,aAFuB,uBAAuB,YAEZ,CAAC,GADf,uBAAuB,SACa;;AAGjE,SAAgB,+BAA+B,aAAqB,UAA4C;AAC9G,QAAO,EACL,eAAe;EACb,UAAU,0BAA0B,aAAa,SAAS;EAC1D;EACD,EACF;;AAGH,SAAgB,2BAA2B,OAAmD;AAC5F,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;CAET,MAAM,MAAO,MAAkC;AAC/C,QAAO,QACL,OACE,OAAO,QAAQ,YACf,CAAC,MAAM,QAAQ,IAAI,IACnB,OAAQ,IAAgC,aAAa,YACrD,OAAQ,IAAgC,aAAa,SACxD;;AAGH,eAAsB,qBACpB,YACA,OACA,WAAW,IAAI,oBAAoB,EACpB;AACf,MAAK,MAAM,UAAU,WAAW,MAAM,WAAW,EAAE,EAAE;EACnD,MAAM,WAAW,MAAM,UAAU,OAAO;AACxC,MAAI,OAAO,aAAa,YAAY,SAAS,MAAM,CAAC,WAAW,EAC7D;AAEF,QAAM,SAAS,WAAW,0BAA0B,WAAW,IAAI,OAAO,IAAI,EAAE,SAAS,MAAM,EAAE,EAC/F,aAAa,WACd,CAAC;;;AAIN,eAAe,uBACb,WACA,UAC6B;AAE7B,QAAO,MADa,SAAS,cAAc,UAAU,cAAc,SAAS,IAC5D,KAAA;;AAGlB,eAAsB,iCACpB,OACA,WAAW,IAAI,oBAAoB,EACjB;AAClB,KAAI,2BAA2B,MAAM,CACnC,QAAO,uBAAuB,OAAO,SAAS;AAEhD,KAAI,MAAM,QAAQ,MAAM,CAEtB,SAAO,MADa,QAAQ,IAAI,MAAM,KAAK,SAAS,iCAAiC,MAAM,SAAS,CAAC,CAAC,EACzF,QAAQ,SAAS,SAAS,KAAA,EAAU;AAEnD,KAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,SAAkC,EAAE;AAC1C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAiC,EAAE;GAC3E,MAAM,WAAW,MAAM,iCAAiC,OAAO,SAAS;AACxE,OAAI,aAAa,KAAA,EACf,QAAO,OAAO;;AAGlB,SAAO;;AAET,QAAO"}