@xopcai/xopc 0.0.231 → 0.0.233

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 (400) hide show
  1. package/README.md +1 -0
  2. package/README.zh-CN.md +1 -0
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/schema/config-schema.d.ts +3 -3
  5. package/dist/extensions/telegram/src/config-schema.d.ts +4 -4
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
  8. package/dist/gateway/static/root/assets/{activity-store-M0nAY5XB.js → activity-store-DQ5L3PTi.js} +1 -1
  9. package/dist/gateway/static/root/assets/agent-avatar-dicebear-Bps8fvBp.js +1 -0
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-JrK80PvP.js +1 -0
  11. package/dist/gateway/static/root/assets/agents-CJYEnz94.js +1 -0
  12. package/dist/gateway/static/root/assets/api-DE6tZKG0.js +1 -0
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-DP7YVRPn.js → app-management-settings-panel-BryzDVod.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-CVQ5n7y6.js → appearance-settings-BoweLBDm.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-Bt8_sWtU.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-7_DXaMTP.js → archive-plugin-DyujzZNu.js} +1 -1
  17. package/dist/gateway/static/root/assets/{attachment-load-mmr_mHRr.js → attachment-load-DmXGUWve.js} +1 -1
  18. package/dist/gateway/static/root/assets/attachment-preview-renderer-BDTD8YUe.js +12 -0
  19. package/dist/gateway/static/root/assets/{automations-page-DfY-T6Ga.js → automations-page-DrTVSK7o.js} +1 -1
  20. package/dist/gateway/static/root/assets/automations-workspace-86UTesz3.js +6 -0
  21. package/dist/gateway/static/root/assets/{binary-plugins-CO9QMEh2.js → binary-plugins-mFyeC74W.js} +2 -2
  22. package/dist/gateway/static/root/assets/{block-editor-CE14CVOy.js → block-editor-D5yMFrgH.js} +4 -4
  23. package/dist/gateway/static/root/assets/browser-settings-page-DfMU7yXv.js +8 -0
  24. package/dist/gateway/static/root/assets/browser-workflow-inputs-B6rLBtua.js +1 -0
  25. package/dist/gateway/static/root/assets/{browser-workflows-page-1wgXyoSO.js → browser-workflows-page-C74sg50f.js} +2 -2
  26. package/dist/gateway/static/root/assets/capabilities-settings-panel-lsHRuBlX.js +7 -0
  27. package/dist/gateway/static/root/assets/channels-settings-CxR_clkO.js +1 -0
  28. package/dist/gateway/static/root/assets/{channel-recipient-api-C5ABr73b.js → channels-status-swr-DowVNjNw.js} +1 -1
  29. package/dist/gateway/static/root/assets/{chat-terminal-dock-CdRW6Euc.js → chat-terminal-dock-BO6_BgjE.js} +2 -2
  30. package/dist/gateway/static/root/assets/{code-editor-dFzqyDXS.js → code-editor-D4_k-6QN.js} +1 -1
  31. package/dist/gateway/static/root/assets/connectors-page-CpNLyKB4.js +2 -0
  32. package/dist/gateway/static/root/assets/cron-expression-CYMXfk4M.js +2 -0
  33. package/dist/gateway/static/root/assets/date-picker-DIM_OkQP.js +1 -0
  34. package/dist/gateway/static/root/assets/dependency-picker-Cp8I6rsL.js +1 -0
  35. package/dist/gateway/static/root/assets/{desktop-pet-settings-MmOR4A3u.js → desktop-pet-settings-NjPiz3M_.js} +1 -1
  36. package/dist/gateway/static/root/assets/{desktop-pet-CMO-J3cG.js → desktop-pet-wzSzZ6S8.js} +1 -1
  37. package/dist/gateway/static/root/assets/dist-DqPZM2MH2.js +1 -0
  38. package/dist/gateway/static/root/assets/{extension-debug-page-DdH0dG2_.js → extension-debug-page-CoMl13ET.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-page-Clg-KktN.js → extension-page-CXc1Lc8x.js} +1 -1
  40. package/dist/gateway/static/root/assets/extension-settings-page-CfEWpgjl.js +1 -0
  41. package/dist/gateway/static/root/assets/{gateway-config-api-DEHnF4Wm.js → gateway-config-api-yH4KAEkK.js} +1 -1
  42. package/dist/gateway/static/root/assets/gateway-config-swr-YyZJKvFf.js +1 -0
  43. package/dist/gateway/static/root/assets/{gateway-settings-DKkEXXj9.js → gateway-settings-BmjJIiKh.js} +1 -1
  44. package/dist/gateway/static/root/assets/{gateway-startup-retry-B_zrtccP.js → gateway-startup-retry-Dnrl91pU.js} +1 -1
  45. package/dist/gateway/static/root/assets/heartbeat-settings-DGq9q4b6.js +1 -0
  46. package/dist/gateway/static/root/assets/home-page-Dj4B1wb3.js +1 -0
  47. package/dist/gateway/static/root/assets/html-workspace-editor-C3DKAkMc.js +1 -0
  48. package/dist/gateway/static/root/assets/{image-generation-api-YKP2me5Z.js → image-generation-api-BNzAAw4Y.js} +1 -1
  49. package/dist/gateway/static/root/assets/index-BGf-TiZj.js +70 -0
  50. package/dist/gateway/static/root/assets/index-BTUuTnc9.css +2 -0
  51. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BvpEeHnm.js → keyboard-shortcuts-settings-CfNV1ysF.js} +1 -1
  52. package/dist/gateway/static/root/assets/local-app-workbench-page-IJg75WaN.js +2 -0
  53. package/dist/gateway/static/root/assets/{local-apps-page-Bzvn99eH.js → local-apps-page-MPd4Fl_l.js} +1 -1
  54. package/dist/gateway/static/root/assets/locale-store-D_dq_0LV.js +1 -0
  55. package/dist/gateway/static/root/assets/logs-page-NsfoazgK.js +2 -0
  56. package/dist/gateway/static/root/assets/management-settings-DeIjN4e0.js +1 -0
  57. package/dist/gateway/static/root/assets/markdown-editor-nDLmA_LF.js +2 -0
  58. package/dist/gateway/static/root/assets/markdown-split-BUAVv6Gu.js +1 -0
  59. package/dist/gateway/static/root/assets/markdown-view-CPkBOY3h.js +201 -0
  60. package/dist/gateway/static/root/assets/{media-plugins-D8I7OGnT.js → media-plugins-DFsVnOY-.js} +1 -1
  61. package/dist/gateway/static/root/assets/messages-D4qOHT4D.js +3 -0
  62. package/dist/gateway/static/root/assets/mobile-device-api-D9JevyCE.js +1 -0
  63. package/dist/gateway/static/root/assets/models-hub-cache-C5y2gzMU.js +1 -0
  64. package/dist/gateway/static/root/assets/{notes-api-EpgG-OQc.js → notes-api-BWSfTP1w.js} +1 -1
  65. package/dist/gateway/static/root/assets/{notes-page-CCvjGMhN.js → notes-page-CV8UJj7g.js} +1 -1
  66. package/dist/gateway/static/root/assets/notes-workbench-DrjMVgEI.js +4 -0
  67. package/dist/gateway/static/root/assets/{oauth-api-BwNLwbI8.js → oauth-api-DnanEBsf.js} +1 -1
  68. package/dist/gateway/static/root/assets/popover-select-3E24E65N.js +1 -0
  69. package/dist/gateway/static/root/assets/{product-open-page-MmMswmOU.js → product-open-page-zNg1KOy2.js} +1 -1
  70. package/dist/gateway/static/root/assets/project-detail-page-tfcGYL-O.js +1 -0
  71. package/dist/gateway/static/root/assets/projects-page-BkjnXLdJ.js +1 -0
  72. package/dist/gateway/static/root/assets/{registry-api-BFZrVYfy.js → registry-api-BeVzfRvs.js} +1 -1
  73. package/dist/gateway/static/root/assets/remote-access-hub-BXn-3n2d.js +1 -0
  74. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Dx6o7sLu.js → runtime-tools-settings-panel-BxoioSvT.js} +2 -2
  75. package/dist/gateway/static/root/assets/{schema-form-Cdd9c4vt.js → schema-form-vzbmscrE.js} +1 -1
  76. package/dist/gateway/static/root/assets/sessions-page-MLNjrOkw.js +1 -0
  77. package/dist/gateway/static/root/assets/settings-advanced-gate-ByNLBY2q.js +1 -0
  78. package/dist/gateway/static/root/assets/{settings-form-section-D0YxMnhm.js → settings-form-section-x9k7MWD3.js} +1 -1
  79. package/dist/gateway/static/root/assets/settings-loading-skeleton-BLFOD9h9.js +1 -0
  80. package/dist/gateway/static/root/assets/settings-page-CwgTooar.js +1 -0
  81. package/dist/gateway/static/root/assets/settings-shell-layer-context-DCp6ykjQ.js +1 -0
  82. package/dist/gateway/static/root/assets/setup-status-panel-bnueBZg8.js +1 -0
  83. package/dist/gateway/static/root/assets/{share-preview-page-DiqBn-oE.js → share-preview-page-COTrPAd-.js} +1 -1
  84. package/dist/gateway/static/root/assets/shares-settings-D-v_psqL.js +1 -0
  85. package/dist/gateway/static/root/assets/skill-reload-api-DJICr4wh.js +1 -0
  86. package/dist/gateway/static/root/assets/{skills-page-CZwhWiRl.js → skills-page-D9wM6_Jn.js} +1 -1
  87. package/dist/gateway/static/root/assets/{skills-page.utils-kBGr8opZ.js → skills-page.utils-PtlQLM5a.js} +1 -1
  88. package/dist/gateway/static/root/assets/{system-settings-panel-CPBs6lWi.js → system-settings-panel-BR74mNEK.js} +1 -1
  89. package/dist/gateway/static/root/assets/task-detail-page-B-rmeE8t.js +1 -0
  90. package/dist/gateway/static/root/assets/{theme-store-Qgvo0Ga7.js → theme-store-Bud54q9e.js} +1 -1
  91. package/dist/gateway/static/root/assets/{use-autosave-C4YcEiP9.js → use-autosave-DH47MH7s.js} +1 -1
  92. package/dist/gateway/static/root/assets/user-context-page-B6eyxxOT.js +1 -0
  93. package/dist/gateway/static/root/assets/{vendor-codemirror-DRr7hFaD.js → vendor-codemirror--gTq3YAI.js} +16 -16
  94. package/dist/gateway/static/root/assets/voice-api-key-field-B59GaqRa.js +1 -0
  95. package/dist/gateway/static/root/assets/voice-config-api-C0ahrZ0e.js +1 -0
  96. package/dist/gateway/static/root/assets/{work-discovery-overlay-CKIdPEen.js → work-discovery-overlay-DTn4RCcx.js} +1 -1
  97. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BK44Vm5W.js → workflow-run-setup-panel-yDFoEX06.js} +2 -2
  98. package/dist/gateway/static/root/assets/workflows-page-BOwSbfWm.js +5 -0
  99. package/dist/gateway/static/root/index.html +16 -16
  100. package/dist/package.js +1 -1
  101. package/dist/packages/endpoint-tools-protocol/src/index.js +162 -2
  102. package/dist/packages/gateway-contract/src/product-delivery.js +6 -2
  103. package/dist/packages/gateway-contract/src/turn-outcome.js +77 -1
  104. package/dist/src/agent/agent-manager.d.ts +1 -2
  105. package/dist/src/agent/agent-manager.js +29 -44
  106. package/dist/src/agent/background-review/run-background-review.js +10 -15
  107. package/dist/src/agent/capabilities/definitions.d.ts +1 -1
  108. package/dist/src/agent/capabilities/definitions.js +2 -1
  109. package/dist/src/agent/embedded/run-for-session.js +1 -1
  110. package/dist/src/agent/external-tools/endpoint-provider.js +5 -1
  111. package/dist/src/agent/external-tools/mcp-provider.js +3 -13
  112. package/dist/src/agent/image/generation/runtime.js +1 -1
  113. package/dist/src/agent/image/tool-model-config.js +13 -14
  114. package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +0 -9
  115. package/dist/src/agent/mcp/bundle-mcp-policy.js +1 -13
  116. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  117. package/dist/src/agent/mcp/index.js +2 -2
  118. package/dist/src/agent/media-generation/runtime-shared.d.ts +1 -1
  119. package/dist/src/agent/media-generation/runtime-shared.js +1 -1
  120. package/dist/src/agent/memory/create-memory-manager.js +1 -1
  121. package/dist/src/agent/memory/manager.d.ts +1 -1
  122. package/dist/src/{agent-runtime/memory-runtime.d.ts → agent/memory/runtime.d.ts} +1 -1
  123. package/dist/src/{agent-runtime/memory-runtime.js → agent/memory/runtime.js} +2 -3
  124. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -3
  125. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -3
  126. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +2 -2
  127. package/dist/src/agent/prompt/sections/tooling.js +5 -0
  128. package/dist/src/agent/service.js +0 -1
  129. package/dist/src/agent/starter-agents.js +1 -8
  130. package/dist/src/agent/tools/create-share-tool.js +2 -1
  131. package/dist/src/agent/tools/exec-command.js +2 -1
  132. package/dist/src/agent/tools/executor.d.ts +1 -1
  133. package/dist/src/agent/tools/factory.js +2 -0
  134. package/dist/src/agent/tools/index.d.ts +1 -0
  135. package/dist/src/agent/tools/index.js +2 -1
  136. package/dist/src/agent/tools/publish-artifacts.d.ts +2 -0
  137. package/dist/src/agent/tools/publish-artifacts.js +82 -0
  138. package/dist/src/agent/tools/send-media.js +2 -1
  139. package/dist/src/agent/tools/workflow-tool.js +1 -5
  140. package/dist/src/agent-config/index.d.ts +2 -0
  141. package/dist/src/agent-config/index.js +11 -0
  142. package/dist/src/agent-config/resolver.d.ts +11 -0
  143. package/dist/src/agent-config/resolver.js +113 -0
  144. package/dist/src/agent-config/schema.d.ts +491 -0
  145. package/dist/src/agent-config/schema.js +172 -0
  146. package/dist/src/chat-commands/builtins/config.js +2 -2
  147. package/dist/src/chat-commands/builtins/review.js +1 -1
  148. package/dist/src/chat-commands/config-paths.js +1 -1
  149. package/dist/src/cli/command-catalog.js +4 -0
  150. package/dist/src/cli/command-loaders.js +1 -0
  151. package/dist/src/cli/command-manifest.js +4 -0
  152. package/dist/src/cli/commands/agents.js +2 -1
  153. package/dist/src/cli/commands/auth.js +1 -1
  154. package/dist/src/cli/commands/config.js +1 -1
  155. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  156. package/dist/src/cli/commands/doctor/checks/provider-auth.js +12 -4
  157. package/dist/src/cli/commands/image.js +3 -4
  158. package/dist/src/cli/commands/models.js +9 -3
  159. package/dist/src/cli/commands/onboard/model.js +13 -12
  160. package/dist/src/cli/commands/onboard.js +1 -1
  161. package/dist/src/cli/commands/providers.js +1 -1
  162. package/dist/src/cli/commands/support.d.ts +1 -0
  163. package/dist/src/cli/commands/support.js +51 -0
  164. package/dist/src/cli/commands/tunnel.js +3 -18
  165. package/dist/src/cli/utils/init-workspace-core.d.ts +1 -1
  166. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  167. package/dist/src/commands/agents.config.d.ts +1 -3
  168. package/dist/src/commands/agents.config.js +9 -26
  169. package/dist/src/config/agent-model-intents.d.ts +10 -0
  170. package/dist/src/config/agent-model-intents.js +39 -0
  171. package/dist/src/config/agent-profile.d.ts +7 -9
  172. package/dist/src/config/agent-profile.js +30 -28
  173. package/dist/src/config/default-model.d.ts +1 -11
  174. package/dist/src/config/default-model.js +3 -11
  175. package/dist/src/config/index.js +3 -3
  176. package/dist/src/config/integration.d.ts +1 -1
  177. package/dist/src/config/reload.js +1 -1
  178. package/dist/src/config/rules.js +3 -3
  179. package/dist/src/config/schema.d.ts +187 -452
  180. package/dist/src/config/schema.js +53 -131
  181. package/dist/src/endpoint-tools/binding-service.d.ts +22 -0
  182. package/dist/src/endpoint-tools/binding-service.js +45 -0
  183. package/dist/src/endpoint-tools/index.d.ts +1 -0
  184. package/dist/src/endpoint-tools/index.js +2 -1
  185. package/dist/src/endpoint-tools/invocation-service.d.ts +1 -0
  186. package/dist/src/endpoint-tools/invocation-service.js +8 -0
  187. package/dist/src/endpoint-tools/policy.d.ts +4 -1
  188. package/dist/src/endpoint-tools/policy.js +68 -5
  189. package/dist/src/endpoint-tools/registry.js +1 -1
  190. package/dist/src/endpoint-tools/runtime.d.ts +2 -0
  191. package/dist/src/endpoint-tools/runtime.js +8 -0
  192. package/dist/src/extensions/activation-context.js +7 -11
  193. package/dist/src/files/file-service.js +14 -5
  194. package/dist/src/gateway/agent-builtin-tools.d.ts +250 -6
  195. package/dist/src/gateway/agent-builtin-tools.js +284 -46
  196. package/dist/src/gateway/agents-admin.d.ts +20 -62
  197. package/dist/src/gateway/agents-admin.js +36 -228
  198. package/dist/src/gateway/chat-stream/turn-outcome-collector.js +41 -6
  199. package/dist/src/gateway/device-routes.d.ts +3 -0
  200. package/dist/src/gateway/device-routes.js +47 -0
  201. package/dist/src/gateway/global-defaults-admin.d.ts +6 -20
  202. package/dist/src/gateway/global-defaults-admin.js +20 -120
  203. package/dist/src/gateway/heartbeat/service.js +1 -1
  204. package/dist/src/gateway/hono/app.js +4 -2
  205. package/dist/src/gateway/hono/lib/config-payload.d.ts +54 -137
  206. package/dist/src/gateway/hono/lib/config-payload.js +2 -4
  207. package/dist/src/gateway/hono/middleware/auth.js +36 -3
  208. package/dist/src/gateway/hono/middleware/scopes.d.ts +2 -12
  209. package/dist/src/gateway/hono/middleware/scopes.js +9 -18
  210. package/dist/src/gateway/hono/routes/agents.js +64 -100
  211. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  212. package/dist/src/gateway/hono/routes/device-push.d.ts +2 -0
  213. package/dist/src/gateway/hono/routes/{mobile.js → device-push.js} +40 -18
  214. package/dist/src/gateway/hono/routes/devices.d.ts +4 -0
  215. package/dist/src/gateway/hono/routes/devices.js +214 -0
  216. package/dist/src/gateway/hono/routes/endpoint-tools.js +68 -1
  217. package/dist/src/gateway/hono/routes/files.js +12 -1
  218. package/dist/src/gateway/hono/routes/global-defaults.js +5 -9
  219. package/dist/src/gateway/hono/routes/index.js +4 -2
  220. package/dist/src/gateway/hono/routes/lazy-bundles.js +12 -20
  221. package/dist/src/gateway/hono/routes/media.js +46 -2
  222. package/dist/src/gateway/hono/routes/models.js +2 -2
  223. package/dist/src/gateway/hono/routes/realtime.js +8 -1
  224. package/dist/src/gateway/hono/routes/status.js +9 -16
  225. package/dist/src/gateway/hono/routes/support.d.ts +3 -0
  226. package/dist/src/gateway/hono/routes/support.js +28 -0
  227. package/dist/src/gateway/hono/routes/tunnel.d.ts +0 -2
  228. package/dist/src/gateway/hono/routes/tunnel.js +10 -199
  229. package/dist/src/gateway/hono/routes/you.js +24 -0
  230. package/dist/src/gateway/image-generation-setup.d.ts +2 -2
  231. package/dist/src/gateway/image-generation-setup.js +8 -7
  232. package/dist/src/gateway/public-url.d.ts +1 -1
  233. package/dist/src/gateway/security/gateway-principal.d.ts +11 -0
  234. package/dist/src/gateway/security/gateway-principal.js +12 -0
  235. package/dist/src/gateway/security/gateway-scopes.d.ts +7 -0
  236. package/dist/src/gateway/security/gateway-scopes.js +66 -0
  237. package/dist/src/gateway/security/index.d.ts +2 -1
  238. package/dist/src/gateway/security/index.js +3 -2
  239. package/dist/src/gateway/service.js +7 -7
  240. package/dist/src/gateway/xopc-cloud-capability-setup.js +19 -21
  241. package/dist/src/heartbeat/index.js +1 -1
  242. package/dist/src/media/store.js +9 -0
  243. package/dist/src/migrations/index.d.ts +0 -1
  244. package/dist/src/migrations/index.js +1 -2
  245. package/dist/src/migrations/runner.js +1 -2
  246. package/dist/src/notifications/device-store.d.ts +1 -1
  247. package/dist/src/notifications/device-store.js +11 -11
  248. package/dist/src/notifications/store.js +3 -3
  249. package/dist/src/providers/index.js +1 -1
  250. package/dist/src/providers/model-reference-auditor.js +14 -9
  251. package/dist/src/realtime/runtime.d.ts +2 -0
  252. package/dist/src/realtime/runtime.js +27 -3
  253. package/dist/src/realtime/tickets.d.ts +6 -1
  254. package/dist/src/realtime/tickets.js +2 -1
  255. package/dist/src/remote-access/exposure-manager.js +3 -3
  256. package/dist/src/share/share-url.js +2 -2
  257. package/dist/src/storage/sqlite/device-access-repository.d.ts +54 -0
  258. package/dist/src/storage/sqlite/device-access-repository.js +194 -0
  259. package/dist/src/storage/sqlite/device-pairing-repository.d.ts +22 -0
  260. package/dist/src/storage/sqlite/device-pairing-repository.js +86 -0
  261. package/dist/src/storage/sqlite/endpoint-session-binding-repository.d.ts +8 -0
  262. package/dist/src/storage/sqlite/endpoint-session-binding-repository.js +32 -0
  263. package/dist/src/storage/sqlite/gateway-identity-repository.d.ts +10 -0
  264. package/dist/src/storage/sqlite/gateway-identity-repository.js +50 -0
  265. package/dist/src/storage/sqlite/index.d.ts +4 -0
  266. package/dist/src/storage/sqlite/index.js +5 -1
  267. package/dist/src/storage/sqlite/migrations/138_device_access.sql +96 -0
  268. package/dist/src/storage/sqlite/migrations/139_turn_outcome_artifact_backfill.sql +231 -0
  269. package/dist/src/storage/sqlite/migrations/140_endpoint_session_bindings.sql +8 -0
  270. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  271. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  272. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  273. package/dist/src/storage/sqlite/schema.js +1 -1
  274. package/dist/src/support/build-support-investigation-prompt.d.ts +2 -0
  275. package/dist/src/support/build-support-investigation-prompt.js +29 -0
  276. package/dist/src/support/collect-support-report.d.ts +16 -0
  277. package/dist/src/support/collect-support-report.js +216 -0
  278. package/dist/src/support/redact-support-report.d.ts +16 -0
  279. package/dist/src/support/redact-support-report.js +89 -0
  280. package/dist/src/support/types.d.ts +76 -0
  281. package/dist/src/support/types.js +18 -0
  282. package/dist/src/tunnel/consent.d.ts +1 -1
  283. package/dist/src/tunnel/consent.js +1 -1
  284. package/dist/src/tunnel/gateway-lifecycle.js +1 -1
  285. package/dist/src/tunnel/index.d.ts +1 -4
  286. package/dist/src/tunnel/index.js +3 -5
  287. package/dist/src/tunnel/tunnel-audit.d.ts +1 -1
  288. package/dist/src/tunnel/tunnel-config.js +1 -1
  289. package/dist/src/tunnel/tunnel-service.d.ts +2 -3
  290. package/dist/src/tunnel/tunnel-service.js +1 -20
  291. package/dist/src/tunnel/tunnel-types.d.ts +0 -6
  292. package/dist/src/user-context/user-avatar.d.ts +17 -0
  293. package/dist/src/user-context/user-avatar.js +116 -0
  294. package/dist/src/workflows/draft/workflow-draft-service.js +2 -2
  295. package/dist/src/workflows/service/workflow-run-service.js +3 -3
  296. package/package.json +4 -4
  297. package/dist/gateway/static/root/assets/agent-avatar-dicebear-CBqUnlvL.js +0 -1
  298. package/dist/gateway/static/root/assets/agents-7YO6znTT.js +0 -68
  299. package/dist/gateway/static/root/assets/api-BywYxpaS.js +0 -1
  300. package/dist/gateway/static/root/assets/apps-page-DSCia0DT.js +0 -1
  301. package/dist/gateway/static/root/assets/attachment-preview-renderer-Cmo-5BP5.js +0 -11
  302. package/dist/gateway/static/root/assets/automations-workspace-BpvD54D6.js +0 -6
  303. package/dist/gateway/static/root/assets/browser-settings-page-CeESA4Oj.js +0 -8
  304. package/dist/gateway/static/root/assets/browser-workflow-inputs-8NC2qDRF.js +0 -1
  305. package/dist/gateway/static/root/assets/capabilities-settings-panel-B_OXTojB.js +0 -7
  306. package/dist/gateway/static/root/assets/capability-presets-api-o0y9WgAI.js +0 -1
  307. package/dist/gateway/static/root/assets/capability-presets-settings-panel-D5nZecxV.js +0 -3
  308. package/dist/gateway/static/root/assets/channels-settings-BzmnWx6X.js +0 -1
  309. package/dist/gateway/static/root/assets/channels-status-swr-38FsOnR0.js +0 -1
  310. package/dist/gateway/static/root/assets/connectors-page-DX6OkwFQ.js +0 -2
  311. package/dist/gateway/static/root/assets/cron-expression-DYSMZsms.js +0 -2
  312. package/dist/gateway/static/root/assets/date-picker-DGCfX4tK.js +0 -1
  313. package/dist/gateway/static/root/assets/dependency-picker-DHDa4ht1.js +0 -1
  314. package/dist/gateway/static/root/assets/directory-picker-path-field-B9qoxDcn.js +0 -1
  315. package/dist/gateway/static/root/assets/dist-J_ySZvz0.js +0 -1
  316. package/dist/gateway/static/root/assets/extension-settings-page-eP3fJ2M6.js +0 -1
  317. package/dist/gateway/static/root/assets/file-code-corner-byQA1VfD.js +0 -1
  318. package/dist/gateway/static/root/assets/gateway-config-swr-BWGjnmDl.js +0 -1
  319. package/dist/gateway/static/root/assets/heartbeat-settings-DlBPNubY.js +0 -1
  320. package/dist/gateway/static/root/assets/home-page-BnOrLRfs.js +0 -1
  321. package/dist/gateway/static/root/assets/html-workspace-editor-bXK5tq64.js +0 -1
  322. package/dist/gateway/static/root/assets/index-0xQO5B_Q.js +0 -70
  323. package/dist/gateway/static/root/assets/index-CCyIdGuQ.css +0 -2
  324. package/dist/gateway/static/root/assets/local-app-workbench-page-Ch1rdUo8.js +0 -2
  325. package/dist/gateway/static/root/assets/locale-store-CXhjfe4q.js +0 -1
  326. package/dist/gateway/static/root/assets/logs-page-zxx2ExlY.js +0 -2
  327. package/dist/gateway/static/root/assets/management-settings-BQaeyOYm.js +0 -1
  328. package/dist/gateway/static/root/assets/markdown-editor-TWGaF7Xa.js +0 -2
  329. package/dist/gateway/static/root/assets/markdown-split-D9tmIiEm.js +0 -1
  330. package/dist/gateway/static/root/assets/markdown-view-RxNHwlNo.js +0 -201
  331. package/dist/gateway/static/root/assets/messages-BMdD0LWk.js +0 -3
  332. package/dist/gateway/static/root/assets/models-hub-cache-0RjEwafI.js +0 -1
  333. package/dist/gateway/static/root/assets/notes-workbench-9cgh77VH.js +0 -4
  334. package/dist/gateway/static/root/assets/popover-select-CccGri5Y.js +0 -1
  335. package/dist/gateway/static/root/assets/project-detail-page-hf6pmH4p.js +0 -1
  336. package/dist/gateway/static/root/assets/projects-page-By2U-Wdh.js +0 -1
  337. package/dist/gateway/static/root/assets/remote-access-hub-CUcpp7CQ.js +0 -1
  338. package/dist/gateway/static/root/assets/sessions-page-ByI82xS1.js +0 -1
  339. package/dist/gateway/static/root/assets/settings-advanced-gate-BCoI5IJ8.js +0 -1
  340. package/dist/gateway/static/root/assets/settings-loading-skeleton-y53gEKsF.js +0 -1
  341. package/dist/gateway/static/root/assets/settings-page-BoE_tToG.js +0 -1
  342. package/dist/gateway/static/root/assets/setup-status-panel-BQmyb5KC.js +0 -1
  343. package/dist/gateway/static/root/assets/shares-settings-Bf3VpZ-R.js +0 -1
  344. package/dist/gateway/static/root/assets/skill-reload-api-CXHlbuGS.js +0 -1
  345. package/dist/gateway/static/root/assets/task-detail-page-Bo0KSZ2v.js +0 -1
  346. package/dist/gateway/static/root/assets/typed-models-lib-q5-Vfqd8.js +0 -1
  347. package/dist/gateway/static/root/assets/user-context-page-Cnj7gMX2.js +0 -1
  348. package/dist/gateway/static/root/assets/voice-api-key-field-BML8zCwZ.js +0 -1
  349. package/dist/gateway/static/root/assets/workflows-page-CB98MTwG.js +0 -5
  350. package/dist/src/agent-manifest/index.d.ts +0 -5
  351. package/dist/src/agent-manifest/index.js +0 -10
  352. package/dist/src/agent-manifest/preset-chain.d.ts +0 -10
  353. package/dist/src/agent-manifest/preset-chain.js +0 -30
  354. package/dist/src/agent-manifest/prompt.d.ts +0 -2
  355. package/dist/src/agent-manifest/prompt.js +0 -49
  356. package/dist/src/agent-manifest/resolver.d.ts +0 -32
  357. package/dist/src/agent-manifest/resolver.js +0 -114
  358. package/dist/src/agent-manifest/schema.d.ts +0 -695
  359. package/dist/src/agent-manifest/schema.js +0 -226
  360. package/dist/src/agent-manifest/validator.d.ts +0 -25
  361. package/dist/src/agent-manifest/validator.js +0 -74
  362. package/dist/src/agent-runtime/boundary-guard.d.ts +0 -12
  363. package/dist/src/agent-runtime/boundary-guard.js +0 -21
  364. package/dist/src/agent-runtime/index.d.ts +0 -7
  365. package/dist/src/agent-runtime/index.js +0 -8
  366. package/dist/src/agent-runtime/model-router.d.ts +0 -11
  367. package/dist/src/agent-runtime/model-router.js +0 -14
  368. package/dist/src/agent-runtime/run-trace.d.ts +0 -27
  369. package/dist/src/agent-runtime/run-trace.js +0 -51
  370. package/dist/src/agent-runtime/runtime-profile.d.ts +0 -26
  371. package/dist/src/agent-runtime/runtime-profile.js +0 -42
  372. package/dist/src/agent-runtime/tool-registry.d.ts +0 -28
  373. package/dist/src/agent-runtime/tool-registry.js +0 -50
  374. package/dist/src/agent-runtime/workflow-runtime.d.ts +0 -31
  375. package/dist/src/agent-runtime/workflow-runtime.js +0 -32
  376. package/dist/src/config/agent-typed-models.d.ts +0 -13
  377. package/dist/src/config/agent-typed-models.js +0 -48
  378. package/dist/src/gateway/capability-presets-admin.d.ts +0 -88
  379. package/dist/src/gateway/capability-presets-admin.js +0 -303
  380. package/dist/src/gateway/hono/lib/agent-model.d.ts +0 -35
  381. package/dist/src/gateway/hono/lib/agent-model.js +0 -97
  382. package/dist/src/gateway/hono/routes/capability-presets.d.ts +0 -3
  383. package/dist/src/gateway/hono/routes/capability-presets.js +0 -187
  384. package/dist/src/gateway/hono/routes/mobile.d.ts +0 -3
  385. package/dist/src/gateway/security/operator-scopes.d.ts +0 -37
  386. package/dist/src/gateway/security/operator-scopes.js +0 -147
  387. package/dist/src/migrations/config/default-capability-preset.d.ts +0 -10
  388. package/dist/src/migrations/config/default-capability-preset.js +0 -133
  389. package/dist/src/tunnel/enable-lan-pairing.d.ts +0 -8
  390. package/dist/src/tunnel/enable-lan-pairing.js +0 -41
  391. package/dist/src/tunnel/pair-context.d.ts +0 -36
  392. package/dist/src/tunnel/pair-context.js +0 -77
  393. package/dist/src/tunnel/pair-url.d.ts +0 -43
  394. package/dist/src/tunnel/pair-url.js +0 -117
  395. package/dist/src/tunnel/pairing-rate-limit.d.ts +0 -12
  396. package/dist/src/tunnel/pairing-rate-limit.js +0 -28
  397. package/dist/src/tunnel/pairing.d.ts +0 -21
  398. package/dist/src/tunnel/pairing.js +0 -103
  399. package/dist/src/tunnel/tunnel-qr.d.ts +0 -9
  400. package/dist/src/tunnel/tunnel-qr.js +0 -29
@@ -6,6 +6,7 @@ import "../../../storage/sqlite/index.js";
6
6
  import { listUserFocuses, updateUserFocus } from "../../../user-context/sources/repository.js";
7
7
  import { canonicalUnderstandingKey, findDuplicateUnderstanding } from "../../../user-context/understanding.js";
8
8
  import { listContextObjects } from "../../../user-context/context-objects.js";
9
+ import { deleteUserAvatar, readUserAvatar, writeUserAvatar } from "../../../user-context/user-avatar.js";
9
10
  import { repairExtractedContext } from "../../../user-context/extraction/repair.js";
10
11
  import { getUserRelationship, listUserRelationships, mergeUserRelationships, patchUserRelationship } from "../../../user-context/relationships/service.js";
11
12
  import { USER_PERSON_KINDS } from "../../../user-context/relationships/types.js";
@@ -95,6 +96,29 @@ function machineCallName() {
95
96
  }
96
97
  function registerYouRoutes(authenticated, deps) {
97
98
  const write = deps.strictRateLimitMiddleware;
99
+ authenticated.get("/api/you/avatar", async (c) => {
100
+ const result = await readUserAvatar();
101
+ if (result.ok === false) return c.json({ error: result.error }, result.status);
102
+ return new Response(result.data.buffer, {
103
+ status: 200,
104
+ headers: {
105
+ "Content-Type": result.data.contentType,
106
+ "Cache-Control": "private, no-store"
107
+ }
108
+ });
109
+ });
110
+ authenticated.put("/api/you/avatar", write, async (c) => {
111
+ const body = await readBody(c);
112
+ if (!body) return c.json({ error: "Invalid JSON" }, 400);
113
+ const result = await writeUserAvatar(typeof body.base64 === "string" ? body.base64 : "", typeof body.mimeType === "string" ? body.mimeType : "");
114
+ if (result.ok === false) return c.json({ error: result.error }, result.status);
115
+ return c.json({ ok: true });
116
+ });
117
+ authenticated.delete("/api/you/avatar", write, async (c) => {
118
+ const result = await deleteUserAvatar();
119
+ if (result.ok === false) return c.json({ error: result.error }, result.status);
120
+ return c.json({ ok: true });
121
+ });
98
122
  authenticated.get("/api/you", (c) => c.json({
99
123
  profile: getUserProfile(),
100
124
  understandings: listUnderstandings(),
@@ -14,9 +14,9 @@ export declare function getAgentImageGenerationConfig(config: Config, agentIdRaw
14
14
  agentId: string;
15
15
  model: {
16
16
  primary: string;
17
- fallbacks?: string[];
17
+ fallbacks: string[];
18
+ autoProviderFallback: boolean;
18
19
  timeoutMs?: number;
19
- autoProviderFallback?: boolean;
20
20
  };
21
21
  };
22
22
  export declare function prepareImageGenerationSetup(config: Config, agentIdRaw: string, input: ImageGenerationSetupInput): {
@@ -1,6 +1,6 @@
1
1
  import { ConfigSchema, init_schema } from "../config/schema.js";
2
2
  import { init_agent_scope, normalizeAgentId } from "../agent/agent-scope.js";
3
- import { resolveEffectiveAgentManifestForAgent } from "../config/agent-profile.js";
3
+ import { resolveEffectiveAgentConfigForAgent } from "../config/agent-profile.js";
4
4
  import { fetchWithTimeoutGuarded } from "../media-shared/http/provider-http.js";
5
5
  import "../media-shared/http/index.js";
6
6
  import { getImageGenerationProvider, listImageGenerationProvidersSummary } from "../agent/image/generation/provider-registry.js";
@@ -56,7 +56,7 @@ function getAgentImageGenerationConfig(config, agentIdRaw) {
56
56
  if (!config.agents.list.some((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId)) throw new Error(`Agent not found: ${agentId}`);
57
57
  return {
58
58
  agentId,
59
- model: resolveEffectiveAgentManifestForAgent(config, agentId).models.imageGenerationModel ?? null
59
+ model: resolveEffectiveAgentConfigForAgent(config, agentId).config.models.imageGeneration ?? null
60
60
  };
61
61
  }
62
62
  function prepareImageGenerationSetup(config, agentIdRaw, input) {
@@ -96,11 +96,12 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
96
96
  };
97
97
  const entry = next.agents.list[index];
98
98
  entry.models = {
99
- ...entry.models ?? {
100
- defaultRole: resolveEffectiveAgentManifestForAgent(config, agentId).models.defaultRole,
101
- roles: {}
102
- },
103
- imageGenerationModel: { primary: `${providerId}/${modelId}` }
99
+ ...entry.models ?? {},
100
+ imageGeneration: {
101
+ primary: `${providerId}/${modelId}`,
102
+ fallbacks: [],
103
+ autoProviderFallback: false
104
+ }
104
105
  };
105
106
  const parsed = ConfigSchema.safeParse(next);
106
107
  if (!parsed.success) return {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Runtime accessors for `gateway.publicUrl` (the user-deployed reverse-proxy
3
3
  * URL). Centralizes the "is it configured?" + "normalized origin" lookup so
4
- * callers (pair-context, exchange-token, CORS allowlist, UI status) all agree
4
+ * callers (device access, CORS allowlist, UI status) all agree
5
5
  * on the same value.
6
6
  */
7
7
  import type { Config } from '../config/schema.js';
@@ -0,0 +1,11 @@
1
+ import type { Context } from 'hono';
2
+ import type { GatewayScope } from './gateway-scopes.js';
3
+ export type GatewayPrincipal = {
4
+ kind: 'owner' | 'device' | 'trusted-proxy';
5
+ principalId: string;
6
+ deviceId?: string;
7
+ accessSessionId?: string;
8
+ scopes: readonly GatewayScope[];
9
+ };
10
+ export declare function setGatewayPrincipal(c: Context, principal: GatewayPrincipal): void;
11
+ export declare function getGatewayPrincipal(c: Context): GatewayPrincipal;
@@ -0,0 +1,12 @@
1
+ //#region src/gateway/security/gateway-principal.ts
2
+ const PRINCIPAL_CONTEXT_KEY = "gatewayPrincipal";
3
+ function setGatewayPrincipal(c, principal) {
4
+ c.set(PRINCIPAL_CONTEXT_KEY, principal);
5
+ }
6
+ function getGatewayPrincipal(c) {
7
+ const principal = c.get(PRINCIPAL_CONTEXT_KEY);
8
+ if (!principal) throw new Error("Gateway principal is unavailable");
9
+ return principal;
10
+ }
11
+ //#endregion
12
+ export { getGatewayPrincipal, setGatewayPrincipal };
@@ -0,0 +1,7 @@
1
+ export declare const GATEWAY_SCOPES: readonly ["gateway.status", "agents.read", "agents.run", "sessions.read", "sessions.write", "workspace.read", "workspace.write", "tasks.read", "tasks.write", "automations.read", "automations.write", "notifications.self", "device.self", "gateway.admin"];
2
+ export type GatewayScope = typeof GATEWAY_SCOPES[number];
3
+ export declare const DEFAULT_MOBILE_SCOPES: readonly GatewayScope[];
4
+ export declare function isGatewayScope(value: unknown): value is GatewayScope;
5
+ export declare function parseGatewayScopes(value: string): GatewayScope[];
6
+ export declare function requiredGatewayScope(method: string, path: string): GatewayScope;
7
+ export declare function hasGatewayScope(granted: readonly GatewayScope[], required: GatewayScope): boolean;
@@ -0,0 +1,66 @@
1
+ //#region src/gateway/security/gateway-scopes.ts
2
+ const GATEWAY_SCOPES = [
3
+ "gateway.status",
4
+ "agents.read",
5
+ "agents.run",
6
+ "sessions.read",
7
+ "sessions.write",
8
+ "workspace.read",
9
+ "workspace.write",
10
+ "tasks.read",
11
+ "tasks.write",
12
+ "automations.read",
13
+ "automations.write",
14
+ "notifications.self",
15
+ "device.self",
16
+ "gateway.admin"
17
+ ];
18
+ const KNOWN_GATEWAY_SCOPES = new Set(GATEWAY_SCOPES);
19
+ const DEFAULT_MOBILE_SCOPES = [
20
+ "gateway.status",
21
+ "agents.read",
22
+ "agents.run",
23
+ "sessions.read",
24
+ "sessions.write",
25
+ "workspace.read",
26
+ "workspace.write",
27
+ "tasks.read",
28
+ "tasks.write",
29
+ "automations.read",
30
+ "automations.write",
31
+ "notifications.self",
32
+ "device.self"
33
+ ];
34
+ function isGatewayScope(value) {
35
+ return typeof value === "string" && KNOWN_GATEWAY_SCOPES.has(value);
36
+ }
37
+ function parseGatewayScopes(value) {
38
+ const parsed = JSON.parse(value);
39
+ if (!Array.isArray(parsed) || !parsed.every(isGatewayScope)) throw new Error("Stored device scopes are invalid");
40
+ return [...new Set(parsed)];
41
+ }
42
+ function methodScope(method, read, write) {
43
+ return method === "GET" ? read : write;
44
+ }
45
+ function requiredGatewayScope(method, path) {
46
+ if (path === "/api/realtime/tickets" || path.startsWith("/api/status")) return "gateway.status";
47
+ if (path === "/api/device-auth/refresh" || path === "/api/devices/me") return "device.self";
48
+ if (path.startsWith("/api/devices/me/push")) return "notifications.self";
49
+ if (path.startsWith("/api/endpoint-tools")) return "device.self";
50
+ if (path === "/api/agent" || path.startsWith("/api/agent/")) return "agents.run";
51
+ if (path.startsWith("/api/agents") || path.startsWith("/api/models")) return methodScope(method, "agents.read", "gateway.admin");
52
+ if (path.startsWith("/api/sessions") || path.startsWith("/api/side-chats")) return methodScope(method, "sessions.read", "sessions.write");
53
+ if (path.startsWith("/api/tasks")) return methodScope(method, "tasks.read", "tasks.write");
54
+ if (path.startsWith("/api/home") || path.startsWith("/api/inbox")) return methodScope(method, "tasks.read", "tasks.write");
55
+ if (path.startsWith("/api/automations") || path.startsWith("/api/automation-runs")) return methodScope(method, "automations.read", "automations.write");
56
+ if (path.startsWith("/api/workflows")) return methodScope(method, "automations.read", "automations.write");
57
+ if (path.startsWith("/api/voice") || path.startsWith("/api/media") || path.startsWith("/api/clarify")) return "sessions.write";
58
+ if (path.startsWith("/api/commands") || path.startsWith("/api/skills")) return methodScope(method, "agents.read", "gateway.admin");
59
+ if (path.startsWith("/api/workspace") || path.startsWith("/api/files") || path.startsWith("/api/projects") || path.startsWith("/api/notes") || path.startsWith("/api/shares")) return methodScope(method, "workspace.read", "workspace.write");
60
+ return "gateway.admin";
61
+ }
62
+ function hasGatewayScope(granted, required) {
63
+ return granted.includes("gateway.admin") || granted.includes(required);
64
+ }
65
+ //#endregion
66
+ export { DEFAULT_MOBILE_SCOPES, GATEWAY_SCOPES, hasGatewayScope, isGatewayScope, parseGatewayScopes, requiredGatewayScope };
@@ -2,7 +2,8 @@ export { safeEqualSecret } from './secret-equal.js';
2
2
  export { assertGatewayAuthNotKnownWeak, KNOWN_WEAK_GATEWAY_TOKEN_PLACEHOLDERS, } from './known-weak-secrets.js';
3
3
  export { checkBrowserOrigin } from './origin-check.js';
4
4
  export { computeInlineScriptHashes, buildGatewayConsoleCspHeader } from './csp.js';
5
- export { ADMIN_SCOPE, READ_SCOPE, WRITE_SCOPE, KNOWN_OPERATOR_SCOPES, DEFAULT_OPERATOR_SCOPES, isOperatorScope, authorizeRouteScope, authorizeScope, parseScopesHeader, type OperatorScope, } from './operator-scopes.js';
5
+ export { GATEWAY_SCOPES, DEFAULT_MOBILE_SCOPES, hasGatewayScope, isGatewayScope, parseGatewayScopes, requiredGatewayScope, type GatewayScope, } from './gateway-scopes.js';
6
+ export { getGatewayPrincipal, setGatewayPrincipal, type GatewayPrincipal, } from './gateway-principal.js';
6
7
  export { DEFAULT_GATEWAY_HTTP_TOOL_DENY, isDangerousHttpTool, filterDangerousHttpTools, } from './dangerous-tools.js';
7
8
  export { createPreauthConnectionBudget, getMaxPreauthConnectionsPerIp, type PreauthConnectionBudget, } from './preauth-connection-budget.js';
8
9
  export { auditGatewayConfig, collectGatewayConfigFindings, collectGatewaySecurityFindings, collectGatewayStartupGuardFindings, type SecurityAuditFinding, } from './audit.js';
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_MOBILE_SCOPES, GATEWAY_SCOPES, hasGatewayScope, isGatewayScope, parseGatewayScopes, requiredGatewayScope } from "./gateway-scopes.js";
1
2
  import { safeEqualSecret } from "./secret-equal.js";
2
3
  import { KNOWN_WEAK_GATEWAY_TOKEN_PLACEHOLDERS, assertGatewayAuthNotKnownWeak } from "./known-weak-secrets.js";
3
4
  import { auditGatewayConfig, collectGatewayConfigFindings, collectGatewaySecurityFindings, collectGatewayStartupGuardFindings } from "./audit.js";
@@ -5,6 +6,6 @@ import { detectSuspiciousPatterns, wrapExternalContent, wrapWebContent } from ".
5
6
  import { createPreauthConnectionBudget, getMaxPreauthConnectionsPerIp } from "./preauth-connection-budget.js";
6
7
  import { buildGatewayConsoleCspHeader, computeInlineScriptHashes } from "./csp.js";
7
8
  import { checkBrowserOrigin } from "./origin-check.js";
8
- import { ADMIN_SCOPE, DEFAULT_OPERATOR_SCOPES, KNOWN_OPERATOR_SCOPES, READ_SCOPE, WRITE_SCOPE, authorizeRouteScope, authorizeScope, isOperatorScope, parseScopesHeader } from "./operator-scopes.js";
9
+ import { getGatewayPrincipal, setGatewayPrincipal } from "./gateway-principal.js";
9
10
  import { DEFAULT_GATEWAY_HTTP_TOOL_DENY, filterDangerousHttpTools, isDangerousHttpTool } from "./dangerous-tools.js";
10
- export { ADMIN_SCOPE, DEFAULT_GATEWAY_HTTP_TOOL_DENY, DEFAULT_OPERATOR_SCOPES, KNOWN_OPERATOR_SCOPES, KNOWN_WEAK_GATEWAY_TOKEN_PLACEHOLDERS, READ_SCOPE, WRITE_SCOPE, assertGatewayAuthNotKnownWeak, auditGatewayConfig, authorizeRouteScope, authorizeScope, buildGatewayConsoleCspHeader, checkBrowserOrigin, collectGatewayConfigFindings, collectGatewaySecurityFindings, collectGatewayStartupGuardFindings, computeInlineScriptHashes, createPreauthConnectionBudget, detectSuspiciousPatterns, filterDangerousHttpTools, getMaxPreauthConnectionsPerIp, isDangerousHttpTool, isOperatorScope, parseScopesHeader, safeEqualSecret, wrapExternalContent, wrapWebContent };
11
+ export { DEFAULT_GATEWAY_HTTP_TOOL_DENY, DEFAULT_MOBILE_SCOPES, GATEWAY_SCOPES, KNOWN_WEAK_GATEWAY_TOKEN_PLACEHOLDERS, assertGatewayAuthNotKnownWeak, auditGatewayConfig, buildGatewayConsoleCspHeader, checkBrowserOrigin, collectGatewayConfigFindings, collectGatewaySecurityFindings, collectGatewayStartupGuardFindings, computeInlineScriptHashes, createPreauthConnectionBudget, detectSuspiciousPatterns, filterDangerousHttpTools, getGatewayPrincipal, getMaxPreauthConnectionsPerIp, hasGatewayScope, isDangerousHttpTool, isGatewayScope, parseGatewayScopes, requiredGatewayScope, safeEqualSecret, setGatewayPrincipal, wrapExternalContent, wrapWebContent };
@@ -50,6 +50,12 @@ import { registerClarifyBridge } from "./clarify-runtime.js";
50
50
  import { ChannelManager } from "../channels/manager.js";
51
51
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
52
52
  import "../config/index.js";
53
+ import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
54
+ import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
55
+ import "../knowledge/index.js";
56
+ import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
57
+ import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
58
+ import { startConnectorSupervisor } from "../connectors/supervisor.js";
53
59
  import { DiscussionService } from "../discussions/service.js";
54
60
  import { DiscussionOrganizer } from "../discussions/organizer.js";
55
61
  import { DiscussionLiveWorker } from "../discussions/live-worker.js";
@@ -58,14 +64,9 @@ import { DiscussionSealer } from "../discussions/sealer.js";
58
64
  import "../discussions/index.js";
59
65
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
60
66
  import "../endpoint-tools/index.js";
61
- import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
62
- import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
63
- import "../knowledge/index.js";
64
- import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
65
- import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
66
- import { startConnectorSupervisor } from "../connectors/supervisor.js";
67
67
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
68
68
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
69
+ import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
69
70
  import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
70
71
  import { NotesStore } from "../notes/store.js";
71
72
  import { buildNoteAgentContext } from "../notes/agent-context.js";
@@ -80,7 +81,6 @@ import { EphemeralSideChatManager } from "./side-chat/manager.js";
80
81
  import { SideChatRunService } from "./side-chat/run-service.js";
81
82
  import "./side-chat/index.js";
82
83
  import { wireTunnelEventsToGateway } from "../tunnel/gateway-lifecycle.js";
83
- import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
84
84
  import { getExposureManager } from "../remote-access/exposure-manager.js";
85
85
  import { sanitizeTunnelConfig } from "../tunnel/tunnel-config.js";
86
86
  import { assertGatewayAuthNotKnownWeak } from "./security/known-weak-secrets.js";
@@ -1,6 +1,6 @@
1
1
  import { getModelCatalogStore, init_model_catalog_store } from "../providers/model-catalog-store.js";
2
2
  import { compareCatalogModels } from "../providers/model-catalog-ranking.js";
3
- import { ensureGlobalDefaultsConfig, prepareUpdateGlobalDefaults } from "./global-defaults-admin.js";
3
+ import { prepareUpdateGlobalDefaults } from "./global-defaults-admin.js";
4
4
  //#region src/gateway/xopc-cloud-capability-setup.ts
5
5
  init_model_catalog_store();
6
6
  function supportsCapability(model, capability) {
@@ -49,27 +49,25 @@ function prepareXopcCloudCapabilitySetup(config, source) {
49
49
  missing: selected.missing
50
50
  };
51
51
  const selection = selected.selection;
52
- const normalized = ensureGlobalDefaultsConfig(config);
53
- const presetId = normalized.agents.defaultPreset;
54
- const currentModels = normalized.agents.capabilityPresets[presetId]?.models;
55
- const defaultRole = currentModels?.defaultRole ?? "deep";
56
- const defaultsUpdate = prepareUpdateGlobalDefaults(normalized, { models: {
57
- ...currentModels,
58
- defaultRole,
59
- roles: {
60
- ...currentModels?.roles ?? {},
61
- [defaultRole]: {
62
- ...currentModels?.roles?.[defaultRole],
63
- model: `xopc-cloud/${selection.chat}`
52
+ const currentModels = config.agents.defaults.models;
53
+ const defaultsUpdate = prepareUpdateGlobalDefaults(config, { defaults: {
54
+ ...config.agents.defaults,
55
+ models: {
56
+ ...currentModels,
57
+ chat: {
58
+ primary: `xopc-cloud/${selection.chat}`,
59
+ fallbacks: []
60
+ },
61
+ imageUnderstanding: {
62
+ ...currentModels.imageUnderstanding,
63
+ primary: `xopc-cloud/${selection.vision}`,
64
+ fallbacks: currentModels.imageUnderstanding?.fallbacks ?? []
65
+ },
66
+ imageGeneration: {
67
+ ...currentModels.imageGeneration,
68
+ primary: `xopc-cloud/${selection.imageGeneration}`,
69
+ fallbacks: currentModels.imageGeneration?.fallbacks ?? []
64
70
  }
65
- },
66
- imageModel: {
67
- ...currentModels?.imageModel,
68
- primary: `xopc-cloud/${selection.vision}`
69
- },
70
- imageGenerationModel: {
71
- ...currentModels?.imageGenerationModel,
72
- primary: `xopc-cloud/${selection.imageGeneration}`
73
71
  }
74
72
  } });
75
73
  if (defaultsUpdate.ok === false) return {
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
2
- import { appendCronEventLines } from "./event-prompt.js";
3
2
  import { isWithinActiveHours } from "./active-hours.js";
4
3
  import { isHeartbeatContentEmpty } from "./content-check.js";
4
+ import { appendCronEventLines } from "./event-prompt.js";
5
5
  import { createHeartbeatWake } from "./wake.js";
6
6
  export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
@@ -17,6 +17,15 @@ const MIME_BY_EXT = {
17
17
  ".svg": "image/svg+xml",
18
18
  ".svgz": "image/svg+xml",
19
19
  ".pdf": "application/pdf",
20
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
21
+ ".doc": "application/msword",
22
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
23
+ ".xls": "application/vnd.ms-excel",
24
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
25
+ ".ppt": "application/vnd.ms-powerpoint",
26
+ ".csv": "text/csv",
27
+ ".tsv": "text/tab-separated-values",
28
+ ".zip": "application/zip",
20
29
  ".txt": "text/plain",
21
30
  ".md": "text/markdown",
22
31
  ".json": "application/json",
@@ -1,4 +1,3 @@
1
1
  export * from './types.js';
2
2
  export * from './runner.js';
3
3
  export * from './registry.js';
4
- export * from './config/default-capability-preset.js';
@@ -1,4 +1,3 @@
1
1
  import { listRegisteredMigrations, registerMigration, unregisterMigrationsForSource } from "./registry.js";
2
- import { DEFAULT_CAPABILITY_PRESET_MIGRATION_ID, createDefaultCapabilityPreset, defaultCapabilityPresetMigration, ensureDefaultCapabilityPresetInitialized } from "./config/default-capability-preset.js";
3
2
  import { CORE_MIGRATIONS, applyMigrations, detectMigrations, runBootstrapMigrationsSync } from "./runner.js";
4
- export { CORE_MIGRATIONS, DEFAULT_CAPABILITY_PRESET_MIGRATION_ID, applyMigrations, createDefaultCapabilityPreset, defaultCapabilityPresetMigration, detectMigrations, ensureDefaultCapabilityPresetInitialized, listRegisteredMigrations, registerMigration, runBootstrapMigrationsSync, unregisterMigrationsForSource };
3
+ export { CORE_MIGRATIONS, applyMigrations, detectMigrations, listRegisteredMigrations, registerMigration, runBootstrapMigrationsSync, unregisterMigrationsForSource };
@@ -2,7 +2,6 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { ConfigSchema, init_schema } from "../config/schema.js";
4
4
  import { listRegisteredMigrations } from "./registry.js";
5
- import { defaultCapabilityPresetMigration } from "./config/default-capability-preset.js";
6
5
  import { dirname, join } from "node:path";
7
6
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
8
7
  //#region src/migrations/runner.ts
@@ -11,7 +10,7 @@ init_logger();
11
10
  const log = createLogger("Migrations");
12
11
  const MIGRATION_LEDGER_FILENAME = "migrations.json";
13
12
  const CONFIG_BACKUP_COUNT = 10;
14
- const CORE_MIGRATIONS = [...[defaultCapabilityPresetMigration]];
13
+ const CORE_MIGRATIONS = [];
15
14
  function listAllMigrations() {
16
15
  return [...CORE_MIGRATIONS, ...listRegisteredMigrations().map((entry) => entry.migration)];
17
16
  }
@@ -1,6 +1,6 @@
1
1
  import { type NotificationDevice, type NotificationDevicePlatform, type NotificationLanguage, type NotificationPermission, type NotificationPreferences } from './types.js';
2
2
  export type RegisterNotificationDeviceInput = {
3
- id: string;
3
+ deviceId: string;
4
4
  platform: NotificationDevicePlatform;
5
5
  pushToken: string;
6
6
  permissions: NotificationPermission;
@@ -41,11 +41,11 @@ function deviceFromRow(row) {
41
41
  }
42
42
  function registerNotificationDevice(input) {
43
43
  const now = Date.now();
44
- const preferences = input.preferences ? normalizePreferences(input.preferences) : getNotificationDevice(input.id)?.preferences ?? normalizePreferences();
44
+ const preferences = input.preferences ? normalizePreferences(input.preferences) : getNotificationDevice(input.deviceId)?.preferences ?? normalizePreferences();
45
45
  runSqliteWriteTransaction((db) => {
46
- db.prepare(`DELETE FROM notification_devices
47
- WHERE push_provider = 'expo' AND push_token = ? AND device_id <> ?`).run(input.pushToken, input.id);
48
- db.prepare(`INSERT INTO notification_devices (
46
+ db.prepare(`DELETE FROM device_push_endpoints
47
+ WHERE push_token = ? AND device_id <> ?`).run(input.pushToken, input.deviceId);
48
+ db.prepare(`INSERT INTO device_push_endpoints (
49
49
  device_id, platform, push_token, enabled, permissions, preferences_json,
50
50
  locale, app_version, lease_expires_at, last_seen_at, created_at, updated_at
51
51
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -59,16 +59,16 @@ function registerNotificationDevice(input) {
59
59
  app_version = excluded.app_version,
60
60
  lease_expires_at = excluded.lease_expires_at,
61
61
  last_seen_at = excluded.last_seen_at,
62
- updated_at = excluded.updated_at`).run(input.id, input.platform, input.pushToken, input.permissions === "granted" ? 1 : 0, input.permissions, JSON.stringify(preferences), input.locale, input.appVersion?.trim() || null, now + DEVICE_LEASE_MS, now, now, now);
62
+ updated_at = excluded.updated_at`).run(input.deviceId, input.platform, input.pushToken, input.permissions === "granted" ? 1 : 0, input.permissions, JSON.stringify(preferences), input.locale, input.appVersion?.trim() || null, now + DEVICE_LEASE_MS, now, now, now);
63
63
  });
64
- return getNotificationDevice(input.id);
64
+ return getNotificationDevice(input.deviceId);
65
65
  }
66
66
  function getNotificationDevice(deviceId) {
67
- const row = getSqliteDatabase().prepare("SELECT * FROM notification_devices WHERE device_id = ?").get(deviceId);
67
+ const row = getSqliteDatabase().prepare("SELECT * FROM device_push_endpoints WHERE device_id = ?").get(deviceId);
68
68
  return row ? deviceFromRow(row) : null;
69
69
  }
70
70
  function listDeliverableNotificationDevices(now = Date.now()) {
71
- return getSqliteDatabase().prepare(`SELECT * FROM notification_devices
71
+ return getSqliteDatabase().prepare(`SELECT * FROM device_push_endpoints
72
72
  WHERE enabled = 1 AND permissions = 'granted' AND lease_expires_at > ?
73
73
  ORDER BY updated_at DESC`).all(now).map(deviceFromRow);
74
74
  }
@@ -80,16 +80,16 @@ function updateNotificationDevicePreferences(deviceId, patch) {
80
80
  ...patch
81
81
  });
82
82
  runSqliteWriteTransaction((db) => {
83
- db.prepare("UPDATE notification_devices SET preferences_json = ?, updated_at = ? WHERE device_id = ?").run(JSON.stringify(preferences), Date.now(), deviceId);
83
+ db.prepare("UPDATE device_push_endpoints SET preferences_json = ?, updated_at = ? WHERE device_id = ?").run(JSON.stringify(preferences), Date.now(), deviceId);
84
84
  });
85
85
  return getNotificationDevice(deviceId);
86
86
  }
87
87
  function removeNotificationDevice(deviceId) {
88
- return runSqliteWriteTransaction((db) => db.prepare("DELETE FROM notification_devices WHERE device_id = ?").run(deviceId).changes > 0);
88
+ return runSqliteWriteTransaction((db) => db.prepare("DELETE FROM device_push_endpoints WHERE device_id = ?").run(deviceId).changes > 0);
89
89
  }
90
90
  function disableNotificationDeviceForPushToken(pushToken) {
91
91
  runSqliteWriteTransaction((db) => {
92
- db.prepare("UPDATE notification_devices SET enabled = 0, updated_at = ? WHERE push_token = ?").run(Date.now(), pushToken);
92
+ db.prepare("UPDATE device_push_endpoints SET enabled = 0, updated_at = ? WHERE push_token = ?").run(Date.now(), pushToken);
93
93
  });
94
94
  }
95
95
  //#endregion
@@ -88,7 +88,7 @@ const DELIVERY_JOIN = `
88
88
  n.push_token, n.locale
89
89
  FROM notification_deliveries d
90
90
  JOIN notification_events e ON e.event_id = d.event_id
91
- JOIN notification_devices n ON n.device_id = d.device_id
91
+ JOIN device_push_endpoints n ON n.device_id = d.device_id
92
92
  `;
93
93
  function listDueNotificationDeliveries(status, now = Date.now(), limit = 100) {
94
94
  return getSqliteDatabase().prepare(`${DELIVERY_JOIN}
@@ -135,7 +135,7 @@ function notificationDeliveryMetrics() {
135
135
  SUM(CASE WHEN enabled = 1 AND permissions = 'granted' AND lease_expires_at > ? THEN 1 ELSE 0 END) AS deliverable,
136
136
  SUM(CASE WHEN enabled = 1 AND lease_expires_at <= ? THEN 1 ELSE 0 END) AS expired,
137
137
  SUM(CASE WHEN enabled = 0 OR permissions <> 'granted' THEN 1 ELSE 0 END) AS disabled
138
- FROM notification_devices`).get(now, now);
138
+ FROM device_push_endpoints`).get(now, now);
139
139
  const oldest = getSqliteDatabase().prepare(`SELECT MIN(next_attempt_at) AS value FROM notification_deliveries
140
140
  WHERE status IN ('pending', 'accepted')`).get();
141
141
  const latestError = getSqliteDatabase().prepare(`SELECT event_id, device_id, last_error, updated_at
@@ -166,7 +166,7 @@ function expireUndeliverableNotificationDeliveries(now = Date.now()) {
166
166
  SET status = 'dead', last_error = 'Device registration is disabled or expired', updated_at = ?
167
167
  WHERE status IN ('pending', 'accepted')
168
168
  AND EXISTS (
169
- SELECT 1 FROM notification_devices n
169
+ SELECT 1 FROM device_push_endpoints n
170
170
  WHERE n.device_id = notification_deliveries.device_id
171
171
  AND (n.enabled = 0 OR n.permissions <> 'granted' OR n.lease_expires_at <= ?)
172
172
  )`).run(now, now).changes));
@@ -90,7 +90,7 @@ function getApiKeySync(provider) {
90
90
  */
91
91
  function resolveModel(ref) {
92
92
  const trimmedRef = typeof ref === "string" ? ref.trim() : "";
93
- if (!trimmedRef) throw new Error("No default model configured. Choose a model in onboarding or set agents.capabilityPresets.default.models.roles.<role>.model.");
93
+ if (!trimmedRef) throw new Error("No default model configured. Choose a model in onboarding or set agents.defaults.models.chat.primary.");
94
94
  const customModel = getModelRegistry().resolve(trimmedRef);
95
95
  if (customModel) return normalizeProviderModel(customModel);
96
96
  const qualifiedRef = splitProviderModelRef(trimmedRef);
@@ -24,19 +24,24 @@ function collectToolModel(out, value, location, kind = "text") {
24
24
  function collectModelPolicy(out, value, location) {
25
25
  const policy = asRecord(value);
26
26
  if (!policy) return;
27
- const roles = asRecord(policy.roles);
28
- for (const [roleId, roleValue] of Object.entries(roles ?? {})) {
29
- const role = asRecord(roleValue);
30
- if (!role) continue;
31
- addRef(out, role.model, `${location}.roles.${roleId}.model`);
32
- if (Array.isArray(role.fallbacks)) role.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.roles.${roleId}.fallbacks[${index}]`));
27
+ const chat = asRecord(policy.chat);
28
+ if (chat) {
29
+ addRef(out, chat.primary, `${location}.chat.primary`);
30
+ if (Array.isArray(chat.fallbacks)) chat.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.chat.fallbacks[${index}]`));
33
31
  }
34
- collectToolModel(out, policy.imageModel, `${location}.imageModel`);
35
- collectToolModel(out, policy.imageGenerationModel, `${location}.imageGenerationModel`, "image-generation");
32
+ const intents = asRecord(policy.intents);
33
+ for (const [intent, routeValue] of Object.entries(intents ?? {})) {
34
+ const route = asRecord(routeValue);
35
+ if (!route) continue;
36
+ addRef(out, route.primary, `${location}.intents.${intent}.primary`);
37
+ if (Array.isArray(route.fallbacks)) route.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.intents.${intent}.fallbacks[${index}]`));
38
+ }
39
+ collectToolModel(out, policy.imageUnderstanding, `${location}.imageUnderstanding`);
40
+ collectToolModel(out, policy.imageGeneration, `${location}.imageGeneration`, "image-generation");
36
41
  }
37
42
  function collectReferences(config, sessionConfigs) {
38
43
  const out = [];
39
- for (const [presetId, preset] of Object.entries(config.agents.capabilityPresets)) collectModelPolicy(out, preset.models, `agents.capabilityPresets.${presetId}.models`);
44
+ collectModelPolicy(out, config.agents.defaults.models, "agents.defaults.models");
40
45
  for (const agent of config.agents.list) collectModelPolicy(out, agent.models, `agents.list.${agent.id}.models`);
41
46
  for (const [sessionKey, sessionConfig] of sessionConfigs) addRef(out, sessionConfig.modelOverride, `sessions.${sessionKey}.modelOverride`);
42
47
  return out;
@@ -10,10 +10,12 @@ export declare class RealtimeRuntime {
10
10
  private readonly preauthBudget;
11
11
  private readonly wss;
12
12
  private readonly topicCleanupTimers;
13
+ private readonly socketsByPrincipal;
13
14
  private closed;
14
15
  constructor(endpointTools?: EndpointToolRuntime);
15
16
  handleUpgrade(req: IncomingMessage, socket: Socket, head: Buffer): boolean;
16
17
  close(): void;
18
+ disconnectPrincipal(principalId: string): void;
17
19
  completeTopic(topic: string, ttlMs?: number): void;
18
20
  private handleConnection;
19
21
  private rawDataToText;
@@ -1,5 +1,6 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
+ import { hasGatewayScope } from "../gateway/security/gateway-scopes.js";
3
4
  import { REALTIME_HEARTBEAT_INTERVAL_MS, REALTIME_HEARTBEAT_TIMEOUT_MS, REALTIME_HELLO_TIMEOUT_MS, REALTIME_MAX_CLIENT_FRAME_BYTES, parseClientRealtimeJsonFrame, parseClientRealtimeMessage } from "../../packages/realtime-protocol/src/index.js";
4
5
  import { createPreauthConnectionBudget } from "../gateway/security/preauth-connection-budget.js";
5
6
  import { RealtimeBroker } from "./broker.js";
@@ -24,8 +25,13 @@ function serverMessage(kind, payload) {
24
25
  payload
25
26
  };
26
27
  }
27
- function isAuthorizedTopic(topic) {
28
- return topic === "gateway" || topic === "sessions" || topic === "logs" || topic.startsWith("session:") && topic.length > 8 || topic.startsWith("run:") && topic.length > 4 || topic.startsWith("workflow:") && topic.length > 9;
28
+ function isAuthorizedTopic(topic, scopes) {
29
+ if (topic === "gateway") return hasGatewayScope(scopes, "gateway.status");
30
+ if (topic === "logs") return hasGatewayScope(scopes, "gateway.admin");
31
+ if (topic === "sessions" || topic.startsWith("session:")) return hasGatewayScope(scopes, "sessions.read");
32
+ if (topic.startsWith("run:")) return hasGatewayScope(scopes, "agents.run");
33
+ if (topic.startsWith("workflow:")) return hasGatewayScope(scopes, "automations.read");
34
+ return false;
29
35
  }
30
36
  var RealtimeRuntime = class {
31
37
  broker = new RealtimeBroker(void 0, (error, topic) => {
@@ -42,6 +48,7 @@ var RealtimeRuntime = class {
42
48
  perMessageDeflate: false
43
49
  });
44
50
  topicCleanupTimers = /* @__PURE__ */ new Map();
51
+ socketsByPrincipal = /* @__PURE__ */ new Map();
45
52
  closed = false;
46
53
  constructor(endpointTools) {
47
54
  this.endpointTools = endpointTools;
@@ -80,6 +87,10 @@ var RealtimeRuntime = class {
80
87
  for (const timer of this.topicCleanupTimers.values()) clearTimeout(timer);
81
88
  this.topicCleanupTimers.clear();
82
89
  this.wss.close();
90
+ this.socketsByPrincipal.clear();
91
+ }
92
+ disconnectPrincipal(principalId) {
93
+ for (const socket of this.socketsByPrincipal.get(principalId) ?? []) socket.close(4403, "Device access revoked");
83
94
  }
84
95
  completeTopic(topic, ttlMs = 5 * 6e4) {
85
96
  const existing = this.topicCleanupTimers.get(topic);
@@ -97,6 +108,8 @@ var RealtimeRuntime = class {
97
108
  let lastSeenAt = Date.now();
98
109
  let connectionId;
99
110
  let endpointId;
111
+ let principalId;
112
+ let grantedScopes = [];
100
113
  let budgetHeld = true;
101
114
  const releaseBudget = () => {
102
115
  if (!budgetHeld) return;
@@ -115,7 +128,7 @@ var RealtimeRuntime = class {
115
128
  };
116
129
  const subscribe = (requested) => {
117
130
  const authorized = requested.filter((item) => {
118
- if (isAuthorizedTopic(item.topic)) return true;
131
+ if (isAuthorizedTopic(item.topic, grantedScopes)) return true;
119
132
  sendError("FORBIDDEN_TOPIC", `Topic is not available: ${item.topic}`);
120
133
  return false;
121
134
  });
@@ -172,6 +185,11 @@ var RealtimeRuntime = class {
172
185
  return;
173
186
  }
174
187
  authenticated = true;
188
+ principalId = claim.principalId;
189
+ grantedScopes = claim.scopes;
190
+ const principalSockets = this.socketsByPrincipal.get(principalId) ?? /* @__PURE__ */ new Set();
191
+ principalSockets.add(socket);
192
+ this.socketsByPrincipal.set(principalId, principalSockets);
175
193
  connectionId = crypto.randomUUID();
176
194
  let endpointReady;
177
195
  if (message.payload.endpoint) {
@@ -215,6 +233,7 @@ var RealtimeRuntime = class {
215
233
  subscribe(message.payload.subscriptions);
216
234
  log.info({
217
235
  connectionId,
236
+ principalId,
218
237
  clientId: claim.clientId,
219
238
  clientKind: claim.clientKind
220
239
  }, "Realtime client connected");
@@ -249,6 +268,11 @@ var RealtimeRuntime = class {
249
268
  for (const handle of subscriptions.values()) handle.unsubscribe();
250
269
  subscriptions.clear();
251
270
  if (endpointId && connectionId) this.endpointTools?.remove(endpointId, connectionId);
271
+ if (principalId) {
272
+ const principalSockets = this.socketsByPrincipal.get(principalId);
273
+ principalSockets?.delete(socket);
274
+ if (principalSockets?.size === 0) this.socketsByPrincipal.delete(principalId);
275
+ }
252
276
  if (connectionId) {
253
277
  const reason = reasonBuffer.toString();
254
278
  log.info({