@opengeni/api-router 3.0.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. package/dist/access-grant-rls.d.ts +8 -1
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/app.d.ts +50 -3
  4. package/dist/app.js +10 -1
  5. package/dist/artifact-catalog-cursor.d.ts +1 -0
  6. package/dist/attached-browser-viewer.d.ts +11 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
  10. package/dist/auth/managed-auth.d.ts +72 -5
  11. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  12. package/dist/auth/new-signups-gate.d.ts +23 -0
  13. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  14. package/dist/azure-live.d.ts +28 -0
  15. package/dist/browser-action-fences.d.ts +13 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-lost-runtime-end.d.ts +24 -0
  19. package/dist/browser-state-authority.d.ts +1 -27
  20. package/dist/chunk-OGQDXVXY.js +18 -0
  21. package/dist/chunk-OGQDXVXY.js.map +1 -0
  22. package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
  23. package/dist/chunk-OT56OY4V.js.map +1 -0
  24. package/dist/claude-default-models.d.ts +19 -0
  25. package/dist/claude-subscription-core.d.ts +50 -0
  26. package/dist/claude-subscription-oauth.d.ts +36 -0
  27. package/dist/claude-subscription-profile.d.ts +9 -0
  28. package/dist/claude-subscription-usage.d.ts +6 -0
  29. package/dist/claude-workspace-connection.d.ts +15 -0
  30. package/dist/codemode.d.ts +40 -5
  31. package/dist/codex-realtime.d.ts +29 -3
  32. package/dist/codex-session-pointers.d.ts +19 -0
  33. package/dist/connection-ownership.d.ts +6 -3
  34. package/dist/controller-data-plane.d.ts +16 -0
  35. package/dist/credit-promotion-snapshot.d.ts +6 -0
  36. package/dist/editable-artifact-source-session.d.ts +3 -0
  37. package/dist/editable-artifact-websocket.d.ts +5 -3
  38. package/dist/fatal-process-boundary.d.ts +9 -1
  39. package/dist/github-access.d.ts +7 -1
  40. package/dist/github-browser-flow.d.ts +1 -1
  41. package/dist/http/acting-person.d.ts +36 -0
  42. package/dist/http/api-contract-compat.d.ts +19 -0
  43. package/dist/http/api-error.d.ts +50 -1
  44. package/dist/http/auth.d.ts +8 -1
  45. package/dist/http/cors.d.ts +12 -0
  46. package/dist/http/deprecation.d.ts +42 -0
  47. package/dist/http/keyed-admission.d.ts +12 -0
  48. package/dist/http/local-browser-boundary.d.ts +72 -0
  49. package/dist/http/metrics-listener.d.ts +22 -0
  50. package/dist/http/path-identifier.d.ts +17 -0
  51. package/dist/http/registered-route-label.d.ts +16 -0
  52. package/dist/http/rejection-telemetry.d.ts +34 -0
  53. package/dist/http/request-body.d.ts +27 -0
  54. package/dist/http/request-source.d.ts +41 -3
  55. package/dist/http/sse.d.ts +12 -1
  56. package/dist/http/unmatched-route.d.ts +18 -0
  57. package/dist/http/user-content.d.ts +36 -0
  58. package/dist/http/variable-sets-removed.d.ts +41 -0
  59. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  60. package/dist/index.js +1279 -108
  61. package/dist/index.js.map +1 -1
  62. package/dist/integration-connect-metrics.d.ts +35 -0
  63. package/dist/integration-endpoint-test.d.ts +20 -0
  64. package/dist/integrations/api-integrations.d.ts +2 -2
  65. package/dist/integrations/atlassian.d.ts +8 -3
  66. package/dist/integrations/fiken.d.ts +3 -1
  67. package/dist/integrations/github-lens-connect.d.ts +37 -66
  68. package/dist/integrations/google-drive.d.ts +2 -0
  69. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  70. package/dist/integrations/marketplace-plugin.d.ts +43 -43
  71. package/dist/integrations/oauth-client.d.ts +171 -12
  72. package/dist/integrations/oauth-profiles.d.ts +42 -13
  73. package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
  74. package/dist/integrations/slack-bot.d.ts +285 -7
  75. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  76. package/dist/integrations/slack-interactions.d.ts +89 -10
  77. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  78. package/dist/integrations/slack-routing.d.ts +1 -1
  79. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  80. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  81. package/dist/integrations/slack-tool-review.d.ts +5 -0
  82. package/dist/interaction-agent-access.d.ts +13 -8
  83. package/dist/interaction-agent-version.d.ts +21 -0
  84. package/dist/interaction-holder-heartbeat.d.ts +5 -0
  85. package/dist/interaction-metrics.d.ts +27 -2
  86. package/dist/interaction-route-stages.d.ts +25 -0
  87. package/dist/interaction-secrets-vault.d.ts +20 -0
  88. package/dist/interaction-secrets.d.ts +103 -0
  89. package/dist/mcp/action-catalog-types.d.ts +14 -0
  90. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  91. package/dist/mcp/action-descriptions.d.ts +4 -0
  92. package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
  93. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  94. package/dist/mcp/child-read-evidence.d.ts +9 -0
  95. package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
  96. package/dist/mcp/contract-input.d.ts +13 -0
  97. package/dist/mcp/documents.d.ts +2 -0
  98. package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
  99. package/dist/mcp/notification-tools.d.ts +26 -0
  100. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  101. package/dist/mcp/scheduled-task-input.d.ts +1309 -0
  102. package/dist/mcp/scheduled-task-view.d.ts +217 -3
  103. package/dist/mcp/secret-tools.d.ts +14 -0
  104. package/dist/mcp/server.d.ts +108 -5
  105. package/dist/mcp/session-admin-access-tools.d.ts +33 -0
  106. package/dist/mcp/session-event-errors.d.ts +28 -0
  107. package/dist/mcp/session-event-view.d.ts +62 -0
  108. package/dist/mcp/session-view.d.ts +15 -0
  109. package/dist/mcp/session-wait.d.ts +18 -0
  110. package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
  111. package/dist/mcp/site-data-tools.d.ts +22 -0
  112. package/dist/mcp/site-publication-tools.d.ts +19 -0
  113. package/dist/mcp/site-sql-tools.d.ts +27 -0
  114. package/dist/mcp-oauth.d.ts +37 -4
  115. package/dist/model-calls/chat-completions.d.ts +87 -0
  116. package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
  117. package/dist/model-calls/service.d.ts +36 -0
  118. package/dist/model-catalog.d.ts +9 -3
  119. package/dist/native-push-dispatch.d.ts +69 -0
  120. package/dist/observability.d.ts +3 -1
  121. package/dist/organization-mcp.d.ts +82 -0
  122. package/dist/prepared-mcp-actor.d.ts +77 -0
  123. package/dist/prepared-mcp-permissions.d.ts +8 -0
  124. package/dist/routes/analytics-consent.d.ts +26 -0
  125. package/dist/routes/api-integrations.d.ts +11 -0
  126. package/dist/routes/api-keys.d.ts +7 -7
  127. package/dist/routes/automations.d.ts +2 -0
  128. package/dist/routes/billing.d.ts +59 -0
  129. package/dist/routes/browser-sessions.d.ts +65 -2
  130. package/dist/routes/chat-completions.d.ts +11 -0
  131. package/dist/routes/claude-core-usage.d.ts +20 -0
  132. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  133. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  134. package/dist/routes/client-errors.d.ts +182 -0
  135. package/dist/routes/codex-core.d.ts +401 -0
  136. package/dist/routes/codex.d.ts +64 -2
  137. package/dist/routes/computer-sessions.d.ts +6 -1
  138. package/dist/routes/desktop-distribution.d.ts +32 -0
  139. package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
  140. package/dist/routes/github-browser-pages.d.ts +27 -0
  141. package/dist/routes/inbox.d.ts +13 -0
  142. package/dist/routes/insights-response-cache.d.ts +10 -0
  143. package/dist/routes/insights-usage.d.ts +12 -0
  144. package/dist/routes/insights.d.ts +28 -0
  145. package/dist/routes/interaction-placement-message.d.ts +7 -0
  146. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  147. package/dist/routes/model-account-choice.d.ts +13 -0
  148. package/dist/routes/model-account-settings.d.ts +19 -0
  149. package/dist/routes/native-app-auth.d.ts +12 -0
  150. package/dist/routes/organization-integration-policy.d.ts +8 -0
  151. package/dist/routes/organization-integrations.d.ts +6 -0
  152. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  153. package/dist/routes/organization-model-defaults.d.ts +9 -0
  154. package/dist/routes/organization-service-accounts.d.ts +3 -0
  155. package/dist/routes/personal-api-keys.d.ts +3 -0
  156. package/dist/routes/session-admin-access.d.ts +3 -0
  157. package/dist/routes/session-artifact-associations.d.ts +4 -0
  158. package/dist/routes/session-history-imports.d.ts +20 -0
  159. package/dist/routes/sessions.d.ts +38 -2
  160. package/dist/routes/site-data.d.ts +18 -0
  161. package/dist/routes/site-publishing.d.ts +5 -0
  162. package/dist/routes/site-runtime.d.ts +31 -0
  163. package/dist/routes/site-sql.d.ts +16 -0
  164. package/dist/routes/slack-bot-access.d.ts +3 -0
  165. package/dist/routes/subscription-account-pools.d.ts +21 -0
  166. package/dist/routes/subscription-core-http.d.ts +5 -0
  167. package/dist/routes/subscription-pool-access.d.ts +37 -0
  168. package/dist/routes/subscription-pool-core.d.ts +153 -0
  169. package/dist/routes/supergrok.d.ts +6 -6
  170. package/dist/routes/usage-allowances.d.ts +12 -0
  171. package/dist/routes/variable-sets-removed.d.ts +2 -0
  172. package/dist/routes/vault-providers.d.ts +34 -0
  173. package/dist/routes/vaults.d.ts +3 -0
  174. package/dist/routes/workspace-integrations.d.ts +35 -0
  175. package/dist/routes/workspace-model-providers.d.ts +4 -0
  176. package/dist/routes/workspaces.d.ts +11 -2
  177. package/dist/sandbox/agent-update.d.ts +64 -0
  178. package/dist/sandbox/auth-callout.d.ts +8 -0
  179. package/dist/sandbox/channel-a.d.ts +15 -1
  180. package/dist/sandbox/enrollment.d.ts +26 -4
  181. package/dist/sandbox/machine-audience.d.ts +29 -0
  182. package/dist/sandbox/machines.d.ts +15 -2
  183. package/dist/sandbox/metrics-ingestion.d.ts +6 -2
  184. package/dist/sandbox/screen-control.d.ts +85 -0
  185. package/dist/sandbox/viewer.d.ts +5 -1
  186. package/dist/sandbox-file-artifacts.d.ts +17 -1
  187. package/dist/scheduled-task-blockers.d.ts +39 -0
  188. package/dist/scheduled-task-deletion.d.ts +3 -4
  189. package/dist/scheduled-task-lifecycle.d.ts +14 -0
  190. package/dist/secret-answers.d.ts +40 -0
  191. package/dist/session-create-observability.d.ts +5 -0
  192. package/dist/session-event-view-36GO3IL7.js +528 -0
  193. package/dist/session-event-view-36GO3IL7.js.map +1 -0
  194. package/dist/signed-state-secret.d.ts +18 -0
  195. package/dist/site-agent-guard.d.ts +53 -0
  196. package/dist/site-data/operations.d.ts +103 -0
  197. package/dist/site-data/service.d.ts +203 -0
  198. package/dist/site-frame-guard.d.ts +32 -0
  199. package/dist/site-publishing/agent-data-tools.d.ts +84 -0
  200. package/dist/site-publishing/agent-model.d.ts +58 -0
  201. package/dist/site-publishing/agent-session.d.ts +16 -0
  202. package/dist/site-publishing/content-scanner.d.ts +31 -0
  203. package/dist/site-publishing/edge-sync.d.ts +48 -0
  204. package/dist/site-publishing/gateway-signature.d.ts +56 -0
  205. package/dist/site-publishing/limits.d.ts +63 -0
  206. package/dist/site-publishing/page-tool-authority.d.ts +30 -0
  207. package/dist/site-publishing/platform-usage.d.ts +113 -0
  208. package/dist/site-publishing/platform.d.ts +21 -0
  209. package/dist/site-publishing/readiness.d.ts +62 -0
  210. package/dist/site-publishing/runtime.d.ts +179 -0
  211. package/dist/site-publishing/service.d.ts +264 -0
  212. package/dist/site-publishing/session-events.d.ts +22 -0
  213. package/dist/site-publishing/session-views.d.ts +36 -0
  214. package/dist/site-publishing/viewer.d.ts +40 -0
  215. package/dist/site-session-origin.d.ts +31 -6
  216. package/dist/site-sql/format.d.ts +47 -0
  217. package/dist/site-sql/gateway.d.ts +50 -0
  218. package/dist/site-sql/service.d.ts +213 -0
  219. package/dist/temporal-schedule-sync.d.ts +26 -0
  220. package/dist/transcription/billing-refusal.d.ts +8 -0
  221. package/dist/transcription/normalize.d.ts +23 -0
  222. package/dist/transcription/providers/azure-mai.d.ts +12 -0
  223. package/dist/transcription/providers/azure-openai.d.ts +4 -0
  224. package/dist/transcription/providers/openai.d.ts +16 -0
  225. package/dist/transcription/providers/subscription-core.d.ts +39 -0
  226. package/dist/transcription/service.d.ts +10 -1
  227. package/dist/transcription/wav-duration.d.ts +8 -0
  228. package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
  229. package/dist/workspace-tool-gateway-observability.d.ts +16 -0
  230. package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
  231. package/dist/workspace-tool-gateway.d.ts +102 -6
  232. package/dist/workspace-tool-target-fence.d.ts +116 -0
  233. package/dist/workspace-tool-target.d.ts +225 -0
  234. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  235. package/dist/xai-subscription-core.d.ts +60 -0
  236. package/package.json +25 -20
  237. package/src/access-grant-rls.ts +64 -14
  238. package/src/admission-trace.ts +14 -0
  239. package/src/app.ts +1684 -252
  240. package/src/artifact-catalog-cursor.ts +1 -0
  241. package/src/attached-browser-viewer.ts +26 -0
  242. package/src/auth/managed-auth-attempt-context.ts +9 -0
  243. package/src/auth/managed-auth-rate-limits.ts +252 -0
  244. package/src/auth/managed-auth-session-adapter.ts +64 -29
  245. package/src/auth/managed-auth.ts +303 -35
  246. package/src/auth/managed-email.ts +18 -1
  247. package/src/auth/managed-sign-in-notifications.ts +81 -0
  248. package/src/auth/new-signups-gate.ts +49 -0
  249. package/src/auth/organization-user-setup.ts +3 -3
  250. package/src/auth/signup-funnel-metrics.ts +164 -0
  251. package/src/azure-live.ts +103 -0
  252. package/src/browser-action-fences.ts +45 -0
  253. package/src/browser-controller-authority.ts +1 -186
  254. package/src/browser-ephemeral.ts +39 -0
  255. package/src/browser-lost-runtime-end.ts +71 -0
  256. package/src/browser-state-authority.ts +1 -236
  257. package/src/claude-default-models.ts +37 -0
  258. package/src/claude-subscription-core.ts +154 -0
  259. package/src/claude-subscription-oauth.ts +352 -0
  260. package/src/claude-subscription-profile.ts +73 -0
  261. package/src/claude-subscription-usage.ts +51 -0
  262. package/src/claude-workspace-connection.ts +82 -0
  263. package/src/codemode.ts +236 -39
  264. package/src/codex-realtime.ts +181 -53
  265. package/src/codex-session-pointers.ts +80 -0
  266. package/src/company-brain-okf.ts +1 -1
  267. package/src/connected-machine-computer-access.ts +2 -1
  268. package/src/connection-ownership.ts +19 -13
  269. package/src/controller-data-plane.ts +34 -0
  270. package/src/credit-promotion-snapshot.ts +36 -0
  271. package/src/editable-artifact-production.ts +10 -0
  272. package/src/editable-artifact-source-session.ts +123 -0
  273. package/src/editable-artifact-websocket.ts +16 -3
  274. package/src/fatal-process-boundary.ts +67 -3
  275. package/src/gateway-realtime.ts +12 -8
  276. package/src/github-access.ts +31 -5
  277. package/src/github-browser-flow.ts +1 -1
  278. package/src/http/acting-person.ts +105 -0
  279. package/src/http/api-contract-compat.ts +49 -0
  280. package/src/http/api-error.ts +210 -2
  281. package/src/http/auth.ts +68 -4
  282. package/src/http/cors.ts +37 -5
  283. package/src/http/deprecation.ts +118 -0
  284. package/src/http/keyed-admission.ts +29 -0
  285. package/src/http/local-browser-boundary.ts +343 -0
  286. package/src/http/metrics-listener.ts +57 -0
  287. package/src/http/path-identifier.ts +54 -0
  288. package/src/http/registered-route-label.ts +34 -0
  289. package/src/http/rejection-telemetry.ts +120 -0
  290. package/src/http/request-body.ts +127 -0
  291. package/src/http/request-source.ts +154 -13
  292. package/src/http/sse.ts +88 -28
  293. package/src/http/unmatched-route.ts +60 -0
  294. package/src/http/user-content.ts +158 -0
  295. package/src/http/variable-sets-removed.ts +122 -0
  296. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  297. package/src/index.ts +107 -57
  298. package/src/integration-connect-metrics.ts +228 -0
  299. package/src/integration-endpoint-test.ts +291 -0
  300. package/src/integrations/api-integrations.ts +81 -7
  301. package/src/integrations/atlassian.ts +202 -83
  302. package/src/integrations/fiken.ts +66 -38
  303. package/src/integrations/github-app-connect.ts +64 -18
  304. package/src/integrations/github-lens-connect.ts +8 -29
  305. package/src/integrations/google-drive.ts +448 -152
  306. package/src/integrations/integration-commit-authority.ts +69 -0
  307. package/src/integrations/marketplace-plugin.ts +1 -1
  308. package/src/integrations/oauth-client.ts +733 -193
  309. package/src/integrations/oauth-profiles.ts +116 -45
  310. package/src/integrations/onepassword-vault-provider.ts +16 -0
  311. package/src/integrations/personal-github-repositories.ts +1 -1
  312. package/src/integrations/personal-github.ts +61 -35
  313. package/src/integrations/provider-oauth.ts +67 -85
  314. package/src/integrations/slack-app-home.ts +5 -5
  315. package/src/integrations/slack-bot.ts +893 -201
  316. package/src/integrations/slack-file-upload-flow.ts +147 -0
  317. package/src/integrations/slack-install.ts +7 -7
  318. package/src/integrations/slack-interactions.ts +1589 -299
  319. package/src/integrations/slack-mrkdwn.ts +193 -0
  320. package/src/integrations/slack-routing.ts +2 -2
  321. package/src/integrations/slack-session-defaults.ts +224 -0
  322. package/src/integrations/slack-task-file-upload.ts +323 -0
  323. package/src/integrations/slack-tool-review.ts +65 -0
  324. package/src/integrations/social-oauth.ts +90 -58
  325. package/src/interaction-agent-access.ts +40 -20
  326. package/src/interaction-agent-version.ts +85 -0
  327. package/src/interaction-holder-heartbeat.ts +24 -8
  328. package/src/interaction-metrics.ts +164 -2
  329. package/src/interaction-route-stages.ts +94 -0
  330. package/src/interaction-secrets-vault.ts +213 -0
  331. package/src/interaction-secrets.ts +426 -0
  332. package/src/mcp/action-catalog-types.ts +14 -0
  333. package/src/mcp/action-catalog.gen.ts +8014 -0
  334. package/src/mcp/action-descriptions.ts +299 -0
  335. package/src/mcp/action-schema-imports.gen.ts +304 -0
  336. package/src/mcp/capability-account-readiness.ts +17 -0
  337. package/src/mcp/child-read-evidence.ts +19 -0
  338. package/src/mcp/company-profile-agent-admin.ts +13 -0
  339. package/src/mcp/contract-input.ts +165 -0
  340. package/src/mcp/documents.ts +9 -2
  341. package/src/mcp/editable-artifacts.ts +29 -11
  342. package/src/mcp/files.ts +5 -1
  343. package/src/mcp/first-party-tool-permissions.ts +7 -285
  344. package/src/mcp/knowledge-entries.ts +108 -34
  345. package/src/mcp/notification-tools.ts +480 -0
  346. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  347. package/src/mcp/scheduled-task-input.ts +89 -0
  348. package/src/mcp/scheduled-task-view.ts +63 -3
  349. package/src/mcp/secret-tools.ts +185 -0
  350. package/src/mcp/server.ts +2213 -1116
  351. package/src/mcp/session-admin-access-tools.ts +163 -0
  352. package/src/mcp/session-event-errors.ts +123 -0
  353. package/src/mcp/session-event-view.ts +395 -13
  354. package/src/mcp/session-view.ts +3 -0
  355. package/src/mcp/session-wait.ts +67 -7
  356. package/src/mcp/site-agent-clamp-tools.ts +140 -0
  357. package/src/mcp/site-data-tools.ts +339 -0
  358. package/src/mcp/site-publication-tools.ts +201 -0
  359. package/src/mcp/site-sql-tools.ts +427 -0
  360. package/src/mcp-oauth.ts +635 -45
  361. package/src/model-calls/chat-completions.ts +352 -0
  362. package/src/model-calls/pending-usage-settlements.ts +125 -0
  363. package/src/model-calls/service.ts +694 -0
  364. package/src/model-catalog.ts +68 -17
  365. package/src/native-push-dispatch.ts +457 -0
  366. package/src/observability.ts +15 -1
  367. package/src/organization-mcp.ts +485 -0
  368. package/src/prepared-mcp-actor.ts +154 -0
  369. package/src/prepared-mcp-permissions.ts +38 -0
  370. package/src/routes/analytics-consent.ts +123 -0
  371. package/src/routes/api-integrations.ts +268 -9
  372. package/src/routes/api-keys.ts +164 -25
  373. package/src/routes/artifact-catalog.ts +111 -0
  374. package/src/routes/automations.ts +163 -90
  375. package/src/routes/billing.ts +535 -59
  376. package/src/routes/browser-sessions.ts +966 -342
  377. package/src/routes/canonical-human-identities.ts +61 -0
  378. package/src/routes/capabilities.ts +112 -5
  379. package/src/routes/channels.ts +4 -3
  380. package/src/routes/chat-completions.ts +235 -0
  381. package/src/routes/claude-core-usage.ts +147 -0
  382. package/src/routes/claude-subscription-accounts.ts +233 -0
  383. package/src/routes/claude-subscription-oauth.ts +175 -0
  384. package/src/routes/client-errors.ts +394 -0
  385. package/src/routes/codex-core.ts +687 -0
  386. package/src/routes/codex.ts +1277 -1119
  387. package/src/routes/company-brain.ts +4 -0
  388. package/src/routes/computer-sessions.ts +319 -85
  389. package/src/routes/connect.ts +277 -175
  390. package/src/routes/connections.ts +690 -363
  391. package/src/routes/desktop-distribution.ts +217 -0
  392. package/src/routes/documents.ts +13 -7
  393. package/src/routes/editable-artifacts.ts +74 -4
  394. package/src/routes/enrollments.ts +110 -16
  395. package/src/routes/external-identity-links.ts +13 -12
  396. package/src/routes/files.ts +41 -16
  397. package/src/routes/github-browser-fonts.gen.ts +12 -0
  398. package/src/routes/github-browser-pages.ts +258 -0
  399. package/src/routes/github.ts +200 -75
  400. package/src/routes/inbox.ts +353 -0
  401. package/src/routes/insights-response-cache.ts +83 -0
  402. package/src/routes/insights-usage.ts +345 -0
  403. package/src/routes/insights.ts +103 -8
  404. package/src/routes/install.ts +51 -10
  405. package/src/routes/integration-facets.ts +70 -28
  406. package/src/routes/interaction-placement-message.ts +12 -0
  407. package/src/routes/knowledge.ts +136 -27
  408. package/src/routes/machines.ts +189 -135
  409. package/src/routes/managed-auth-session-sets.ts +43 -10
  410. package/src/routes/managed-onboarding.ts +39 -19
  411. package/src/routes/managed-sign-in-methods.ts +433 -0
  412. package/src/routes/memory-slack-publications.ts +3 -2
  413. package/src/routes/model-account-choice.ts +194 -0
  414. package/src/routes/model-account-settings.ts +235 -0
  415. package/src/routes/model-connection-access.ts +210 -48
  416. package/src/routes/native-app-auth.ts +296 -0
  417. package/src/routes/organization-integration-policy.ts +116 -0
  418. package/src/routes/organization-integrations.ts +326 -0
  419. package/src/routes/organization-mcp-connections.ts +183 -0
  420. package/src/routes/organization-memberships.ts +205 -19
  421. package/src/routes/organization-model-defaults.ts +110 -0
  422. package/src/routes/organization-model-providers.ts +74 -3
  423. package/src/routes/organization-service-accounts.ts +128 -0
  424. package/src/routes/organization-sessions.ts +21 -5
  425. package/src/routes/personal-api-keys.ts +184 -0
  426. package/src/routes/personal-github-git-broker.ts +2 -2
  427. package/src/routes/personal-github.ts +9 -4
  428. package/src/routes/plugins.ts +46 -7
  429. package/src/routes/pr-review-github.ts +105 -118
  430. package/src/routes/pr-review.ts +88 -82
  431. package/src/routes/preference-registry.ts +18 -0
  432. package/src/routes/rigs.ts +48 -13
  433. package/src/routes/scheduled-tasks.ts +347 -27
  434. package/src/routes/session-admin-access.ts +271 -0
  435. package/src/routes/session-artifact-associations.ts +164 -0
  436. package/src/routes/session-history-imports.ts +305 -0
  437. package/src/routes/sessions.ts +1682 -363
  438. package/src/routes/site-data.ts +340 -0
  439. package/src/routes/site-publishing.ts +584 -0
  440. package/src/routes/site-runtime.ts +1944 -0
  441. package/src/routes/site-sql.ts +263 -0
  442. package/src/routes/skill-content.ts +72 -7
  443. package/src/routes/skills.ts +5 -4
  444. package/src/routes/slack-bot-access.ts +108 -0
  445. package/src/routes/social.ts +27 -15
  446. package/src/routes/subscription-account-pools.ts +209 -0
  447. package/src/routes/subscription-core-http.ts +18 -0
  448. package/src/routes/subscription-pool-access.ts +180 -0
  449. package/src/routes/subscription-pool-core.ts +552 -0
  450. package/src/routes/supergrok.ts +174 -655
  451. package/src/routes/transcription-recordings.ts +71 -4
  452. package/src/routes/transcriptions.ts +26 -2
  453. package/src/routes/usage-allowances.ts +381 -0
  454. package/src/routes/variable-sets-removed.ts +19 -0
  455. package/src/routes/vault-providers.ts +782 -0
  456. package/src/routes/vaults.ts +421 -0
  457. package/src/routes/video-generation.ts +30 -12
  458. package/src/routes/workspace-artifacts.ts +165 -53
  459. package/src/routes/workspace-integrations.ts +576 -0
  460. package/src/routes/workspace-model-providers.ts +148 -0
  461. package/src/routes/workspace-state.ts +4 -0
  462. package/src/routes/workspaces.ts +625 -117
  463. package/src/sandbox/agent-update.ts +315 -0
  464. package/src/sandbox/auth-callout.ts +104 -21
  465. package/src/sandbox/channel-a.ts +165 -55
  466. package/src/sandbox/enrollment.ts +131 -22
  467. package/src/sandbox/machine-audience.ts +192 -0
  468. package/src/sandbox/machines.ts +75 -31
  469. package/src/sandbox/metrics-ingestion.ts +133 -2
  470. package/src/sandbox/rematerialize.ts +51 -21
  471. package/src/sandbox/screen-control.ts +289 -0
  472. package/src/sandbox/viewer.ts +33 -58
  473. package/src/sandbox-file-artifacts.ts +53 -27
  474. package/src/scheduled-task-blockers.ts +293 -0
  475. package/src/scheduled-task-deletion.ts +13 -3
  476. package/src/scheduled-task-lifecycle.ts +84 -0
  477. package/src/secret-answers.ts +119 -0
  478. package/src/session-create-observability.ts +46 -0
  479. package/src/session-realtime-context.ts +26 -4
  480. package/src/signed-state-secret.ts +58 -0
  481. package/src/site-agent-guard.ts +261 -0
  482. package/src/site-data/operations.ts +777 -0
  483. package/src/site-data/service.ts +1043 -0
  484. package/src/site-frame-guard.ts +107 -0
  485. package/src/site-publishing/agent-data-tools.ts +250 -0
  486. package/src/site-publishing/agent-model.ts +127 -0
  487. package/src/site-publishing/agent-session.ts +148 -0
  488. package/src/site-publishing/content-scanner.ts +93 -0
  489. package/src/site-publishing/edge-sync.ts +148 -0
  490. package/src/site-publishing/gateway-signature.ts +198 -0
  491. package/src/site-publishing/limits.ts +315 -0
  492. package/src/site-publishing/page-tool-authority.ts +111 -0
  493. package/src/site-publishing/platform-usage.ts +479 -0
  494. package/src/site-publishing/platform.ts +98 -0
  495. package/src/site-publishing/readiness.ts +330 -0
  496. package/src/site-publishing/runtime.ts +831 -0
  497. package/src/site-publishing/service.ts +1282 -0
  498. package/src/site-publishing/session-events.ts +262 -0
  499. package/src/site-publishing/session-views.ts +262 -0
  500. package/src/site-publishing/viewer.ts +75 -0
  501. package/src/site-session-origin.ts +91 -6
  502. package/src/site-sql/format.ts +134 -0
  503. package/src/site-sql/gateway.ts +168 -0
  504. package/src/site-sql/service.ts +1636 -0
  505. package/src/site-uploads.ts +27 -5
  506. package/src/temporal-schedule-sync.ts +74 -0
  507. package/src/transcription/billing-refusal.ts +14 -0
  508. package/src/transcription/normalize.ts +77 -0
  509. package/src/transcription/providers/azure-mai.ts +98 -0
  510. package/src/transcription/providers/azure-openai.ts +16 -7
  511. package/src/transcription/providers/codex-subscription.ts +190 -67
  512. package/src/transcription/providers/openai.ts +79 -5
  513. package/src/transcription/providers/subscription-core.ts +125 -0
  514. package/src/transcription/providers/xai-subscription.ts +81 -83
  515. package/src/transcription/segmenter.ts +7 -1
  516. package/src/transcription/service.ts +239 -10
  517. package/src/transcription/wav-duration.ts +39 -0
  518. package/src/workspace-deletion.ts +25 -1
  519. package/src/workspace-tool-gateway-attestations.ts +133 -0
  520. package/src/workspace-tool-gateway-observability.ts +64 -0
  521. package/src/workspace-tool-gateway-secrets.ts +104 -0
  522. package/src/workspace-tool-gateway.ts +921 -103
  523. package/src/workspace-tool-target-fence.ts +380 -0
  524. package/src/workspace-tool-target.ts +554 -0
  525. package/src/workspace-webhook-dispatch.ts +225 -0
  526. package/src/xai-realtime.ts +85 -81
  527. package/src/xai-subscription-core.ts +172 -0
  528. package/dist/browser-auth-broker.d.ts +0 -20
  529. package/dist/chunk-AJ62T5QN.js.map +0 -1
  530. package/dist/connection-authority-owner.d.ts +0 -59
  531. package/dist/routes/connection-authorities.d.ts +0 -3
  532. package/dist/routes/environments.d.ts +0 -5
  533. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  534. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  535. package/dist/routes/packs.d.ts +0 -3
  536. package/dist/session-event-view-MU3HMNV3.js +0 -264
  537. package/dist/session-event-view-MU3HMNV3.js.map +0 -1
  538. package/dist/xai-subscription-auth.d.ts +0 -23
  539. package/src/browser-auth-broker.ts +0 -155
  540. package/src/connection-authority-owner.ts +0 -61
  541. package/src/routes/connection-authorities.ts +0 -139
  542. package/src/routes/environments.ts +0 -388
  543. package/src/routes/host-mcp-bindings.ts +0 -122
  544. package/src/routes/host-mcp-resolvers.ts +0 -41
  545. package/src/routes/packs.ts +0 -784
  546. package/src/xai-subscription-auth.ts +0 -139
@@ -1,7 +1,17 @@
1
+ import {
2
+ withOrganizationIntegrationAcquisition,
3
+ withOrganizationIntegrationPolicyFence,
4
+ } from "@opengeni/db/organization-integration-policy";
5
+ import {
6
+ claimOAuthAcquisition,
7
+ finishOAuthAcquisition,
8
+ integrationSourceSelectionRequiresAcquisition,
9
+ } from "./oauth-client";
1
10
  import {
2
11
  scheduledTaskKnowledgeSource,
3
12
  requireScheduledTaskKnowledgeSource,
4
13
  knowledgeSourceAgentConfig,
14
+ assertOrganizationIntegrationAllowed,
5
15
  } from "@opengeni/contracts";
6
16
  import { createHash, randomBytes } from "node:crypto";
7
17
  import { ExternalActorContinuation } from "@opengeni/contracts/external-identities";
@@ -48,6 +58,7 @@ import {
48
58
  } from "@opengeni/contracts";
49
59
  import {
50
60
  GOOGLE_DRIVE_INTEGRATION_DEFINITION,
61
+ CORE_INTEGRATION_DEFINITIONS,
51
62
  integrationDefinitionProviderDomain,
52
63
  } from "@opengeni/capabilities";
53
64
  import {
@@ -68,10 +79,10 @@ import {
68
79
  ConnectionDisconnectGenerationError,
69
80
  ConnectionDisconnectIdempotencyError,
70
81
  consumeIntegrationOAuthStateNonce,
71
- claimConnectOperation,
72
82
  finishConnectOperation,
73
83
  getConnectAttempt,
74
84
  type Database,
85
+ listInstalledApiIntegrations,
75
86
  createConnection,
76
87
  decryptEnvironmentValue,
77
88
  disconnectConnectionIdempotently,
@@ -105,6 +116,7 @@ import {
105
116
  } from "../connection-ownership";
106
117
  import {
107
118
  integrationBaseUrl,
119
+ oauthStateFailureReturn,
108
120
  oauthStateTtlMs,
109
121
  requireIntegrationsStateSecret,
110
122
  } from "./oauth-client";
@@ -146,6 +158,8 @@ type GoogleDriveOAuthState = {
146
158
  returnPath: string;
147
159
  encryptedPkceVerifier: string;
148
160
  capability: "source_read" | "publish";
161
+ /** Server-verified Picker selection, carried only into the scope-upgrade step. */
162
+ publishingFolderId?: string;
149
163
  connectionId?: string;
150
164
  connectionVersion?: number;
151
165
  nonce: string;
@@ -254,7 +268,8 @@ export async function startGoogleDriveOAuth(
254
268
  externalContinuation?: ExternalActorContinuation;
255
269
  },
256
270
  ): Promise<GoogleDriveOAuthStartResponse> {
257
- const google = requireGoogleDriveSettings(deps.settings);
271
+ await withOrganizationIntegrationAcquisition(deps.db, input, ["google-drive"], async () => {});
272
+ requireGoogleDriveSettings(deps.settings);
258
273
  const existing = input.payload.connectionId
259
274
  ? await getConnectionMetadata(
260
275
  deps.db,
@@ -275,46 +290,64 @@ export async function startGoogleDriveOAuth(
275
290
  requireGoogleDriveConnection(existing, input.subjectId);
276
291
  }
277
292
 
278
- const key = requireEnvironmentEncryption(deps.settings);
279
- const verifier = randomBytes(48).toString("base64url");
280
- const redirectUri = requireGoogleDriveOAuthCallbackUrl(deps.settings);
281
- const state = createSignedState(requireIntegrationsStateSecret(deps.settings), {
293
+ return googleDriveOAuthAuthorization(deps.settings, {
282
294
  accountId: input.accountId,
283
295
  workspaceId: input.workspaceId,
284
296
  subjectId: input.subjectId,
285
- kind: GOOGLE_DRIVE_OAUTH_STATE_KIND,
286
297
  ...(input.connectAttemptId ? { connectAttemptId: input.connectAttemptId } : {}),
287
- ...(input.externalContinuation
298
+ ...(input.externalContinuation ? { externalContinuation: input.externalContinuation } : {}),
299
+ // The route admits only a managed human, so reaching here is the proof; the
300
+ // callback has no live principal and enforces exactly this claim.
301
+ [PERSONAL_OWNER_VERIFIED_STATE_CLAIM]: true,
302
+ returnPath: GOOGLE_DRIVE_RETURN_PATH(input.workspaceId),
303
+ capability: input.payload.capability,
304
+ ...(existing ? { connectionId: existing.id, connectionVersion: existing.version } : {}),
305
+ });
306
+ }
307
+
308
+ function googleDriveOAuthAuthorization(
309
+ settings: Settings,
310
+ authority: Omit<GoogleDriveOAuthState, "nonce" | "iat" | "encryptedPkceVerifier">,
311
+ ): GoogleDriveOAuthStartResponse {
312
+ const key = requireEnvironmentEncryption(settings);
313
+ const verifier = randomBytes(48).toString("base64url");
314
+ const { externalContinuation, ...claims } = authority;
315
+ const state = createSignedState(requireIntegrationsStateSecret(settings), {
316
+ ...claims,
317
+ kind: GOOGLE_DRIVE_OAUTH_STATE_KIND,
318
+ ...(externalContinuation
288
319
  ? {
289
320
  encryptedExternalContinuation: encryptEnvironmentValue(
290
321
  key,
291
- JSON.stringify(ExternalActorContinuation.parse(input.externalContinuation)),
322
+ JSON.stringify(ExternalActorContinuation.parse(externalContinuation)),
292
323
  ),
293
324
  }
294
325
  : {}),
295
- // The route admits only a managed human, so reaching here is the proof; the
296
- // callback has no live principal and enforces exactly this claim.
297
- [PERSONAL_OWNER_VERIFIED_STATE_CLAIM]: true,
298
- returnPath: GOOGLE_DRIVE_RETURN_PATH(input.workspaceId),
299
326
  encryptedPkceVerifier: encryptEnvironmentValue(key, verifier),
300
- capability: input.payload.capability,
301
- ...(existing ? { connectionId: existing.id, connectionVersion: existing.version } : {}),
302
327
  });
328
+ const pickingFolder = authority.capability === "publish" && !authority.publishingFolderId;
303
329
  const authorizationUrl = new URL(GOOGLE_AUTHORIZATION_URL);
304
- authorizationUrl.searchParams.set("client_id", google.clientId);
305
- authorizationUrl.searchParams.set("redirect_uri", redirectUri);
330
+ authorizationUrl.searchParams.set("client_id", requireGoogleDriveSettings(settings).clientId);
331
+ authorizationUrl.searchParams.set("redirect_uri", requireGoogleDriveOAuthCallbackUrl(settings));
306
332
  authorizationUrl.searchParams.set("response_type", "code");
307
333
  authorizationUrl.searchParams.set(
308
334
  "scope",
309
- input.payload.capability === "publish" ? GOOGLE_DRIVE_FILE_SCOPE : GOOGLE_DRIVE_READONLY_SCOPE,
335
+ pickingFolder
336
+ ? GOOGLE_DRIVE_FILE_SCOPE
337
+ : authority.capability === "publish"
338
+ ? `${GOOGLE_DRIVE_READONLY_SCOPE} ${GOOGLE_DRIVE_FILE_SCOPE}`
339
+ : GOOGLE_DRIVE_READONLY_SCOPE,
310
340
  );
311
341
  authorizationUrl.searchParams.set("access_type", "offline");
312
- authorizationUrl.searchParams.set("include_granted_scopes", "true");
342
+ // Google's OAuth-integrated Picker permits drive.file alone. Incremental
343
+ // authorization would import existing Drive/Gmail grants and reject it with
344
+ // invalid_scope. Merge grants only in a separate ordinary OAuth request.
345
+ authorizationUrl.searchParams.set("include_granted_scopes", pickingFolder ? "false" : "true");
313
346
  authorizationUrl.searchParams.set(
314
347
  "prompt",
315
- input.payload.capability === "publish" ? "consent" : "consent select_account",
348
+ authority.capability === "publish" ? "consent" : "consent select_account",
316
349
  );
317
- if (input.payload.capability === "publish") {
350
+ if (pickingFolder) {
318
351
  authorizationUrl.searchParams.set("trigger_onepick", "true");
319
352
  authorizationUrl.searchParams.set("allow_folder_selection", "true");
320
353
  authorizationUrl.searchParams.set("allow_multiple", "false");
@@ -348,6 +381,8 @@ export async function completeGoogleDriveOAuthCallback(
348
381
  let state: GoogleDriveOAuthState | null = null;
349
382
  let exactReturnUrl: string | undefined;
350
383
  let operation: { attemptId: string; operationId: string; inputDigest: string } | undefined;
384
+ let operationClaimed = false;
385
+ let operationSettlementStarted = false;
351
386
  try {
352
387
  state = readGoogleDriveOAuthState(input.state, deps.settings);
353
388
  if (state.connectAttemptId) {
@@ -364,13 +399,32 @@ export async function completeGoogleDriveOAuthCallback(
364
399
  operationId: `oauth:${state.nonce}`,
365
400
  inputDigest: createHash("sha256").update(input.state!).digest("hex"),
366
401
  };
367
- const claim = await claimConnectOperation(deps.db, state, {
368
- ...operation,
369
- expectedRevision: stored.attempt.revision,
370
- authorize: (tx, _attempt, origin) =>
371
- requireConnectOwnerAuthority(tx, state!, "connections:write", origin),
372
- });
373
- if (claim.status === "replayed") return { redirectTo: exactReturnUrl, exactReturn: true };
402
+ const claim = await claimOAuthAcquisition(
403
+ deps.db,
404
+ state,
405
+ {
406
+ ...operation,
407
+ expectedRevision: stored.attempt.revision,
408
+ authorize: (tx, _attempt, origin) =>
409
+ requireConnectOwnerAuthority(tx, state!, "connections:write", origin),
410
+ },
411
+ "google-drive",
412
+ Boolean(input.code && !input.error),
413
+ );
414
+ if (claim.status === "replayed") {
415
+ // A first-stage receipt retains its continuation even after final
416
+ // completion or cancellation. Reopen only the still-current action.
417
+ const latest = await getConnectAttempt(deps.db, state, state.connectAttemptId);
418
+ if (
419
+ claim.attempt.nextAction.type === "authorize" &&
420
+ latest.attempt.nextAction.type === "authorize" &&
421
+ latest.attempt.nextAction.url === claim.attempt.nextAction.url
422
+ ) {
423
+ return { redirectTo: claim.attempt.nextAction.url };
424
+ }
425
+ return { redirectTo: exactReturnUrl, exactReturn: true };
426
+ }
427
+ operationClaimed = true;
374
428
  }
375
429
  await requireGoogleDriveCallbackGrant(deps, state);
376
430
  const consumed = await consumeIntegrationOAuthStateNonce(deps.db, {
@@ -382,9 +436,10 @@ export async function completeGoogleDriveOAuthCallback(
382
436
  now: new Date(),
383
437
  });
384
438
  if (!consumed) {
385
- throw new HTTPException(400, { message: "Google Drive OAuth state has already been used" });
439
+ throw new GoogleDriveCallbackError("state_replayed");
386
440
  }
387
441
  if (operation && (input.error || !input.code)) {
442
+ operationSettlementStarted = true;
388
443
  await finishConnectOperation(deps.db, state, {
389
444
  ...operation,
390
445
  authorize: (tx, _attempt, origin) =>
@@ -409,6 +464,7 @@ export async function completeGoogleDriveOAuthCallback(
409
464
  if (!input.code) {
410
465
  throw new GoogleDriveCallbackError("missing_code");
411
466
  }
467
+ await withOrganizationIntegrationAcquisition(deps.db, state, ["google-drive"], async () => {});
412
468
 
413
469
  const google = requireGoogleDriveSettings(deps.settings);
414
470
  const key = requireEnvironmentEncryption(deps.settings);
@@ -431,8 +487,7 @@ export async function completeGoogleDriveOAuthCallback(
431
487
  if (
432
488
  !scopeDecision.accessMode ||
433
489
  !scopeDecision.capabilities.includes(requiredCapability) ||
434
- (state.capability === "publish" &&
435
- !scopeDecision.capabilities.includes("recursive_source_sync"))
490
+ (state.publishingFolderId && !scopeDecision.capabilities.includes("recursive_source_sync"))
436
491
  ) {
437
492
  throw new GoogleDriveCallbackError("scope_not_granted");
438
493
  }
@@ -461,12 +516,43 @@ export async function completeGoogleDriveOAuthCallback(
461
516
  state.capability === "publish"
462
517
  ? await verifyPickedGoogleDriveOutputDestination(
463
518
  token.accessToken,
464
- input.pickedFileIds,
519
+ state.publishingFolderId ?? input.pickedFileIds,
465
520
  fetchImpl,
466
521
  )
467
522
  : previousMetadata?.outputDestination;
468
523
  if (state.capability === "publish") {
469
524
  if (!existing) throw new GoogleDriveCallbackError("connection_conflict");
525
+ if (!state.publishingFolderId) {
526
+ // The file-only Picker credential must never replace the existing
527
+ // recursive-read credential. Carry only its verified folder into a
528
+ // fresh, single-use PKCE flow that obtains both capabilities.
529
+ const { nonce: _nonce, iat: _iat, encryptedPkceVerifier: _verifier, ...authority } = state;
530
+ const continuation = googleDriveOAuthAuthorization(deps.settings, {
531
+ ...authority,
532
+ publishingFolderId: outputDestination!.folderId,
533
+ });
534
+ if (operation) {
535
+ const acceptedState = state;
536
+ operationSettlementStarted = true;
537
+ await finishOAuthAcquisition(
538
+ deps.db,
539
+ acceptedState,
540
+ {
541
+ ...operation,
542
+ authorize: (tx, _attempt, origin) =>
543
+ requireConnectOwnerAuthority(tx, acceptedState, "connections:write", origin),
544
+ commit: async (_tx, current) => ({
545
+ ...current,
546
+ revision: current.revision + 1,
547
+ state: "requires_user_action",
548
+ nextAction: { type: "authorize", url: continuation.authorizationUrl },
549
+ }),
550
+ },
551
+ "google-drive",
552
+ );
553
+ }
554
+ return { redirectTo: continuation.authorizationUrl };
555
+ }
470
556
  }
471
557
  let refreshToken = token.refreshToken;
472
558
  if (!refreshToken && existing) {
@@ -562,36 +648,47 @@ export async function completeGoogleDriveOAuthCallback(
562
648
  });
563
649
  };
564
650
  if (operation) {
565
- await finishConnectOperation(deps.db, acceptedState, {
566
- ...operation,
567
- authorize: (tx, _attempt, origin) =>
568
- requireConnectOwnerAuthority(tx, acceptedState, "connections:write", origin),
569
- commit: async (tx, current) => {
570
- const connection = await persist(tx);
571
- if (!connection) throw new GoogleDriveCallbackError("connection_conflict");
572
- return {
573
- ...current,
574
- revision: current.revision + 1,
575
- state: "complete",
576
- credentialsCommitted: true,
577
- nextAction: { type: "none" },
578
- account: {
579
- id: connection.id,
580
- version: connection.version,
581
- providerId: current.providerId,
582
- label: identity.emailAddress ?? identity.displayName,
583
- ownership: "personal",
584
- status: "connected",
585
- },
586
- };
651
+ operationSettlementStarted = true;
652
+ await finishOAuthAcquisition(
653
+ deps.db,
654
+ acceptedState,
655
+ {
656
+ ...operation,
657
+ authorize: (tx, _attempt, origin) =>
658
+ requireConnectOwnerAuthority(tx, acceptedState, "connections:write", origin),
659
+ commit: async (tx, current) => {
660
+ const connection = await persist(tx);
661
+ if (!connection) throw new GoogleDriveCallbackError("connection_conflict");
662
+ return {
663
+ ...current,
664
+ revision: current.revision + 1,
665
+ state: "complete",
666
+ credentialsCommitted: true,
667
+ nextAction: { type: "none" },
668
+ account: {
669
+ id: connection.id,
670
+ version: connection.version,
671
+ providerId: current.providerId,
672
+ label: identity.emailAddress ?? identity.displayName,
673
+ ownership: "personal",
674
+ status: "connected",
675
+ },
676
+ };
677
+ },
587
678
  },
588
- });
679
+ "google-drive",
680
+ );
589
681
  return { redirectTo: exactReturnUrl!, exactReturn: true };
590
682
  }
591
- const connection = await deps.db.transaction(async (tx) => {
592
- await requireGoogleDriveCallbackGrant({ ...deps, db: tx }, acceptedState);
593
- return persist(tx);
594
- });
683
+ const connection = await withOrganizationIntegrationAcquisition(
684
+ deps.db,
685
+ acceptedState,
686
+ ["google-drive"],
687
+ async (tx) => {
688
+ await requireGoogleDriveCallbackGrant({ ...deps, db: tx }, acceptedState);
689
+ return persist(tx);
690
+ },
691
+ );
595
692
  if (!connection) {
596
693
  throw new GoogleDriveCallbackError("connection_conflict");
597
694
  }
@@ -599,13 +696,60 @@ export async function completeGoogleDriveOAuthCallback(
599
696
  redirectTo: googleDriveReturnUrl(returnBaseUrl, state.returnPath, "connected", connection.id),
600
697
  };
601
698
  } catch (error) {
699
+ if (
700
+ state &&
701
+ operation &&
702
+ operationClaimed &&
703
+ !operationSettlementStarted &&
704
+ error instanceof GoogleDriveCallbackError &&
705
+ [
706
+ "state_replayed",
707
+ "scope_not_granted",
708
+ "connection_conflict",
709
+ "account_mismatch",
710
+ "output_folder_required",
711
+ "output_folder_unavailable",
712
+ "refresh_token_missing",
713
+ "identity_verification_failed",
714
+ ].includes(error.reason)
715
+ ) {
716
+ // A definite validation rejection before persistence has no connection
717
+ // effect. Record a terminal receipt so polling and replay can finish.
718
+ // Transport failures and errors after settlement starts remain fenced:
719
+ // their outcome may be unknown, so never overwrite or retry them here.
720
+ const acceptedState = state;
721
+ try {
722
+ await finishConnectOperation(deps.db, acceptedState, {
723
+ ...operation,
724
+ authorize: (tx, _attempt, origin) =>
725
+ requireConnectOwnerAuthority(tx, acceptedState, "connections:write", origin),
726
+ commit: async (_tx, current) => ({
727
+ ...current,
728
+ revision: current.revision + 1,
729
+ state: "failed",
730
+ nextAction: { type: "none" },
731
+ error: {
732
+ code: error.reason,
733
+ message: "Authorization was not completed. Start a new connection attempt.",
734
+ retryable: false,
735
+ },
736
+ }),
737
+ });
738
+ } catch {
739
+ // Revoked authority or unavailable storage cannot authorize settlement.
740
+ // Preserve the claim rather than manufacture a terminal outcome.
741
+ }
742
+ }
602
743
  if (exactReturnUrl) return { redirectTo: exactReturnUrl, exactReturn: true };
744
+ // Reading the state is the first step, so no state means the link itself
745
+ // was unusable: say whether it expired rather than blame configuration.
746
+ const failure = state ? null : oauthStateFailureReturn(deps.settings, input.state);
603
747
  return {
604
748
  redirectTo: googleDriveReturnUrl(
605
749
  returnBaseUrl,
606
- state?.returnPath ?? "/integrations",
750
+ state?.returnPath ?? failure!.returnPath,
607
751
  "error",
608
- googleDriveErrorReason(error),
752
+ failure?.reason ?? googleDriveErrorReason(error),
609
753
  ),
610
754
  };
611
755
  }
@@ -682,19 +826,45 @@ export async function transitionGoogleDriveLifecycle(
682
826
  );
683
827
  }
684
828
 
685
- const updated = await transitionConnectionState(deps.db, {
686
- workspaceId: input.workspaceId,
687
- connectionId: existing.id,
688
- visibleToSubjectId: input.subjectId,
689
- expectedVersion: existing.version,
690
- status: "active",
691
- metadata: GoogleDriveConnectionMetadata.parse({
692
- ...metadata,
693
- lifecycle: googleDriveLifecycle(targetState),
694
- }),
695
- lastError: null,
696
- updatedBySubjectId: input.subjectId,
697
- });
829
+ const persist = (tx: Database) =>
830
+ transitionConnectionState(tx, {
831
+ workspaceId: input.workspaceId,
832
+ connectionId: existing.id,
833
+ visibleToSubjectId: input.subjectId,
834
+ expectedVersion: existing.version,
835
+ status: "active",
836
+ metadata: GoogleDriveConnectionMetadata.parse({
837
+ ...metadata,
838
+ lifecycle: googleDriveLifecycle(targetState),
839
+ }),
840
+ lastError: null,
841
+ updatedBySubjectId: input.subjectId,
842
+ });
843
+ const updated =
844
+ input.payload.action === "resume"
845
+ ? await withOrganizationIntegrationPolicyFence(
846
+ deps.db,
847
+ { accountId: existing.accountId, workspaceId: input.workspaceId },
848
+ async (tx, policy) => {
849
+ const current = await getConnectionMetadata(
850
+ tx,
851
+ input.workspaceId,
852
+ input.connectionId,
853
+ input.subjectId,
854
+ );
855
+ if (
856
+ current?.status === "active" &&
857
+ effectiveGoogleDriveLifecycle(
858
+ current,
859
+ requireGoogleDriveConnection(current, input.subjectId),
860
+ ).state === "active"
861
+ )
862
+ return current;
863
+ assertOrganizationIntegrationAllowed(policy, "google-drive");
864
+ return persist(tx);
865
+ },
866
+ )
867
+ : await persist(deps.db);
698
868
  if (!updated) {
699
869
  const converged = await getConnectionMetadata(
700
870
  deps.db,
@@ -972,58 +1142,141 @@ export async function saveGoogleDriveFacetSource(
972
1142
  }
973
1143
  const requestedDestination = bindGoogleDriveDocumentDestination(input, payload);
974
1144
  const requestedConfig = googleDriveFacetConfig(requestedSources, requestedDestination, payload);
975
- const replayed = await replayCompletedIntegrationFacetOperation<IntegrationFacetMutationResult>(
1145
+ const admitted = await withOrganizationIntegrationPolicyFence(
976
1146
  deps.db,
977
- {
978
- accountId: input.accountId,
979
- workspaceId: input.workspaceId,
980
- subjectId: input.subjectId,
981
- capabilityId: input.capabilityId,
982
- instanceKey: input.instanceKey,
983
- facetKey: input.facetKey,
984
- idempotencyKey: payload.idempotencyKey,
985
- kind: "configure",
986
- expectedRequestDigest: (result) => {
987
- const displayName = integrationFacetReceiptDisplayName(result);
988
- if (displayName === null) return "invalid-integration-facet-receipt";
989
- return integrationFacetConfigureRequestDigest({
1147
+ input,
1148
+ async (tx, policy) => {
1149
+ const replayed =
1150
+ await replayCompletedIntegrationFacetOperation<IntegrationFacetMutationResult>(tx, {
1151
+ accountId: input.accountId,
1152
+ workspaceId: input.workspaceId,
1153
+ subjectId: input.subjectId,
990
1154
  capabilityId: input.capabilityId,
991
1155
  instanceKey: input.instanceKey,
992
1156
  facetKey: input.facetKey,
993
- displayName,
994
- config: requestedConfig,
995
- ...(payload.expectedVersion !== undefined
996
- ? { expectedVersion: payload.expectedVersion }
997
- : {}),
1157
+ idempotencyKey: payload.idempotencyKey,
1158
+ kind: "configure",
1159
+ expectedRequestDigest: (result) => {
1160
+ const displayName = integrationFacetReceiptDisplayName(result);
1161
+ if (displayName === null) return "invalid-integration-facet-receipt";
1162
+ return integrationFacetConfigureRequestDigest({
1163
+ capabilityId: input.capabilityId,
1164
+ instanceKey: input.instanceKey,
1165
+ facetKey: input.facetKey,
1166
+ displayName,
1167
+ config: requestedConfig,
1168
+ ...(payload.expectedVersion !== undefined
1169
+ ? { expectedVersion: payload.expectedVersion }
1170
+ : {}),
1171
+ });
1172
+ },
998
1173
  });
999
- },
1174
+ if (replayed) return { replayed: IntegrationFacetMutationResult.parse(replayed) };
1175
+ const context = await requireGoogleDriveIntegrationFacet({ ...deps, db: tx }, input);
1176
+ googleDriveDocumentDestination(input, payload);
1177
+ const acquiring = googleDriveFacetSelectionRequiresAcquisition(context, requestedConfig);
1178
+ if (acquiring) {
1179
+ const installed = (
1180
+ await listInstalledApiIntegrations(tx, input.workspaceId, input.subjectId)
1181
+ ).find(
1182
+ (candidate) =>
1183
+ candidate.capabilityId === input.capabilityId &&
1184
+ candidate.instanceKey === input.instanceKey,
1185
+ );
1186
+ assertOrganizationIntegrationAllowed(
1187
+ policy,
1188
+ installed
1189
+ ? installedGoogleDriveFacetKey({
1190
+ apiProtocol: installed.protocol,
1191
+ definitionId: installed.definitionId,
1192
+ definitionProvenance: installed.definitionProvenance,
1193
+ })
1194
+ : null,
1195
+ );
1196
+ }
1197
+ return { context, acquiring };
1000
1198
  },
1001
1199
  );
1002
- if (replayed) return IntegrationFacetMutationResult.parse(replayed);
1003
- const context = await requireGoogleDriveIntegrationFacet(deps, input);
1004
- googleDriveDocumentDestination(input, payload);
1005
- await verifyGoogleDriveSources(deps, {
1006
- workspaceId: input.workspaceId,
1007
- subjectId: input.subjectId,
1008
- connectionId: context.connection.id,
1009
- sources: requestedSources,
1010
- });
1011
- return IntegrationFacetMutationResult.parse(
1012
- await configureIntegrationFacet(deps.db, {
1013
- accountId: input.accountId,
1200
+ if (admitted.replayed) return admitted.replayed;
1201
+ const context = admitted.context!;
1202
+ if (admitted.acquiring)
1203
+ await verifyGoogleDriveSources(deps, {
1014
1204
  workspaceId: input.workspaceId,
1015
1205
  subjectId: input.subjectId,
1016
- capabilityId: input.capabilityId,
1017
- instanceKey: input.instanceKey,
1018
- facetKey: input.facetKey,
1019
- displayName:
1020
- context.facet.binding?.displayName ?? `${input.instanceKey} — Google Drive content`,
1021
- config: requestedConfig,
1022
- ...(payload.expectedVersion !== undefined
1023
- ? { expectedVersion: payload.expectedVersion }
1024
- : {}),
1025
- idempotencyKey: payload.idempotencyKey,
1026
- }),
1206
+ connectionId: context.connection.id,
1207
+ sources: requestedSources,
1208
+ });
1209
+ return IntegrationFacetMutationResult.parse(
1210
+ await withOrganizationIntegrationPolicyFence(deps.db, input, (tx, policy) =>
1211
+ configureIntegrationFacet(tx, {
1212
+ accountId: input.accountId,
1213
+ workspaceId: input.workspaceId,
1214
+ subjectId: input.subjectId,
1215
+ capabilityId: input.capabilityId,
1216
+ instanceKey: input.instanceKey,
1217
+ facetKey: input.facetKey,
1218
+ displayName:
1219
+ context.facet.binding?.displayName ?? `${input.instanceKey} — Google Drive content`,
1220
+ config: requestedConfig,
1221
+ ...(payload.expectedVersion !== undefined
1222
+ ? { expectedVersion: payload.expectedVersion }
1223
+ : {}),
1224
+ idempotencyKey: payload.idempotencyKey,
1225
+ beforeAcquire: async (locked, installed) => {
1226
+ const current = await requireGoogleDriveIntegrationFacet({ ...deps, db: locked }, input);
1227
+ if (googleDriveFacetSelectionRequiresAcquisition(current, requestedConfig)) {
1228
+ assertOrganizationIntegrationAllowed(policy, installedGoogleDriveFacetKey(installed));
1229
+ if (!admitted.acquiring)
1230
+ throw new HTTPException(409, {
1231
+ message: "Google Drive source binding changed; verify the selection again",
1232
+ });
1233
+ }
1234
+ },
1235
+ }),
1236
+ ),
1237
+ );
1238
+ }
1239
+
1240
+ /** This is installed server-authored version provenance, not a facet's mutable
1241
+ * capabilities.provider, URL, domain, or client-authored credential metadata. */
1242
+ function installedGoogleDriveFacetKey(context: {
1243
+ apiProtocol: string | null;
1244
+ definitionId: string | null;
1245
+ definitionProvenance: string | null;
1246
+ }): string | null {
1247
+ if (context.apiProtocol !== "openapi" && context.apiProtocol !== "graphql") return null;
1248
+ if (context.definitionProvenance === "workspace") return `custom:${context.apiProtocol}`;
1249
+ return context.definitionProvenance === "curated" &&
1250
+ CORE_INTEGRATION_DEFINITIONS.some((definition) => definition.id === context.definitionId)
1251
+ ? context.definitionId
1252
+ : null;
1253
+ }
1254
+
1255
+ function googleDriveFacetSelectionRequiresAcquisition(
1256
+ context: Awaited<ReturnType<typeof requireGoogleDriveIntegrationFacet>>,
1257
+ requested: ReturnType<typeof googleDriveFacetConfig>,
1258
+ ): boolean {
1259
+ const binding = context.facet.binding;
1260
+ if (
1261
+ !binding ||
1262
+ binding.status !== "active" ||
1263
+ !binding.directlyOwned ||
1264
+ binding.connectionId !== context.connection.id
1265
+ )
1266
+ return true;
1267
+ const previous = GoogleDriveKnowledgeSourceConfig.safeParse(binding.config);
1268
+ if (!previous.success) return true;
1269
+ const selection = (config: ReturnType<typeof googleDriveFacetConfig>) =>
1270
+ config.sources.map((source) => ({
1271
+ ...source,
1272
+ destination: config.destination,
1273
+ syncCadence: config.syncCadence,
1274
+ syncEnabled: true,
1275
+ readPolicy: config.readPolicy,
1276
+ }));
1277
+ return integrationSourceSelectionRequiresAcquisition(
1278
+ selection(previous.data),
1279
+ selection(requested),
1027
1280
  );
1028
1281
  }
1029
1282
 
@@ -1065,14 +1318,34 @@ export async function saveGoogleDriveSource(
1065
1318
  if (existing.accountId !== input.accountId || existing.workspaceId !== input.workspaceId) {
1066
1319
  throw new HTTPException(403, { message: "Google Drive connection authority mismatch" });
1067
1320
  }
1068
- await requireGoogleDriveSourceConnection(deps, existing, input.subjectId);
1321
+ const existingMetadata = await requireGoogleDriveSourceConnection(
1322
+ deps,
1323
+ existing,
1324
+ input.subjectId,
1325
+ );
1069
1326
  const documentDestination = googleDriveDocumentDestination(input, payload);
1070
- const verifiedSources = await verifyGoogleDriveSources(deps, {
1071
- workspaceId: input.workspaceId,
1072
- subjectId: input.subjectId,
1073
- connectionId: input.connectionId,
1074
- sources: payload.sources,
1075
- });
1327
+ const requestedSelection = payload.sources.map((source) => ({
1328
+ ...source,
1329
+ destination: documentDestination,
1330
+ syncCadence: payload.syncCadence,
1331
+ syncEnabled: payload.syncEnabled,
1332
+ readPolicy: payload.readPolicy,
1333
+ }));
1334
+ const acquiring = integrationSourceSelectionRequiresAcquisition(
1335
+ existingMetadata.selectedSources ??
1336
+ (existingMetadata.selectedSource ? [existingMetadata.selectedSource] : []),
1337
+ requestedSelection,
1338
+ );
1339
+ if (acquiring)
1340
+ await withOrganizationIntegrationAcquisition(deps.db, input, ["google-drive"], async () => {});
1341
+ const verifiedSources = acquiring
1342
+ ? await verifyGoogleDriveSources(deps, {
1343
+ workspaceId: input.workspaceId,
1344
+ subjectId: input.subjectId,
1345
+ connectionId: input.connectionId,
1346
+ sources: payload.sources,
1347
+ })
1348
+ : payload.sources;
1076
1349
  const latest =
1077
1350
  (await getConnectionMetadata(
1078
1351
  deps.db,
@@ -1084,33 +1357,46 @@ export async function saveGoogleDriveSource(
1084
1357
  const previousSources =
1085
1358
  latestMetadata.selectedSources ??
1086
1359
  (latestMetadata.selectedSource ? [latestMetadata.selectedSource] : []);
1087
- const updated = await transitionConnectionState(deps.db, {
1088
- workspaceId: input.workspaceId,
1089
- connectionId: latest.id,
1090
- visibleToSubjectId: input.subjectId,
1091
- expectedVersion: latest.version,
1092
- metadata: GoogleDriveConnectionMetadata.parse({
1093
- ...latestMetadata,
1094
- documentDestination,
1095
- selectedSource: null,
1096
- selectedSources: verifiedSources.map((verified) => {
1097
- const previous = previousSources.find((source) => source.id === verified.id);
1098
- return {
1099
- id: verified.id,
1100
- name: verified.name,
1101
- mimeType: verified.mimeType,
1102
- driveId: verified.driveId,
1103
- destination: documentDestination,
1104
- syncCadence: payload.syncCadence,
1105
- syncEnabled: payload.syncEnabled,
1106
- configGeneration: (previous?.configGeneration ?? 0) + 1,
1107
- readPolicy: payload.readPolicy,
1108
- selectedAt: new Date().toISOString(),
1109
- };
1110
- }),
1111
- }),
1112
- updatedBySubjectId: input.subjectId,
1113
- });
1360
+ const updated = await withOrganizationIntegrationPolicyFence(
1361
+ deps.db,
1362
+ input,
1363
+ async (tx, policy) => {
1364
+ if (integrationSourceSelectionRequiresAcquisition(previousSources, requestedSelection)) {
1365
+ assertOrganizationIntegrationAllowed(policy, "google-drive");
1366
+ if (!acquiring)
1367
+ throw new HTTPException(409, {
1368
+ message: "Google Drive sources changed; verify the selection again",
1369
+ });
1370
+ }
1371
+ return transitionConnectionState(tx, {
1372
+ workspaceId: input.workspaceId,
1373
+ connectionId: latest.id,
1374
+ visibleToSubjectId: input.subjectId,
1375
+ expectedVersion: latest.version,
1376
+ metadata: GoogleDriveConnectionMetadata.parse({
1377
+ ...latestMetadata,
1378
+ documentDestination,
1379
+ selectedSource: null,
1380
+ selectedSources: verifiedSources.map((verified) => {
1381
+ const previous = previousSources.find((source) => source.id === verified.id);
1382
+ return {
1383
+ id: verified.id,
1384
+ name: verified.name,
1385
+ mimeType: verified.mimeType,
1386
+ driveId: verified.driveId,
1387
+ destination: documentDestination,
1388
+ syncCadence: payload.syncCadence,
1389
+ syncEnabled: payload.syncEnabled,
1390
+ configGeneration: (previous?.configGeneration ?? 0) + 1,
1391
+ readPolicy: payload.readPolicy,
1392
+ selectedAt: new Date().toISOString(),
1393
+ };
1394
+ }),
1395
+ }),
1396
+ updatedBySubjectId: input.subjectId,
1397
+ });
1398
+ },
1399
+ );
1114
1400
  if (!updated) {
1115
1401
  throw new HTTPException(409, { message: "Google Drive connection changed; try again" });
1116
1402
  }
@@ -1542,7 +1828,6 @@ async function materializeGoogleDriveKnowledgeSchedules(
1542
1828
  action: { kind: "agent_turn" },
1543
1829
  runMode: "new_session_per_run",
1544
1830
  targetSessionId: null,
1545
- connectionAuthorities: [],
1546
1831
  agentConfig: knowledgeSourceAgentConfig(action),
1547
1832
  variableSetId: null,
1548
1833
  environmentId: null,
@@ -2108,6 +2393,16 @@ function readGoogleDriveOAuthState(
2108
2393
  if (capability !== "source_read" && capability !== "publish") {
2109
2394
  throw new HTTPException(400, { message: "invalid Google Drive OAuth capability" });
2110
2395
  }
2396
+ const publishingFolderId = optionalString(payload.publishingFolderId) ?? undefined;
2397
+ if (
2398
+ payload.publishingFolderId !== undefined &&
2399
+ (!publishingFolderId ||
2400
+ publishingFolderId.length > 512 ||
2401
+ capability !== "publish" ||
2402
+ !connectionId)
2403
+ ) {
2404
+ throw new HTTPException(400, { message: "invalid Google Drive publishing state" });
2405
+ }
2111
2406
  if (
2112
2407
  (connectionVersion !== undefined && !Number.isInteger(connectionVersion)) ||
2113
2408
  Boolean(connectionId) !== Boolean(connectionVersion)
@@ -2140,6 +2435,7 @@ function readGoogleDriveOAuthState(
2140
2435
  "state.encryptedPkceVerifier",
2141
2436
  ),
2142
2437
  capability,
2438
+ ...(publishingFolderId ? { publishingFolderId } : {}),
2143
2439
  ...(connectionId ? { connectionId, connectionVersion: connectionVersion! } : {}),
2144
2440
  nonce: requiredString(payload.nonce, "state.nonce"),
2145
2441
  iat,