@opengeni/api-router 3.0.1 → 3.1.2

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 (546) hide show
  1. package/dist/access-grant-rls.d.ts +8 -1
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/app.d.ts +50 -3
  4. package/dist/app.js +10 -1
  5. package/dist/artifact-catalog-cursor.d.ts +1 -0
  6. package/dist/attached-browser-viewer.d.ts +11 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
  10. package/dist/auth/managed-auth.d.ts +72 -5
  11. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  12. package/dist/auth/new-signups-gate.d.ts +23 -0
  13. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  14. package/dist/azure-live.d.ts +28 -0
  15. package/dist/browser-action-fences.d.ts +13 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-lost-runtime-end.d.ts +24 -0
  19. package/dist/browser-state-authority.d.ts +1 -27
  20. package/dist/chunk-OGQDXVXY.js +18 -0
  21. package/dist/chunk-OGQDXVXY.js.map +1 -0
  22. package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
  23. package/dist/chunk-OT56OY4V.js.map +1 -0
  24. package/dist/claude-default-models.d.ts +19 -0
  25. package/dist/claude-subscription-core.d.ts +50 -0
  26. package/dist/claude-subscription-oauth.d.ts +36 -0
  27. package/dist/claude-subscription-profile.d.ts +9 -0
  28. package/dist/claude-subscription-usage.d.ts +6 -0
  29. package/dist/claude-workspace-connection.d.ts +15 -0
  30. package/dist/codemode.d.ts +40 -5
  31. package/dist/codex-realtime.d.ts +29 -3
  32. package/dist/codex-session-pointers.d.ts +19 -0
  33. package/dist/connection-ownership.d.ts +6 -3
  34. package/dist/controller-data-plane.d.ts +16 -0
  35. package/dist/credit-promotion-snapshot.d.ts +6 -0
  36. package/dist/editable-artifact-source-session.d.ts +3 -0
  37. package/dist/editable-artifact-websocket.d.ts +5 -3
  38. package/dist/fatal-process-boundary.d.ts +9 -1
  39. package/dist/github-access.d.ts +7 -1
  40. package/dist/github-browser-flow.d.ts +1 -1
  41. package/dist/http/acting-person.d.ts +36 -0
  42. package/dist/http/api-contract-compat.d.ts +19 -0
  43. package/dist/http/api-error.d.ts +50 -1
  44. package/dist/http/auth.d.ts +8 -1
  45. package/dist/http/cors.d.ts +12 -0
  46. package/dist/http/deprecation.d.ts +42 -0
  47. package/dist/http/keyed-admission.d.ts +12 -0
  48. package/dist/http/local-browser-boundary.d.ts +72 -0
  49. package/dist/http/metrics-listener.d.ts +22 -0
  50. package/dist/http/path-identifier.d.ts +17 -0
  51. package/dist/http/registered-route-label.d.ts +16 -0
  52. package/dist/http/rejection-telemetry.d.ts +34 -0
  53. package/dist/http/request-body.d.ts +27 -0
  54. package/dist/http/request-source.d.ts +41 -3
  55. package/dist/http/sse.d.ts +12 -1
  56. package/dist/http/unmatched-route.d.ts +18 -0
  57. package/dist/http/user-content.d.ts +36 -0
  58. package/dist/http/variable-sets-removed.d.ts +41 -0
  59. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  60. package/dist/index.js +1279 -108
  61. package/dist/index.js.map +1 -1
  62. package/dist/integration-connect-metrics.d.ts +35 -0
  63. package/dist/integration-endpoint-test.d.ts +20 -0
  64. package/dist/integrations/api-integrations.d.ts +2 -2
  65. package/dist/integrations/atlassian.d.ts +8 -3
  66. package/dist/integrations/fiken.d.ts +3 -1
  67. package/dist/integrations/github-lens-connect.d.ts +37 -66
  68. package/dist/integrations/google-drive.d.ts +2 -0
  69. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  70. package/dist/integrations/marketplace-plugin.d.ts +43 -43
  71. package/dist/integrations/oauth-client.d.ts +171 -12
  72. package/dist/integrations/oauth-profiles.d.ts +42 -13
  73. package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
  74. package/dist/integrations/slack-bot.d.ts +285 -7
  75. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  76. package/dist/integrations/slack-interactions.d.ts +89 -10
  77. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  78. package/dist/integrations/slack-routing.d.ts +1 -1
  79. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  80. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  81. package/dist/integrations/slack-tool-review.d.ts +5 -0
  82. package/dist/interaction-agent-access.d.ts +13 -8
  83. package/dist/interaction-agent-version.d.ts +21 -0
  84. package/dist/interaction-holder-heartbeat.d.ts +5 -0
  85. package/dist/interaction-metrics.d.ts +27 -2
  86. package/dist/interaction-route-stages.d.ts +25 -0
  87. package/dist/interaction-secrets-vault.d.ts +20 -0
  88. package/dist/interaction-secrets.d.ts +103 -0
  89. package/dist/mcp/action-catalog-types.d.ts +14 -0
  90. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  91. package/dist/mcp/action-descriptions.d.ts +4 -0
  92. package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
  93. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  94. package/dist/mcp/child-read-evidence.d.ts +9 -0
  95. package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
  96. package/dist/mcp/contract-input.d.ts +13 -0
  97. package/dist/mcp/documents.d.ts +2 -0
  98. package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
  99. package/dist/mcp/notification-tools.d.ts +26 -0
  100. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  101. package/dist/mcp/scheduled-task-input.d.ts +1309 -0
  102. package/dist/mcp/scheduled-task-view.d.ts +217 -3
  103. package/dist/mcp/secret-tools.d.ts +14 -0
  104. package/dist/mcp/server.d.ts +108 -5
  105. package/dist/mcp/session-admin-access-tools.d.ts +33 -0
  106. package/dist/mcp/session-event-errors.d.ts +28 -0
  107. package/dist/mcp/session-event-view.d.ts +62 -0
  108. package/dist/mcp/session-view.d.ts +15 -0
  109. package/dist/mcp/session-wait.d.ts +18 -0
  110. package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
  111. package/dist/mcp/site-data-tools.d.ts +22 -0
  112. package/dist/mcp/site-publication-tools.d.ts +19 -0
  113. package/dist/mcp/site-sql-tools.d.ts +27 -0
  114. package/dist/mcp-oauth.d.ts +37 -4
  115. package/dist/model-calls/chat-completions.d.ts +87 -0
  116. package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
  117. package/dist/model-calls/service.d.ts +36 -0
  118. package/dist/model-catalog.d.ts +9 -3
  119. package/dist/native-push-dispatch.d.ts +69 -0
  120. package/dist/observability.d.ts +3 -1
  121. package/dist/organization-mcp.d.ts +82 -0
  122. package/dist/prepared-mcp-actor.d.ts +77 -0
  123. package/dist/prepared-mcp-permissions.d.ts +8 -0
  124. package/dist/routes/analytics-consent.d.ts +26 -0
  125. package/dist/routes/api-integrations.d.ts +11 -0
  126. package/dist/routes/api-keys.d.ts +7 -7
  127. package/dist/routes/automations.d.ts +2 -0
  128. package/dist/routes/billing.d.ts +59 -0
  129. package/dist/routes/browser-sessions.d.ts +65 -2
  130. package/dist/routes/chat-completions.d.ts +11 -0
  131. package/dist/routes/claude-core-usage.d.ts +20 -0
  132. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  133. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  134. package/dist/routes/client-errors.d.ts +182 -0
  135. package/dist/routes/codex-core.d.ts +401 -0
  136. package/dist/routes/codex.d.ts +64 -2
  137. package/dist/routes/computer-sessions.d.ts +6 -1
  138. package/dist/routes/desktop-distribution.d.ts +32 -0
  139. package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
  140. package/dist/routes/github-browser-pages.d.ts +27 -0
  141. package/dist/routes/inbox.d.ts +13 -0
  142. package/dist/routes/insights-response-cache.d.ts +10 -0
  143. package/dist/routes/insights-usage.d.ts +12 -0
  144. package/dist/routes/insights.d.ts +28 -0
  145. package/dist/routes/interaction-placement-message.d.ts +7 -0
  146. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  147. package/dist/routes/model-account-choice.d.ts +13 -0
  148. package/dist/routes/model-account-settings.d.ts +19 -0
  149. package/dist/routes/native-app-auth.d.ts +12 -0
  150. package/dist/routes/organization-integration-policy.d.ts +8 -0
  151. package/dist/routes/organization-integrations.d.ts +6 -0
  152. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  153. package/dist/routes/organization-model-defaults.d.ts +9 -0
  154. package/dist/routes/organization-service-accounts.d.ts +3 -0
  155. package/dist/routes/personal-api-keys.d.ts +3 -0
  156. package/dist/routes/session-admin-access.d.ts +3 -0
  157. package/dist/routes/session-artifact-associations.d.ts +4 -0
  158. package/dist/routes/session-history-imports.d.ts +20 -0
  159. package/dist/routes/sessions.d.ts +38 -2
  160. package/dist/routes/site-data.d.ts +18 -0
  161. package/dist/routes/site-publishing.d.ts +5 -0
  162. package/dist/routes/site-runtime.d.ts +31 -0
  163. package/dist/routes/site-sql.d.ts +16 -0
  164. package/dist/routes/slack-bot-access.d.ts +3 -0
  165. package/dist/routes/subscription-account-pools.d.ts +21 -0
  166. package/dist/routes/subscription-core-http.d.ts +5 -0
  167. package/dist/routes/subscription-pool-access.d.ts +37 -0
  168. package/dist/routes/subscription-pool-core.d.ts +153 -0
  169. package/dist/routes/supergrok.d.ts +6 -6
  170. package/dist/routes/usage-allowances.d.ts +12 -0
  171. package/dist/routes/variable-sets-removed.d.ts +2 -0
  172. package/dist/routes/vault-providers.d.ts +34 -0
  173. package/dist/routes/vaults.d.ts +3 -0
  174. package/dist/routes/workspace-integrations.d.ts +35 -0
  175. package/dist/routes/workspace-model-providers.d.ts +4 -0
  176. package/dist/routes/workspaces.d.ts +11 -2
  177. package/dist/sandbox/agent-update.d.ts +64 -0
  178. package/dist/sandbox/auth-callout.d.ts +8 -0
  179. package/dist/sandbox/channel-a.d.ts +15 -1
  180. package/dist/sandbox/enrollment.d.ts +26 -4
  181. package/dist/sandbox/machine-audience.d.ts +29 -0
  182. package/dist/sandbox/machines.d.ts +15 -2
  183. package/dist/sandbox/metrics-ingestion.d.ts +6 -2
  184. package/dist/sandbox/screen-control.d.ts +85 -0
  185. package/dist/sandbox/viewer.d.ts +5 -1
  186. package/dist/sandbox-file-artifacts.d.ts +17 -1
  187. package/dist/scheduled-task-blockers.d.ts +39 -0
  188. package/dist/scheduled-task-deletion.d.ts +3 -4
  189. package/dist/scheduled-task-lifecycle.d.ts +14 -0
  190. package/dist/secret-answers.d.ts +40 -0
  191. package/dist/session-create-observability.d.ts +5 -0
  192. package/dist/session-event-view-36GO3IL7.js +528 -0
  193. package/dist/session-event-view-36GO3IL7.js.map +1 -0
  194. package/dist/signed-state-secret.d.ts +18 -0
  195. package/dist/site-agent-guard.d.ts +53 -0
  196. package/dist/site-data/operations.d.ts +103 -0
  197. package/dist/site-data/service.d.ts +203 -0
  198. package/dist/site-frame-guard.d.ts +32 -0
  199. package/dist/site-publishing/agent-data-tools.d.ts +84 -0
  200. package/dist/site-publishing/agent-model.d.ts +58 -0
  201. package/dist/site-publishing/agent-session.d.ts +16 -0
  202. package/dist/site-publishing/content-scanner.d.ts +31 -0
  203. package/dist/site-publishing/edge-sync.d.ts +48 -0
  204. package/dist/site-publishing/gateway-signature.d.ts +56 -0
  205. package/dist/site-publishing/limits.d.ts +63 -0
  206. package/dist/site-publishing/page-tool-authority.d.ts +30 -0
  207. package/dist/site-publishing/platform-usage.d.ts +113 -0
  208. package/dist/site-publishing/platform.d.ts +21 -0
  209. package/dist/site-publishing/readiness.d.ts +62 -0
  210. package/dist/site-publishing/runtime.d.ts +179 -0
  211. package/dist/site-publishing/service.d.ts +264 -0
  212. package/dist/site-publishing/session-events.d.ts +22 -0
  213. package/dist/site-publishing/session-views.d.ts +36 -0
  214. package/dist/site-publishing/viewer.d.ts +40 -0
  215. package/dist/site-session-origin.d.ts +31 -6
  216. package/dist/site-sql/format.d.ts +47 -0
  217. package/dist/site-sql/gateway.d.ts +50 -0
  218. package/dist/site-sql/service.d.ts +213 -0
  219. package/dist/temporal-schedule-sync.d.ts +26 -0
  220. package/dist/transcription/billing-refusal.d.ts +8 -0
  221. package/dist/transcription/normalize.d.ts +23 -0
  222. package/dist/transcription/providers/azure-mai.d.ts +12 -0
  223. package/dist/transcription/providers/azure-openai.d.ts +4 -0
  224. package/dist/transcription/providers/openai.d.ts +16 -0
  225. package/dist/transcription/providers/subscription-core.d.ts +39 -0
  226. package/dist/transcription/service.d.ts +10 -1
  227. package/dist/transcription/wav-duration.d.ts +8 -0
  228. package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
  229. package/dist/workspace-tool-gateway-observability.d.ts +16 -0
  230. package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
  231. package/dist/workspace-tool-gateway.d.ts +102 -6
  232. package/dist/workspace-tool-target-fence.d.ts +116 -0
  233. package/dist/workspace-tool-target.d.ts +225 -0
  234. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  235. package/dist/xai-subscription-core.d.ts +60 -0
  236. package/package.json +25 -20
  237. package/src/access-grant-rls.ts +64 -14
  238. package/src/admission-trace.ts +14 -0
  239. package/src/app.ts +1684 -252
  240. package/src/artifact-catalog-cursor.ts +1 -0
  241. package/src/attached-browser-viewer.ts +26 -0
  242. package/src/auth/managed-auth-attempt-context.ts +9 -0
  243. package/src/auth/managed-auth-rate-limits.ts +252 -0
  244. package/src/auth/managed-auth-session-adapter.ts +64 -29
  245. package/src/auth/managed-auth.ts +303 -35
  246. package/src/auth/managed-email.ts +18 -1
  247. package/src/auth/managed-sign-in-notifications.ts +81 -0
  248. package/src/auth/new-signups-gate.ts +49 -0
  249. package/src/auth/organization-user-setup.ts +3 -3
  250. package/src/auth/signup-funnel-metrics.ts +164 -0
  251. package/src/azure-live.ts +103 -0
  252. package/src/browser-action-fences.ts +45 -0
  253. package/src/browser-controller-authority.ts +1 -186
  254. package/src/browser-ephemeral.ts +39 -0
  255. package/src/browser-lost-runtime-end.ts +71 -0
  256. package/src/browser-state-authority.ts +1 -236
  257. package/src/claude-default-models.ts +37 -0
  258. package/src/claude-subscription-core.ts +154 -0
  259. package/src/claude-subscription-oauth.ts +352 -0
  260. package/src/claude-subscription-profile.ts +73 -0
  261. package/src/claude-subscription-usage.ts +51 -0
  262. package/src/claude-workspace-connection.ts +82 -0
  263. package/src/codemode.ts +236 -39
  264. package/src/codex-realtime.ts +181 -53
  265. package/src/codex-session-pointers.ts +80 -0
  266. package/src/company-brain-okf.ts +1 -1
  267. package/src/connected-machine-computer-access.ts +2 -1
  268. package/src/connection-ownership.ts +19 -13
  269. package/src/controller-data-plane.ts +34 -0
  270. package/src/credit-promotion-snapshot.ts +36 -0
  271. package/src/editable-artifact-production.ts +10 -0
  272. package/src/editable-artifact-source-session.ts +123 -0
  273. package/src/editable-artifact-websocket.ts +16 -3
  274. package/src/fatal-process-boundary.ts +67 -3
  275. package/src/gateway-realtime.ts +12 -8
  276. package/src/github-access.ts +31 -5
  277. package/src/github-browser-flow.ts +1 -1
  278. package/src/http/acting-person.ts +105 -0
  279. package/src/http/api-contract-compat.ts +49 -0
  280. package/src/http/api-error.ts +210 -2
  281. package/src/http/auth.ts +68 -4
  282. package/src/http/cors.ts +37 -5
  283. package/src/http/deprecation.ts +118 -0
  284. package/src/http/keyed-admission.ts +29 -0
  285. package/src/http/local-browser-boundary.ts +343 -0
  286. package/src/http/metrics-listener.ts +57 -0
  287. package/src/http/path-identifier.ts +54 -0
  288. package/src/http/registered-route-label.ts +34 -0
  289. package/src/http/rejection-telemetry.ts +120 -0
  290. package/src/http/request-body.ts +127 -0
  291. package/src/http/request-source.ts +154 -13
  292. package/src/http/sse.ts +88 -28
  293. package/src/http/unmatched-route.ts +60 -0
  294. package/src/http/user-content.ts +158 -0
  295. package/src/http/variable-sets-removed.ts +122 -0
  296. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  297. package/src/index.ts +107 -57
  298. package/src/integration-connect-metrics.ts +228 -0
  299. package/src/integration-endpoint-test.ts +291 -0
  300. package/src/integrations/api-integrations.ts +81 -7
  301. package/src/integrations/atlassian.ts +202 -83
  302. package/src/integrations/fiken.ts +66 -38
  303. package/src/integrations/github-app-connect.ts +64 -18
  304. package/src/integrations/github-lens-connect.ts +8 -29
  305. package/src/integrations/google-drive.ts +448 -152
  306. package/src/integrations/integration-commit-authority.ts +69 -0
  307. package/src/integrations/marketplace-plugin.ts +1 -1
  308. package/src/integrations/oauth-client.ts +733 -193
  309. package/src/integrations/oauth-profiles.ts +116 -45
  310. package/src/integrations/onepassword-vault-provider.ts +16 -0
  311. package/src/integrations/personal-github-repositories.ts +1 -1
  312. package/src/integrations/personal-github.ts +61 -35
  313. package/src/integrations/provider-oauth.ts +67 -85
  314. package/src/integrations/slack-app-home.ts +5 -5
  315. package/src/integrations/slack-bot.ts +893 -201
  316. package/src/integrations/slack-file-upload-flow.ts +147 -0
  317. package/src/integrations/slack-install.ts +7 -7
  318. package/src/integrations/slack-interactions.ts +1589 -299
  319. package/src/integrations/slack-mrkdwn.ts +193 -0
  320. package/src/integrations/slack-routing.ts +2 -2
  321. package/src/integrations/slack-session-defaults.ts +224 -0
  322. package/src/integrations/slack-task-file-upload.ts +323 -0
  323. package/src/integrations/slack-tool-review.ts +65 -0
  324. package/src/integrations/social-oauth.ts +90 -58
  325. package/src/interaction-agent-access.ts +40 -20
  326. package/src/interaction-agent-version.ts +85 -0
  327. package/src/interaction-holder-heartbeat.ts +24 -8
  328. package/src/interaction-metrics.ts +164 -2
  329. package/src/interaction-route-stages.ts +94 -0
  330. package/src/interaction-secrets-vault.ts +213 -0
  331. package/src/interaction-secrets.ts +426 -0
  332. package/src/mcp/action-catalog-types.ts +14 -0
  333. package/src/mcp/action-catalog.gen.ts +8014 -0
  334. package/src/mcp/action-descriptions.ts +299 -0
  335. package/src/mcp/action-schema-imports.gen.ts +304 -0
  336. package/src/mcp/capability-account-readiness.ts +17 -0
  337. package/src/mcp/child-read-evidence.ts +19 -0
  338. package/src/mcp/company-profile-agent-admin.ts +13 -0
  339. package/src/mcp/contract-input.ts +165 -0
  340. package/src/mcp/documents.ts +9 -2
  341. package/src/mcp/editable-artifacts.ts +29 -11
  342. package/src/mcp/files.ts +5 -1
  343. package/src/mcp/first-party-tool-permissions.ts +7 -285
  344. package/src/mcp/knowledge-entries.ts +108 -34
  345. package/src/mcp/notification-tools.ts +480 -0
  346. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  347. package/src/mcp/scheduled-task-input.ts +89 -0
  348. package/src/mcp/scheduled-task-view.ts +63 -3
  349. package/src/mcp/secret-tools.ts +185 -0
  350. package/src/mcp/server.ts +2213 -1116
  351. package/src/mcp/session-admin-access-tools.ts +163 -0
  352. package/src/mcp/session-event-errors.ts +123 -0
  353. package/src/mcp/session-event-view.ts +395 -13
  354. package/src/mcp/session-view.ts +3 -0
  355. package/src/mcp/session-wait.ts +67 -7
  356. package/src/mcp/site-agent-clamp-tools.ts +140 -0
  357. package/src/mcp/site-data-tools.ts +339 -0
  358. package/src/mcp/site-publication-tools.ts +201 -0
  359. package/src/mcp/site-sql-tools.ts +427 -0
  360. package/src/mcp-oauth.ts +635 -45
  361. package/src/model-calls/chat-completions.ts +352 -0
  362. package/src/model-calls/pending-usage-settlements.ts +125 -0
  363. package/src/model-calls/service.ts +694 -0
  364. package/src/model-catalog.ts +68 -17
  365. package/src/native-push-dispatch.ts +457 -0
  366. package/src/observability.ts +15 -1
  367. package/src/organization-mcp.ts +485 -0
  368. package/src/prepared-mcp-actor.ts +154 -0
  369. package/src/prepared-mcp-permissions.ts +38 -0
  370. package/src/routes/analytics-consent.ts +123 -0
  371. package/src/routes/api-integrations.ts +268 -9
  372. package/src/routes/api-keys.ts +164 -25
  373. package/src/routes/artifact-catalog.ts +111 -0
  374. package/src/routes/automations.ts +163 -90
  375. package/src/routes/billing.ts +535 -59
  376. package/src/routes/browser-sessions.ts +966 -342
  377. package/src/routes/canonical-human-identities.ts +61 -0
  378. package/src/routes/capabilities.ts +112 -5
  379. package/src/routes/channels.ts +4 -3
  380. package/src/routes/chat-completions.ts +235 -0
  381. package/src/routes/claude-core-usage.ts +147 -0
  382. package/src/routes/claude-subscription-accounts.ts +233 -0
  383. package/src/routes/claude-subscription-oauth.ts +175 -0
  384. package/src/routes/client-errors.ts +394 -0
  385. package/src/routes/codex-core.ts +687 -0
  386. package/src/routes/codex.ts +1277 -1119
  387. package/src/routes/company-brain.ts +4 -0
  388. package/src/routes/computer-sessions.ts +319 -85
  389. package/src/routes/connect.ts +277 -175
  390. package/src/routes/connections.ts +690 -363
  391. package/src/routes/desktop-distribution.ts +217 -0
  392. package/src/routes/documents.ts +13 -7
  393. package/src/routes/editable-artifacts.ts +74 -4
  394. package/src/routes/enrollments.ts +110 -16
  395. package/src/routes/external-identity-links.ts +13 -12
  396. package/src/routes/files.ts +41 -16
  397. package/src/routes/github-browser-fonts.gen.ts +12 -0
  398. package/src/routes/github-browser-pages.ts +258 -0
  399. package/src/routes/github.ts +200 -75
  400. package/src/routes/inbox.ts +353 -0
  401. package/src/routes/insights-response-cache.ts +83 -0
  402. package/src/routes/insights-usage.ts +345 -0
  403. package/src/routes/insights.ts +103 -8
  404. package/src/routes/install.ts +51 -10
  405. package/src/routes/integration-facets.ts +70 -28
  406. package/src/routes/interaction-placement-message.ts +12 -0
  407. package/src/routes/knowledge.ts +136 -27
  408. package/src/routes/machines.ts +189 -135
  409. package/src/routes/managed-auth-session-sets.ts +43 -10
  410. package/src/routes/managed-onboarding.ts +39 -19
  411. package/src/routes/managed-sign-in-methods.ts +433 -0
  412. package/src/routes/memory-slack-publications.ts +3 -2
  413. package/src/routes/model-account-choice.ts +194 -0
  414. package/src/routes/model-account-settings.ts +235 -0
  415. package/src/routes/model-connection-access.ts +210 -48
  416. package/src/routes/native-app-auth.ts +296 -0
  417. package/src/routes/organization-integration-policy.ts +116 -0
  418. package/src/routes/organization-integrations.ts +326 -0
  419. package/src/routes/organization-mcp-connections.ts +183 -0
  420. package/src/routes/organization-memberships.ts +205 -19
  421. package/src/routes/organization-model-defaults.ts +110 -0
  422. package/src/routes/organization-model-providers.ts +74 -3
  423. package/src/routes/organization-service-accounts.ts +128 -0
  424. package/src/routes/organization-sessions.ts +21 -5
  425. package/src/routes/personal-api-keys.ts +184 -0
  426. package/src/routes/personal-github-git-broker.ts +2 -2
  427. package/src/routes/personal-github.ts +9 -4
  428. package/src/routes/plugins.ts +46 -7
  429. package/src/routes/pr-review-github.ts +105 -118
  430. package/src/routes/pr-review.ts +88 -82
  431. package/src/routes/preference-registry.ts +18 -0
  432. package/src/routes/rigs.ts +48 -13
  433. package/src/routes/scheduled-tasks.ts +347 -27
  434. package/src/routes/session-admin-access.ts +271 -0
  435. package/src/routes/session-artifact-associations.ts +164 -0
  436. package/src/routes/session-history-imports.ts +305 -0
  437. package/src/routes/sessions.ts +1682 -363
  438. package/src/routes/site-data.ts +340 -0
  439. package/src/routes/site-publishing.ts +584 -0
  440. package/src/routes/site-runtime.ts +1944 -0
  441. package/src/routes/site-sql.ts +263 -0
  442. package/src/routes/skill-content.ts +72 -7
  443. package/src/routes/skills.ts +5 -4
  444. package/src/routes/slack-bot-access.ts +108 -0
  445. package/src/routes/social.ts +27 -15
  446. package/src/routes/subscription-account-pools.ts +209 -0
  447. package/src/routes/subscription-core-http.ts +18 -0
  448. package/src/routes/subscription-pool-access.ts +180 -0
  449. package/src/routes/subscription-pool-core.ts +552 -0
  450. package/src/routes/supergrok.ts +174 -655
  451. package/src/routes/transcription-recordings.ts +71 -4
  452. package/src/routes/transcriptions.ts +26 -2
  453. package/src/routes/usage-allowances.ts +381 -0
  454. package/src/routes/variable-sets-removed.ts +19 -0
  455. package/src/routes/vault-providers.ts +782 -0
  456. package/src/routes/vaults.ts +421 -0
  457. package/src/routes/video-generation.ts +30 -12
  458. package/src/routes/workspace-artifacts.ts +165 -53
  459. package/src/routes/workspace-integrations.ts +576 -0
  460. package/src/routes/workspace-model-providers.ts +148 -0
  461. package/src/routes/workspace-state.ts +4 -0
  462. package/src/routes/workspaces.ts +625 -117
  463. package/src/sandbox/agent-update.ts +315 -0
  464. package/src/sandbox/auth-callout.ts +104 -21
  465. package/src/sandbox/channel-a.ts +165 -55
  466. package/src/sandbox/enrollment.ts +131 -22
  467. package/src/sandbox/machine-audience.ts +192 -0
  468. package/src/sandbox/machines.ts +75 -31
  469. package/src/sandbox/metrics-ingestion.ts +133 -2
  470. package/src/sandbox/rematerialize.ts +51 -21
  471. package/src/sandbox/screen-control.ts +289 -0
  472. package/src/sandbox/viewer.ts +33 -58
  473. package/src/sandbox-file-artifacts.ts +53 -27
  474. package/src/scheduled-task-blockers.ts +293 -0
  475. package/src/scheduled-task-deletion.ts +13 -3
  476. package/src/scheduled-task-lifecycle.ts +84 -0
  477. package/src/secret-answers.ts +119 -0
  478. package/src/session-create-observability.ts +46 -0
  479. package/src/session-realtime-context.ts +26 -4
  480. package/src/signed-state-secret.ts +58 -0
  481. package/src/site-agent-guard.ts +261 -0
  482. package/src/site-data/operations.ts +777 -0
  483. package/src/site-data/service.ts +1043 -0
  484. package/src/site-frame-guard.ts +107 -0
  485. package/src/site-publishing/agent-data-tools.ts +250 -0
  486. package/src/site-publishing/agent-model.ts +127 -0
  487. package/src/site-publishing/agent-session.ts +148 -0
  488. package/src/site-publishing/content-scanner.ts +93 -0
  489. package/src/site-publishing/edge-sync.ts +148 -0
  490. package/src/site-publishing/gateway-signature.ts +198 -0
  491. package/src/site-publishing/limits.ts +315 -0
  492. package/src/site-publishing/page-tool-authority.ts +111 -0
  493. package/src/site-publishing/platform-usage.ts +479 -0
  494. package/src/site-publishing/platform.ts +98 -0
  495. package/src/site-publishing/readiness.ts +330 -0
  496. package/src/site-publishing/runtime.ts +831 -0
  497. package/src/site-publishing/service.ts +1282 -0
  498. package/src/site-publishing/session-events.ts +262 -0
  499. package/src/site-publishing/session-views.ts +262 -0
  500. package/src/site-publishing/viewer.ts +75 -0
  501. package/src/site-session-origin.ts +91 -6
  502. package/src/site-sql/format.ts +134 -0
  503. package/src/site-sql/gateway.ts +168 -0
  504. package/src/site-sql/service.ts +1636 -0
  505. package/src/site-uploads.ts +27 -5
  506. package/src/temporal-schedule-sync.ts +74 -0
  507. package/src/transcription/billing-refusal.ts +14 -0
  508. package/src/transcription/normalize.ts +77 -0
  509. package/src/transcription/providers/azure-mai.ts +98 -0
  510. package/src/transcription/providers/azure-openai.ts +16 -7
  511. package/src/transcription/providers/codex-subscription.ts +190 -67
  512. package/src/transcription/providers/openai.ts +79 -5
  513. package/src/transcription/providers/subscription-core.ts +125 -0
  514. package/src/transcription/providers/xai-subscription.ts +81 -83
  515. package/src/transcription/segmenter.ts +7 -1
  516. package/src/transcription/service.ts +239 -10
  517. package/src/transcription/wav-duration.ts +39 -0
  518. package/src/workspace-deletion.ts +25 -1
  519. package/src/workspace-tool-gateway-attestations.ts +133 -0
  520. package/src/workspace-tool-gateway-observability.ts +64 -0
  521. package/src/workspace-tool-gateway-secrets.ts +104 -0
  522. package/src/workspace-tool-gateway.ts +921 -103
  523. package/src/workspace-tool-target-fence.ts +380 -0
  524. package/src/workspace-tool-target.ts +554 -0
  525. package/src/workspace-webhook-dispatch.ts +225 -0
  526. package/src/xai-realtime.ts +85 -81
  527. package/src/xai-subscription-core.ts +172 -0
  528. package/dist/browser-auth-broker.d.ts +0 -20
  529. package/dist/chunk-AJ62T5QN.js.map +0 -1
  530. package/dist/connection-authority-owner.d.ts +0 -59
  531. package/dist/routes/connection-authorities.d.ts +0 -3
  532. package/dist/routes/environments.d.ts +0 -5
  533. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  534. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  535. package/dist/routes/packs.d.ts +0 -3
  536. package/dist/session-event-view-MU3HMNV3.js +0 -264
  537. package/dist/session-event-view-MU3HMNV3.js.map +0 -1
  538. package/dist/xai-subscription-auth.d.ts +0 -23
  539. package/src/browser-auth-broker.ts +0 -155
  540. package/src/connection-authority-owner.ts +0 -61
  541. package/src/routes/connection-authorities.ts +0 -139
  542. package/src/routes/environments.ts +0 -388
  543. package/src/routes/host-mcp-bindings.ts +0 -122
  544. package/src/routes/host-mcp-resolvers.ts +0 -41
  545. package/src/routes/packs.ts +0 -784
  546. package/src/xai-subscription-auth.ts +0 -139
@@ -15,6 +15,9 @@
15
15
  // The downsampled (~1/min) history for ONE machine over a time window.
16
16
 
17
17
  import {
18
+ ChangeMachineAudienceRequest,
19
+ MachineAudiencePreviewRequest,
20
+ OpenMachinePrivacySettingsRequest,
18
21
  MachineMetricsSeriesResponse,
19
22
  MachineOperationPolicy,
20
23
  MachinesResponse,
@@ -24,18 +27,19 @@ import {
24
27
  UpdateMachineAgentResponse,
25
28
  } from "@opengeni/contracts";
26
29
  import {
27
- advanceEnrollmentAgentUpdate,
28
- beginEnrollmentAgentUpdate,
30
+ changeMachineAudience,
29
31
  getLiveEnrollmentConnection,
30
32
  listEnrollments,
33
+ previewMachineAudienceChange,
31
34
  readMachineMetricsSeries,
32
35
  requireSession,
33
36
  updateEnrollmentOperationPolicy,
34
37
  } from "@opengeni/db";
35
- import type { Hono } from "hono";
38
+ import type { Context, Hono } from "hono";
36
39
  import { HTTPException } from "hono/http-exception";
37
40
  import {
38
41
  grantHasAgentAttemptAuthority,
42
+ mayStartOnlyMe,
39
43
  requireAccessGrant,
40
44
  requireAccessGrantAuthorization,
41
45
  requireSessionAuthorization,
@@ -44,10 +48,23 @@ import {
44
48
  } from "@opengeni/core";
45
49
  import type { ApiRouteDeps } from "@opengeni/core";
46
50
  import { buildFleetContextForSession, swapActiveSandbox } from "@opengeni/core";
51
+ import {
52
+ enableMachineScreenControl,
53
+ enrollmentAccess,
54
+ MachineNotActiveError,
55
+ openMachinePrivacySettings,
56
+ } from "../sandbox/screen-control";
47
57
  import { listMachines, metricRowToSample } from "../sandbox/machines";
58
+ import { requestAgentUpdate } from "../sandbox/agent-update";
59
+ import {
60
+ machineAudienceChangeResponse,
61
+ machineAudiencePreview,
62
+ machineAudienceRefusalError,
63
+ machineAudienceRequestFor,
64
+ } from "../sandbox/machine-audience";
48
65
  import { ensureSessionGroupReady as ensureViewerSessionGroupReady } from "../sandbox/viewer";
49
- import { ControlRequest, ErrorCode } from "@opengeni/agent-proto";
50
- import { NatsControlRpc, subjectFor } from "@opengeni/runtime/sandbox";
66
+ import { parseRequestJson } from "../http/request-body";
67
+ import { requireFullAccessIfAgent } from "../http/acting-person";
51
68
 
52
69
  // The supported series windows → milliseconds. An unknown/absent window defaults
53
70
  // to 1h (the default). Bounded so a caller cannot request an unbounded
@@ -183,6 +200,164 @@ export function registerMachineRoutes(app: Hono, deps: ApiRouteDeps): void {
183
200
  return c.json(MachineOperationPolicy.parse(updated.operationPolicy));
184
201
  });
185
202
 
203
+ // ── Who can use a machine: Workspace or Only me, changed in place ──────────
204
+ // POST .../audience/preview lists what the change would affect with the
205
+ // caller's choices applied; PUT .../audience applies it in one transaction at
206
+ // the previewed generation. The enrollment, sandbox ID, credentials and live
207
+ // connection stay, so chats, schedules and the installed agent keep working.
208
+ // A person decides this: in the app, through the API, or through an agent
209
+ // they gave their full access (admin access, a full-access connected agent),
210
+ // which acts as them. An agent acting as itself, or one with less than the
211
+ // person's full access, is refused: the change decides who else can use the
212
+ // machine.
213
+ async function requireAudienceCaller(c: Context, workspaceId: string) {
214
+ const authorization = await requireAccessGrantAuthorization(
215
+ c,
216
+ deps,
217
+ workspaceId,
218
+ "enrollments:manage",
219
+ );
220
+ const grant = authorization.grant;
221
+ assertSelfhostedEnabled();
222
+ if (grantHasAgentAttemptAuthority(grant)) {
223
+ throw new HTTPException(403, {
224
+ message:
225
+ "only a person, or an agent they gave admin access acting as them, can change who can use a machine",
226
+ });
227
+ }
228
+ requireFullAccessIfAgent(c, "Changing who can use a machine");
229
+ return grant;
230
+ }
231
+
232
+ // The new owner's Workspace schedules on the machine become Only me when
233
+ // they may have Only me schedules; otherwise they pause.
234
+ async function schedulesMayBeOnlyMe(workspaceId: string, ownerSubjectId: string | null) {
235
+ return ownerSubjectId === null
236
+ ? false
237
+ : await mayStartOnlyMe(db, settings, workspaceId, ownerSubjectId);
238
+ }
239
+
240
+ app.post("/v1/workspaces/:workspaceId/machines/:enrollmentId/audience/preview", async (c) => {
241
+ const workspaceId = c.req.param("workspaceId");
242
+ const grant = await requireAudienceCaller(c, workspaceId);
243
+ const enrollmentId = c.req.param("enrollmentId");
244
+ const body = await parseRequestJson(c, MachineAudiencePreviewRequest);
245
+ const machine = await requireScopedEnrollment(grant, enrollmentId);
246
+ const { ownerSubjectId } = machineAudienceRequestFor(grant, workspaceId, machine, body);
247
+ const preview = await previewMachineAudienceChange(db, {
248
+ accountId: grant.accountId,
249
+ workspaceId,
250
+ subjectId: grant.subjectId,
251
+ enrollmentId,
252
+ target: body.audience,
253
+ ownerSubjectId,
254
+ schedulesMayBeOnlyMe: await schedulesMayBeOnlyMe(workspaceId, ownerSubjectId),
255
+ });
256
+ if (typeof preview === "string") throw machineAudienceRefusalError(preview);
257
+ return c.json(machineAudiencePreview(preview));
258
+ });
259
+
260
+ app.put("/v1/workspaces/:workspaceId/machines/:enrollmentId/audience", async (c) => {
261
+ const workspaceId = c.req.param("workspaceId");
262
+ const grant = await requireAudienceCaller(c, workspaceId);
263
+ const enrollmentId = c.req.param("enrollmentId");
264
+ const body = await parseRequestJson(c, ChangeMachineAudienceRequest);
265
+ const machine = await requireScopedEnrollment(grant, enrollmentId);
266
+ const { ownerSubjectId } = machineAudienceRequestFor(grant, workspaceId, machine, body);
267
+ const changed = await changeMachineAudience(db, {
268
+ accountId: grant.accountId,
269
+ workspaceId,
270
+ subjectId: grant.subjectId,
271
+ enrollmentId,
272
+ target: body.audience,
273
+ ownerSubjectId,
274
+ schedulesMayBeOnlyMe: await schedulesMayBeOnlyMe(workspaceId, ownerSubjectId),
275
+ expectedGeneration: body.expectedGeneration,
276
+ });
277
+ return c.json(machineAudienceChangeResponse(changed));
278
+ });
279
+
280
+ // ── POST /workspaces/:ws/machines/:enrollmentId/screen-control ─────────────
281
+ // Turn screen control on for one connected machine, in place (see
282
+ // ../sandbox/screen-control.ts): record the consent, then have the live agent
283
+ // renew its credentials. Needs enrollments:manage, like connecting the
284
+ // machine; agents holding it call this too (or the
285
+ // connected_machine_enable_screen_control tool). No request body.
286
+ app.post("/v1/workspaces/:workspaceId/machines/:enrollmentId/screen-control", async (c) => {
287
+ const workspaceId = c.req.param("workspaceId");
288
+ const authorization = await requireAccessGrantAuthorization(
289
+ c,
290
+ deps,
291
+ workspaceId,
292
+ "enrollments:manage",
293
+ );
294
+ const grant = authorization.grant;
295
+ assertSelfhostedEnabled();
296
+ const enrollmentId = c.req.param("enrollmentId");
297
+ const enrollment = await requireScopedEnrollment(grant, enrollmentId);
298
+ if (
299
+ enrollment.scope === "organization" &&
300
+ authorization.accountGrant?.permissions.includes("account:admin") !== true
301
+ ) {
302
+ throw new HTTPException(403, { message: "missing permission: account:admin" });
303
+ }
304
+ try {
305
+ return c.json(
306
+ await enableMachineScreenControl(
307
+ { db, settings, bus, observability: deps.observability },
308
+ {
309
+ enrollment,
310
+ access: enrollmentAccess(enrollment, grant),
311
+ actor: { subjectId: grant.subjectId },
312
+ },
313
+ ),
314
+ );
315
+ } catch (error) {
316
+ if (error instanceof MachineNotActiveError) {
317
+ throw new HTTPException(404, { message: error.message });
318
+ }
319
+ throw error;
320
+ }
321
+ });
322
+
323
+ // ── POST /workspaces/:ws/machines/:enrollmentId/privacy-settings ───────────
324
+ // Open one macOS Privacy & Security pane on the connected Mac, so the person
325
+ // only flips the switch for Opengeni. Opening a pane grants nothing.
326
+ app.post("/v1/workspaces/:workspaceId/machines/:enrollmentId/privacy-settings", async (c) => {
327
+ const workspaceId = c.req.param("workspaceId");
328
+ const authorization = await requireAccessGrantAuthorization(
329
+ c,
330
+ deps,
331
+ workspaceId,
332
+ "enrollments:manage",
333
+ );
334
+ const grant = authorization.grant;
335
+ assertSelfhostedEnabled();
336
+ const enrollmentId = c.req.param("enrollmentId");
337
+ const parsed = OpenMachinePrivacySettingsRequest.safeParse(
338
+ await c.req.json().catch(() => null),
339
+ );
340
+ if (!parsed.success) {
341
+ throw new HTTPException(400, { message: "invalid privacy settings request" });
342
+ }
343
+ const enrollment = await requireScopedEnrollment(grant, enrollmentId);
344
+ if (
345
+ enrollment.scope === "organization" &&
346
+ authorization.accountGrant?.permissions.includes("account:admin") !== true
347
+ ) {
348
+ throw new HTTPException(403, { message: "missing permission: account:admin" });
349
+ }
350
+ if (enrollment.os !== "macos") {
351
+ throw new HTTPException(422, { message: "privacy settings panes exist only on macOS" });
352
+ }
353
+ return c.json(
354
+ await openMachinePrivacySettings(
355
+ { db, settings, bus, observability: deps.observability },
356
+ { enrollment, access: enrollmentAccess(enrollment, grant), pane: parsed.data.pane },
357
+ ),
358
+ );
359
+ });
360
+
186
361
  // ── POST /workspaces/:ws/machines/:enrollmentId/update ─────────────────────
187
362
  // Reserve one exact-generation operation, ask the authoritative runner to
188
363
  // drain and apply the signed promoted release, then let progress events + the
@@ -211,143 +386,22 @@ export function registerMachineRoutes(app: Hono, deps: ApiRouteDeps): void {
211
386
  visibleEnrollment.scope === "user" ? grant : originWorkspaceId,
212
387
  enrollmentId,
213
388
  );
214
- if (!live?.connectionInstanceId || !live.agentVersion) {
389
+ if (!live || live.id !== enrollmentId || live.workspaceId !== originWorkspaceId) {
215
390
  throw new HTTPException(409, {
216
391
  message: "machine has no authoritative live agent build",
217
392
  });
218
393
  }
219
- const channel = live.agentUpdateChannel ?? "stable";
220
- const targetVersion =
221
- channel === "beta"
222
- ? (settings.agentBetaVersion ?? settings.agentStableVersion)
223
- : settings.agentStableVersion;
224
- const reusableRequest =
225
- live.agentUpdate?.status === "requested" &&
226
- live.agentUpdate.targetVersion === targetVersion &&
227
- live.agentUpdate.connectionInstanceId === live.connectionInstanceId &&
228
- live.agentUpdate.connectionGeneration === live.connectionGeneration
229
- ? live.agentUpdate
230
- : null;
231
- if (
232
- !reusableRequest &&
233
- live.agentVersion === targetVersion &&
234
- live.agentUpdate?.status !== "failed"
235
- ) {
236
- throw new HTTPException(409, {
237
- message: "machine already runs the promoted version",
238
- });
239
- }
240
- const operationId = reusableRequest?.operationId ?? crypto.randomUUID();
241
- if (!reusableRequest) {
242
- const reserved = await beginEnrollmentAgentUpdate(db, {
243
- accountId: grant.accountId,
244
- workspaceId: originWorkspaceId,
245
- enrollmentId,
246
- connectionInstanceId: live.connectionInstanceId,
247
- connectionGeneration: live.connectionGeneration,
248
- operationId,
249
- targetVersion,
250
- });
251
- if (!reserved) {
252
- throw new HTTPException(409, {
253
- message: "machine update state changed; refresh and retry",
254
- });
255
- }
256
- }
257
-
258
- const rpc = new NatsControlRpc(async () => bus?.getRequestConnection() ?? null);
259
- const request: ControlRequest = {
260
- requestId: operationId,
261
- // The subject already selects the exact authoritative process instance.
262
- // `epoch` is the sandbox lease epoch, not the enrollment connection
263
- // generation, so this process-scoped operation intentionally leaves it 0.
264
- epoch: 0,
265
- resourcePolicy: undefined,
266
- op: {
267
- $case: "agentUpdateApply",
268
- agentUpdateApply: {
269
- operationId,
270
- targetVersion,
271
- channel,
272
- expectedCurrentVersion: live.agentVersion,
273
- expectedCurrentSha256: live.agentBinarySha256 ?? "",
274
- releaseBaseUrl: (settings.publicBaseUrl ?? new URL(c.req.url).origin).replace(/\/+$/, ""),
275
- },
276
- },
277
- };
278
- let response = await rpc.request(
279
- subjectFor(originWorkspaceId, enrollmentId, live.connectionInstanceId),
280
- request,
281
- { timeoutMs: 10_000 },
282
- );
283
- // The operation id is idempotent. One retry heals an ambiguous lost reply;
284
- // the agent returns the same acceptance and never starts a second update.
285
- if (response.error?.code === ErrorCode.ERROR_CODE_TIMEOUT) {
286
- response = await rpc.request(
287
- subjectFor(originWorkspaceId, enrollmentId, live.connectionInstanceId),
288
- request,
289
- { timeoutMs: 10_000 },
290
- );
291
- }
292
- if (response.error) {
293
- // A second timeout remains ambiguous: progress/Hello may still prove the
294
- // operation. Keep it requested rather than racing a false terminal failure.
295
- if (response.error.code !== ErrorCode.ERROR_CODE_TIMEOUT) {
296
- await advanceEnrollmentAgentUpdate(db, {
297
- accountId: grant.accountId,
298
- workspaceId: originWorkspaceId,
299
- enrollmentId,
300
- connectionInstanceId: live.connectionInstanceId,
301
- connectionGeneration: live.connectionGeneration,
302
- operationId,
303
- status: "failed",
304
- errorCode:
305
- response.error.detail.failure_code ??
306
- (response.error.code === ErrorCode.ERROR_CODE_AGENT_OFFLINE
307
- ? "agent_offline"
308
- : "update_dispatch_rejected"),
309
- retryable: response.error.retryable,
310
- rolledBack: false,
311
- });
312
- throw new HTTPException(response.error.retryable ? 409 : 422, {
313
- message: response.error.message,
314
- });
315
- }
316
- } else if (
317
- response.result?.$case !== "agentUpdateApply" ||
318
- !response.result.agentUpdateApply.accepted
319
- ) {
320
- await advanceEnrollmentAgentUpdate(db, {
321
- accountId: grant.accountId,
322
- workspaceId: originWorkspaceId,
323
- enrollmentId,
324
- connectionInstanceId: live.connectionInstanceId,
325
- connectionGeneration: live.connectionGeneration,
326
- operationId,
327
- status: "failed",
328
- errorCode: "invalid_agent_response",
329
- retryable: true,
330
- rolledBack: false,
331
- });
332
- throw new HTTPException(502, {
333
- message: "agent returned an invalid update response",
334
- });
335
- } else {
336
- await advanceEnrollmentAgentUpdate(db, {
337
- accountId: grant.accountId,
338
- workspaceId: originWorkspaceId,
339
- enrollmentId,
340
- connectionInstanceId: live.connectionInstanceId,
341
- connectionGeneration: live.connectionGeneration,
342
- operationId,
343
- status: "accepted",
344
- });
394
+ const result = await requestAgentUpdate({ db, bus, settings }, live, {
395
+ releaseBaseUrl: settings.publicBaseUrl ?? new URL(c.req.url).origin,
396
+ });
397
+ if (result.kind === "refused") {
398
+ throw new HTTPException(result.status, { message: result.message });
345
399
  }
346
400
  return c.json(
347
401
  UpdateMachineAgentResponse.parse({
348
- operationId,
402
+ operationId: result.operationId,
349
403
  accepted: true,
350
- targetVersion,
404
+ targetVersion: result.targetVersion,
351
405
  }),
352
406
  202,
353
407
  );
@@ -388,7 +442,7 @@ export function registerMachineRoutes(app: Hono, deps: ApiRouteDeps): void {
388
442
  throw error;
389
443
  }
390
444
  }
391
- const body = SwapActiveSandboxRequest.parse(await c.req.json());
445
+ const body = await parseRequestJson(c, SwapActiveSandboxRequest);
392
446
  const ctx = await buildFleetContextForSession(deps, {
393
447
  accountId: grant.accountId,
394
448
  workspaceId,
@@ -1,3 +1,8 @@
1
+ import {
2
+ assertManagedUserAdmission,
3
+ getManagedSession,
4
+ withManagedAuthSessionLookup,
5
+ } from "@opengeni/core";
1
6
  import { randomUUID } from "node:crypto";
2
7
  import {
3
8
  BeginManagedAuthLoginTransactionRequest,
@@ -64,7 +69,10 @@ import { sql } from "drizzle-orm";
64
69
  import type { Context, Hono } from "hono";
65
70
  import { deleteCookie, getCookie, setCookie } from "hono/cookie";
66
71
  import { HTTPException } from "hono/http-exception";
72
+ import { SIGNUP_ATTRIBUTION_AUTH_FIELD } from "../auth/signup-funnel-metrics";
67
73
  import { ApiHttpError } from "../http/api-error";
74
+ import { trustedRequestSourceRateLimitKey } from "../http/request-source";
75
+ import { ManagedAuthEmailThrottleError } from "../auth/managed-auth-rate-limits";
68
76
  import { z } from "zod";
69
77
 
70
78
  const ManagedAuthSocialStartReceipt = z
@@ -97,6 +105,11 @@ export function registerManagedAuthSessionSetRoutes(app: Hono, deps: ApiRouteDep
97
105
  app.get("/v1/auth/get-session", async (context) => {
98
106
  if (deps.settings.managedAuthSessionSetMode === "legacy") {
99
107
  if (!deps.managedAuth) throw new HTTPException(404);
108
+ if (deps.settings.allowedUserEmails !== undefined) {
109
+ const session = await getManagedSession(context, deps.managedAuth, { db: deps.db });
110
+ context.header("cache-control", "no-store");
111
+ return context.json(session ? safeBetterAuthSession(session) : null);
112
+ }
100
113
  return await deps.managedAuth.handler(context.req.raw);
101
114
  }
102
115
  context.header("cache-control", "no-store");
@@ -188,10 +201,13 @@ export function registerManagedAuthSessionSetRoutes(app: Hono, deps: ApiRouteDep
188
201
  app.post("/v1/auth/session-set/bootstrap", async (context) => {
189
202
  const body = await bodyAs(context, BootstrapManagedAuthSessionSetRequest);
190
203
  const { authority, actorEpoch } = await requireMutation(context, deps, body.expectedGeneration);
191
- const ambient = await requireAvailable(deps).managedAuth!.api.getSession({
192
- headers: context.req.raw.headers,
193
- returnHeaders: true,
194
- });
204
+ const ambient = await withManagedAuthSessionLookup(() =>
205
+ requireAvailable(deps).managedAuth!.api.getSession({
206
+ headers: context.req.raw.headers,
207
+ returnHeaders: true,
208
+ }),
209
+ );
210
+ assertManagedUserAdmission(deps.managedAuth!, ambient.response?.user);
195
211
  const authSessionId = ambient.response?.session?.id;
196
212
  if (typeof authSessionId !== "string") {
197
213
  throw managedAuthApiError(401, "managed_authentication_required");
@@ -313,7 +329,7 @@ export function registerManagedAuthSessionSetRoutes(app: Hono, deps: ApiRouteDep
313
329
  }),
314
330
  );
315
331
  } catch (error) {
316
- throwHttp(error);
332
+ throwHttp(error, context);
317
333
  }
318
334
  });
319
335
 
@@ -392,6 +408,9 @@ export function registerManagedAuthSessionSetRoutes(app: Hono, deps: ApiRouteDep
392
408
  expectedGeneration: body.expectedGeneration,
393
409
  expectedActorEpoch: actorEpoch,
394
410
  },
411
+ // Content-free acquisition metrics read this from the OAuth
412
+ // state if the callback creates a new account.
413
+ ...(body.attribution ? { [SIGNUP_ATTRIBUTION_AUTH_FIELD]: body.attribution } : {}),
395
414
  },
396
415
  },
397
416
  headers: isolatedManagedAuthHeaders(context.req.raw),
@@ -1009,11 +1028,9 @@ function digest(deps: ApiRouteDeps, value: unknown): string {
1009
1028
  }
1010
1029
 
1011
1030
  function loginTransactionClientScope(context: Context, deps: ApiRouteDeps): string {
1012
- const forwarded = context.req.header("x-forwarded-for")?.split(",")[0]?.trim();
1013
- const address = forwarded || context.req.header("x-real-ip")?.trim() || "unknown";
1014
1031
  return digest(deps, {
1015
1032
  purpose: "managed-auth-login-transaction-rate-limit",
1016
- client: address.slice(0, 128),
1033
+ client: trustedRequestSourceRateLimitKey(context, deps.settings),
1017
1034
  });
1018
1035
  }
1019
1036
 
@@ -1107,7 +1124,7 @@ function appendCookies(context: Context, cookies: readonly string[]): void {
1107
1124
  for (const cookie of cookies) context.header("set-cookie", cookie, { append: true });
1108
1125
  }
1109
1126
 
1110
- function throwHttp(error: unknown): never {
1127
+ function throwHttp(error: unknown, context?: Context): never {
1111
1128
  if (error instanceof HTTPException) throw error;
1112
1129
  if (error instanceof ManagedAuthSessionSetGenerationConflictError) {
1113
1130
  throw managedAuthApiError(409, "generation_conflict", { cause: error, retryable: true });
@@ -1127,6 +1144,16 @@ function throwHttp(error: unknown): never {
1127
1144
  if (error instanceof ManagedAuthActorMutationInFlightError) {
1128
1145
  throw managedAuthApiError(409, "actor_mutation_in_flight", { cause: error, retryable: true });
1129
1146
  }
1147
+ if (error instanceof ManagedAuthEmailThrottleError) {
1148
+ // A per-email window lasts 15 minutes to an hour; tell the client when,
1149
+ // unlike the short login-transaction backoff.
1150
+ context?.header("Retry-After", String(error.retryAfterSeconds));
1151
+ throw managedAuthApiError(429, "login_transaction_rate_limited", {
1152
+ cause: error,
1153
+ retryable: true,
1154
+ retryAfterSeconds: error.retryAfterSeconds,
1155
+ });
1156
+ }
1130
1157
  if (error instanceof ManagedAuthLoginTransactionRateLimitError) {
1131
1158
  throw managedAuthApiError(429, "login_transaction_rate_limited", {
1132
1159
  cause: error,
@@ -1153,6 +1180,7 @@ function managedAuthApiError(
1153
1180
  cause?: unknown;
1154
1181
  retryable?: boolean;
1155
1182
  outcomeUnknown?: boolean;
1183
+ retryAfterSeconds?: number;
1156
1184
  } = {},
1157
1185
  ): ApiHttpError {
1158
1186
  ManagedAuthSessionSetErrorCode.parse(code);
@@ -1177,7 +1205,12 @@ function managedAuthApiError(
1177
1205
  message: code,
1178
1206
  retryable: options.retryable ?? false,
1179
1207
  ...(options.outcomeUnknown === undefined ? {} : { outcomeUnknown: options.outcomeUnknown }),
1180
- details: { managedAuthCode: code },
1208
+ details: {
1209
+ managedAuthCode: code,
1210
+ ...(options.retryAfterSeconds === undefined
1211
+ ? {}
1212
+ : { retryAfterSeconds: options.retryAfterSeconds }),
1213
+ },
1181
1214
  });
1182
1215
  if (options.cause !== undefined) (error as Error & { cause?: unknown }).cause = options.cause;
1183
1216
  return error;
@@ -1,3 +1,4 @@
1
+ import { signupCreditModelIds } from "@opengeni/config";
1
2
  import {
2
3
  CompleteSelfServiceOrganizationSetupRequest,
3
4
  CompleteSelfServiceOrganizationSetupResponse,
@@ -15,6 +16,7 @@ import {
15
16
  nestedPostgresSqlState,
16
17
  preflightOrganizationUserSetup,
17
18
  previewOrganizationUserSetup,
19
+ recordOrganizationSignupUseCase,
18
20
  } from "@opengeni/db";
19
21
  import type { Context, Hono } from "hono";
20
22
  import { HTTPException } from "hono/http-exception";
@@ -24,7 +26,9 @@ import {
24
26
  organizationUserSetupTokenDigest,
25
27
  selfServiceOrganizationSetupRequestFingerprint,
26
28
  } from "../auth/organization-user-setup";
29
+ import { recordOrganizationSetupOutcome } from "../auth/signup-funnel-metrics";
27
30
  import { hashManagedAuthPassword } from "../auth/managed-auth";
31
+ import { trustedRequestSourceRateLimitKey } from "../http/request-source";
28
32
 
29
33
  export type ManagedOnboardingRouteOptions = {
30
34
  accountSetupLimiter?: { take(key: string): boolean };
@@ -59,6 +63,7 @@ export function registerManagedOnboardingRoutes(
59
63
  await context.req.json().catch(() => null),
60
64
  );
61
65
  if (!parsed.success) {
66
+ recordOrganizationSetupOutcome(deps.observability, "failed");
62
67
  throw new HTTPException(422, {
63
68
  message: "invalid organization setup request",
64
69
  });
@@ -69,18 +74,38 @@ export function registerManagedOnboardingRoutes(
69
74
  authUserId: session.user.id,
70
75
  organizationName,
71
76
  });
72
- return context.json(
73
- CompleteSelfServiceOrganizationSetupResponse.parse(
74
- await completeSelfServiceOrganizationSetup(deps.db, {
75
- authUserId: session.user.id,
76
- actorSubjectId: `user:${session.user.id}`,
77
- organizationName,
78
- operationId: parsed.data.operationId,
79
- requestFingerprint,
80
- }),
81
- ),
77
+ const completed = CompleteSelfServiceOrganizationSetupResponse.parse(
78
+ await completeSelfServiceOrganizationSetup(deps.db, {
79
+ authUserId: session.user.id,
80
+ actorSubjectId: `user:${session.user.id}`,
81
+ organizationName,
82
+ operationId: parsed.data.operationId,
83
+ requestFingerprint,
84
+ trialCreditModelIds: signupCreditModelIds(deps.settings),
85
+ trialCreditsEnabled:
86
+ deps.settings.productAccessMode === "managed" &&
87
+ deps.settings.verifiedSignupTrialCreditsEnabled,
88
+ }),
82
89
  );
90
+ // An idempotent replay of the same operation returns the same committed
91
+ // setup and is counted again; clients retry only on an ambiguous response.
92
+ recordOrganizationSetupOutcome(deps.observability, "created");
93
+ if (parsed.data.useCase) {
94
+ // The organization is already committed, so a failure to keep the
95
+ // signup answer must not fail its setup. The first answer wins.
96
+ await recordOrganizationSignupUseCase(deps.db, {
97
+ organizationId: completed.organizationId,
98
+ subjectId: `user:${session.user.id}`,
99
+ useCase: parsed.data.useCase,
100
+ }).catch((error: unknown) => {
101
+ console.warn("[api] could not record the signup use case", {
102
+ sqlState: nestedPostgresSqlState(error) ?? null,
103
+ });
104
+ });
105
+ }
106
+ return context.json(completed);
83
107
  } catch (error) {
108
+ recordOrganizationSetupOutcome(deps.observability, "failed");
84
109
  const sqlState = nestedPostgresSqlState(error);
85
110
  if (sqlState === "22023") {
86
111
  throw new HTTPException(422, {
@@ -105,7 +130,7 @@ export function registerManagedOnboardingRoutes(
105
130
  if (deps.settings.productAccessMode !== "managed" || !deps.managedAuth) {
106
131
  throw new HTTPException(404, { message: "account setup is unavailable" });
107
132
  }
108
- enforceAccountSetupRateLimit(context, accountSetupLimiter);
133
+ enforceAccountSetupRateLimit(context, deps, accountSetupLimiter);
109
134
  const parsed = PreviewOrganizationUserSetupRequest.safeParse(
110
135
  await context.req.json().catch(() => null),
111
136
  );
@@ -126,7 +151,7 @@ export function registerManagedOnboardingRoutes(
126
151
  if (deps.settings.productAccessMode !== "managed" || !deps.managedAuth) {
127
152
  throw new HTTPException(404, { message: "account setup is unavailable" });
128
153
  }
129
- enforceAccountSetupRateLimit(context, accountSetupLimiter);
154
+ enforceAccountSetupRateLimit(context, deps, accountSetupLimiter);
130
155
  const parsed = CompleteOrganizationUserSetupRequest.safeParse(
131
156
  await context.req.json().catch(() => null),
132
157
  );
@@ -189,11 +214,12 @@ export function registerManagedOnboardingRoutes(
189
214
 
190
215
  function enforceAccountSetupRateLimit(
191
216
  context: Context,
217
+ deps: ApiRouteDeps,
192
218
  limiter: { take(key: string): boolean },
193
219
  ): void {
194
220
  let allowed = false;
195
221
  try {
196
- allowed = limiter.take(accountSetupClientKey(context));
222
+ allowed = limiter.take(trustedRequestSourceRateLimitKey(context, deps.settings));
197
223
  } catch {
198
224
  // A public credential-setting endpoint must fail closed if its abuse gate
199
225
  // cannot make a decision.
@@ -203,12 +229,6 @@ function enforceAccountSetupRateLimit(
203
229
  }
204
230
  }
205
231
 
206
- function accountSetupClientKey(context: Context): string {
207
- const forwarded = context.req.header("x-forwarded-for")?.split(",")[0]?.trim();
208
- const address = forwarded || context.req.header("x-real-ip")?.trim() || "unknown";
209
- return address.slice(0, 128);
210
- }
211
-
212
232
  /**
213
233
  * Bounded application-tier protection for the public setup bearer endpoint.
214
234
  * The global bucket prevents spoofed/high-cardinality client keys from