@opengeni/api-router 0.30.3 → 1.0.0

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 (434) hide show
  1. package/dist/access-grant-rls.d.ts +3 -0
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/api-websocket.d.ts +18 -0
  4. package/dist/app.d.ts +50 -2
  5. package/dist/app.js +12 -1
  6. package/dist/artifact-catalog-cursor.d.ts +27 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +10 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +6 -0
  10. package/dist/auth/managed-auth.d.ts +102 -3
  11. package/dist/auth/managed-email.d.ts +29 -0
  12. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  13. package/dist/auth/new-signups-gate.d.ts +23 -0
  14. package/dist/auth/organization-user-setup.d.ts +80 -0
  15. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-state-authority.d.ts +1 -27
  19. package/dist/chunk-6TZ5LG3O.js +123948 -0
  20. package/dist/chunk-6TZ5LG3O.js.map +1 -0
  21. package/dist/chunk-OGQDXVXY.js +18 -0
  22. package/dist/chunk-OGQDXVXY.js.map +1 -0
  23. package/dist/claude-subscription-account-conflicts.d.ts +1 -0
  24. package/dist/claude-subscription-account-usage.d.ts +39 -0
  25. package/dist/claude-subscription-oauth.d.ts +25 -0
  26. package/dist/claude-subscription-profile.d.ts +9 -0
  27. package/dist/claude-subscription-usage.d.ts +44 -0
  28. package/dist/claude-workspace-connection.d.ts +15 -0
  29. package/dist/codemode.d.ts +32 -1
  30. package/dist/company-brain-okf.d.ts +24 -0
  31. package/dist/connected-machine-computer-access.d.ts +11 -0
  32. package/dist/connection-ownership.d.ts +54 -0
  33. package/dist/controller-data-plane.d.ts +32 -0
  34. package/dist/editable-artifact-source-session.d.ts +3 -0
  35. package/dist/editable-artifact-websocket.d.ts +10 -18
  36. package/dist/editable-artifact-workspace-files.d.ts +1 -1
  37. package/dist/fatal-process-boundary.d.ts +25 -0
  38. package/dist/github-access.d.ts +31 -2
  39. package/dist/http/acting-person.d.ts +24 -0
  40. package/dist/http/api-contract-compat.d.ts +19 -0
  41. package/dist/http/api-error.d.ts +27 -1
  42. package/dist/http/cors.d.ts +17 -0
  43. package/dist/http/deprecation.d.ts +42 -0
  44. package/dist/http/interaction-control-error.d.ts +13 -0
  45. package/dist/http/keyed-admission.d.ts +12 -0
  46. package/dist/http/local-browser-boundary.d.ts +72 -0
  47. package/dist/http/metrics-listener.d.ts +22 -0
  48. package/dist/http/path-identifier.d.ts +17 -0
  49. package/dist/http/registered-route-label.d.ts +16 -0
  50. package/dist/http/request-body.d.ts +27 -0
  51. package/dist/http/request-source.d.ts +52 -0
  52. package/dist/http/sse.d.ts +17 -6
  53. package/dist/http/unmatched-route.d.ts +18 -0
  54. package/dist/http/user-content.d.ts +36 -0
  55. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  56. package/dist/index.d.ts +10 -3
  57. package/dist/index.js +1091 -162
  58. package/dist/index.js.map +1 -1
  59. package/dist/integration-endpoint-test.d.ts +20 -0
  60. package/dist/integrations/api-integrations.d.ts +2 -2
  61. package/dist/integrations/atlassian.d.ts +29 -3
  62. package/dist/integrations/connect-authority.d.ts +1 -0
  63. package/dist/integrations/connect-callback-return.d.ts +6 -0
  64. package/dist/integrations/fiken.d.ts +16 -2
  65. package/dist/integrations/github-app-connect.d.ts +47 -0
  66. package/dist/integrations/github-installation-proof.d.ts +3 -0
  67. package/dist/integrations/github-lens-connect.d.ts +116 -0
  68. package/dist/integrations/github-skill-source.d.ts +1 -5
  69. package/dist/integrations/google-drive.d.ts +24 -0
  70. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  71. package/dist/integrations/marketplace-plugin.d.ts +2691 -0
  72. package/dist/integrations/oauth-client.d.ts +178 -18
  73. package/dist/integrations/oauth-profiles.d.ts +222 -0
  74. package/dist/integrations/oauth-return-path.d.ts +1 -0
  75. package/dist/integrations/personal-github-repositories.d.ts +84 -0
  76. package/dist/integrations/personal-github.d.ts +42 -0
  77. package/dist/integrations/pr-review-provider.d.ts +22 -0
  78. package/dist/integrations/provider-oauth.d.ts +19 -1
  79. package/dist/integrations/slack-app-home.d.ts +24 -0
  80. package/dist/integrations/slack-bot.d.ts +367 -12
  81. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  82. package/dist/integrations/slack-install.d.ts +20 -0
  83. package/dist/integrations/slack-interactions.d.ts +107 -9
  84. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  85. package/dist/integrations/slack-routing.d.ts +120 -0
  86. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  87. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  88. package/dist/integrations/social-oauth.d.ts +7 -0
  89. package/dist/interaction-agent-access.d.ts +15 -0
  90. package/dist/interaction-frame-proxy.d.ts +68 -0
  91. package/dist/interaction-metrics.d.ts +2 -0
  92. package/dist/mcp/action-catalog-types.d.ts +9 -0
  93. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  94. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  95. package/dist/mcp/child-read-evidence.d.ts +9 -0
  96. package/dist/mcp/command-read.d.ts +24 -0
  97. package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
  98. package/dist/mcp/contract-input.d.ts +11 -0
  99. package/dist/mcp/documents.d.ts +7 -5
  100. package/dist/mcp/files.d.ts +2 -2
  101. package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
  102. package/dist/mcp/knowledge-entries.d.ts +5 -0
  103. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  104. package/dist/mcp/receipts.d.ts +9 -0
  105. package/dist/mcp/request-abort.d.ts +19 -0
  106. package/dist/mcp/scheduled-task-input.d.ts +1189 -0
  107. package/dist/mcp/scheduled-task-view.d.ts +22 -4
  108. package/dist/mcp/server.d.ts +255 -3
  109. package/dist/mcp/session-event-view.d.ts +94 -0
  110. package/dist/mcp/session-view.d.ts +66 -2
  111. package/dist/mcp/session-wait.d.ts +174 -0
  112. package/dist/mcp-oauth.d.ts +52 -0
  113. package/dist/model-catalog.d.ts +11 -31
  114. package/dist/observability.d.ts +3 -1
  115. package/dist/organization-mcp.d.ts +52 -0
  116. package/dist/organization-recovery-notifications.d.ts +41 -0
  117. package/dist/routes/analytics-consent.d.ts +26 -0
  118. package/dist/routes/api-integrations.d.ts +25 -0
  119. package/dist/routes/api-keys.d.ts +17 -0
  120. package/dist/routes/artifact-catalog.d.ts +6 -0
  121. package/dist/routes/automations.d.ts +19 -0
  122. package/dist/routes/billing.d.ts +49 -0
  123. package/dist/routes/browser-sessions.d.ts +59 -2
  124. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  125. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  126. package/dist/routes/client-errors.d.ts +146 -0
  127. package/dist/routes/codex.d.ts +76 -2
  128. package/dist/routes/company-brain.d.ts +3 -0
  129. package/dist/routes/company-profile.d.ts +2 -1
  130. package/dist/routes/computer-sessions.d.ts +14 -0
  131. package/dist/routes/connect.d.ts +5 -0
  132. package/dist/routes/editable-artifacts.d.ts +2 -0
  133. package/dist/routes/external-identity-links.d.ts +6 -0
  134. package/dist/routes/feedback.d.ts +3 -0
  135. package/dist/routes/github-browser-pages.d.ts +12 -0
  136. package/dist/routes/github.d.ts +2 -0
  137. package/dist/routes/insights-response-cache.d.ts +10 -0
  138. package/dist/routes/insights-usage.d.ts +12 -0
  139. package/dist/routes/insights.d.ts +30 -1
  140. package/dist/routes/knowledge.d.ts +3 -0
  141. package/dist/routes/managed-auth-session-sets.d.ts +26 -0
  142. package/dist/routes/managed-onboarding.d.ts +29 -0
  143. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  144. package/dist/routes/model-connection-access.d.ts +3 -0
  145. package/dist/routes/organization-integration-policy.d.ts +3 -0
  146. package/dist/routes/organization-integrations.d.ts +6 -0
  147. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  148. package/dist/routes/organization-model-providers.d.ts +3 -0
  149. package/dist/routes/organization-recovery.d.ts +19 -0
  150. package/dist/routes/organization-service-accounts.d.ts +3 -0
  151. package/dist/routes/organization-sessions.d.ts +26 -0
  152. package/dist/routes/personal-github-git-broker.d.ts +29 -0
  153. package/dist/routes/personal-github.d.ts +3 -0
  154. package/dist/routes/pr-review-github.d.ts +3 -0
  155. package/dist/routes/pr-review.d.ts +3 -0
  156. package/dist/routes/session-artifact-associations.d.ts +4 -0
  157. package/dist/routes/session-history-imports.d.ts +9 -0
  158. package/dist/routes/sessions.d.ts +44 -6
  159. package/dist/routes/skill-content.d.ts +4 -0
  160. package/dist/routes/skill-install-authority.d.ts +6 -0
  161. package/dist/routes/subscription-account-pools.d.ts +34 -0
  162. package/dist/routes/subscription-pool-access.d.ts +16 -0
  163. package/dist/routes/supergrok.d.ts +6 -1
  164. package/dist/routes/usage-allowances.d.ts +12 -0
  165. package/dist/routes/user-resource-authorities.d.ts +3 -0
  166. package/dist/routes/workspace-artifacts.d.ts +2 -1
  167. package/dist/routes/workspace-capture.d.ts +10 -2
  168. package/dist/routes/workspace-integrations.d.ts +35 -0
  169. package/dist/routes/workspace-learning.d.ts +3 -0
  170. package/dist/routes/workspace-model-providers.d.ts +4 -0
  171. package/dist/routes/workspaces.d.ts +29 -0
  172. package/dist/sandbox/auth-callout.d.ts +8 -0
  173. package/dist/sandbox/channel-a.d.ts +19 -1
  174. package/dist/sandbox/connection-authority.d.ts +3 -0
  175. package/dist/sandbox/enrollment.d.ts +9 -1
  176. package/dist/sandbox/machines.d.ts +5 -2
  177. package/dist/sandbox/metrics-ingestion.d.ts +28 -20
  178. package/dist/sandbox/rematerialize.d.ts +2 -0
  179. package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
  180. package/dist/sandbox/viewer.d.ts +26 -1
  181. package/dist/sandbox-file-artifacts.d.ts +50 -0
  182. package/dist/scheduled-task-deletion.d.ts +13 -0
  183. package/dist/session-create-observability.d.ts +5 -0
  184. package/dist/session-event-view-MPS2OZD3.js +292 -0
  185. package/dist/session-event-view-MPS2OZD3.js.map +1 -0
  186. package/dist/site-session-origin.d.ts +13 -0
  187. package/dist/site-uploads.d.ts +41 -0
  188. package/dist/slack-reaction-files.d.ts +1 -1
  189. package/dist/temporal-schedule-cleanup.d.ts +1 -0
  190. package/dist/temporal-schedule-sync.d.ts +26 -0
  191. package/dist/transcription/providers/xai-subscription.d.ts +1 -0
  192. package/dist/transcription/service.d.ts +2 -1
  193. package/dist/work-discovery-observability.d.ts +33 -0
  194. package/dist/workspace-artifact-content.d.ts +28 -0
  195. package/dist/workspace-artifact-provenance.d.ts +7 -0
  196. package/dist/workspace-delete-observability.d.ts +10 -0
  197. package/dist/workspace-deletion.d.ts +6 -0
  198. package/dist/workspace-state-projection.d.ts +3 -5
  199. package/dist/workspace-tool-gateway-observability.d.ts +17 -0
  200. package/dist/workspace-tool-gateway.d.ts +123 -0
  201. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  202. package/package.json +23 -19
  203. package/src/access-grant-rls.ts +75 -0
  204. package/src/admission-trace.ts +14 -0
  205. package/src/api-websocket.ts +23 -0
  206. package/src/app.ts +1967 -252
  207. package/src/artifact-catalog-cursor.ts +60 -0
  208. package/src/auth/managed-auth-attempt-context.ts +70 -0
  209. package/src/auth/managed-auth-rate-limits.ts +252 -0
  210. package/src/auth/managed-auth-session-adapter.ts +222 -0
  211. package/src/auth/managed-auth.ts +536 -60
  212. package/src/auth/managed-email.ts +174 -0
  213. package/src/auth/managed-sign-in-notifications.ts +81 -0
  214. package/src/auth/new-signups-gate.ts +49 -0
  215. package/src/auth/organization-user-setup.ts +307 -0
  216. package/src/auth/signup-funnel-metrics.ts +164 -0
  217. package/src/browser-controller-authority.ts +1 -186
  218. package/src/browser-ephemeral.ts +39 -0
  219. package/src/browser-state-authority.ts +1 -236
  220. package/src/claude-subscription-account-conflicts.ts +12 -0
  221. package/src/claude-subscription-account-usage.ts +48 -0
  222. package/src/claude-subscription-oauth.ts +362 -0
  223. package/src/claude-subscription-profile.ts +73 -0
  224. package/src/claude-subscription-usage.ts +97 -0
  225. package/src/claude-workspace-connection.ts +82 -0
  226. package/src/codemode.ts +194 -30
  227. package/src/codex-realtime.ts +8 -2
  228. package/src/company-brain-okf.ts +340 -0
  229. package/src/connected-machine-computer-access.ts +33 -0
  230. package/src/connection-ownership.ts +199 -0
  231. package/src/controller-data-plane.ts +81 -0
  232. package/src/editable-artifact-native-kernel.ts +26 -15
  233. package/src/editable-artifact-office-import.ts +28 -3
  234. package/src/editable-artifact-production.ts +23 -7
  235. package/src/editable-artifact-source-session.ts +123 -0
  236. package/src/editable-artifact-websocket.ts +27 -21
  237. package/src/editable-artifact-workspace-files.ts +31 -6
  238. package/src/fatal-process-boundary.ts +246 -0
  239. package/src/gateway-realtime.ts +1 -1
  240. package/src/github-access.ts +147 -5
  241. package/src/http/acting-person.ts +71 -0
  242. package/src/http/api-contract-compat.ts +49 -0
  243. package/src/http/api-error.ts +115 -1
  244. package/src/http/auth.ts +48 -0
  245. package/src/http/cors.ts +67 -0
  246. package/src/http/deprecation.ts +118 -0
  247. package/src/http/interaction-control-error.ts +164 -0
  248. package/src/http/keyed-admission.ts +29 -0
  249. package/src/http/local-browser-boundary.ts +343 -0
  250. package/src/http/metrics-listener.ts +57 -0
  251. package/src/http/path-identifier.ts +54 -0
  252. package/src/http/registered-route-label.ts +34 -0
  253. package/src/http/request-body.ts +127 -0
  254. package/src/http/request-source.ts +178 -0
  255. package/src/http/sse.ts +486 -132
  256. package/src/http/unmatched-route.ts +60 -0
  257. package/src/http/user-content.ts +158 -0
  258. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  259. package/src/index.ts +157 -52
  260. package/src/integration-endpoint-test.ts +291 -0
  261. package/src/integrations/api-integrations.ts +98 -11
  262. package/src/integrations/atlassian.ts +474 -136
  263. package/src/integrations/connect-authority.ts +2 -0
  264. package/src/integrations/connect-callback-return.ts +86 -0
  265. package/src/integrations/fiken.ts +354 -64
  266. package/src/integrations/github-app-connect.ts +435 -0
  267. package/src/integrations/github-installation-proof.ts +60 -0
  268. package/src/integrations/github-lens-connect.ts +76 -0
  269. package/src/integrations/github-skill-source.ts +2 -142
  270. package/src/integrations/google-drive.ts +717 -225
  271. package/src/integrations/integration-commit-authority.ts +69 -0
  272. package/src/integrations/marketplace-plugin.ts +48 -0
  273. package/src/integrations/oauth-client.ts +1356 -459
  274. package/src/integrations/oauth-profiles.ts +537 -0
  275. package/src/integrations/oauth-return-path.ts +18 -0
  276. package/src/integrations/personal-github-repositories.ts +674 -0
  277. package/src/integrations/personal-github.ts +825 -0
  278. package/src/integrations/pr-review-provider.ts +246 -0
  279. package/src/integrations/provider-oauth.ts +250 -22
  280. package/src/integrations/slack-app-home.ts +300 -0
  281. package/src/integrations/slack-bot.ts +963 -239
  282. package/src/integrations/slack-file-upload-flow.ts +147 -0
  283. package/src/integrations/slack-install.ts +83 -0
  284. package/src/integrations/slack-interactions.ts +3167 -474
  285. package/src/integrations/slack-mrkdwn.ts +193 -0
  286. package/src/integrations/slack-routing.ts +337 -0
  287. package/src/integrations/slack-session-defaults.ts +224 -0
  288. package/src/integrations/slack-task-file-upload.ts +323 -0
  289. package/src/integrations/social-oauth.ts +213 -15
  290. package/src/interaction-agent-access.ts +48 -0
  291. package/src/interaction-frame-proxy.ts +409 -0
  292. package/src/interaction-metrics.ts +30 -0
  293. package/src/mcp/action-catalog-types.ts +9 -0
  294. package/src/mcp/action-catalog.gen.ts +6696 -0
  295. package/src/mcp/capability-account-readiness.ts +17 -0
  296. package/src/mcp/child-read-evidence.ts +19 -0
  297. package/src/mcp/command-read.ts +109 -0
  298. package/src/mcp/company-profile-agent-admin.ts +198 -0
  299. package/src/mcp/contract-input.ts +141 -0
  300. package/src/mcp/documents.ts +65 -377
  301. package/src/mcp/editable-artifacts.ts +12 -6
  302. package/src/mcp/files.ts +80 -43
  303. package/src/mcp/first-party-tool-permissions.ts +305 -0
  304. package/src/mcp/knowledge-entries.ts +322 -0
  305. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  306. package/src/mcp/receipts.ts +34 -0
  307. package/src/mcp/request-abort.ts +44 -0
  308. package/src/mcp/scheduled-task-input.ts +76 -0
  309. package/src/mcp/scheduled-task-view.ts +44 -3
  310. package/src/mcp/server.ts +3030 -1267
  311. package/src/mcp/session-event-view.ts +383 -0
  312. package/src/mcp/session-view.ts +84 -3
  313. package/src/mcp/session-wait.ts +665 -0
  314. package/src/mcp-oauth.ts +1123 -0
  315. package/src/model-catalog.ts +91 -333
  316. package/src/observability.ts +15 -1
  317. package/src/organization-mcp.ts +397 -0
  318. package/src/organization-recovery-notifications.ts +103 -0
  319. package/src/routes/analytics-consent.ts +123 -0
  320. package/src/routes/api-integrations.ts +364 -74
  321. package/src/routes/api-keys.ts +336 -10
  322. package/src/routes/artifact-catalog.ts +279 -0
  323. package/src/routes/automations.ts +768 -0
  324. package/src/routes/billing.ts +461 -46
  325. package/src/routes/browser-sessions.ts +780 -112
  326. package/src/routes/canonical-human-identities.ts +90 -14
  327. package/src/routes/capabilities.ts +107 -6
  328. package/src/routes/channels.ts +20 -3
  329. package/src/routes/claude-subscription-accounts.ts +334 -0
  330. package/src/routes/claude-subscription-oauth.ts +142 -0
  331. package/src/routes/client-errors.ts +362 -0
  332. package/src/routes/codex.ts +833 -116
  333. package/src/routes/company-brain.ts +322 -0
  334. package/src/routes/company-profile.ts +65 -1
  335. package/src/routes/computer-sessions.ts +557 -106
  336. package/src/routes/connect.ts +1938 -0
  337. package/src/routes/connections.ts +1039 -349
  338. package/src/routes/documents.ts +488 -287
  339. package/src/routes/editable-artifacts.ts +79 -9
  340. package/src/routes/enrollments.ts +135 -39
  341. package/src/routes/environments.ts +154 -58
  342. package/src/routes/external-identity-links.ts +201 -0
  343. package/src/routes/feedback.ts +113 -0
  344. package/src/routes/files.ts +267 -33
  345. package/src/routes/github-browser-pages.ts +162 -0
  346. package/src/routes/github.ts +446 -144
  347. package/src/routes/insights-response-cache.ts +83 -0
  348. package/src/routes/insights-usage.ts +345 -0
  349. package/src/routes/insights.ts +153 -19
  350. package/src/routes/install.ts +133 -38
  351. package/src/routes/integration-facets.ts +107 -33
  352. package/src/routes/interaction-resources.ts +30 -3
  353. package/src/routes/knowledge.ts +488 -0
  354. package/src/routes/machines.ts +313 -15
  355. package/src/routes/managed-auth-session-sets.ts +1218 -0
  356. package/src/routes/managed-onboarding.ts +337 -0
  357. package/src/routes/managed-sign-in-methods.ts +433 -0
  358. package/src/routes/memory-slack-publications.ts +3 -2
  359. package/src/routes/model-connection-access.ts +208 -0
  360. package/src/routes/organization-integration-policy.ts +116 -0
  361. package/src/routes/organization-integrations.ts +326 -0
  362. package/src/routes/organization-mcp-connections.ts +178 -0
  363. package/src/routes/organization-memberships.ts +1019 -27
  364. package/src/routes/organization-model-providers.ts +293 -0
  365. package/src/routes/organization-recovery.ts +325 -0
  366. package/src/routes/organization-service-accounts.ts +128 -0
  367. package/src/routes/organization-sessions.ts +350 -0
  368. package/src/routes/personal-github-git-broker.ts +785 -0
  369. package/src/routes/personal-github.ts +370 -0
  370. package/src/routes/plugins.ts +251 -22
  371. package/src/routes/pr-review-github.ts +881 -0
  372. package/src/routes/pr-review.ts +622 -0
  373. package/src/routes/preference-registry.ts +12 -93
  374. package/src/routes/rigs.ts +167 -50
  375. package/src/routes/scheduled-tasks.ts +346 -41
  376. package/src/routes/session-artifact-associations.ts +87 -0
  377. package/src/routes/session-history-imports.ts +280 -0
  378. package/src/routes/sessions.ts +2306 -264
  379. package/src/routes/skill-content.ts +297 -0
  380. package/src/routes/skill-install-authority.ts +64 -0
  381. package/src/routes/skills.ts +62 -9
  382. package/src/routes/social.ts +46 -18
  383. package/src/routes/subscription-account-pools.ts +436 -0
  384. package/src/routes/subscription-pool-access.ts +126 -0
  385. package/src/routes/supergrok.ts +219 -303
  386. package/src/routes/transcription-recordings.ts +38 -3
  387. package/src/routes/transcriptions.ts +4 -0
  388. package/src/routes/usage-allowances.ts +378 -0
  389. package/src/routes/user-resource-authorities.ts +138 -0
  390. package/src/routes/video-generation.ts +14 -10
  391. package/src/routes/workspace-artifacts.ts +275 -69
  392. package/src/routes/workspace-capture.ts +21 -0
  393. package/src/routes/workspace-integrations.ts +576 -0
  394. package/src/routes/workspace-learning.ts +159 -0
  395. package/src/routes/workspace-model-providers.ts +148 -0
  396. package/src/routes/workspace-state.ts +38 -25
  397. package/src/routes/workspaces.ts +1004 -127
  398. package/src/sandbox/auth-callout.ts +96 -19
  399. package/src/sandbox/channel-a.ts +323 -24
  400. package/src/sandbox/connection-authority.ts +3 -0
  401. package/src/sandbox/enrollment.ts +81 -6
  402. package/src/sandbox/machines.ts +218 -76
  403. package/src/sandbox/metrics-ingestion.ts +411 -62
  404. package/src/sandbox/rematerialize.ts +121 -19
  405. package/src/sandbox/session-attach-variable-sets.ts +131 -0
  406. package/src/sandbox/viewer.ts +280 -25
  407. package/src/sandbox-file-artifacts.ts +413 -0
  408. package/src/scheduled-task-deletion.ts +138 -0
  409. package/src/session-create-observability.ts +46 -0
  410. package/src/session-realtime-context.ts +6 -3
  411. package/src/site-session-origin.ts +48 -0
  412. package/src/site-uploads.ts +224 -0
  413. package/src/slack-reaction-files.ts +16 -5
  414. package/src/temporal-schedule-cleanup.ts +13 -0
  415. package/src/temporal-schedule-sync.ts +74 -0
  416. package/src/transcription/providers/codex-subscription.ts +2 -0
  417. package/src/transcription/providers/openai.ts +1 -0
  418. package/src/transcription/providers/xai-subscription.ts +49 -3
  419. package/src/transcription/segmenter.ts +8 -2
  420. package/src/transcription/service.ts +43 -6
  421. package/src/work-discovery-observability.ts +121 -0
  422. package/src/workspace-artifact-content.ts +144 -0
  423. package/src/workspace-artifact-provenance.ts +104 -0
  424. package/src/workspace-delete-observability.ts +75 -0
  425. package/src/workspace-deletion.ts +73 -0
  426. package/src/workspace-state-projection.ts +18 -148
  427. package/src/workspace-tool-gateway-observability.ts +100 -0
  428. package/src/workspace-tool-gateway.ts +870 -0
  429. package/src/workspace-webhook-dispatch.ts +190 -0
  430. package/src/xai-subscription-auth.ts +9 -2
  431. package/dist/chunk-WCXHI3FF.js +0 -49920
  432. package/dist/chunk-WCXHI3FF.js.map +0 -1
  433. package/dist/routes/packs.d.ts +0 -3
  434. package/src/routes/packs.ts +0 -729
@@ -44,15 +44,34 @@ const BAKED_DIR = new URL("baked/", INSTALL_DIR);
44
44
  // The static text artifacts served verbatim, with their content types. Each is
45
45
  // read once at first request and memoized (committed files; immutable per deploy).
46
46
  const TEXT_ASSETS: Record<string, { file: string; contentType: string }> = {
47
- "/install.sh": { file: "install.sh", contentType: "text/x-shellscript; charset=utf-8" },
48
- "/install.ps1": { file: "install.ps1", contentType: "text/plain; charset=utf-8" },
49
- "/uninstall.sh": { file: "uninstall.sh", contentType: "text/x-shellscript; charset=utf-8" },
47
+ "/install.sh": {
48
+ file: "install.sh",
49
+ contentType: "text/x-shellscript; charset=utf-8",
50
+ },
51
+ "/install.ps1": {
52
+ file: "install.ps1",
53
+ contentType: "text/plain; charset=utf-8",
54
+ },
55
+ "/uninstall.sh": {
56
+ file: "uninstall.sh",
57
+ contentType: "text/x-shellscript; charset=utf-8",
58
+ },
50
59
  "/opengeni-agent-minisign.pub": {
51
60
  file: "opengeni-agent-minisign.pub",
52
61
  contentType: "text/plain; charset=utf-8",
53
62
  },
54
63
  };
55
64
 
65
+ // Non-executable resources needed to assemble a complete platform bundle. These
66
+ // stay committed beside the installer rather than depending on a release/CDN so
67
+ // an exact-SHA local or private deployment remains self-contained.
68
+ const COMMITTED_BINARY_ASSETS: Record<string, { file: string; contentType: string }> = {
69
+ "OpenGeni-Agent.icns": {
70
+ file: "OpenGeni-Agent.icns",
71
+ contentType: "image/icns",
72
+ },
73
+ };
74
+
56
75
  const assetCache = new Map<string, string>();
57
76
 
58
77
  async function loadAsset(file: string): Promise<string> {
@@ -73,26 +92,40 @@ async function loadAsset(file: string): Promise<string> {
73
92
  // `curl https://<this-host>/install.sh | sh` installs the exact agent that
74
93
  // matches the API it enrolls against, with NO dependency on a public CDN (which a
75
94
  // private/air-gapped deploy may not even resolve). When a public base URL is
76
- // configured we therefore rewrite each script's default-base-URL marker line to
77
- // that origin before serving. The user's OPENGENI_INSTALL_BASE_URL env override
78
- // still wins at run time (the scripts use `:-default`); only the built-in DEFAULT
79
- // changes. The marker lines are kept shape-stable in agent/install/install.{sh,ps1}.
80
- const DEFAULT_BASE_REWRITES: Record<string, (base: string) => { from: string; to: string }> = {
81
- "install.sh": (base) => ({
82
- from: 'OPENGENI_INSTALL_DEFAULT_BASE_URL="https://get.opengeni.ai"',
83
- to: `OPENGENI_INSTALL_DEFAULT_BASE_URL="${base}"`,
84
- }),
85
- "install.ps1": (base) => ({
86
- from: "$OpengeniInstallDefaultBaseUrl = 'https://get.opengeni.ai'",
87
- to: `$OpengeniInstallDefaultBaseUrl = '${base}'`,
88
- }),
95
+ // configured we therefore rewrite each script's release-asset AND connection-API
96
+ // default markers to that origin before serving. The user's
97
+ // OPENGENI_INSTALL_BASE_URL / OPENGENI_API_URL overrides still win at run time;
98
+ // only the built-in defaults change. The marker lines are kept shape-stable in
99
+ // agent/install/install.{sh,ps1}.
100
+ type DefaultRewrite = { from: string; to: string };
101
+
102
+ const DEFAULT_BASE_REWRITES: Record<string, (base: string) => DefaultRewrite[]> = {
103
+ "install.sh": (base) => [
104
+ {
105
+ from: 'OPENGENI_INSTALL_DEFAULT_BASE_URL="https://get.opengeni.ai"',
106
+ to: `OPENGENI_INSTALL_DEFAULT_BASE_URL="${base}"`,
107
+ },
108
+ {
109
+ from: 'OPENGENI_API_DEFAULT_URL="https://app.opengeni.ai"',
110
+ to: `OPENGENI_API_DEFAULT_URL="${base}"`,
111
+ },
112
+ ],
113
+ "install.ps1": (base) => [
114
+ {
115
+ from: "$OpengeniInstallDefaultBaseUrl = 'https://get.opengeni.ai'",
116
+ to: `$OpengeniInstallDefaultBaseUrl = '${base}'`,
117
+ },
118
+ {
119
+ from: "$OpengeniApiDefaultUrl = 'https://app.opengeni.ai'",
120
+ to: `$OpengeniApiDefaultUrl = '${base}'`,
121
+ },
122
+ ],
89
123
  };
90
124
 
91
- // Rewrite a served script's default release-asset base URL to this deployment's
92
- // own public origin. A no-op when no public base URL is configured (the public
93
- // archive default stands), when the URL is not absolute http(s) (never serve a
94
- // script with a broken base), or when the file has no marker (script drift — fail
95
- // safe to serving it verbatim rather than crashing the install surface).
125
+ // Rewrite a served script's default release-asset and connection-API URLs to this
126
+ // deployment's own public origin. A no-op when no public base URL is configured,
127
+ // when the URL is not absolute http(s), or when either marker is absent (script
128
+ // drift — fail safe to serving it verbatim rather than splitting the two origins).
96
129
  function rewriteDefaultBaseUrl(
97
130
  file: string,
98
131
  body: string,
@@ -102,11 +135,11 @@ function rewriteDefaultBaseUrl(
102
135
  return body;
103
136
  }
104
137
  const base = publicBaseUrl.replace(/\/+$/, "");
105
- const rule = DEFAULT_BASE_REWRITES[file]?.(base);
106
- if (!rule || !body.includes(rule.from)) {
138
+ const rules = DEFAULT_BASE_REWRITES[file]?.(base);
139
+ if (!rules || rules.some((rule) => !body.includes(rule.from))) {
107
140
  return body;
108
141
  }
109
- return body.replace(rule.from, rule.to);
142
+ return rules.reduce((rewritten, rule) => rewritten.replace(rule.from, rule.to), body);
110
143
  }
111
144
 
112
145
  // The content type for a baked release asset. The binary is an
@@ -125,18 +158,53 @@ function bakedContentType(asset: string): string {
125
158
  // BAKED_DIR is a fixed sibling, so the resolved path cannot escape the dir.
126
159
  async function readBaked(asset: string): Promise<ArrayBuffer | null> {
127
160
  const url = new URL(asset, BAKED_DIR);
128
- try {
129
- const info = await stat(url);
130
- if (!info.isFile()) {
161
+ const runtime =
162
+ /^(?:opengeni-agent-browser|opengeni-computer-native|opengeni-browserd|opengeni-agent)-(.+?)(?:\.(?:sha256|minisig))?$/.exec(
163
+ asset,
164
+ );
165
+ if (runtime) {
166
+ const target = runtime[1]!;
167
+ const cohort = [
168
+ "opengeni-agent",
169
+ "opengeni-browserd",
170
+ "opengeni-agent-browser",
171
+ "opengeni-computer-native",
172
+ ].flatMap((component) =>
173
+ ["", ".sha256", ".minisig"].map((suffix) => `${component}-${target}${suffix}`),
174
+ );
175
+ const members = await Promise.all(
176
+ cohort.map(async (name) => {
177
+ try {
178
+ const info = await stat(new URL(name, BAKED_DIR));
179
+ return info.isFile() && info.size > 0 ? "complete" : "invalid";
180
+ } catch (error) {
181
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return "absent";
182
+ throw new HTTPException(503, { message: "baked interaction runtime is unavailable" });
183
+ }
184
+ }),
185
+ );
186
+ // A target is either wholly absent or wholly baked. A partial image cannot
187
+ // combine its agent with helpers or verification sidecars from an archive.
188
+ if (members.every((member) => member === "absent")) return null;
189
+ if (members.some((member) => member !== "complete")) {
190
+ throw new HTTPException(503, { message: "baked interaction runtime is incomplete" });
191
+ }
192
+ } else {
193
+ try {
194
+ const info = await stat(url);
195
+ if (!info.isFile()) return null;
196
+ } catch {
131
197
  return null;
132
198
  }
133
- } catch {
134
- return null;
135
199
  }
136
200
  // Return a standalone ArrayBuffer (a valid Response BodyInit). `readFile`'s
137
201
  // Buffer may be a view into a larger pooled allocation, so copy out the exact
138
202
  // byte range with `.slice` rather than handing over the backing store.
139
- const buf = await readFile(url);
203
+ const buf = await readFile(url).catch(() => {
204
+ // Never redirect after selecting a baked cohort, even if a file becomes
205
+ // unreadable between the completeness check and the byte read.
206
+ throw new HTTPException(503, { message: "baked interaction runtime is unavailable" });
207
+ });
140
208
  return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
141
209
  }
142
210
 
@@ -172,8 +240,24 @@ export function registerInstallRoutes(app: Hono, deps: ApiRouteDeps): void {
172
240
  // otherwise 302 to the GitHub Release at `redirectUrl` (mac/windows + any
173
241
  // un-baked asset). The baked path makes the agent the API enrolls against
174
242
  // identical to the API that serves it — no version skew, no extra hop.
175
- async function serveAsset(asset: string, redirectUrl: string): Promise<Response> {
176
- const baked = await readBaked(asset);
243
+ async function serveAsset(
244
+ asset: string,
245
+ redirectUrl: string,
246
+ allowBaked: boolean,
247
+ ): Promise<Response> {
248
+ const committed = COMMITTED_BINARY_ASSETS[asset];
249
+ if (committed) {
250
+ const buf = await readFile(new URL(committed.file, INSTALL_DIR));
251
+ return new Response(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength), {
252
+ status: 200,
253
+ headers: {
254
+ "content-type": committed.contentType,
255
+ "cache-control": "public, max-age=3600",
256
+ "x-opengeni-agent-source": "committed",
257
+ },
258
+ });
259
+ }
260
+ const baked = allowBaked ? await readBaked(asset) : null;
177
261
  if (baked !== null) {
178
262
  return new Response(baked, {
179
263
  status: 200,
@@ -189,7 +273,10 @@ export function registerInstallRoutes(app: Hono, deps: ApiRouteDeps): void {
189
273
  }
190
274
  // Not baked here → the GitHub Release is the source of truth (the public
191
275
  // archive + the documented install.sh fallback). 302 so the client refetches.
192
- return new Response(null, { status: 302, headers: { location: redirectUrl } });
276
+ return new Response(null, {
277
+ status: 302,
278
+ headers: { location: redirectUrl },
279
+ });
193
280
  }
194
281
 
195
282
  // `latest` → the BAKED binary if present, else the operator-selected immutable
@@ -203,7 +290,7 @@ export function registerInstallRoutes(app: Hono, deps: ApiRouteDeps): void {
203
290
  if (!ASSET_NAME.test(asset)) {
204
291
  throw new HTTPException(400, { message: "invalid asset name" });
205
292
  }
206
- return serveAsset(asset, `${releasesBase}/download/${stableAgentTag}/${asset}`);
293
+ return serveAsset(asset, `${releasesBase}/download/${stableAgentTag}/${asset}`, true);
207
294
  });
208
295
 
209
296
  // Signed self-update channel manifests. Each deployment exposes its own
@@ -217,10 +304,14 @@ export function registerInstallRoutes(app: Hono, deps: ApiRouteDeps): void {
217
304
  app.get(`/agent/${channel}/:manifestAsset`, (c) => {
218
305
  const manifestAsset = c.req.param("manifestAsset");
219
306
  if (manifestAsset !== "manifest.json" && manifestAsset !== "manifest.json.minisig") {
220
- throw new HTTPException(404, { message: "update manifest asset not found" });
307
+ throw new HTTPException(404, {
308
+ message: "update manifest asset not found",
309
+ });
221
310
  }
222
311
  if (!version) {
223
- throw new HTTPException(404, { message: `${channel} agent channel is not configured` });
312
+ throw new HTTPException(404, {
313
+ message: `${channel} agent channel is not configured`,
314
+ });
224
315
  }
225
316
  return new Response(null, {
226
317
  status: 302,
@@ -240,9 +331,13 @@ export function registerInstallRoutes(app: Hono, deps: ApiRouteDeps): void {
240
331
  // `/agent/latest/<asset>` is handled by the more specific route above; any
241
332
  // other version segment must be the `v<ver>` shape.
242
333
  if (!VERSION_SEG.test(versionSeg) || !ASSET_NAME.test(asset)) {
243
- throw new HTTPException(400, { message: "invalid version or asset name" });
334
+ throw new HTTPException(400, {
335
+ message: "invalid version or asset name",
336
+ });
244
337
  }
245
- return serveAsset(asset, `${releasesBase}/download/agent-${versionSeg}/${asset}`);
338
+ // A pinned release must never be substituted with this deployment's baked
339
+ // canary, even when its semver happens to match. The archive owns its bytes.
340
+ return serveAsset(asset, `${releasesBase}/download/agent-${versionSeg}/${asset}`, false);
246
341
  });
247
342
  }
248
343
 
@@ -1,10 +1,13 @@
1
1
  import {
2
+ assertOrganizationIntegrationAllowed,
2
3
  IntegrationFacetMutationResult,
3
4
  IntegrationFacetRemovalResult,
4
5
  IntegrationInstanceFacetsResponse,
5
6
  MutateIntegrationFacetRequest,
6
7
  UpsertIntegrationFacetRequest,
7
8
  } from "@opengeni/contracts";
9
+ import { withOrganizationIntegrationPolicyFence } from "@opengeni/db/organization-integration-policy";
10
+ import { CORE_INTEGRATION_DEFINITIONS } from "@opengeni/capabilities";
8
11
  import {
9
12
  hasPermission,
10
13
  requireAccessGrant,
@@ -13,6 +16,7 @@ import {
13
16
  } from "@opengeni/core";
14
17
  import {
15
18
  configureIntegrationFacet,
19
+ integrationFacetConfigureRequestDigest,
16
20
  IntegrationFacetBindingOwnershipConflictError,
17
21
  IntegrationFacetBindingVersionConflictError,
18
22
  IntegrationFacetBindingVersionRequiredError,
@@ -22,7 +26,9 @@ import {
22
26
  IntegrationFacetOperationIdempotencyError,
23
27
  listIntegrationInstanceFacets,
24
28
  removeIntegrationFacet,
29
+ replayCompletedIntegrationFacetOperation,
25
30
  setIntegrationFacetLifecycle,
31
+ type IntegrationFacetAcquisitionAuthorizer,
26
32
  } from "@opengeni/db";
27
33
  import type { Hono } from "hono";
28
34
  import { HTTPException } from "hono/http-exception";
@@ -31,6 +37,7 @@ import {
31
37
  browseGoogleDriveFacetSource,
32
38
  saveGoogleDriveFacetSource,
33
39
  } from "../integrations/google-drive";
40
+ import { parseRequestJson } from "../http/request-body";
34
41
 
35
42
  export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): void {
36
43
  app.get(
@@ -64,7 +71,7 @@ export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): v
64
71
  c,
65
72
  deps,
66
73
  workspaceId,
67
- "workspace:admin",
74
+ "capabilities:manage",
68
75
  );
69
76
  const { grant } = authorization;
70
77
  try {
@@ -80,7 +87,10 @@ export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): v
80
87
  payload: await c.req.json(),
81
88
  canManageOrganizationDestination:
82
89
  authorization.accountGrant?.permissions.includes("account:admin") === true,
83
- canManageWorkspaceDestination: hasPermission(grant.permissions, "workspace:admin"),
90
+ canManageWorkspaceDestination: hasPermission(
91
+ grant.permissions,
92
+ "capabilities:manage",
93
+ ),
84
94
  canManagePersonalDestination:
85
95
  authorization.contextIntegrity &&
86
96
  authorization.authenticatedSubjectId === grant.subjectId,
@@ -120,12 +130,39 @@ export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): v
120
130
  "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey",
121
131
  async (c) => {
122
132
  const workspaceId = c.req.param("workspaceId");
123
- const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
124
- const payload = UpsertIntegrationFacetRequest.parse(await c.req.json());
133
+ const grant = await requireAccessGrant(c, deps, workspaceId, "capabilities:manage");
134
+ const payload = await parseRequestJson(c, UpsertIntegrationFacetRequest);
125
135
  const capabilityId = decoded(c.req.param("capabilityId"));
126
136
  const instanceKey = decoded(c.req.param("instanceKey"));
127
137
  const facetKey = decoded(c.req.param("facetKey"));
128
138
  try {
139
+ const replayed =
140
+ await replayCompletedIntegrationFacetOperation<IntegrationFacetMutationResult>(deps.db, {
141
+ accountId: grant.accountId,
142
+ workspaceId,
143
+ subjectId: grant.subjectId,
144
+ capabilityId,
145
+ instanceKey,
146
+ facetKey,
147
+ idempotencyKey: payload.idempotencyKey,
148
+ kind: "configure",
149
+ expectedRequestDigest: integrationFacetConfigureRequestDigest({
150
+ capabilityId,
151
+ instanceKey,
152
+ facetKey,
153
+ displayName: payload.displayName,
154
+ config: payload.config,
155
+ ...(payload.expectedVersion !== undefined
156
+ ? { expectedVersion: payload.expectedVersion }
157
+ : {}),
158
+ }),
159
+ });
160
+ if (replayed) {
161
+ return c.json(
162
+ IntegrationFacetMutationResult.parse(replayed),
163
+ payload.expectedVersion === undefined ? 201 : 200,
164
+ );
165
+ }
129
166
  const instance = await listIntegrationInstanceFacets(
130
167
  deps.db,
131
168
  workspaceId,
@@ -147,20 +184,30 @@ export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): v
147
184
  }
148
185
  return c.json(
149
186
  IntegrationFacetMutationResult.parse(
150
- await configureIntegrationFacet(deps.db, {
151
- accountId: grant.accountId,
152
- workspaceId,
153
- subjectId: grant.subjectId,
154
- capabilityId,
155
- instanceKey,
156
- facetKey,
157
- displayName: payload.displayName,
158
- config: payload.config,
159
- ...(payload.expectedVersion !== undefined
160
- ? { expectedVersion: payload.expectedVersion }
161
- : {}),
162
- idempotencyKey: payload.idempotencyKey,
163
- }),
187
+ await withOrganizationIntegrationPolicyFence(
188
+ deps.db,
189
+ { accountId: grant.accountId, workspaceId },
190
+ (tx, policy) =>
191
+ configureIntegrationFacet(tx, {
192
+ accountId: grant.accountId,
193
+ workspaceId,
194
+ subjectId: grant.subjectId,
195
+ capabilityId,
196
+ instanceKey,
197
+ facetKey,
198
+ displayName: payload.displayName,
199
+ config: payload.config,
200
+ ...(payload.expectedVersion !== undefined
201
+ ? { expectedVersion: payload.expectedVersion }
202
+ : {}),
203
+ idempotencyKey: payload.idempotencyKey,
204
+ beforeAcquire: async (_db, context) =>
205
+ assertOrganizationIntegrationAllowed(
206
+ policy,
207
+ installedFacetIntegrationKey(context),
208
+ ),
209
+ }),
210
+ ),
164
211
  ),
165
212
  payload.expectedVersion === undefined ? 201 : 200,
166
213
  );
@@ -175,22 +222,32 @@ export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): v
175
222
  `/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/${action}`,
176
223
  async (c) => {
177
224
  const workspaceId = c.req.param("workspaceId");
178
- const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
179
- const payload = MutateIntegrationFacetRequest.parse(await c.req.json());
225
+ const grant = await requireAccessGrant(c, deps, workspaceId, "capabilities:manage");
226
+ const payload = await parseRequestJson(c, MutateIntegrationFacetRequest);
180
227
  try {
181
228
  return c.json(
182
229
  IntegrationFacetMutationResult.parse(
183
- await setIntegrationFacetLifecycle(deps.db, {
184
- accountId: grant.accountId,
185
- workspaceId,
186
- subjectId: grant.subjectId,
187
- capabilityId: decoded(c.req.param("capabilityId")),
188
- instanceKey: decoded(c.req.param("instanceKey")),
189
- facetKey: decoded(c.req.param("facetKey")),
190
- action,
191
- expectedVersion: payload.expectedVersion,
192
- idempotencyKey: payload.idempotencyKey,
193
- }),
230
+ await withOrganizationIntegrationPolicyFence(
231
+ deps.db,
232
+ { accountId: grant.accountId, workspaceId },
233
+ (tx, policy) =>
234
+ setIntegrationFacetLifecycle(tx, {
235
+ accountId: grant.accountId,
236
+ workspaceId,
237
+ subjectId: grant.subjectId,
238
+ capabilityId: decoded(c.req.param("capabilityId")),
239
+ instanceKey: decoded(c.req.param("instanceKey")),
240
+ facetKey: decoded(c.req.param("facetKey")),
241
+ action,
242
+ expectedVersion: payload.expectedVersion,
243
+ idempotencyKey: payload.idempotencyKey,
244
+ beforeAcquire: async (_db, context) =>
245
+ assertOrganizationIntegrationAllowed(
246
+ policy,
247
+ installedFacetIntegrationKey(context),
248
+ ),
249
+ }),
250
+ ),
194
251
  ),
195
252
  );
196
253
  } catch (error) {
@@ -204,8 +261,8 @@ export function registerIntegrationFacetRoutes(app: Hono, deps: ApiRouteDeps): v
204
261
  "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey",
205
262
  async (c) => {
206
263
  const workspaceId = c.req.param("workspaceId");
207
- const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
208
- const payload = MutateIntegrationFacetRequest.parse(await c.req.json());
264
+ const grant = await requireAccessGrant(c, deps, workspaceId, "capabilities:manage");
265
+ const payload = await parseRequestJson(c, MutateIntegrationFacetRequest);
209
266
  try {
210
267
  return c.json(
211
268
  IntegrationFacetRemovalResult.parse(
@@ -232,6 +289,23 @@ function decoded(value: string): string {
232
289
  return decodeURIComponent(value);
233
290
  }
234
291
 
292
+ /** The DB context comes from the matching installed API facet and immutable
293
+ * server-authored version manifest, never request metadata or a provider domain.
294
+ */
295
+ function installedFacetIntegrationKey(
296
+ context: Parameters<IntegrationFacetAcquisitionAuthorizer>[1],
297
+ ): string | null {
298
+ if (context.apiProtocol !== "openapi" && context.apiProtocol !== "graphql") return null;
299
+ if (context.definitionProvenance === "workspace") return `custom:${context.apiProtocol}`;
300
+ if (
301
+ context.definitionProvenance === "curated" &&
302
+ CORE_INTEGRATION_DEFINITIONS.some((definition) => definition.id === context.definitionId)
303
+ ) {
304
+ return context.definitionId;
305
+ }
306
+ return null;
307
+ }
308
+
235
309
  function facetHttpError(error: unknown): HTTPException {
236
310
  if (error instanceof HTTPException) return error;
237
311
  if (error instanceof IntegrationFacetNotFoundError) {
@@ -45,9 +45,12 @@ import {
45
45
  updateSiteAuthConnection,
46
46
  } from "@opengeni/db";
47
47
  import {
48
+ getManagedAuthRequestActorEpoch,
48
49
  SessionAuthorizationDeniedError,
49
50
  SessionAuthorizationUnavailableError,
50
51
  requireAccessGrant,
52
+ requireFreshAccessGrant,
53
+ requirePermission,
51
54
  requireSessionAuthorization,
52
55
  type ApiRouteDeps,
53
56
  workflowIdForSession,
@@ -55,7 +58,11 @@ import {
55
58
  import { publishDurableSessionEvents } from "@opengeni/events";
56
59
  import type { Context, Hono } from "hono";
57
60
  import { HTTPException } from "hono/http-exception";
58
- import { sseWorkspaceInteractionRevisionStream, sseWorkspaceLiveStream } from "../http/sse";
61
+ import {
62
+ browserSseDeliveryOptions,
63
+ sseWorkspaceInteractionRevisionStream,
64
+ sseWorkspaceLiveStream,
65
+ } from "../http/sse";
59
66
  import { observeInterventionMutation } from "../interaction-metrics";
60
67
 
61
68
  export function registerInteractionResourceRoutes(app: Hono, deps: ApiRouteDeps): void {
@@ -70,7 +77,20 @@ export function registerInteractionResourceRoutes(app: Hono, deps: ApiRouteDeps)
70
77
  nonnegativeSafeIntegerQuery(context, "controlAfter", 0),
71
78
  nonnegativeSafeIntegerQuery(context, "interactionAfter", 0),
72
79
  context.req.raw.signal,
73
- { observability: deps.observability },
80
+ {
81
+ ...browserSseDeliveryOptions(context.req.query("transport")),
82
+ observability: deps.observability,
83
+ actorEpoch: getManagedAuthRequestActorEpoch(context.req.raw) ?? undefined,
84
+ reauthorize: async () => {
85
+ const freshGrant = await requireFreshAccessGrant(
86
+ context,
87
+ deps,
88
+ workspaceId,
89
+ "sessions:read",
90
+ );
91
+ requirePermission(freshGrant, "workspace:read");
92
+ },
93
+ },
74
94
  );
75
95
  });
76
96
 
@@ -83,7 +103,14 @@ export function registerInteractionResourceRoutes(app: Hono, deps: ApiRouteDeps)
83
103
  workspaceId,
84
104
  after,
85
105
  context.req.raw.signal,
86
- { observability: deps.observability },
106
+ {
107
+ ...browserSseDeliveryOptions(context.req.query("transport")),
108
+ observability: deps.observability,
109
+ actorEpoch: getManagedAuthRequestActorEpoch(context.req.raw) ?? undefined,
110
+ reauthorize: async () => {
111
+ await requireFreshAccessGrant(context, deps, workspaceId, "sessions:read");
112
+ },
113
+ },
87
114
  );
88
115
  });
89
116