@opengeni/api-router 3.0.1 → 3.0.2-canary.38894290271001

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-AJ62T5QN.js → chunk-GBUJ2DYZ.js} +80507 -39878
  21. package/dist/chunk-GBUJ2DYZ.js.map +1 -0
  22. package/dist/chunk-OGQDXVXY.js +18 -0
  23. package/dist/chunk-OGQDXVXY.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 +150 -49
  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
@@ -1,8 +1,10 @@
1
- import type {
2
- GitHubAppRepositoryBranchPage,
3
- GitHubBindingStatus,
4
- GitHubInstallationBinding,
5
- GitHubRepository,
1
+ import {
2
+ defaultRepositoryMountPath,
3
+ type GitHubAppRepositoryBranchPage,
4
+ type GitHubBindingStatus,
5
+ type GitHubInstallationBinding,
6
+ type GitHubRepository,
7
+ type RepositoryResourceRef,
6
8
  } from "@opengeni/contracts";
7
9
  import {
8
10
  GitHubRepositoryBranchesResponse as GitHubRepositoryBranchesResponseSchema,
@@ -200,6 +202,30 @@ export async function listWorkspaceGitHubRepositories(
200
202
  });
201
203
  }
202
204
 
205
+ /**
206
+ * The exact session repository resource for one workspace GitHub App
207
+ * repository: its default branch, a canonical clone URI, and the installation
208
+ * identity that platform-brokered Git auth and create-time validation check.
209
+ */
210
+ export function githubRepositoryResourceRef(repository: GitHubRepository): RepositoryResourceRef {
211
+ const uri = normalizedRepositoryUri(repository.cloneUrl);
212
+ return {
213
+ kind: "repository",
214
+ uri,
215
+ ref: repository.defaultBranch,
216
+ provider: "github",
217
+ mountPath: defaultRepositoryMountPath(uri, "github"),
218
+ githubInstallationId: repository.installationId,
219
+ githubRepositoryId: repository.id,
220
+ };
221
+ }
222
+
223
+ function normalizedRepositoryUri(value: string): string {
224
+ const url = new URL(value);
225
+ const path = url.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
226
+ return `https://${url.host.toLowerCase()}/${path}.git`;
227
+ }
228
+
203
229
  export async function listWorkspaceGitHubRepositoryBranches(
204
230
  deps: ApiRouteDeps,
205
231
  input: {
@@ -5,7 +5,7 @@ import type { GitHubSignedStatePayload } from "@opengeni/github";
5
5
 
6
6
  /**
7
7
  * Bounded configured-token browser handoff. These signed claims preserve only
8
- * the exact OpenGeni github:manage grant across GitHub redirects; the callback
8
+ * the exact Opengeni github:manage grant across GitHub redirects; the callback
9
9
  * independently proves current GitHub personal/organization ownership. This
10
10
  * state must never be interpreted as GitHub installation authority.
11
11
  */
@@ -0,0 +1,105 @@
1
+ import { organizationAccessPresetPermissions, type Permission } from "@opengeni/contracts";
2
+ import { verifiedDelegatedHumanAuthorizationForRequest } from "@opengeni/core";
3
+ import type { Context } from "hono";
4
+ import { HTTPException } from "hono/http-exception";
5
+
6
+ /* ----------------------------------------------------------------------------
7
+ An agent acting as a person: an organization MCP action this server
8
+ dispatched in process for someone who signed the agent in, or who gave a
9
+ session admin access (see organization-mcp.ts). Routes that otherwise need
10
+ the person's browser cookie accept it, within the organization and the
11
+ access the person gave it. The person's live role is still checked by the
12
+ route, exactly as for the browser.
13
+
14
+ With the person's full access, the agent can do what the person can in that
15
+ organization, including approving agent sign-ins, managing connected agents
16
+ and giving sessions admin access. An agent with less can't do those, so it
17
+ can never widen its own access. Only Opengeni sign-in itself, sign-in
18
+ methods and recovery, and provider sign-in pages (Claude, integration
19
+ OAuth) stay in the browser. Device-code sign-in (Codex, SuperGrok) is
20
+ allowed: the agent relays the code and the person approves at the provider.
21
+ -------------------------------------------------------------------------- */
22
+
23
+ export type ActingPerson = { subjectId: string };
24
+
25
+ /** True when this request is an agent acting as a person. */
26
+ export function isAgentActingAsPerson(c: Context): boolean {
27
+ return verifiedDelegatedHumanAuthorizationForRequest(c.req.raw) !== null;
28
+ }
29
+
30
+ /**
31
+ * The person this agent acts as, for an action in `organizationId` that needs
32
+ * `permission`; null when the request is not an agent acting as a person.
33
+ * Another organization reads as not found; a permission the connection's
34
+ * access setting leaves out is refused.
35
+ */
36
+ export function agentActingAsPerson(
37
+ c: Context,
38
+ organizationId: string,
39
+ permission: Permission,
40
+ ): ActingPerson | null {
41
+ const proof = verifiedDelegatedHumanAuthorizationForRequest(c.req.raw);
42
+ if (!proof) return null;
43
+ if (proof.organizationId.toLowerCase() !== organizationId.toLowerCase()) {
44
+ throw new HTTPException(404, { message: "organization not found" });
45
+ }
46
+ if (!proof.permissions.includes(permission)) {
47
+ throw new HTTPException(403, {
48
+ message: `This connection's access doesn't include ${permission}.`,
49
+ });
50
+ }
51
+ return { subjectId: proof.subjectId };
52
+ }
53
+
54
+ /**
55
+ * The person an agent acts as, with no organization or permission check here:
56
+ * only for a route that next requires this same person's workspace grant,
57
+ * which carries the connection's organization, workspaces and access.
58
+ */
59
+ export function agentActingAsPersonBeforeGrantCheck(c: Context): ActingPerson | null {
60
+ const proof = verifiedDelegatedHumanAuthorizationForRequest(c.req.raw);
61
+ return proof ? { subjectId: proof.subjectId } : null;
62
+ }
63
+
64
+ const FULL_ACCESS = organizationAccessPresetPermissions("full");
65
+
66
+ /**
67
+ * True when this request is an agent with the person's full access: every
68
+ * permission, in every workspace. Session admin access always is; a connected
69
+ * agent is when the person chose full access for it.
70
+ */
71
+ export function isAgentWithFullAccess(c: Context): boolean {
72
+ const proof = verifiedDelegatedHumanAuthorizationForRequest(c.req.raw);
73
+ return (
74
+ proof !== null &&
75
+ proof.workspaceScope.kind === "all" &&
76
+ FULL_ACCESS.every((permission) => proof.permissions.includes(permission))
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Refuse an agent with less than the person's full access on a step that
82
+ * gives or approves access (agent sign-ins, connected agents, admin access),
83
+ * so it can never widen its own. The person and a full-access agent pass.
84
+ */
85
+ export function requireFullAccessIfAgent(c: Context, what: string): void {
86
+ if (isAgentActingAsPerson(c) && !isAgentWithFullAccess(c)) {
87
+ throw new HTTPException(403, {
88
+ message: `${what} needs full access, and this agent's access is limited. The person can do it in the Opengeni app.`,
89
+ });
90
+ }
91
+ }
92
+
93
+ /** Organization settings: reading needs account:read, changing needs account:admin. */
94
+ export function organizationSettingsPermission(c: Context): Permission {
95
+ return c.req.method === "GET" || c.req.method === "HEAD" ? "account:read" : "account:admin";
96
+ }
97
+
98
+ /** Refuse an agent on a step that only works in a browser: signing in at a provider's own page. */
99
+ export function requireNotAgent(c: Context, what: string): void {
100
+ if (isAgentActingAsPerson(c)) {
101
+ throw new HTTPException(403, {
102
+ message: `${what} has to be done by the person in the Opengeni app in a browser.`,
103
+ });
104
+ }
105
+ }
@@ -0,0 +1,49 @@
1
+ import type { MiddlewareHandler } from "hono";
2
+ import { OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION } from "@opengeni/contracts";
3
+
4
+ const BEARER_AUTHORIZATION = /^bearer\s+\S/i;
5
+
6
+ /**
7
+ * Keep published SDKs working across additive contract-revision bumps.
8
+ *
9
+ * Every `@opengeni/sdk` release up to 7.x throws `OpenGeniApiContractMismatchError`
10
+ * on ANY response whose `x-opengeni-api-contract` header differs from the
11
+ * revision it was built with, reads included. The header exists to make a
12
+ * stale first-party browser tab reload (docs/design/api-compatibility-policy.md
13
+ * (e)); a backend integration pinned to an SDK version cannot reload, so the
14
+ * next additive revision bump would break every call it makes.
15
+ *
16
+ * For a bearer-authenticated caller (API key, delegated token) that announced a
17
+ * different revision, the response therefore omits the header instead of
18
+ * advertising one the caller is known to reject. Cookie/unauthenticated
19
+ * callers (the stock web app) keep it, and so does an explicit
20
+ * `API_CONTRACT_CHANGED` refusal, so a refused client can still explain the
21
+ * mismatch. This is not an authorization boundary: routes authorize as usual.
22
+ */
23
+ export function bearerApiContractHeaderCompatibility(): MiddlewareHandler {
24
+ return async (context, next) => {
25
+ await next();
26
+ const claimed = context.req.header(OPENGENI_API_CONTRACT_HEADER);
27
+ if (claimed === undefined || claimed === OPENGENI_API_CONTRACT_REVISION) return;
28
+ if (!BEARER_AUTHORIZATION.test(context.req.header("authorization") ?? "")) return;
29
+ if (!context.res.headers.has(OPENGENI_API_CONTRACT_HEADER)) return;
30
+ if (context.res.status === 409 && (await isContractRefusal(context.res))) return;
31
+ try {
32
+ context.res.headers.delete(OPENGENI_API_CONTRACT_HEADER);
33
+ } catch {
34
+ // Immutable headers (a proxied or redirect response): copy once.
35
+ context.res = new Response(context.res.body, context.res);
36
+ context.res.headers.delete(OPENGENI_API_CONTRACT_HEADER);
37
+ }
38
+ };
39
+ }
40
+
41
+ async function isContractRefusal(response: Response): Promise<boolean> {
42
+ if (!/^application\/json/i.test(response.headers.get("content-type") ?? "")) return false;
43
+ try {
44
+ const body = (await response.clone().json()) as { code?: unknown };
45
+ return body?.code === "API_CONTRACT_CHANGED";
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
@@ -1,5 +1,17 @@
1
- import type { ErrorCode } from "@opengeni/contracts";
2
- import { WorkspaceControlBusyError } from "@opengeni/db";
1
+ import {
2
+ AgentConfigError,
3
+ AllowanceExhaustedRefusal,
4
+ ModelUnavailableError,
5
+ ScheduledTaskTargetAccessChange,
6
+ type ErrorCode,
7
+ } from "@opengeni/contracts";
8
+ import {
9
+ isDatabaseConnectionLoss,
10
+ SessionUsageLimitUnavailableError,
11
+ nestedPostgresSqlState,
12
+ WorkspaceControlBusyError,
13
+ } from "@opengeni/db";
14
+ import { SessionUsageLimitHttpError, sessionUsageLimitRefusalFromError } from "@opengeni/core";
3
15
  import type { ContentfulStatusCode } from "hono/utils/http-status";
4
16
  import { HTTPException } from "hono/http-exception";
5
17
 
@@ -28,6 +40,99 @@ export class ApiHttpError extends HTTPException {
28
40
  }
29
41
  }
30
42
 
43
+ export function scheduledTaskTargetAccessHttpError(error: unknown): ApiHttpError | null {
44
+ if (!(error instanceof HTTPException) || error.status !== 409) return null;
45
+ const result = ScheduledTaskTargetAccessChange.safeParse(error.cause);
46
+ return result.success
47
+ ? new ApiHttpError(409, {
48
+ code: "conflict",
49
+ message: error.message,
50
+ retryable: false,
51
+ outcomeUnknown: false,
52
+ details: result.data,
53
+ })
54
+ : null;
55
+ }
56
+
57
+ /** Preserve typed admission details through the common public error envelope. */
58
+ export function allowanceExhaustedHttpError(error: unknown): ApiHttpError | null {
59
+ if (!(error instanceof HTTPException) || error.status !== 402) return null;
60
+ const parsed = AllowanceExhaustedRefusal.safeParse(
61
+ error.cause && typeof error.cause === "object"
62
+ ? Object.fromEntries(Object.entries(error.cause).filter(([key]) => key !== "allowed"))
63
+ : error.cause,
64
+ );
65
+ if (!parsed.success) return null;
66
+ const { code, message, ...details } = parsed.data;
67
+ return new ApiHttpError(402, {
68
+ code,
69
+ message,
70
+ retryable: false,
71
+ outcomeUnknown: false,
72
+ details,
73
+ });
74
+ }
75
+
76
+ const SESSION_USAGE_LIMIT_ERROR_CODES: Record<SessionUsageLimitHttpError["code"], ErrorCode> = {
77
+ session_usage_limit_conflict: "conflict",
78
+ session_usage_limit_not_root: "conflict",
79
+ session_usage_limit_preparing: "conflict",
80
+ session_usage_limit_disabled: "validation_failed",
81
+ session_usage_limit_forbidden: "forbidden",
82
+ session_usage_limit_unavailable: "upstream_unavailable",
83
+ session_not_found: "not_found",
84
+ };
85
+
86
+ /**
87
+ * Per-task usage limits. A reached root limit is a non-retryable 402
88
+ * `session_usage_limit_reached` whose details carry only the public refusal
89
+ * fields; it is never `allowance_exhausted`, `payment_required` or a purchase
90
+ * prompt. Limit writes map to stable `details.code` values. Unreadable usage
91
+ * state is a retryable 503 that was not applied (never unlimited).
92
+ */
93
+ export function sessionUsageLimitHttpError(error: unknown): ApiHttpError | null {
94
+ const refusal = sessionUsageLimitRefusalFromError(error);
95
+ if (refusal) {
96
+ return new ApiHttpError(402, {
97
+ code: "session_usage_limit_reached",
98
+ message: refusal.message,
99
+ retryable: false,
100
+ outcomeUnknown: false,
101
+ details: {
102
+ basis: refusal.basis,
103
+ rootSessionId: refusal.rootSessionId,
104
+ limitMicros: refusal.limitMicros,
105
+ usedMicros: refusal.usedMicros,
106
+ },
107
+ });
108
+ }
109
+ if (error instanceof SessionUsageLimitHttpError) {
110
+ return new ApiHttpError(error.status, {
111
+ code: SESSION_USAGE_LIMIT_ERROR_CODES[error.code],
112
+ message: error.message,
113
+ retryable: error.code === "session_usage_limit_unavailable",
114
+ outcomeUnknown: false,
115
+ details: { ...error.details, code: error.code },
116
+ });
117
+ }
118
+ const unavailable =
119
+ error instanceof SessionUsageLimitUnavailableError
120
+ ? error
121
+ : error instanceof HTTPException && error.cause instanceof SessionUsageLimitUnavailableError
122
+ ? error.cause
123
+ : null;
124
+ if (unavailable) {
125
+ return new ApiHttpError(503, {
126
+ code: "upstream_unavailable",
127
+ message: "Usage for this task is temporarily unavailable. Try again shortly.",
128
+ retryable: true,
129
+ outcomeUnknown: false,
130
+ details: { code: "session_usage_limit_unavailable" },
131
+ });
132
+ }
133
+ return null;
134
+ }
135
+
31
136
  /**
32
137
  * A request-scoped session/workspace mutation could not enter the workspace
33
138
  * control prefix within its bounded wait. The transaction rolled back before
@@ -51,3 +156,106 @@ export function workspaceControlBusyHttpError(error: unknown): ApiHttpError | nu
51
156
  details: { code: busy.code, lockTimeoutMs: busy.lockTimeoutMs },
52
157
  });
53
158
  }
159
+
160
+ /** `details.code` of the retryable 503 for a request whose database connection was lost. */
161
+ export const DATABASE_UNAVAILABLE_ERROR_DETAIL_CODE = "DATABASE_UNAVAILABLE";
162
+
163
+ /**
164
+ * The request's database connection went away (an operator drain, failover,
165
+ * restart, or socket loss) rather than the statement being rejected. That is a
166
+ * brief, retryable outage, not an internal error. A read is safe to repeat. A
167
+ * mutation's outcome is unknown: the connection may have dropped after COMMIT,
168
+ * or after an earlier transaction of the same request committed, so the client
169
+ * must reconcile by its own idempotency key before resending.
170
+ */
171
+ export function databaseUnavailableHttpError(error: unknown, method: string): ApiHttpError | null {
172
+ if (error instanceof ApiHttpError) return null;
173
+ if (error instanceof HTTPException && error.status < 500) return null;
174
+ if (!isDatabaseConnectionLoss(error)) return null;
175
+ const safeMethod = method === "GET" || method === "HEAD" || method === "OPTIONS";
176
+ return new ApiHttpError(503, {
177
+ code: "upstream_unavailable",
178
+ message: "Opengeni is temporarily unavailable. Retry shortly.",
179
+ retryable: true,
180
+ outcomeUnknown: !safeMethod,
181
+ details: { code: DATABASE_UNAVAILABLE_ERROR_DETAIL_CODE },
182
+ });
183
+ }
184
+
185
+ /** `details.code` of the retryable 503 for a deadlock/serialization victim. */
186
+ export const DATABASE_CONTENTION_ERROR_DETAIL_CODE = "DATABASE_CONTENTION";
187
+
188
+ /**
189
+ * PostgreSQL aborted the request's transaction as a deadlock (40P01) or
190
+ * serialization (40001) victim after any in-process retry was exhausted. The
191
+ * aborted transaction committed nothing, so this is transient contention, not
192
+ * an internal error. A read is safe to repeat. For a mutation the default is
193
+ * `outcomeUnknown` because an earlier transaction of the same request may have
194
+ * committed; a route whose only write is the aborted idempotent transaction
195
+ * passes `outcomeUnknown: false`.
196
+ */
197
+ export function databaseContentionHttpError(
198
+ error: unknown,
199
+ method: string,
200
+ options: { outcomeUnknown?: boolean } = {},
201
+ ): ApiHttpError | null {
202
+ if (error instanceof ApiHttpError) return null;
203
+ if (error instanceof HTTPException && error.status < 500) return null;
204
+ const sqlState = nestedPostgresSqlState(error);
205
+ if (sqlState !== "40P01" && sqlState !== "40001") return null;
206
+ const safeMethod = method === "GET" || method === "HEAD" || method === "OPTIONS";
207
+ return new ApiHttpError(503, {
208
+ code: "upstream_unavailable",
209
+ message: "Opengeni hit transient database contention. Retry shortly.",
210
+ retryable: true,
211
+ outcomeUnknown: options.outcomeUnknown ?? !safeMethod,
212
+ details: { code: DATABASE_CONTENTION_ERROR_DETAIL_CODE, sqlState },
213
+ });
214
+ }
215
+
216
+ /**
217
+ * A typed agent-configuration failure (capability unavailable, conflict,
218
+ * widening, not enabled). Rendered as 422 validation_failed with the specific
219
+ * code in `details.code` so clients can branch without parsing messages.
220
+ */
221
+ export function agentConfigHttpError(error: unknown): ApiHttpError | null {
222
+ const cause =
223
+ error instanceof AgentConfigError
224
+ ? error
225
+ : error instanceof HTTPException && error.cause instanceof AgentConfigError
226
+ ? error.cause
227
+ : null;
228
+ if (!cause) return null;
229
+ return new ApiHttpError(422, {
230
+ code: "validation_failed",
231
+ message: cause.message,
232
+ retryable: false,
233
+ details: {
234
+ code: cause.code,
235
+ ...(cause.capability ? { capability: cause.capability } : {}),
236
+ },
237
+ });
238
+ }
239
+
240
+ /**
241
+ * The requested or stored model is not in the live catalog. Rendered as the
242
+ * same 422 `validation_failed` with its historical message, plus
243
+ * `details.code: "model_unavailable"` and the model id so clients can ask for
244
+ * another model rather than offer a retry that cannot succeed.
245
+ */
246
+ export function modelUnavailableHttpError(error: unknown): ApiHttpError | null {
247
+ const cause =
248
+ error instanceof ModelUnavailableError
249
+ ? error
250
+ : error instanceof HTTPException && error.cause instanceof ModelUnavailableError
251
+ ? error.cause
252
+ : null;
253
+ if (!cause) return null;
254
+ return new ApiHttpError(422, {
255
+ code: "validation_failed",
256
+ message: cause.message,
257
+ retryable: false,
258
+ outcomeUnknown: false,
259
+ details: { code: cause.code, modelId: cause.modelId },
260
+ });
261
+ }
package/src/http/auth.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { resolveFirstPartyDelegationSecret, type Settings } from "@opengeni/config";
2
2
  import { verifyDelegatedAccessToken } from "@opengeni/contracts";
3
+ import { verifiedDelegatedHumanAuthorizationForRequest } from "@opengeni/core";
3
4
  import type { Context, MiddlewareHandler } from "hono";
5
+ import { ANALYTICS_CONSENT_PATH } from "../routes/analytics-consent";
6
+ import { CLIENT_ERRORS_PATH } from "../routes/client-errors";
7
+ import { isDesktopDistributionPath } from "../routes/desktop-distribution";
4
8
  import { installExactPaths, isInstallRedirectPath } from "../routes/install";
5
9
  import {
6
10
  isMcpOAuthPublicProtocolPath,
@@ -9,6 +13,15 @@ import {
9
13
  } from "../mcp-oauth";
10
14
 
11
15
  const githubConnectPathPattern = /^\/v1\/workspaces\/[^/]+\/github\/connect$/;
16
+ // The Connected Machine agent's own protocol. A machine never holds the
17
+ // deployment key; each route authenticates its own enroll token, device code,
18
+ // or signed install-key proof, and is rate limited by its route.
19
+ const connectedMachineProtocolPaths = new Set([
20
+ "/v1/enrollments/token/exchange",
21
+ "/v1/enrollments/device/start",
22
+ "/v1/enrollments/device/poll",
23
+ "/v1/enrollments/renew",
24
+ ]);
12
25
  const githubInstallationLinkPathPattern = /^\/v1\/workspaces\/[^/]+\/github\/installations$/;
13
26
  const prReviewGithubBrowserPathPattern =
14
27
  /^\/v1\/workspaces\/[^/]+\/pr-review\/github\/(?:connect|installations\/select|installations\/[^/]+\/configure)$/;
@@ -18,7 +31,7 @@ export function requireAccessKey(settings: Settings): MiddlewareHandler {
18
31
  // §7.2 P1: requireAccessKey is the coarse NETWORK perimeter, not the
19
32
  // per-tenant identity gate (that is resolveAccessContext). When
20
33
  // `authRequired:false` it is a NO-OP — the embedded (Path 2) case where the
21
- // host's own auth is the sole human gate and OpenGeni is mounted behind it.
34
+ // host's own auth is the sole human gate and Opengeni is mounted behind it.
22
35
  // Standalone/separate deployments set `authRequired:true` to keep this ON as
23
36
  // the shared-deployment-key perimeter.
24
37
  if (!settings.authRequired || isAuthExempt(c, settings)) {
@@ -37,6 +50,11 @@ function isAuthExempt(c: Context, settings: Settings): boolean {
37
50
  if (c.req.method === "OPTIONS") {
38
51
  return true;
39
52
  }
53
+ // An organization MCP action dispatched in this process for a verified
54
+ // person. Only server code can stamp the exact Request object.
55
+ if (verifiedDelegatedHumanAuthorizationForRequest(c.req.raw)) {
56
+ return true;
57
+ }
40
58
  const path = new URL(c.req.url).pathname;
41
59
  if (settings.mcpOauthEnabled && isMcpOAuthPublicProtocolPath(path)) {
42
60
  return true;
@@ -47,6 +65,21 @@ function isAuthExempt(c: Context, settings: Settings): boolean {
47
65
  if (path === "/v1/config/client") {
48
66
  return true;
49
67
  }
68
+ // The Site gateway authenticates every site-runtime call with its own
69
+ // signature, which the routes verify before anything else.
70
+ if (path === "/v1/site-runtime" || path.startsWith("/v1/site-runtime/")) {
71
+ return true;
72
+ }
73
+ // The web error beacon must count failures before sign-in. Its payload is a
74
+ // closed, content-free report and the route bounds its own admission.
75
+ if (c.req.method === "POST" && path === CLIENT_ERRORS_PATH) {
76
+ return true;
77
+ }
78
+ // The analytics banner is answered before sign-in too. The report is one
79
+ // closed decision and the route bounds its own admission.
80
+ if (c.req.method === "POST" && path === ANALYTICS_CONSENT_PATH) {
81
+ return true;
82
+ }
50
83
  if (path === "/v1/auth" || path.startsWith("/v1/auth/")) {
51
84
  return true;
52
85
  }
@@ -117,9 +150,18 @@ function isAuthExempt(c: Context, settings: Settings): boolean {
117
150
  return true;
118
151
  }
119
152
  // The get.<domain> install-serving routes (install.sh/.ps1/uninstall.sh/
120
- // minisign pub + the release-binary redirects). Reached by a fresh machine
121
- // with no credentials; the bodies carry no secrets.
122
- if (installExactPaths.has(path) || isInstallRedirectPath(path)) {
153
+ // minisign pub + the release-binary redirects) and the desktop app downloads.
154
+ // Reached by a fresh machine with no credentials; the bodies carry no secrets.
155
+ if (
156
+ installExactPaths.has(path) ||
157
+ isInstallRedirectPath(path) ||
158
+ isDesktopDistributionPath(path)
159
+ ) {
160
+ return true;
161
+ }
162
+ // Without this a key-protected deployment could never enroll or renew a
163
+ // machine. Human approval and lookup stay behind the key.
164
+ if (c.req.method === "POST" && connectedMachineProtocolPaths.has(path)) {
123
165
  return true;
124
166
  }
125
167
  if (
@@ -163,6 +205,28 @@ async function isAuthorized(c: Context, settings: Settings): Promise<boolean> {
163
205
  );
164
206
  }
165
207
 
208
+ /**
209
+ * A request to a key-only (configured) deployment that presents the deployment
210
+ * key itself, from the operator rather than an agent acting for someone. The
211
+ * key travels in a request header that a page on another site can't add, so
212
+ * browser same-origin checks have nothing to protect on such a request.
213
+ */
214
+ export function isConfiguredDeploymentKeyRequest(c: Context, settings: Settings): boolean {
215
+ const expected = settings.accessKey;
216
+ if (settings.productAccessMode !== "configured" || !settings.authRequired || !expected) {
217
+ return false;
218
+ }
219
+ if (verifiedDelegatedHumanAuthorizationForRequest(c.req.raw) !== null) return false;
220
+ const authorization = c.req.header("authorization");
221
+ const bearer = authorization?.startsWith("Bearer ")
222
+ ? authorization.slice("Bearer ".length)
223
+ : undefined;
224
+ return (
225
+ constantTimeEqual(c.req.header("x-opengeni-access-key"), expected) ||
226
+ constantTimeEqual(bearer, expected)
227
+ );
228
+ }
229
+
166
230
  function constantTimeEqual(actual: string | undefined, expected: string): boolean {
167
231
  if (typeof actual !== "string") {
168
232
  return false;
package/src/http/cors.ts CHANGED
@@ -26,13 +26,45 @@ export function validateInteractionRequestOrigin(
26
26
  ) {
27
27
  throw new HTTPException(400, { message: "invalid request origin" });
28
28
  }
29
- if (
30
- allowedCorsOrigin(input.corsAllowOriginRegex, url.origin) ||
29
+ if (isConfiguredBrowserOrigin(url.origin, input)) {
30
+ return url.origin;
31
+ }
32
+ throw new HTTPException(403, { message: "request origin is not allowed" });
33
+ }
34
+
35
+ type BrowserOriginSettings = {
36
+ corsAllowOriginRegex: string;
37
+ publicBaseUrl?: string | undefined;
38
+ webBaseUrl?: string | undefined;
39
+ };
40
+
41
+ function isConfiguredBrowserOrigin(origin: string, input: BrowserOriginSettings): boolean {
42
+ return (
43
+ allowedCorsOrigin(input.corsAllowOriginRegex, origin) ||
31
44
  [input.publicBaseUrl, input.webBaseUrl].some((baseUrl) =>
32
- baseUrl ? new URL(baseUrl).origin === url.origin : false,
45
+ baseUrl ? new URL(baseUrl).origin === origin : false,
33
46
  )
47
+ );
48
+ }
49
+
50
+ /**
51
+ * Whether a present `Origin` header names a browser origin this deployment
52
+ * serves its web app from: the CORS allowlist, the public base URL, or the
53
+ * separate web base URL. `null` and malformed values are never allowed.
54
+ */
55
+ export function isAllowedBrowserOrigin(value: string, input: BrowserOriginSettings): boolean {
56
+ let url: URL;
57
+ try {
58
+ url = new URL(value);
59
+ } catch {
60
+ return false;
61
+ }
62
+ if (
63
+ url.origin === "null" ||
64
+ (url.protocol !== "http:" && url.protocol !== "https:") ||
65
+ url.origin !== value
34
66
  ) {
35
- return url.origin;
67
+ return false;
36
68
  }
37
- throw new HTTPException(403, { message: "request origin is not allowed" });
69
+ return isConfiguredBrowserOrigin(url.origin, input);
38
70
  }