@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
@@ -0,0 +1,323 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ hasOpenGeniSlackFileUploadScope,
4
+ OPENGENI_SLACK_BOT_CREDENTIAL_LABEL,
5
+ OPENGENI_SLACK_BOT_CREDENTIAL_ROLE,
6
+ type AccessGrant,
7
+ } from "@opengeni/contracts";
8
+ import {
9
+ fileOwnerContextForAgent,
10
+ hasPermission,
11
+ requireOpenGeniSlackBotConnection,
12
+ requirePermission,
13
+ type ApiRouteDeps,
14
+ } from "@opengeni/core";
15
+ import {
16
+ checkpointSlackFileUpload,
17
+ claimSlackFileUpload,
18
+ getSlackBotUserLink,
19
+ getSlackInteractionForSession,
20
+ recordAuditEvent,
21
+ releaseSlackFileUploadClaim,
22
+ renewSlackFileUploadClaim,
23
+ requireFileForSubject,
24
+ resolveSlackInstallationRoute,
25
+ resolveSlackTargetAuthority,
26
+ withSessionRlsActorContext,
27
+ type SlackInteraction,
28
+ } from "@opengeni/db";
29
+ import { HTTPException } from "hono/http-exception";
30
+ import { createOpenGeniSlackBotInteractionClient } from "./slack-bot";
31
+ import { runSlackFileUpload, SlackFileUploadClaimLostError } from "./slack-file-upload-flow";
32
+
33
+ export const SLACK_TASK_FILE_UPLOAD_MAX_BYTES = 25 * 1024 * 1024;
34
+ const CLAIM_LEASE_MS = 60_000;
35
+
36
+ /** The source and destination are canonical authorities, never a URL or channel supplied by the model. */
37
+ export async function uploadSlackTaskFile(
38
+ deps: ApiRouteDeps,
39
+ input: {
40
+ grant: AccessGrant;
41
+ sessionId: string;
42
+ fileId: string;
43
+ operationId: string;
44
+ authorize: () => Promise<void>;
45
+ },
46
+ ) {
47
+ await input.authorize();
48
+ const { grant } = input;
49
+ requirePermission(grant, "connections:read");
50
+ const actor = await fileOwnerContextForAgent(deps, grant, "files:read");
51
+ const scope = { accountId: grant.accountId, workspaceId: grant.workspaceId };
52
+ const resolveTarget = async () => {
53
+ const interaction = await getSlackInteractionForSession(deps.db, {
54
+ ...scope,
55
+ sessionId: input.sessionId,
56
+ });
57
+ if (
58
+ !interaction?.initiatingSlackUserId ||
59
+ !interaction.slackThreadTs ||
60
+ !/^\d{1,20}\.\d{1,12}$/.test(interaction.slackThreadTs)
61
+ ) {
62
+ throw new HTTPException(422, {
63
+ message: "File delivery requires this session's existing Slack task thread",
64
+ });
65
+ }
66
+ if (
67
+ interaction.visibility === "private" &&
68
+ actor.initiatingHumanSubjectId !== interaction.owningSubjectId
69
+ ) {
70
+ throw new HTTPException(403, {
71
+ message: "Private Slack file delivery requires the task owner's current attempt",
72
+ });
73
+ }
74
+ assertSlackTaskUploadTarget(interaction);
75
+ const home = await resolveSlackInstallationRoute(deps.db, interaction.slackTeamId);
76
+ if (
77
+ !home ||
78
+ home.accountId !== grant.accountId ||
79
+ home.connectionId !== interaction.connectionId
80
+ ) {
81
+ throw new HTTPException(403, { message: "Slack task installation authority changed" });
82
+ }
83
+ const link = await getSlackBotUserLink(
84
+ deps.db,
85
+ home.workspaceId,
86
+ interaction.connectionId,
87
+ interaction.initiatingSlackUserId,
88
+ );
89
+ if (!link || link.subjectId !== interaction.owningSubjectId) {
90
+ throw new HTTPException(403, { message: "Slack task requester is no longer linked" });
91
+ }
92
+ const requester = await resolveSlackTargetAuthority(deps.db, {
93
+ subjectId: link.subjectId,
94
+ targetAccountId: grant.accountId,
95
+ targetWorkspaceId: grant.workspaceId,
96
+ });
97
+ if (!requester || !slackTaskRequesterCanReceiveFile(requester.permissions)) {
98
+ throw new HTTPException(403, {
99
+ message: "Slack task requester no longer has file delivery access",
100
+ });
101
+ }
102
+ return { interaction, home };
103
+ };
104
+
105
+ return withSessionRlsActorContext(actor, async () => {
106
+ const target = await resolveTarget();
107
+ const file = await requireFileForSubject(deps.db, {
108
+ ...scope,
109
+ subjectId: grant.subjectId,
110
+ fileId: input.fileId,
111
+ });
112
+ if (file.workspaceId !== grant.workspaceId) {
113
+ throw new HTTPException(422, {
114
+ message: "Select a retained file from this Slack task's workspace",
115
+ });
116
+ }
117
+ assertSlackTaskUploadFile(file, target.interaction.visibility);
118
+ const connection = await requireOpenGeniSlackBotConnection(
119
+ deps.db,
120
+ target.home.workspaceId,
121
+ target.interaction.connectionId,
122
+ );
123
+ if (!hasOpenGeniSlackFileUploadScope(connection.grantedScopes)) {
124
+ throw new HTTPException(422, {
125
+ message:
126
+ "A Slack administrator must apply the Opengeni bot manifest and reinstall the bot to grant files:write. A personal Slack connection is not needed.",
127
+ });
128
+ }
129
+ if (!deps.objectStorage)
130
+ throw new HTTPException(503, { message: "Retained file storage is unavailable" });
131
+ let stored;
132
+ try {
133
+ stored = await deps.objectStorage.getObjectBytes(file.objectKey);
134
+ } catch {
135
+ throw new HTTPException(503, { message: "Retained file content is unavailable" });
136
+ }
137
+ if (
138
+ !stored ||
139
+ stored.bytes.byteLength !== file.sizeBytes ||
140
+ createHash("sha256").update(stored.bytes).digest("hex") !== file.sha256
141
+ ) {
142
+ throw new HTTPException(409, {
143
+ message: "Retained file content does not match its immutable identity",
144
+ });
145
+ }
146
+ const filename = file.safeFilename.slice(0, 200);
147
+ if (!filename || /[\r\n\0]/.test(filename))
148
+ throw new HTTPException(422, { message: "Invalid retained filename" });
149
+ const binding = {
150
+ ...scope,
151
+ sessionId: input.sessionId,
152
+ interactionId: target.interaction.id,
153
+ connectionId: target.interaction.connectionId,
154
+ fileId: input.fileId,
155
+ subjectId: actor.initiatingHumanSubjectId ?? grant.subjectId,
156
+ operationId: input.operationId,
157
+ requestDigest: createHash("sha256")
158
+ .update(
159
+ JSON.stringify({
160
+ fileId: file.id,
161
+ sha256: file.sha256,
162
+ sizeBytes: file.sizeBytes,
163
+ contentType: file.contentType,
164
+ filename,
165
+ channelId: target.interaction.slackChannelId,
166
+ threadTimestamp: target.interaction.slackThreadTs,
167
+ connectionId: target.interaction.connectionId,
168
+ slackTeamId: target.interaction.slackTeamId,
169
+ }),
170
+ )
171
+ .digest("hex"),
172
+ };
173
+ const claimHolderId = crypto.randomUUID();
174
+ const claim = await claimSlackFileUpload(deps.db, {
175
+ ...binding,
176
+ claimHolderId,
177
+ leaseMs: CLAIM_LEASE_MS,
178
+ });
179
+ if (claim.status === "conflict")
180
+ throw new HTTPException(409, {
181
+ message: "operationId is already bound to a different Slack file delivery",
182
+ });
183
+ if (claim.status === "busy")
184
+ throw new HTTPException(409, {
185
+ message: "Slack file delivery is already in progress; retry with the same operationId",
186
+ });
187
+ const claimScope = {
188
+ ...scope,
189
+ sessionId: input.sessionId,
190
+ operationId: input.operationId,
191
+ claimHolderId,
192
+ };
193
+ const authorizeProviderRequest = async () => {
194
+ await input.authorize();
195
+ await fileOwnerContextForAgent(deps, grant, "files:read");
196
+ const currentTarget = await resolveTarget();
197
+ if (
198
+ currentTarget.interaction.id !== target.interaction.id ||
199
+ currentTarget.interaction.connectionId !== target.interaction.connectionId ||
200
+ currentTarget.interaction.slackChannelId !== target.interaction.slackChannelId ||
201
+ currentTarget.interaction.slackThreadTs !== target.interaction.slackThreadTs ||
202
+ currentTarget.interaction.visibility !== target.interaction.visibility ||
203
+ currentTarget.home.workspaceId !== target.home.workspaceId
204
+ )
205
+ throw new HTTPException(403, { message: "Slack file delivery target changed" });
206
+ const currentFile = await requireFileForSubject(deps.db, {
207
+ ...scope,
208
+ subjectId: grant.subjectId,
209
+ fileId: file.id,
210
+ });
211
+ assertSlackTaskUploadFile(currentFile, currentTarget.interaction.visibility);
212
+ if (
213
+ currentFile.sha256 !== file.sha256 ||
214
+ currentFile.sizeBytes !== file.sizeBytes ||
215
+ currentFile.objectKey !== file.objectKey
216
+ ) {
217
+ throw new HTTPException(409, { message: "Slack file delivery source changed" });
218
+ }
219
+ if (!(await renewSlackFileUploadClaim(deps.db, { ...claimScope, leaseMs: CLAIM_LEASE_MS })))
220
+ throw new SlackFileUploadClaimLostError();
221
+ };
222
+ try {
223
+ const client = await createOpenGeniSlackBotInteractionClient(
224
+ { ...deps, authorizeProviderRequest },
225
+ {
226
+ accountId: target.home.accountId,
227
+ workspaceId: target.home.workspaceId,
228
+ connectionId: target.interaction.connectionId,
229
+ subjectId: grant.subjectId,
230
+ sessionId: input.sessionId,
231
+ },
232
+ );
233
+ const result = await runSlackFileUpload({
234
+ state: claim.operation,
235
+ provider: client,
236
+ checkpoint: (update) => checkpointSlackFileUpload(deps.db, { ...claimScope, ...update }),
237
+ channelId: target.interaction.slackChannelId,
238
+ threadTimestamp: target.interaction.slackThreadTs!,
239
+ ...(target.interaction.visibility === "private"
240
+ ? { privateRecipientSlackUserId: target.interaction.initiatingSlackUserId! }
241
+ : {}),
242
+ filename,
243
+ bytes: stored.bytes,
244
+ });
245
+ await recordAuditEvent(deps.db, {
246
+ ...scope,
247
+ subjectId: grant.subjectId,
248
+ action: "slack.file.upload",
249
+ targetType: "workspace_file",
250
+ targetId: file.id,
251
+ metadata: {
252
+ operationId: input.operationId,
253
+ sessionId: input.sessionId,
254
+ interactionId: target.interaction.id,
255
+ slackFileId: result.slackFileId,
256
+ replayed: result.replayed,
257
+ },
258
+ });
259
+ return {
260
+ status: "uploaded" as const,
261
+ fileId: file.id,
262
+ ...result,
263
+ channelId: target.interaction.slackChannelId,
264
+ threadTimestamp: target.interaction.slackThreadTs,
265
+ receipt: {
266
+ credentialRole: OPENGENI_SLACK_BOT_CREDENTIAL_ROLE,
267
+ credentialLabel: OPENGENI_SLACK_BOT_CREDENTIAL_LABEL,
268
+ connectionId: target.interaction.connectionId,
269
+ slackTeamId: target.interaction.slackTeamId,
270
+ operation: "file.upload",
271
+ operationId: input.operationId,
272
+ },
273
+ };
274
+ } finally {
275
+ if (claim.status === "claimed") await releaseSlackFileUploadClaim(deps.db, claimScope);
276
+ }
277
+ });
278
+ }
279
+
280
+ export function slackTaskRequesterCanReceiveFile(permissions: AccessGrant["permissions"]): boolean {
281
+ return hasPermission(permissions, "files:read") && hasPermission(permissions, "sessions:read");
282
+ }
283
+
284
+ /** Private shortcuts bind a runnable session before its bot-DM route commits. */
285
+ export function assertSlackTaskUploadTarget(
286
+ interaction: Pick<
287
+ SlackInteraction,
288
+ "visibility" | "slackChannelId" | "slackThreadTs" | "routeKey" | "ackSlackMessageTs"
289
+ >,
290
+ ): void {
291
+ if (
292
+ interaction.visibility === "private" &&
293
+ (!interaction.slackChannelId.startsWith("D") ||
294
+ interaction.routeKey !== `${interaction.slackChannelId}:${interaction.slackThreadTs}` ||
295
+ (interaction.ackSlackMessageTs !== null &&
296
+ interaction.ackSlackMessageTs !== interaction.slackThreadTs))
297
+ ) {
298
+ throw new HTTPException(409, {
299
+ message: "Private Slack file delivery must wait for this task's committed bot-DM thread",
300
+ });
301
+ }
302
+ }
303
+
304
+ export function assertSlackTaskUploadFile(
305
+ file: { status: string; scope?: string | undefined; sizeBytes: number; sha256: string | null },
306
+ visibility: string,
307
+ ): void {
308
+ if (file.status !== "ready" || !file.sha256 || !/^[a-f0-9]{64}$/.test(file.sha256)) {
309
+ throw new HTTPException(422, {
310
+ message: "Publish a ready, immutable file before uploading it to Slack",
311
+ });
312
+ }
313
+ if (file.scope === "personal" && visibility !== "private") {
314
+ throw new HTTPException(403, {
315
+ message: "Personal files cannot be uploaded to a shared Slack task thread",
316
+ });
317
+ }
318
+ if (file.sizeBytes < 1 || file.sizeBytes > SLACK_TASK_FILE_UPLOAD_MAX_BYTES) {
319
+ throw new HTTPException(413, {
320
+ message: "Slack task file delivery supports nonempty files up to 25 MiB",
321
+ });
322
+ }
323
+ }
@@ -0,0 +1,65 @@
1
+ import type { ToolActionReview } from "@opengeni/contracts";
2
+ import type { SlackMessageBlock } from "./slack-bot";
3
+
4
+ /** Shared review facts, projected only into a proven private bot conversation. */
5
+ export function slackToolReviewCanDecide(review: ToolActionReview): boolean {
6
+ // Delivery retries belong to the original review event. Its content must not
7
+ // change when a later decision changes status, revision or availableActions.
8
+ return (
9
+ review.detailsAvailable &&
10
+ reviewLines(review).every((line) => line.length <= 2800) &&
11
+ JSON.stringify({
12
+ title: review.title,
13
+ account: review.accountLabel,
14
+ consequence: review.consequence,
15
+ effects: review.effects,
16
+ samples: review.samples,
17
+ fields: review.fields,
18
+ moreFields: review.moreFields,
19
+ reason: review.reason,
20
+ }).length <= 6000
21
+ );
22
+ }
23
+
24
+ export function slackToolReviewBlocks(
25
+ review: ToolActionReview,
26
+ privateAudience: boolean,
27
+ ): SlackMessageBlock[] {
28
+ if (!privateAudience || !slackToolReviewCanDecide(review))
29
+ return [
30
+ {
31
+ type: "section",
32
+ text: {
33
+ type: "plain_text",
34
+ text: "An action needs review. Open the task to review its private details.",
35
+ },
36
+ },
37
+ ];
38
+ const lines = reviewLines(review);
39
+ const blocks: SlackMessageBlock[] = [];
40
+ let text = "";
41
+ for (const line of lines) {
42
+ if (text && text.length + line.length + 1 > 2800) {
43
+ blocks.push({ type: "section", text: { type: "plain_text", text } });
44
+ text = "";
45
+ }
46
+ text += `${text ? "\n" : ""}${line}`;
47
+ }
48
+ if (text) blocks.push({ type: "section", text: { type: "plain_text", text } });
49
+ return blocks;
50
+ }
51
+
52
+ function reviewLines(review: ToolActionReview): string[] {
53
+ return [
54
+ review.title,
55
+ review.accountLabel,
56
+ review.consequence,
57
+ ...review.effects,
58
+ ...(review.samples ?? []).map((sample) =>
59
+ [sample.title, sample.subtitle].filter(Boolean).join(" — "),
60
+ ),
61
+ ...review.fields.map((field) => `${field.label}: ${field.preview}`),
62
+ review.moreFields ? `${review.moreFields} more fields in full details.` : null,
63
+ review.reason,
64
+ ].filter((line): line is string => Boolean(line));
65
+ }
@@ -1,3 +1,5 @@
1
+ import { withOrganizationIntegrationAcquisition } from "@opengeni/db/organization-integration-policy";
2
+ import { claimOAuthAcquisition, finishOAuthAcquisition } from "./oauth-client";
1
3
  import { parseSocialOauthClientsJson, type Settings } from "@opengeni/config";
2
4
  import {
3
5
  OAuthStartResponse,
@@ -15,7 +17,6 @@ import {
15
17
  loadSocialConnectionCredential,
16
18
  updateSocialConnectionCredential,
17
19
  upsertSocialOAuthConnection,
18
- claimConnectOperation,
19
20
  finishConnectOperation,
20
21
  getConnectAttempt,
21
22
  type Database,
@@ -35,8 +36,10 @@ import { ApiHttpError } from "../http/api-error";
35
36
  import { requireConnectOwnerAuthority } from "./connect-authority";
36
37
  import {
37
38
  integrationBaseUrl,
39
+ oauthStateFailureReturn,
38
40
  oauthStateTtlMs,
39
41
  requireIntegrationsStateSecret,
42
+ workspaceIntegrationsPath,
40
43
  } from "./oauth-client";
41
44
 
42
45
  // Reddit requires a descriptive, stable User-Agent on every request (token
@@ -196,9 +199,12 @@ export async function startSocialOAuth(
196
199
  ): Promise<OAuthStartResponse> {
197
200
  const { settings } = deps;
198
201
  const provider = SOCIAL_OAUTH_PROVIDERS[context.payload.provider];
202
+ await withOrganizationIntegrationAcquisition(deps.db, context, [provider.id], async () => {});
199
203
  const client = socialOAuthClientFor(settings, provider.id);
200
204
  const redirectUri = socialOAuthRedirectUri(settings, context.requestUrl);
201
- const returnPath = safeReturnPath(context.payload.returnPath ?? "/integrations");
205
+ const returnPath = safeReturnPath(
206
+ context.payload.returnPath ?? workspaceIntegrationsPath(context.workspaceId),
207
+ );
202
208
  const scopes = uniqueScopes(context.payload.scopes) ?? provider.defaultScopes;
203
209
  const verifier = provider.pkce ? randomBytes(32).toString("base64url") : null;
204
210
  // Require the encryption key for every provider (not just PKCE ones) so a
@@ -258,8 +264,9 @@ export async function completeSocialOAuthCallback(
258
264
  state = readSocialOAuthState(input.state, settings);
259
265
  } catch (error) {
260
266
  logSocialOAuthFailure(observability, "state_verify", state, error);
267
+ const failure = oauthStateFailureReturn(settings, input.state);
261
268
  return {
262
- redirectTo: callbackReturnPath("/integrations", "error", { reason: "state_invalid" }),
269
+ redirectTo: callbackReturnPath(failure.returnPath, "error", { reason: failure.reason }),
263
270
  };
264
271
  }
265
272
  if (state.connectAttemptId) return completeSocialConnect(deps, state, input);
@@ -323,6 +330,7 @@ export async function completeSocialOAuthCallback(
323
330
  }
324
331
  try {
325
332
  const provider = SOCIAL_OAUTH_PROVIDERS[state.provider];
333
+ await withOrganizationIntegrationAcquisition(db, state, [provider.id], async () => {});
326
334
  const client = socialOAuthClientFor(settings, provider.id);
327
335
  const key = requireEnvironmentEncryption(settings);
328
336
  const verifier = state.encryptedPkceVerifier
@@ -344,18 +352,31 @@ export async function completeSocialOAuthCallback(
344
352
  ...(token.scope ? { scope: token.scope } : {}),
345
353
  };
346
354
  const grantedScopes = token.scope ? token.scope.split(/[\s,]+/).filter(Boolean) : state.scopes;
347
- const connection = await upsertSocialOAuthConnection(db, {
348
- accountId: state.accountId,
349
- workspaceId: state.workspaceId,
350
- subjectId: state.ownership === "personal" ? state.subjectId : null,
351
- provider: provider.id,
352
- accountHandle: identity.handle,
353
- accountName: identity.name ?? null,
354
- externalAccountId: identity.externalAccountId,
355
- scopes: grantedScopes,
356
- credentialEncrypted: encryptEnvironmentValue(key, JSON.stringify(bundle)),
357
- tokenMetadata: publicTokenMetadata(bundle),
358
- });
355
+ const acceptedState = state;
356
+ const connection = await withOrganizationIntegrationAcquisition(
357
+ db,
358
+ acceptedState,
359
+ [provider.id],
360
+ async (tx) => {
361
+ await requireConnectOwnerAuthority(
362
+ tx,
363
+ acceptedState,
364
+ acceptedState.ownership === "workspace" ? "workspace:admin" : "workspace:read",
365
+ );
366
+ return upsertSocialOAuthConnection(tx, {
367
+ accountId: acceptedState.accountId,
368
+ workspaceId: acceptedState.workspaceId,
369
+ subjectId: acceptedState.ownership === "personal" ? acceptedState.subjectId : null,
370
+ provider: provider.id,
371
+ accountHandle: identity.handle,
372
+ accountName: identity.name ?? null,
373
+ externalAccountId: identity.externalAccountId,
374
+ scopes: grantedScopes,
375
+ credentialEncrypted: encryptEnvironmentValue(key, JSON.stringify(bundle)),
376
+ tokenMetadata: publicTokenMetadata(bundle),
377
+ });
378
+ },
379
+ );
359
380
  return {
360
381
  redirectTo: callbackReturnPath(state.returnPath, "success", {
361
382
  connectionId: connection.id,
@@ -407,10 +428,16 @@ async function completeSocialConnect(
407
428
  authorize,
408
429
  };
409
430
  try {
410
- const claim = await claimConnectOperation(deps.db, state, {
411
- ...operation,
412
- expectedRevision: stored.attempt.revision,
413
- });
431
+ const claim = await claimOAuthAcquisition(
432
+ deps.db,
433
+ state,
434
+ {
435
+ ...operation,
436
+ expectedRevision: stored.attempt.revision,
437
+ },
438
+ state.provider,
439
+ Boolean(input.code && !input.error),
440
+ );
414
441
  if (claim.status === "replayed") return { redirectTo: stored.returnUrl, exactReturn: true };
415
442
  if (!personalOwnerStateAccepted(state))
416
443
  throw new HTTPException(403, { message: PERSONAL_CONNECTION_PRINCIPAL_MESSAGE });
@@ -455,46 +482,51 @@ async function completeSocialConnect(
455
482
  ...(token.expiresAt ? { expiresAt: token.expiresAt } : {}),
456
483
  ...(token.scope ? { scope: token.scope } : {}),
457
484
  };
458
- await finishConnectOperation(deps.db, state, {
459
- ...operation,
460
- commit: async (tx, current) => {
461
- const connection = await upsertSocialOAuthConnection(tx, {
462
- accountId: state.accountId,
463
- workspaceId: state.workspaceId,
464
- ...(current.account
465
- ? {
466
- expectedConnection: {
467
- id: current.account.id.slice("social:".length),
468
- version: current.account.version!,
469
- },
470
- }
471
- : {}),
472
- subjectId: state.ownership === "personal" ? state.subjectId : null,
473
- provider: provider.id,
474
- accountHandle: identity.handle,
475
- accountName: identity.name ?? null,
476
- externalAccountId: identity.externalAccountId,
477
- scopes: token.scope ? token.scope.split(/[\s,]+/).filter(Boolean) : state.scopes,
478
- credentialEncrypted: encryptEnvironmentValue(key, JSON.stringify(bundle)),
479
- tokenMetadata: publicTokenMetadata(bundle),
480
- });
481
- return {
482
- ...current,
483
- revision: current.revision + 1,
484
- state: "complete",
485
- credentialsCommitted: true,
486
- nextAction: { type: "none" },
487
- account: {
488
- id: `social:${connection.id}`,
489
- providerId: provider.id,
490
- version: connection.version!,
491
- label: identity.handle,
492
- ownership: state.ownership,
493
- status: "connected",
494
- },
495
- };
485
+ await finishOAuthAcquisition(
486
+ deps.db,
487
+ state,
488
+ {
489
+ ...operation,
490
+ commit: async (tx, current) => {
491
+ const connection = await upsertSocialOAuthConnection(tx, {
492
+ accountId: state.accountId,
493
+ workspaceId: state.workspaceId,
494
+ ...(current.account
495
+ ? {
496
+ expectedConnection: {
497
+ id: current.account.id.slice("social:".length),
498
+ version: current.account.version!,
499
+ },
500
+ }
501
+ : {}),
502
+ subjectId: state.ownership === "personal" ? state.subjectId : null,
503
+ provider: provider.id,
504
+ accountHandle: identity.handle,
505
+ accountName: identity.name ?? null,
506
+ externalAccountId: identity.externalAccountId,
507
+ scopes: token.scope ? token.scope.split(/[\s,]+/).filter(Boolean) : state.scopes,
508
+ credentialEncrypted: encryptEnvironmentValue(key, JSON.stringify(bundle)),
509
+ tokenMetadata: publicTokenMetadata(bundle),
510
+ });
511
+ return {
512
+ ...current,
513
+ revision: current.revision + 1,
514
+ state: "complete",
515
+ credentialsCommitted: true,
516
+ nextAction: { type: "none" },
517
+ account: {
518
+ id: `social:${connection.id}`,
519
+ providerId: provider.id,
520
+ version: connection.version!,
521
+ label: identity.handle,
522
+ ownership: state.ownership,
523
+ status: "connected",
524
+ },
525
+ };
526
+ },
496
527
  },
497
- });
528
+ state.provider,
529
+ );
498
530
  }
499
531
  } catch (error) {
500
532
  // An uncertain exchange stays occupied: do not replay a consumed OAuth code.