@xopcai/xopc 0.0.270 → 0.0.272

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 (245) hide show
  1. package/dist/browser-ext/dist/assets/{auth-cwEj8rFb.js → auth-C1QI-uMG.js} +65 -14
  2. package/dist/browser-ext/dist/background.js +23 -2
  3. package/dist/browser-ext/dist/pairing-handoff.js +51 -0
  4. package/dist/browser-ext/dist/sidepanel.html +1 -1
  5. package/dist/browser-ext/dist/sidepanel.js +39 -27
  6. package/dist/browser-ext/manifest.json +12 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{activity-store-D_0FmdRj.js → activity-store-DffqjeqQ.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-IZvEXak_.js → agent-avatar-dicebear-Cwj4HCYY.js} +1 -1
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-6CLfLxVc.js +1 -0
  11. package/dist/gateway/static/root/assets/agents-B6mu64fY.js +1 -0
  12. package/dist/gateway/static/root/assets/{api-O3TTQ4qN.js → api-CGLdye4i.js} +1 -1
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cqqsbzri.js → app-management-settings-panel-BLujSbaw.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-DaJyf32s.js → appearance-settings-BXMcueb8.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-BEgy4hY3.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-kDPnDTJI.js → archive-plugin-D4bUampf.js} +1 -1
  17. package/dist/gateway/static/root/assets/{attachment-load-CJ3VceKS.js → attachment-load-CBGNA2Ys.js} +1 -1
  18. package/dist/gateway/static/root/assets/{automations-page-JwMtU8XB.js → automations-page-dQyolNmy.js} +1 -1
  19. package/dist/gateway/static/root/assets/automations-workspace-DxRFrmrV.js +6 -0
  20. package/dist/gateway/static/root/assets/{binary-plugins-DzyZXLBX.js → binary-plugins-bbvp81h2.js} +1 -1
  21. package/dist/gateway/static/root/assets/{block-editor-kTt3gYIJ.js → block-editor-C8e6Wri4.js} +3 -3
  22. package/dist/gateway/static/root/assets/{browser-automation-inputs-BKohPYR4.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
  23. package/dist/gateway/static/root/assets/{browser-automations-page-ktQfFPk-.js → browser-automations-page-CAcJQSjN.js} +2 -2
  24. package/dist/gateway/static/root/assets/browser-settings-page-TLAlqcPo.js +8 -0
  25. package/dist/gateway/static/root/assets/capabilities-settings-panel-z-K_jrZz.js +8 -0
  26. package/dist/gateway/static/root/assets/channels-settings-Dzrk33aB.js +1 -0
  27. package/dist/gateway/static/root/assets/{channels-status-swr-DrqzYmDr.js → channels-status-swr-CfOPNnVr.js} +1 -1
  28. package/dist/gateway/static/root/assets/{chat-terminal-dock-CIFGGLGa.js → chat-terminal-dock-9ZOl92kh.js} +2 -2
  29. package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
  30. package/dist/gateway/static/root/assets/connectors-page-B1dIoRNi.js +2 -0
  31. package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
  32. package/dist/gateway/static/root/assets/date-picker-Dj6FRLF9.js +1 -0
  33. package/dist/gateway/static/root/assets/{dependency-picker-D3vNIjRI.js → dependency-picker-D1q89tVc.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-fQwRb_3p.js → desktop-pet-DfqZBvhp.js} +1 -1
  35. package/dist/gateway/static/root/assets/{desktop-pet-settings-DfOJ-GvT.js → desktop-pet-settings-HCEh2MOm.js} +1 -1
  36. package/dist/gateway/static/root/assets/device-pairing-wizard-CPth92s6.js +1 -0
  37. package/dist/gateway/static/root/assets/{extension-debug-page-Cn53jB5-.js → extension-debug-page-C8cAWVoK.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-page-IDpLCxpC.js → extension-page-5N87Vaym.js} +1 -1
  39. package/dist/gateway/static/root/assets/extension-settings-page-D85SAUFP.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-config-swr-B7dcmP7Q.js → gateway-config-swr-BjsDnB_n.js} +1 -1
  41. package/dist/gateway/static/root/assets/gateway-settings-Dqx8PmcT.js +1 -0
  42. package/dist/gateway/static/root/assets/{gateway-startup-retry-JGhGMhVZ.js → gateway-startup-retry-BIf0eLWX.js} +1 -1
  43. package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
  44. package/dist/gateway/static/root/assets/heartbeat-settings-BpDWGE1a.js +1 -0
  45. package/dist/gateway/static/root/assets/home-page-DJaqpC8-.js +1 -0
  46. package/dist/gateway/static/root/assets/{image-generation-api-BJLX7Qrh.js → image-generation-api-1m8xTVS_.js} +1 -1
  47. package/dist/gateway/static/root/assets/index-C6PmD0cK.js +74 -0
  48. package/dist/gateway/static/root/assets/index-DKy1Qn1_.css +2 -0
  49. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CBvMTFFx.js → keyboard-shortcuts-settings-Byy8mCSq.js} +1 -1
  50. package/dist/gateway/static/root/assets/local-app-workbench-page-l2AEiG2C.js +2 -0
  51. package/dist/gateway/static/root/assets/{local-apps-page-APCMNDvU.js → local-apps-page-BPo0wBgM.js} +1 -1
  52. package/dist/gateway/static/root/assets/locale-store-CRNble2Z.js +1 -0
  53. package/dist/gateway/static/root/assets/logs-page-X5FdLlXK.js +2 -0
  54. package/dist/gateway/static/root/assets/management-settings-DT6NoIjm.js +1 -0
  55. package/dist/gateway/static/root/assets/{markdown-view-BwjpJVPs.js → markdown-view-AglreSOj.js} +1 -1
  56. package/dist/gateway/static/root/assets/{media-plugins-C10byeaa.js → media-plugins-Bzka9qXu.js} +1 -1
  57. package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +1 -0
  58. package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
  59. package/dist/gateway/static/root/assets/{messages-D0V_bgRP.js → messages-DH_HCgmw.js} +3 -3
  60. package/dist/gateway/static/root/assets/note-detail-panel-BUJPoaGZ.js +5 -0
  61. package/dist/gateway/static/root/assets/notes-page-BwFpWRuo.js +8 -0
  62. package/dist/gateway/static/root/assets/{page-tabs-qQ36zncF.js → page-tabs-Ys0p65Lt.js} +1 -1
  63. package/dist/gateway/static/root/assets/popover-select-Dz_Qis2R.js +1 -0
  64. package/dist/gateway/static/root/assets/{preview-open-alternatives-BiAJvvCo.js → preview-open-alternatives-iknB5xEp.js} +1 -1
  65. package/dist/gateway/static/root/assets/{proactive-card-CcNBqHoH.js → proactive-card-BPZDgNNR.js} +1 -1
  66. package/dist/gateway/static/root/assets/{proactive-page-C3K61jve.js → proactive-page-CxdZR-p2.js} +1 -1
  67. package/dist/gateway/static/root/assets/{product-open-page-CunnDP4w.js → product-open-page-W1o3f-kz.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-BU1RKAcy.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-z0X0tL8G.js +1 -0
  70. package/dist/gateway/static/root/assets/{registry-api-0JSegbNl.js → registry-api-DmYFpjsH.js} +1 -1
  71. package/dist/gateway/static/root/assets/remote-access-hub-NNTut2I8.js +1 -0
  72. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bu_mwBTr.js → runtime-tools-settings-panel-DP1XyYO8.js} +2 -2
  73. package/dist/gateway/static/root/assets/{schema-form-BE0sgZyz.js → schema-form-BMYKdzsH.js} +1 -1
  74. package/dist/gateway/static/root/assets/sessions-page-B6SsHlz5.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-BQu8bAcN.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-CBo517lV.js → settings-form-section-2LGjz7bu.js} +1 -1
  77. package/dist/gateway/static/root/assets/{settings-page-DBPimx93.js → settings-page-7DjpC9_C.js} +1 -1
  78. package/dist/gateway/static/root/assets/setup-status-panel-Dj9jFWJt.js +1 -0
  79. package/dist/gateway/static/root/assets/{share-preview-page-DdV75VTe.js → share-preview-page-BxYdSi8c.js} +1 -1
  80. package/dist/gateway/static/root/assets/shares-settings-CMqE0KuK.js +1 -0
  81. package/dist/gateway/static/root/assets/skill-reload-api-BXqSJymN.js +1 -0
  82. package/dist/gateway/static/root/assets/{skills-page-Cn_-nvRo.js → skills-page-DNEScMZH.js} +1 -1
  83. package/dist/gateway/static/root/assets/skills-page.utils-q88l65YU.js +1 -0
  84. package/dist/gateway/static/root/assets/system-settings-panel-8NIssGKj.js +1 -0
  85. package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
  86. package/dist/gateway/static/root/assets/{theme-store-1wryLgBQ.js → theme-store-BXZG3S25.js} +1 -1
  87. package/dist/gateway/static/root/assets/tunnel-api-CWsRPM84.js +1 -0
  88. package/dist/gateway/static/root/assets/{use-autosave-N_lm4FdD.js → use-autosave-BwQuoTQU.js} +1 -1
  89. package/dist/gateway/static/root/assets/user-model-page-D4BucMrZ.js +2 -0
  90. package/dist/gateway/static/root/assets/{voice-api-key-field-DMsyVfri.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-config-api-QWVmiAp3.js → voice-config-api-gggUp3u9.js} +1 -1
  92. package/dist/gateway/static/root/assets/{work-discovery-overlay-BC0vAxp1.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cz9jQIlP.js → workflow-run-setup-panel-BiAAWlir.js} +2 -2
  94. package/dist/gateway/static/root/assets/workflows-page-DryKUMfA.js +6 -0
  95. package/dist/gateway/static/root/index.html +15 -11
  96. package/dist/package.js +1 -1
  97. package/dist/packages/gateway-contract/src/device-pairing.js +2 -1
  98. package/dist/packages/gateway-contract/src/session-identity.js +37 -0
  99. package/dist/src/agent/memory/compaction-chunks.d.ts +18 -0
  100. package/dist/src/agent/memory/compaction-chunks.js +53 -0
  101. package/dist/src/agent/memory/compaction-request.d.ts +12 -0
  102. package/dist/src/agent/memory/compaction-request.js +72 -0
  103. package/dist/src/agent/memory/compaction.d.ts +3 -0
  104. package/dist/src/agent/memory/compaction.js +166 -118
  105. package/dist/src/agent/service.js +1 -0
  106. package/dist/src/browser/native-messaging-host.js +3 -1
  107. package/dist/src/cli/bin.js +2 -2
  108. package/dist/src/cli/commands/agent.js +2 -2
  109. package/dist/src/cli/commands/auth.js +1 -1
  110. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  111. package/dist/src/cli/commands/extension-dev.js +1 -1
  112. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  113. package/dist/src/cli/commands/extension.js +1 -1
  114. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  115. package/dist/src/cli/commands/gateway-ssh-tunnel.js +1 -1
  116. package/dist/src/cli/commands/models.js +2 -2
  117. package/dist/src/cli/commands/onboard.js +1 -1
  118. package/dist/src/cli/commands/platform.js +1 -1
  119. package/dist/src/cli/commands/profile.js +1 -1
  120. package/dist/src/cli/commands/tunnel.js +6 -1
  121. package/dist/src/cli/commands/update.js +1 -1
  122. package/dist/src/cli/extension-cli-register.js +1 -1
  123. package/dist/src/config/index.js +1 -1
  124. package/dist/src/gateway/heartbeat/service.js +1 -1
  125. package/dist/src/gateway/hono/app.js +1 -0
  126. package/dist/src/gateway/hono/middleware/auth.d.ts +1 -2
  127. package/dist/src/gateway/hono/middleware/auth.js +49 -31
  128. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +11 -15
  129. package/dist/src/gateway/hono/routes/browser-session.d.ts +3 -0
  130. package/dist/src/gateway/hono/routes/browser-session.js +43 -0
  131. package/dist/src/gateway/hono/routes/devices.js +61 -96
  132. package/dist/src/gateway/hono/routes/exposure.js +3 -7
  133. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  134. package/dist/src/gateway/hono/routes/models.js +60 -1
  135. package/dist/src/gateway/hono/routes/notes.js +3 -7
  136. package/dist/src/gateway/hono/routes/sessions.js +11 -0
  137. package/dist/src/gateway/hono/routes/shares.js +8 -20
  138. package/dist/src/gateway/hono/routes/site-shares.js +4 -8
  139. package/dist/src/gateway/hono/routes/tunnel.js +13 -13
  140. package/dist/src/gateway/image-generation-setup.d.ts +17 -0
  141. package/dist/src/gateway/image-generation-setup.js +30 -21
  142. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  143. package/dist/src/gateway/rate-limit/buckets.js +10 -0
  144. package/dist/src/gateway/run-loop.js +1 -1
  145. package/dist/src/gateway/runtime-config.js +2 -0
  146. package/dist/src/gateway/security/browser-session.d.ts +5 -0
  147. package/dist/src/gateway/security/browser-session.js +45 -0
  148. package/dist/src/gateway/security/gateway-principal.d.ts +1 -0
  149. package/dist/src/gateway/server.js +1 -1
  150. package/dist/src/gateway/service.d.ts +1 -0
  151. package/dist/src/gateway/service.js +11 -1
  152. package/dist/src/heartbeat/index.js +1 -1
  153. package/dist/src/infra/rate-limit/keyed-store.d.ts +3 -0
  154. package/dist/src/infra/rate-limit/keyed-store.js +9 -2
  155. package/dist/src/proactive/policy/service.d.ts +1 -1
  156. package/dist/src/realtime/runtime.d.ts +2 -1
  157. package/dist/src/realtime/runtime.js +9 -3
  158. package/dist/src/realtime/tickets.d.ts +1 -0
  159. package/dist/src/realtime/tickets.js +3 -0
  160. package/dist/src/session/store.d.ts +2 -0
  161. package/dist/src/session/store.js +17 -2
  162. package/dist/src/session/types.d.ts +2 -1
  163. package/dist/src/storage/sqlite/browser-session-repository.d.ts +17 -0
  164. package/dist/src/storage/sqlite/browser-session-repository.js +54 -0
  165. package/dist/src/storage/sqlite/device-pairing-approval.js +2 -1
  166. package/dist/src/storage/sqlite/device-pairing-repository.d.ts +4 -10
  167. package/dist/src/storage/sqlite/device-pairing-repository.js +10 -62
  168. package/dist/src/storage/sqlite/index.d.ts +1 -1
  169. package/dist/src/storage/sqlite/index.js +2 -2
  170. package/dist/src/storage/sqlite/migrations/164_browser_sessions.sql +8 -0
  171. package/dist/src/storage/sqlite/migrations/165_device_pairing_target.sql +40 -0
  172. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  173. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  174. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  175. package/dist/src/storage/sqlite/schema.js +1 -1
  176. package/dist/src/storage/sqlite/session-identity-sql.d.ts +2 -0
  177. package/dist/src/storage/sqlite/session-identity-sql.js +18 -0
  178. package/dist/src/storage/sqlite/session-repository.js +26 -22
  179. package/dist/src/tunnel/auth-policy.d.ts +3 -0
  180. package/dist/src/tunnel/auth-policy.js +8 -0
  181. package/dist/src/tunnel/broker-client.d.ts +5 -15
  182. package/dist/src/tunnel/broker-client.js +37 -49
  183. package/dist/src/tunnel/frpc-binary.d.ts +8 -6
  184. package/dist/src/tunnel/frpc-binary.js +76 -88
  185. package/dist/src/tunnel/frpc-config.d.ts +2 -1
  186. package/dist/src/tunnel/frpc-config.js +29 -12
  187. package/dist/src/tunnel/frpc-release.d.ts +27 -0
  188. package/dist/src/tunnel/frpc-release.js +30 -0
  189. package/dist/src/tunnel/gateway-lifecycle.js +8 -2
  190. package/dist/src/tunnel/index.js +2 -1
  191. package/dist/src/tunnel/registration-proof.d.ts +19 -0
  192. package/dist/src/tunnel/registration-proof.js +37 -0
  193. package/dist/src/tunnel/tunnel-persist.js +3 -1
  194. package/dist/src/tunnel/tunnel-service.d.ts +1 -0
  195. package/dist/src/tunnel/tunnel-service.js +35 -8
  196. package/dist/src/tunnel/tunnel-state.js +11 -5
  197. package/dist/src/tunnel/tunnel-types.d.ts +2 -0
  198. package/dist/src/tunnel/well-known.js +5 -1
  199. package/dist/src/user-context/config.js +2 -2
  200. package/dist/src/utils/logger/redact.js +4 -0
  201. package/dist/src/voice/realtime/runtime.d.ts +1 -0
  202. package/dist/src/voice/realtime/runtime.js +17 -1
  203. package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
  204. package/dist/src/workflows/service/workflow-run-service.js +2 -0
  205. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
  206. package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
  207. package/package.json +4 -4
  208. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CE3ygr3l.js +0 -1
  209. package/dist/gateway/static/root/assets/agents-DzG2qw-c.js +0 -1
  210. package/dist/gateway/static/root/assets/apps-page-B4lX6yoT.js +0 -1
  211. package/dist/gateway/static/root/assets/automations-workspace-BiNBewg0.js +0 -6
  212. package/dist/gateway/static/root/assets/browser-settings-page-Dgdt5uVL.js +0 -8
  213. package/dist/gateway/static/root/assets/capabilities-settings-panel-BpDW-R9f.js +0 -7
  214. package/dist/gateway/static/root/assets/channels-settings-DU4EQnR0.js +0 -1
  215. package/dist/gateway/static/root/assets/connectors-page-CfJqy284.js +0 -2
  216. package/dist/gateway/static/root/assets/cron-expression-BNwbnrEb.js +0 -2
  217. package/dist/gateway/static/root/assets/date-picker-DKyirU4K.js +0 -1
  218. package/dist/gateway/static/root/assets/extension-settings-page-B1dds2bP.js +0 -1
  219. package/dist/gateway/static/root/assets/gateway-settings-pp9jN0wl.js +0 -1
  220. package/dist/gateway/static/root/assets/heartbeat-settings-B8_zTyev.js +0 -1
  221. package/dist/gateway/static/root/assets/home-page-g1KdAdLb.js +0 -1
  222. package/dist/gateway/static/root/assets/index-1zRt56Zt.css +0 -2
  223. package/dist/gateway/static/root/assets/index-OMnem2nr.js +0 -74
  224. package/dist/gateway/static/root/assets/local-app-workbench-page-bj75v2ZE.js +0 -2
  225. package/dist/gateway/static/root/assets/locale-store-BThkG0W5.js +0 -1
  226. package/dist/gateway/static/root/assets/logs-page-BX7n39zV.js +0 -2
  227. package/dist/gateway/static/root/assets/management-settings-CM62j8ZX.js +0 -1
  228. package/dist/gateway/static/root/assets/mobile-pairing-wizard-BCWfwVx3.js +0 -1
  229. package/dist/gateway/static/root/assets/note-detail-panel-koOqb0gX.js +0 -5
  230. package/dist/gateway/static/root/assets/notes-page-BH54rY3B.js +0 -8
  231. package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
  232. package/dist/gateway/static/root/assets/project-detail-page-SL2g8MZY.js +0 -1
  233. package/dist/gateway/static/root/assets/projects-page-BtxazT5J.js +0 -1
  234. package/dist/gateway/static/root/assets/remote-access-hub-BSb7b67A.js +0 -1
  235. package/dist/gateway/static/root/assets/sessions-page-ljcS2KVz.js +0 -1
  236. package/dist/gateway/static/root/assets/settings-advanced-gate-CR9Y9LQm.js +0 -1
  237. package/dist/gateway/static/root/assets/setup-status-panel-J3AnooPW.js +0 -1
  238. package/dist/gateway/static/root/assets/shares-settings-AAm4Iwcp.js +0 -1
  239. package/dist/gateway/static/root/assets/skill-reload-api-pRCjP5sm.js +0 -1
  240. package/dist/gateway/static/root/assets/skills-page.utils-CfVAc_lu.js +0 -1
  241. package/dist/gateway/static/root/assets/system-settings-panel-B-pzalp-.js +0 -1
  242. package/dist/gateway/static/root/assets/task-detail-page-CmrLy3PO.js +0 -1
  243. package/dist/gateway/static/root/assets/tunnel-api-Cgpnm2fL.js +0 -1
  244. package/dist/gateway/static/root/assets/user-model-page-u3QLDX6L.js +0 -2
  245. package/dist/gateway/static/root/assets/workflows-page-DA6OOK6X.js +0 -6
@@ -1,13 +1,15 @@
1
- import { runSqliteWriteTransaction } from "../../../storage/sqlite/transaction.js";
2
- import { DEFAULT_BROWSER_EXTENSION_SCOPES, DEFAULT_MOBILE_SCOPES } from "../../security/gateway-scopes.js";
3
- import { createDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken } from "../../../storage/sqlite/device-access-repository.js";
1
+ import { devicePairingTargetKindSchema } from "../../../../packages/gateway-contract/src/device-pairing.js";
2
+ import { listDevices, revokeDevice, rotateDeviceRefreshToken } from "../../../storage/sqlite/device-access-repository.js";
4
3
  import { getGatewayIdentityPublicKeyRaw, getOrCreateGatewayIdentity, signGatewayPayload } from "../../../storage/sqlite/gateway-identity-repository.js";
5
- import { consumeDevicePairingToken, createDevicePairingSetup, isDevicePairingSetupActive } from "../../../storage/sqlite/device-pairing-repository.js";
4
+ import { createDevicePairingSetup, isDevicePairingSetupActive } from "../../../storage/sqlite/device-pairing-repository.js";
6
5
  import { resolveSecureDeviceRoutes } from "../../device-routes.js";
6
+ import { buckets } from "../../rate-limit/buckets.js";
7
+ import "../../rate-limit/index.js";
7
8
  import { getGatewayPrincipal } from "../../security/gateway-principal.js";
8
9
  import { registerPairingApprovalAdminRoutes, registerPairingApprovalPublicRoutes } from "./device-pairing-approval.js";
9
10
  import os from "node:os";
10
11
  import { z } from "zod";
12
+ import { bodyLimit } from "hono/body-limit";
11
13
  //#region src/gateway/hono/routes/devices.ts
12
14
  const refreshRequestSchema = z.strictObject({
13
15
  refreshToken: z.string().min(1).max(256),
@@ -17,40 +19,33 @@ const refreshRequestSchema = z.strictObject({
17
19
  nextRefreshToken: z.string().min(80).max(256),
18
20
  signature: z.string().min(1).max(256)
19
21
  });
20
- const pairingExchangeSchema = z.strictObject({
21
- pairingToken: z.string().min(1).max(256),
22
- device: z.strictObject({
23
- displayName: z.string().trim().min(1).max(80),
24
- platform: z.enum([
25
- "ios",
26
- "android",
27
- "chrome"
28
- ]),
29
- extensionId: z.string().regex(/^[a-p]{32}$/).optional(),
30
- publicKeyJwk: z.strictObject({
31
- kty: z.literal("EC"),
32
- crv: z.literal("P-256"),
33
- x: z.string().min(40).max(64),
34
- y: z.string().min(40).max(64)
35
- })
36
- })
37
- }).superRefine((value, context) => {
38
- if (value.device.platform === "chrome" && !value.device.extensionId) context.addIssue({
39
- code: "custom",
40
- path: ["device", "extensionId"],
41
- message: "Chrome devices require an extension id"
42
- });
43
- if (value.device.platform !== "chrome" && value.device.extensionId) context.addIssue({
44
- code: "custom",
45
- path: ["device", "extensionId"],
46
- message: "Only Chrome devices may set an extension id"
47
- });
48
- });
49
22
  const pairingProbeSchema = z.strictObject({ pairingId: z.string().uuid() });
23
+ const pairingSetupSchema = z.strictObject({ targetKind: devicePairingTargetKindSchema });
50
24
  function pairingLinkPayload(input) {
51
25
  return Buffer.from(JSON.stringify(input)).toString("base64url");
52
26
  }
53
27
  function registerDeviceAuthPublicRoutes(app) {
28
+ app.post("/api/gateway-identity/challenge", bodyLimit({ maxSize: 512 }), async (c) => {
29
+ const budget = buckets.identityChallenge().consume("gateway");
30
+ if (!budget.allowed) {
31
+ c.header("Retry-After", String(Math.ceil(budget.retryAfterMs / 1e3)));
32
+ return c.json({ error: "Too many identity challenges" }, 429);
33
+ }
34
+ const parsed = z.strictObject({ nonce: z.string().regex(/^[A-Za-z0-9_-]{32,64}$/) }).safeParse(await c.req.json().catch(() => null));
35
+ if (!parsed.success) return c.json({ error: "Invalid identity challenge" }, 400);
36
+ const identity = getOrCreateGatewayIdentity();
37
+ const signedPayload = Buffer.from(JSON.stringify({
38
+ purpose: "gateway-route-v1",
39
+ gatewayId: identity.id,
40
+ nonce: parsed.data.nonce,
41
+ expiresAt: Date.now() + 3e4
42
+ })).toString("base64url");
43
+ c.header("Cache-Control", "no-store");
44
+ return c.json({
45
+ signedPayload,
46
+ signature: signGatewayPayload(signedPayload)
47
+ });
48
+ });
54
49
  registerPairingApprovalPublicRoutes(app);
55
50
  app.post("/api/device-auth/refresh", async (c) => {
56
51
  const parsed = refreshRequestSchema.safeParse(await c.req.json().catch(() => null));
@@ -62,9 +57,19 @@ function registerDeviceAuthPublicRoutes(app) {
62
57
  }
63
58
  }, 400);
64
59
  try {
60
+ const tokens = rotateDeviceRefreshToken(parsed.data);
61
+ const signedPayload = Buffer.from(JSON.stringify({
62
+ purpose: "device-refresh-v3",
63
+ gatewayId: getOrCreateGatewayIdentity().id,
64
+ requestId: parsed.data.requestId,
65
+ nonce: parsed.data.nonce,
66
+ expiresAt: Date.now() + 3e4,
67
+ tokens
68
+ })).toString("base64url");
65
69
  return c.json({
66
70
  ok: true,
67
- payload: rotateDeviceRefreshToken(parsed.data)
71
+ signedPayload,
72
+ signature: signGatewayPayload(signedPayload)
68
73
  });
69
74
  } catch (error) {
70
75
  return c.json({
@@ -97,61 +102,6 @@ function registerDeviceAuthPublicRoutes(app) {
97
102
  signature: signGatewayPayload(payload)
98
103
  });
99
104
  });
100
- app.post("/api/device-pairing/exchange", async (c) => {
101
- const parsed = pairingExchangeSchema.safeParse(await c.req.json().catch(() => null));
102
- if (!parsed.success) return c.json({
103
- ok: false,
104
- error: {
105
- code: "BAD_REQUEST",
106
- message: "Invalid pairing request"
107
- }
108
- }, 400);
109
- const completed = runSqliteWriteTransaction(() => {
110
- const pairing = consumeDevicePairingToken(parsed.data.pairingToken);
111
- if (!pairing.ok && "reason" in pairing) return {
112
- success: false,
113
- reason: pairing.reason
114
- };
115
- const device = createDevice({
116
- displayName: parsed.data.device.displayName,
117
- platform: parsed.data.device.platform,
118
- publicKeyJwk: parsed.data.device.publicKeyJwk,
119
- extensionId: parsed.data.device.extensionId,
120
- scopes: parsed.data.device.platform === "chrome" ? DEFAULT_BROWSER_EXTENSION_SCOPES : DEFAULT_MOBILE_SCOPES
121
- });
122
- return {
123
- success: true,
124
- device,
125
- routes: pairing.routes,
126
- tokens: issueDeviceTokenPair(device.id)
127
- };
128
- });
129
- if ("reason" in completed) return c.json({
130
- ok: false,
131
- error: {
132
- code: "PAIRING_DENIED",
133
- message: `Pairing ${completed.reason}`
134
- }
135
- }, 401);
136
- const identity = getOrCreateGatewayIdentity();
137
- const payload = Buffer.from(JSON.stringify({
138
- gateway: {
139
- id: identity.id,
140
- name: os.hostname()
141
- },
142
- device: {
143
- id: completed.device.id,
144
- scopes: completed.device.scopes
145
- },
146
- routes: completed.routes,
147
- tokens: completed.tokens
148
- })).toString("base64url");
149
- return c.json({
150
- ok: true,
151
- signedPayload: payload,
152
- signature: signGatewayPayload(payload)
153
- }, 201);
154
- });
155
105
  }
156
106
  function registerDeviceRoutes(authenticated, deps) {
157
107
  registerPairingApprovalAdminRoutes(authenticated);
@@ -161,14 +111,21 @@ function registerDeviceRoutes(authenticated, deps) {
161
111
  ok: true,
162
112
  ready: routes.length > 0,
163
113
  routes,
164
- protocolVersions: [2, 3],
114
+ protocolVersion: 3,
165
115
  routeState: routes.length > 0 ? "configured" : "missing",
166
116
  nextAction: routes.length > 0 ? "scan" : "configure-route",
167
117
  serverTime: Date.now()
168
118
  });
169
119
  });
170
120
  authenticated.post("/api/device-pairing/setups", async (c) => {
171
- const version = (await c.req.json().catch(() => ({}))).protocolVersion === 3 ? 3 : 2;
121
+ const parsed = pairingSetupSchema.safeParse(await c.req.json().catch(() => null));
122
+ if (!parsed.success) return c.json({
123
+ ok: false,
124
+ error: {
125
+ code: "BAD_REQUEST",
126
+ message: "Choose a device type"
127
+ }
128
+ }, 400);
172
129
  const routes = resolveSecureDeviceRoutes(deps.service.currentConfig);
173
130
  if (routes.length === 0) return c.json({
174
131
  ok: false,
@@ -177,15 +134,16 @@ function registerDeviceRoutes(authenticated, deps) {
177
134
  message: "Configure XOPC Secure Link, Tailscale Serve, or an HTTPS public URL first"
178
135
  }
179
136
  }, 409);
180
- const setup = createDevicePairingSetup(routes, Date.now(), version);
137
+ const setup = createDevicePairingSetup(routes, Date.now(), { targetKind: parsed.data.targetKind });
181
138
  const identity = getOrCreateGatewayIdentity();
182
139
  const encoded = pairingLinkPayload({
183
- version,
140
+ version: 3,
184
141
  pairingToken: setup.token,
185
142
  gatewayId: identity.id,
186
143
  gatewayName: os.hostname(),
187
144
  gatewayPublicKey: getGatewayIdentityPublicKeyRaw(identity),
188
145
  routes,
146
+ targetKind: setup.targetKind,
189
147
  expiresAt: setup.expiresAt
190
148
  });
191
149
  return c.json({
@@ -195,7 +153,8 @@ function registerDeviceRoutes(authenticated, deps) {
195
153
  universalLink: `https://link.xopc.ai/connect#p=${encoded}`,
196
154
  expiresAt: setup.expiresAt,
197
155
  routes,
198
- protocolVersion: version
156
+ protocolVersion: 3,
157
+ targetKind: setup.targetKind
199
158
  }
200
159
  }, 201);
201
160
  });
@@ -234,7 +193,10 @@ function registerDeviceRoutes(authenticated, deps) {
234
193
  }
235
194
  }, 403);
236
195
  const revoked = revokeDevice(principal.deviceId);
237
- if (revoked) deps.service.realtime.disconnectPrincipal(principal.deviceId);
196
+ if (revoked) {
197
+ deps.service.realtime.disconnectPrincipal(principal.deviceId);
198
+ deps.service.voiceRealtime.disconnectPrincipal(principal.deviceId);
199
+ }
238
200
  return c.json({
239
201
  ok: true,
240
202
  revoked
@@ -243,7 +205,10 @@ function registerDeviceRoutes(authenticated, deps) {
243
205
  authenticated.delete("/api/devices/:deviceId", (c) => {
244
206
  const deviceId = c.req.param("deviceId");
245
207
  const revoked = revokeDevice(deviceId);
246
- if (revoked) deps.service.realtime.disconnectPrincipal(deviceId);
208
+ if (revoked) {
209
+ deps.service.realtime.disconnectPrincipal(deviceId);
210
+ deps.service.voiceRealtime.disconnectPrincipal(deviceId);
211
+ }
247
212
  return c.json({
248
213
  ok: true,
249
214
  revoked
@@ -1,15 +1,11 @@
1
- import { extractToken } from "../../auth.js";
2
1
  import { getExposureManager } from "../../../remote-access/exposure-manager.js";
2
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
3
3
  import { consumeTunnelMutationLimit } from "../../../tunnel/tunnel-rate-limit.js";
4
4
  //#region src/gateway/hono/routes/exposure.ts
5
- function requireGatewayToken(c) {
6
- return extractToken({ authorization: c.req.header("authorization") ?? void 0 }) ?? null;
7
- }
8
5
  function createExposureMutationRateLimitMiddleware() {
9
6
  return async (c, next) => {
10
- const token = requireGatewayToken(c);
11
- if (!token) return c.json({ error: "Gateway token required" }, 401);
12
- const result = consumeTunnelMutationLimit(token);
7
+ const principalId = getGatewayPrincipal(c).principalId;
8
+ const result = consumeTunnelMutationLimit(principalId);
13
9
  if (!result.allowed) {
14
10
  const retryAfterSec = Math.ceil(result.retryAfterMs / 1e3);
15
11
  c.header("Retry-After", String(retryAfterSec));
@@ -3,6 +3,14 @@ function startsWithAny(path, prefixes) {
3
3
  return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
4
4
  }
5
5
  const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
6
+ {
7
+ id: "browser-session",
8
+ match: (path) => path === "/api/browser-session",
9
+ load: async () => {
10
+ const { registerBrowserSessionRoutes } = await import("./browser-session.js");
11
+ return { register: registerBrowserSessionRoutes };
12
+ }
13
+ },
6
14
  {
7
15
  id: "proactive",
8
16
  match: (path) => startsWithAny(path, [
@@ -13,7 +13,7 @@ import { getImageGenerationProvider, reloadImageGenerationProviders, resolveImag
13
13
  import { SessionConfigStore } from "../../../session/config-store.js";
14
14
  import { getModelThinking } from "../../../providers/model-thinking.js";
15
15
  import { deleteCustomImageProvider, listCustomImageProviders, upsertCustomImageProvider } from "../../custom-image-providers.js";
16
- import { getAgentImageGenerationConfig, getImageGenerationCatalog, prepareImageGenerationSetup, verifyImageGenerationCredential } from "../../image-generation-setup.js";
16
+ import { getAgentImageGenerationConfig, getDefaultImageGenerationConfig, getImageGenerationCatalog, prepareDefaultImageGenerationSetup, prepareImageGenerationSetup, verifyImageGenerationCredential } from "../../image-generation-setup.js";
17
17
  import { discoverProviderModels, isProviderApiDiscoverable } from "../../../providers/model-discovery.js";
18
18
  import { getXopcCloudCatalogCoordinator } from "../../../providers/xopc-cloud-catalog-coordinator.js";
19
19
  import { respondStartupUnavailable } from "../lib/startup-unavailable.js";
@@ -505,6 +505,65 @@ function registerModelsRoutes(authenticated, deps) {
505
505
  }, 502);
506
506
  }
507
507
  });
508
+ authenticated.get("/api/image-generation/default", (c) => c.json({
509
+ ok: true,
510
+ payload: getDefaultImageGenerationConfig(service.currentConfig)
511
+ }));
512
+ authenticated.post("/api/image-generation/default/setup", strictRateLimitMiddleware, async (c) => {
513
+ const body = await c.req.json().catch(() => null);
514
+ if (!body || typeof body.providerId !== "string") return c.json({
515
+ ok: false,
516
+ error: { message: "providerId is required" }
517
+ }, 400);
518
+ const prepared = prepareDefaultImageGenerationSetup(service.currentConfig, {
519
+ providerId: body.providerId,
520
+ ...typeof body.modelId === "string" ? { modelId: body.modelId } : {},
521
+ ...body.providerConfig && typeof body.providerConfig === "object" && !Array.isArray(body.providerConfig) ? { providerConfig: body.providerConfig } : {}
522
+ });
523
+ if (prepared.ok === false) return c.json({
524
+ ok: false,
525
+ error: { message: prepared.error }
526
+ }, 400);
527
+ const resolver = new CredentialResolver();
528
+ const usesApiKey = resolveImageGenerationCredentialMode(getImageGenerationProvider(prepared.providerId)) === "api-key";
529
+ const previousKey = usesApiKey ? await resolver.revealGatewayStoredApiKey(prepared.providerId) : void 0;
530
+ const suppliedKey = typeof body.apiKey === "string" ? body.apiKey.trim() : "";
531
+ const effectiveKey = usesApiKey ? suppliedKey || await resolver.resolveApiKey(prepared.providerId) : void 0;
532
+ if (usesApiKey && !effectiveKey) return c.json({
533
+ ok: false,
534
+ error: { message: "API key is required" }
535
+ }, 400);
536
+ const verification = usesApiKey && suppliedKey ? await verifyImageGenerationCredential({
537
+ providerId: prepared.providerId,
538
+ apiKey: suppliedKey,
539
+ baseUrl: typeof body.providerConfig?.baseUrl === "string" ? body.providerConfig.baseUrl : void 0
540
+ }) : {
541
+ verified: false,
542
+ supported: false
543
+ };
544
+ if (verification.supported && !verification.verified) return c.json({
545
+ ok: false,
546
+ error: { message: verification.message ?? "Credential verification failed" }
547
+ }, 400);
548
+ if (usesApiKey && suppliedKey) await resolver.saveApiKey(prepared.providerId, suppliedKey, { profileName: "default" });
549
+ const saved = await service.saveConfig(prepared.config);
550
+ if (!saved.saved) {
551
+ if (usesApiKey && suppliedKey) if (previousKey) await resolver.saveApiKey(prepared.providerId, previousKey, { profileName: "default" });
552
+ else await resolver.deleteProfile(`${prepared.providerId}:default`);
553
+ return c.json({
554
+ ok: false,
555
+ error: { message: saved.error ?? "Failed to save configuration" }
556
+ }, 500);
557
+ }
558
+ return c.json({
559
+ ok: true,
560
+ payload: {
561
+ default: getDefaultImageGenerationConfig(service.currentConfig),
562
+ providers: getImageGenerationCatalog(service.currentConfig),
563
+ verification
564
+ }
565
+ });
566
+ });
508
567
  authenticated.get("/api/agents/:agentId/image-generation", (c) => {
509
568
  try {
510
569
  return c.json({
@@ -5,7 +5,7 @@ import { resolveGatewayEffectiveHost } from "../../../config/gateway-bind.js";
5
5
  import { getShareStore } from "../../../share/share-store.js";
6
6
  import { resolveShareUrl } from "../../../share/share-url.js";
7
7
  import { resolveReverseProxyPublicUrl } from "../../public-url.js";
8
- import { extractToken } from "../../auth.js";
8
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
9
9
  import { NoteShareService, NoteShareVersionConflictError } from "../../../share/note-share-service.js";
10
10
  import { createReadStream } from "node:fs";
11
11
  import { createHash } from "node:crypto";
@@ -412,11 +412,7 @@ function registerNotesRoutes(authenticated, deps) {
412
412
  });
413
413
  });
414
414
  authenticated.post("/api/notes/:id/shares", async (c) => {
415
- const gatewayToken = extractToken({ authorization: c.req.header("authorization") ?? void 0 });
416
- if (!gatewayToken) return c.json({
417
- ok: false,
418
- error: { message: "Token required" }
419
- }, 401);
415
+ const principalId = getGatewayPrincipal(c).principalId;
420
416
  const body = await c.req.json().catch(() => ({}));
421
417
  const shares = noteShares();
422
418
  try {
@@ -426,7 +422,7 @@ function registerNotesRoutes(authenticated, deps) {
426
422
  ttlMs: typeof body.ttlMs === "number" ? body.ttlMs : void 0,
427
423
  maxViews: body.maxViews === null ? null : typeof body.maxViews === "number" ? body.maxViews : void 0,
428
424
  description: typeof body.description === "string" ? body.description.trim() || void 0 : void 0,
429
- gatewayTokenHash: createHash("sha256").update(gatewayToken, "utf8").digest("hex").slice(0, 12)
425
+ gatewayTokenHash: createHash("sha256").update(principalId, "utf8").digest("hex").slice(0, 12)
430
426
  });
431
427
  const resolved = resolveShareUrl(record.token, shareUrlContext());
432
428
  return c.json({
@@ -1,4 +1,5 @@
1
1
  import { deleteBrowserTabBinding } from "../../../storage/sqlite/browser-tab-binding-repository.js";
2
+ import { SessionDiscoveryQuerySchema } from "../../../../packages/gateway-contract/src/session-identity.js";
2
3
  import { buildSessionKey, init_session_key } from "../../../routing/session-key.js";
3
4
  import { resolveProjectAgentId } from "../../../projects/project-agent.js";
4
5
  import "../../../projects/index.js";
@@ -259,8 +260,18 @@ function registerSessionsRoutes(authenticated, deps) {
259
260
  const blocked = ensureGatewayReadyForSessions(c, service, "sessions.list");
260
261
  if (blocked) return blocked;
261
262
  const query = c.req.query();
263
+ const discovery = SessionDiscoveryQuerySchema.safeParse({
264
+ sources: query.sources?.split(","),
265
+ purposes: query.purposes?.split(","),
266
+ activity: query.activity,
267
+ agentId: query.agentId,
268
+ excludeArchived: query.excludeArchived === "true"
269
+ });
270
+ if (!discovery.success) return c.json({ error: "Invalid session filters" }, 400);
271
+ if (query.updatedAfter && !Number.isFinite(Number(query.updatedAfter))) return c.json({ error: "Invalid session time filter" }, 400);
262
272
  const sessionTypes = query.types?.split(",").map((value) => value.trim()).filter(isSessionType);
263
273
  const result = await service.sessions.listSessions({
274
+ ...discovery.data,
264
275
  status: query.status,
265
276
  search: query.search,
266
277
  channel: query.channel,
@@ -15,10 +15,10 @@ import { publishHostedStaticSite } from "../../../share/hosted-static-site-publi
15
15
  import { resolveReverseProxyPublicUrl } from "../../public-url.js";
16
16
  import { audienceDefaults, cleanupStagedSite, decideShareKind, forgetStagedSite, makeDescription, makeTitle, probeShareTarget, rememberStagedSite, stageSingleHtmlAsSite } from "../../../share/share-auto.js";
17
17
  import { deleteThumbnail, placeholderSvg, readThumbnail, scheduleThumbnail, thumbnailContentType, thumbnailExists } from "../../../share/share-thumbnail.js";
18
- import { extractToken } from "../../auth.js";
19
18
  import { getGatewayFileSpaceService } from "../../file-space-service.js";
20
19
  import { getClientIpFromHeaders } from "../../security/loopback.js";
21
20
  import { SHARED_HTML_CSP } from "../../security/csp.js";
21
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
22
22
  import { renderFolderLandingPage, renderShareExpiredPage, renderShareLandingPage, renderSnapshotShareLandingPage } from "../../../share/share-landing.js";
23
23
  import { resolveScopedMediaReference } from "../../media-access.js";
24
24
  import { NoteShareService } from "../../../share/note-share-service.js";
@@ -56,7 +56,7 @@ function resolveShareConfig(service) {
56
56
  if (!raw || typeof raw !== "object") return {};
57
57
  return raw;
58
58
  }
59
- function hashGatewayToken(token) {
59
+ function hashPrincipal(token) {
60
60
  return createHash("sha256").update(token, "utf8").digest("hex").slice(0, 12);
61
61
  }
62
62
  const MAX_CONCURRENT_DOWNLOADS_PER_TOKEN = 5;
@@ -594,11 +594,7 @@ function registerShareRoutes(authenticated, deps) {
594
594
  });
595
595
  });
596
596
  authenticated.post("/api/sessions/:key/shares", async (c) => {
597
- const gatewayToken = extractToken({ authorization: c.req.header("authorization") ?? void 0 });
598
- if (!gatewayToken) return c.json({
599
- ok: false,
600
- error: { message: "Token required" }
601
- }, 401);
597
+ const principalId = getGatewayPrincipal(c).principalId;
602
598
  const body = await c.req.json().catch(() => ({}));
603
599
  if (typeof body.expectedSessionId !== "string" || typeof body.expectedCutoffSeq !== "number" || typeof body.expectedMetadataUpdatedAt !== "string") return c.json({
604
600
  ok: false,
@@ -614,7 +610,7 @@ function registerShareRoutes(authenticated, deps) {
614
610
  description: typeof body.description === "string" ? body.description.trim() || void 0 : void 0,
615
611
  includeToolActivities: body.includeToolActivities === true,
616
612
  attachmentIds: Array.isArray(body.attachmentIds) ? body.attachmentIds.filter((id) => typeof id === "string") : void 0,
617
- gatewayTokenHash: hashGatewayToken(gatewayToken)
613
+ gatewayTokenHash: hashPrincipal(principalId)
618
614
  });
619
615
  const resolved = resolveShareUrl(record.token, getShareUrlContext(service));
620
616
  return c.json({
@@ -1130,11 +1126,7 @@ function registerShareRoutes(authenticated, deps) {
1130
1126
  }
1131
1127
  });
1132
1128
  authenticated.post("/api/shares", async (c) => {
1133
- const gatewayToken = extractToken({ authorization: c.req.header("authorization") ?? void 0 });
1134
- if (!gatewayToken) return c.json({
1135
- ok: false,
1136
- error: { message: "Token required" }
1137
- }, 401);
1129
+ const principalId = getGatewayPrincipal(c).principalId;
1138
1130
  let body;
1139
1131
  try {
1140
1132
  body = await c.req.json();
@@ -1201,7 +1193,7 @@ function registerShareRoutes(authenticated, deps) {
1201
1193
  sessionKey,
1202
1194
  agentId,
1203
1195
  workspaceRoot,
1204
- gatewayTokenHash: hashGatewayToken(gatewayToken),
1196
+ gatewayTokenHash: hashPrincipal(principalId),
1205
1197
  kind,
1206
1198
  directoryMode,
1207
1199
  followSymlinks,
@@ -1242,11 +1234,7 @@ function registerShareRoutes(authenticated, deps) {
1242
1234
  * reachability) in a single round-trip.
1243
1235
  */
1244
1236
  authenticated.post("/api/shares/auto", async (c) => {
1245
- const gatewayToken = extractToken({ authorization: c.req.header("authorization") ?? void 0 });
1246
- if (!gatewayToken) return c.json({
1247
- ok: false,
1248
- error: { message: "Token required" }
1249
- }, 401);
1237
+ const principalId = getGatewayPrincipal(c).principalId;
1250
1238
  let body;
1251
1239
  try {
1252
1240
  body = await c.req.json();
@@ -1309,7 +1297,7 @@ function registerShareRoutes(authenticated, deps) {
1309
1297
  const defaults = audienceDefaults(audience);
1310
1298
  const ttlMs = ttlOverride ?? defaults.ttlMs;
1311
1299
  const maxViews = maxViewsOverride !== void 0 ? maxViewsOverride : defaults.maxViews;
1312
- const tokenHash = hashGatewayToken(gatewayToken);
1300
+ const tokenHash = hashPrincipal(principalId);
1313
1301
  const urlCtx = getShareUrlContext(service);
1314
1302
  try {
1315
1303
  if (decision.kind === "site") {
@@ -3,10 +3,10 @@ import { resolveSiteShareConfig } from "../../../share/site-share-config.js";
3
3
  import { getSiteShareStore } from "../../../share/site-share-store.js";
4
4
  import { resolveSiteShareUrl } from "../../../share/share-url.js";
5
5
  import { resolveReverseProxyPublicUrl } from "../../public-url.js";
6
- import { extractToken } from "../../auth.js";
6
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
7
7
  import { createHash } from "node:crypto";
8
8
  //#region src/gateway/hono/routes/site-shares.ts
9
- function hashGatewayToken(token) {
9
+ function hashPrincipal(token) {
10
10
  return createHash("sha256").update(token, "utf8").digest("hex").slice(0, 12);
11
11
  }
12
12
  function buildShareUrls(record, publicHostSuffix, service) {
@@ -42,11 +42,7 @@ function registerSiteShareRoutes(authenticated, deps) {
42
42
  return resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
43
43
  }
44
44
  authenticated.post("/api/site-shares", async (c) => {
45
- const gatewayToken = extractToken({ authorization: c.req.header("authorization") ?? void 0 });
46
- if (!gatewayToken) return c.json({
47
- ok: false,
48
- error: { message: "Token required" }
49
- }, 401);
45
+ const principalId = getGatewayPrincipal(c).principalId;
50
46
  let body;
51
47
  try {
52
48
  body = await c.req.json();
@@ -96,7 +92,7 @@ function registerSiteShareRoutes(authenticated, deps) {
96
92
  sessionKey,
97
93
  agentId,
98
94
  workspaceRoot,
99
- gatewayTokenHash: hashGatewayToken(gatewayToken)
95
+ gatewayTokenHash: hashPrincipal(principalId)
100
96
  });
101
97
  const urls = buildShareUrls(record, store.getConfig().publicHostSuffix, service);
102
98
  return c.json({
@@ -2,10 +2,11 @@ import { init_public_url, validatePublicUrl } from "../../../config/public-url.j
2
2
  import { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, readTunnelRegistrationSecretFromConfigOnly, resolveTunnelBrokerUrl } from "../../../tunnel/env.js";
3
3
  import { logTunnelAudit } from "../../../tunnel/tunnel-audit.js";
4
4
  import { getTunnelService, hashGatewayToken } from "../../../tunnel/tunnel-service.js";
5
- import { extractToken } from "../../auth.js";
5
+ import { requireTunnelGatewayToken } from "../../../tunnel/auth-policy.js";
6
6
  import { TUNNEL_CONSENT_REQUIRED_CODE, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState } from "../../../tunnel/consent.js";
7
7
  import { configureTunnelFromGatewayConfig } from "../../../tunnel/gateway-lifecycle.js";
8
8
  import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../../tunnel/tunnel-config.js";
9
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
9
10
  import { consumeTunnelMutationLimit } from "../../../tunnel/tunnel-rate-limit.js";
10
11
  import "../../../tunnel/index.js";
11
12
  import { provisionTunnelRegistrationKey } from "../../../tunnel/xopc-cloud-registration.js";
@@ -36,14 +37,9 @@ function enrichTunnelStatus(config, status) {
36
37
  registrationSecret
37
38
  };
38
39
  }
39
- function requireGatewayToken(c) {
40
- return extractToken({ authorization: c.req.header("authorization") ?? void 0 }) ?? null;
41
- }
42
40
  function createTunnelMutationRateLimitMiddleware() {
43
41
  return async (c, next) => {
44
- const token = requireGatewayToken(c);
45
- if (!token) return c.json({ error: "Gateway token required" }, 401);
46
- const result = consumeTunnelMutationLimit(token);
42
+ const result = consumeTunnelMutationLimit(getGatewayPrincipal(c).principalId);
47
43
  if (!result.allowed) {
48
44
  c.header("Retry-After", String(Math.ceil(result.retryAfterMs / 1e3)));
49
45
  return c.json({
@@ -66,7 +62,6 @@ function registerTunnelRoutes(authenticated, deps) {
66
62
  * the UI can render targeted hints (TLS / DNS / wrong service / blocked path).
67
63
  */
68
64
  authenticated.post("/api/tunnel/probe-public", tunnelMutationLimit, async (c) => {
69
- if (!requireGatewayToken(c)) return c.json({ error: "Gateway token required" }, 401);
70
65
  let body;
71
66
  try {
72
67
  body = await c.req.json();
@@ -142,8 +137,6 @@ function registerTunnelRoutes(authenticated, deps) {
142
137
  return c.json(enrichTunnelStatus(config, tunnel.getStatus()));
143
138
  });
144
139
  authenticated.post("/api/tunnel/consent", tunnelMutationLimit, async (c) => {
145
- const token = requireGatewayToken(c);
146
- if (!token) return c.json({ error: "Gateway token required" }, 401);
147
140
  const config = deps.service.currentConfig;
148
141
  applyTunnelConsentToConfig(config);
149
142
  const result = await deps.service.saveConfig(config);
@@ -154,7 +147,7 @@ function registerTunnelRoutes(authenticated, deps) {
154
147
  const consent = getTunnelConsentState(config);
155
148
  logTunnelAudit("tunnel.consent", {
156
149
  consentVersion: consent.currentVersion,
157
- gatewayTokenHash: hashGatewayToken(token).slice(0, 12)
150
+ principalId: getGatewayPrincipal(c).principalId
158
151
  }, "Remote access security consent recorded");
159
152
  return c.json({
160
153
  ok: true,
@@ -190,10 +183,17 @@ function registerTunnelRoutes(authenticated, deps) {
190
183
  }
191
184
  });
192
185
  authenticated.post("/api/tunnel/start", tunnelMutationLimit, async (c) => {
186
+ let token;
187
+ try {
188
+ token = requireTunnelGatewayToken(deps.service.getResolvedAuth());
189
+ } catch (error) {
190
+ return c.json({
191
+ error: error.message,
192
+ code: "TUNNEL_AUTH_REQUIRED"
193
+ }, 403);
194
+ }
193
195
  await configureTunnelFromService(deps, { force: true });
194
196
  const config = deps.service.currentConfig;
195
- const token = requireGatewayToken(c);
196
- if (!token) return c.json({ error: "Gateway token required" }, 401);
197
197
  try {
198
198
  assertTunnelMayStart(config);
199
199
  } catch (err) {
@@ -19,6 +19,23 @@ export declare function getAgentImageGenerationConfig(config: Config, agentIdRaw
19
19
  timeoutMs?: number;
20
20
  };
21
21
  };
22
+ export declare function getDefaultImageGenerationConfig(config: Config): {
23
+ model: {
24
+ primary: string;
25
+ fallbacks: string[];
26
+ autoProviderFallback: boolean;
27
+ timeoutMs?: number;
28
+ };
29
+ };
30
+ export declare function prepareDefaultImageGenerationSetup(config: Config, input: ImageGenerationSetupInput): {
31
+ ok: true;
32
+ config: Config;
33
+ providerId: string;
34
+ modelId: string;
35
+ } | {
36
+ ok: false;
37
+ error: string;
38
+ };
22
39
  export declare function prepareImageGenerationSetup(config: Config, agentIdRaw: string, input: ImageGenerationSetupInput): {
23
40
  ok: true;
24
41
  config: Config;