@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
@@ -0,0 +1,293 @@
1
+ import { claudeProviderId } from "@opengeni/config";
2
+ import {
3
+ CreateOrganizationProviderCustomModelRequest,
4
+ DeleteOrganizationProviderCustomModelRequest,
5
+ OrganizationModelProviderConnectionResponse,
6
+ OrganizationModelProviderKind,
7
+ OrganizationProviderCustomModel,
8
+ OrganizationProviderCustomModelsResponse,
9
+ RevokeOrganizationModelProviderConnectionRequest,
10
+ UpsertOrganizationModelProviderConnectionRequest,
11
+ } from "@opengeni/contracts";
12
+ import { requireEnvironmentEncryption, type ApiRouteDeps } from "@opengeni/core";
13
+ import {
14
+ createOrganizationModelProviderCustomModel,
15
+ encryptEnvironmentValue,
16
+ getOrganizationModelProviderConnection,
17
+ listOrganizationModelProviderCustomModels,
18
+ organizationModelProviderCredentialDigest,
19
+ OrganizationModelProviderConflictError,
20
+ OrganizationModelProviderLimitError,
21
+ retireOrganizationModelProviderCustomModel,
22
+ revokeOrganizationModelProviderConnection,
23
+ upsertOrganizationModelProviderConnection,
24
+ } from "@opengeni/db";
25
+ import type { Context, Hono } from "hono";
26
+ import { HTTPException } from "hono/http-exception";
27
+ import { z } from "zod";
28
+
29
+ import { requireOrganizationCodexHuman, requireSameOriginBrowserMutation } from "./codex";
30
+
31
+ const OrganizationId = z.string().uuid();
32
+
33
+ function parseOrganizationId(value: string): string {
34
+ const parsed = OrganizationId.safeParse(value);
35
+ if (!parsed.success) throw new HTTPException(404, { message: "organization not found" });
36
+ return parsed.data;
37
+ }
38
+
39
+ async function jsonBody<T>(c: Context, schema: z.ZodType<T>, message: string): Promise<T> {
40
+ const parsed = schema.safeParse(await c.req.json().catch(() => null));
41
+ if (!parsed.success) throw new HTTPException(422, { message });
42
+ return parsed.data;
43
+ }
44
+
45
+ function providerKind(value: string) {
46
+ const parsed = OrganizationModelProviderKind.safeParse(value);
47
+ if (!parsed.success) throw new HTTPException(404, { message: "model provider not found" });
48
+ return parsed.data;
49
+ }
50
+
51
+ function connectionJson(connection: {
52
+ providerKind: "vercel_gateway" | "openrouter" | "anthropic" | "claude_subscription";
53
+ status: "active" | "revoked";
54
+ version: number;
55
+ createdAt: Date;
56
+ updatedAt: Date;
57
+ }) {
58
+ return OrganizationModelProviderConnectionResponse.parse({
59
+ ...connection,
60
+ createdAt: connection.createdAt.toISOString(),
61
+ updatedAt: connection.updatedAt.toISOString(),
62
+ });
63
+ }
64
+
65
+ function modelJson(model: {
66
+ id: string;
67
+ upstreamModelId: string;
68
+ label: string | null;
69
+ version: number;
70
+ createdAt: Date;
71
+ updatedAt: Date;
72
+ }) {
73
+ return OrganizationProviderCustomModel.parse({
74
+ ...model,
75
+ createdAt: model.createdAt.toISOString(),
76
+ updatedAt: model.updatedAt.toISOString(),
77
+ });
78
+ }
79
+
80
+ function conflict(error: unknown): never {
81
+ if (error instanceof OrganizationModelProviderConflictError) {
82
+ throw new HTTPException(409, { message: "organization model provider version conflict" });
83
+ }
84
+ if (error instanceof OrganizationModelProviderLimitError) {
85
+ throw new HTTPException(409, { message: "organization custom model limit reached" });
86
+ }
87
+ throw error;
88
+ }
89
+
90
+ export function registerOrganizationModelProviderRoutes(app: Hono, deps: ApiRouteDeps): void {
91
+ app.use("/v1/organizations/:organizationId/model-providers/:providerKind", async (c, next) => {
92
+ if (
93
+ c.req.param("providerKind") === "claude_subscription" &&
94
+ !deps.settings.claudeSubscriptionEnabled
95
+ )
96
+ throw new HTTPException(404, { message: "Claude subscriptions are not enabled" });
97
+ await next();
98
+ });
99
+ app.use("/v1/organizations/:organizationId/model-providers/:providerKind/*", async (c, next) => {
100
+ if (
101
+ c.req.param("providerKind") === "claude_subscription" &&
102
+ !deps.settings.claudeSubscriptionEnabled
103
+ )
104
+ throw new HTTPException(404, { message: "Claude subscriptions are not enabled" });
105
+ await next();
106
+ });
107
+ app.get("/v1/organizations/:organizationId/model-providers/:providerKind", async (c) => {
108
+ c.header("cache-control", "private, no-store");
109
+ const organizationId = parseOrganizationId(c.req.param("organizationId"));
110
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
111
+ if (c.req.param("providerKind") === "claude_subscription")
112
+ throw new HTTPException(410, { message: "Claude subscriptions use individual accounts." });
113
+ const connection = await getOrganizationModelProviderConnection(deps.db, {
114
+ organizationId,
115
+ actorSubjectId: human.subjectId,
116
+ providerKind: providerKind(c.req.param("providerKind")),
117
+ });
118
+ return connection ? c.json(connectionJson(connection)) : c.json(null);
119
+ });
120
+ const usagePath = "/v1/organizations/:organizationId/model-providers/:providerKind/usage";
121
+ async function usageScope(c: Context) {
122
+ c.header("cache-control", "private, no-store");
123
+ if (providerKind(c.req.param("providerKind")!) !== "claude_subscription")
124
+ throw new HTTPException(404, { message: "Usage not available for this provider" });
125
+ const organizationId = parseOrganizationId(c.req.param("organizationId")!);
126
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
127
+ return {
128
+ accountId: organizationId,
129
+ workspaceId: null,
130
+ scope: "organization" as const,
131
+ actorSubjectId: human.subjectId,
132
+ };
133
+ }
134
+ app.get(usagePath, async (c) => {
135
+ await usageScope(c);
136
+ throw new HTTPException(410, { message: "Check usage on the individual Claude account." });
137
+ });
138
+ app.post(`${usagePath}/refresh`, async (c) => {
139
+ requireSameOriginBrowserMutation(c, deps);
140
+ await usageScope(c);
141
+ throw new HTTPException(410, { message: "Check usage on the individual Claude account." });
142
+ });
143
+
144
+ app.put("/v1/organizations/:organizationId/model-providers/:providerKind", async (c) => {
145
+ c.header("cache-control", "private, no-store");
146
+ requireSameOriginBrowserMutation(c, deps);
147
+ const organizationId = parseOrganizationId(c.req.param("organizationId"));
148
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
149
+ const payload = await jsonBody(
150
+ c,
151
+ UpsertOrganizationModelProviderConnectionRequest,
152
+ "invalid organization model provider connection",
153
+ );
154
+ const kind = providerKind(c.req.param("providerKind"));
155
+ if (kind === "claude_subscription")
156
+ throw new HTTPException(410, { message: "Claude subscriptions use individual accounts." });
157
+ if (kind === "anthropic" && !/^sk-ant-api[0-9]+-\S+$/.test(payload.apiKey))
158
+ throw new HTTPException(422, {
159
+ message: "Enter an Anthropic API key. Use Claude subscription for setup tokens.",
160
+ });
161
+ if (payload.claudeIdentity)
162
+ throw new HTTPException(422, {
163
+ message: "Claude identity is only valid for subscription connections.",
164
+ });
165
+ const credential = payload.apiKey;
166
+ try {
167
+ const connection = await upsertOrganizationModelProviderConnection(deps.db, {
168
+ organizationId,
169
+ actorSubjectId: human.subjectId,
170
+ providerKind: providerKind(c.req.param("providerKind")),
171
+ credentialEncrypted: encryptEnvironmentValue(
172
+ requireEnvironmentEncryption(deps.settings),
173
+ credential,
174
+ ),
175
+ credentialDigest: organizationModelProviderCredentialDigest(credential),
176
+ operationId: payload.operationId,
177
+ ...(payload.expectedVersion === undefined
178
+ ? {}
179
+ : { expectedVersion: payload.expectedVersion }),
180
+ });
181
+ return c.json(connectionJson(connection));
182
+ } catch (error) {
183
+ conflict(error);
184
+ }
185
+ });
186
+
187
+ app.delete("/v1/organizations/:organizationId/model-providers/:providerKind", async (c) => {
188
+ c.header("cache-control", "private, no-store");
189
+ requireSameOriginBrowserMutation(c, deps);
190
+ const organizationId = parseOrganizationId(c.req.param("organizationId"));
191
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
192
+ const payload = await jsonBody(
193
+ c,
194
+ RevokeOrganizationModelProviderConnectionRequest,
195
+ "invalid organization model provider disconnect",
196
+ );
197
+ try {
198
+ if (c.req.param("providerKind") === "claude_subscription")
199
+ throw new HTTPException(410, { message: "Claude subscriptions use individual accounts." });
200
+ const connection = await revokeOrganizationModelProviderConnection(deps.db, {
201
+ organizationId,
202
+ actorSubjectId: human.subjectId,
203
+ providerKind: providerKind(c.req.param("providerKind")),
204
+ ...payload,
205
+ });
206
+ return c.json(connectionJson(connection));
207
+ } catch (error) {
208
+ conflict(error);
209
+ }
210
+ });
211
+
212
+ app.get(
213
+ "/v1/organizations/:organizationId/model-providers/:providerKind/custom-models",
214
+ async (c) => {
215
+ c.header("cache-control", "private, no-store");
216
+ const organizationId = parseOrganizationId(c.req.param("organizationId"));
217
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
218
+ const models = await listOrganizationModelProviderCustomModels(deps.db, {
219
+ organizationId,
220
+ actorSubjectId: human.subjectId,
221
+ providerKind: providerKind(c.req.param("providerKind")),
222
+ });
223
+ return c.json(
224
+ OrganizationProviderCustomModelsResponse.parse({ models: models.map(modelJson) }),
225
+ );
226
+ },
227
+ );
228
+
229
+ app.post(
230
+ "/v1/organizations/:organizationId/model-providers/:providerKind/custom-models",
231
+ async (c) => {
232
+ c.header("cache-control", "private, no-store");
233
+ requireSameOriginBrowserMutation(c, deps);
234
+ const organizationId = parseOrganizationId(c.req.param("organizationId"));
235
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
236
+ const payload = await jsonBody(
237
+ c,
238
+ CreateOrganizationProviderCustomModelRequest,
239
+ "invalid organization custom model",
240
+ );
241
+ const kind = providerKind(c.req.param("providerKind"));
242
+ if (
243
+ (kind === "anthropic" || kind === "claude_subscription") &&
244
+ `${claudeProviderId(kind)}/${payload.upstreamModelId}`.length > 256
245
+ )
246
+ throw new HTTPException(422, { message: "Claude model ID is too long" });
247
+ try {
248
+ const model = await createOrganizationModelProviderCustomModel(deps.db, {
249
+ organizationId,
250
+ actorSubjectId: human.subjectId,
251
+ providerKind: providerKind(c.req.param("providerKind")),
252
+ operationId: payload.operationId,
253
+ upstreamModelId: payload.upstreamModelId,
254
+ ...(payload.label === undefined ? {} : { label: payload.label }),
255
+ });
256
+ return c.json(modelJson(model), 201);
257
+ } catch (error) {
258
+ conflict(error);
259
+ }
260
+ },
261
+ );
262
+
263
+ app.delete(
264
+ "/v1/organizations/:organizationId/model-providers/:providerKind/custom-models/:customModelId",
265
+ async (c) => {
266
+ c.header("cache-control", "private, no-store");
267
+ requireSameOriginBrowserMutation(c, deps);
268
+ const organizationId = parseOrganizationId(c.req.param("organizationId"));
269
+ const human = await requireOrganizationCodexHuman(c, deps, organizationId);
270
+ const payload = await jsonBody(
271
+ c,
272
+ DeleteOrganizationProviderCustomModelRequest,
273
+ "invalid organization custom model deletion",
274
+ );
275
+ const customModelId = z.string().uuid().safeParse(c.req.param("customModelId"));
276
+ if (!customModelId.success) {
277
+ throw new HTTPException(422, { message: "invalid organization custom model id" });
278
+ }
279
+ try {
280
+ const model = await retireOrganizationModelProviderCustomModel(deps.db, {
281
+ organizationId,
282
+ actorSubjectId: human.subjectId,
283
+ providerKind: providerKind(c.req.param("providerKind")),
284
+ customModelId: customModelId.data,
285
+ ...payload,
286
+ });
287
+ return c.json(modelJson(model));
288
+ } catch (error) {
289
+ conflict(error);
290
+ }
291
+ },
292
+ );
293
+ }
@@ -0,0 +1,325 @@
1
+ import {
2
+ AcceptOrganizationRecoveryCustodyRequest,
3
+ ConfigureOrganizationRecoveryPolicyRequest,
4
+ DisableOrganizationRecoveryPolicyRequest,
5
+ OrganizationRecoveryMutationResponse,
6
+ OrganizationRecoveryOperationCommandRequest,
7
+ OrganizationRecoveryOverview,
8
+ StartOrganizationRecoveryOperationRequest,
9
+ } from "@opengeni/contracts/organization-recovery";
10
+ import {
11
+ getManagedAuthRequestActorAdmissionStamp,
12
+ getManagedAuthRequestActorLeaseStamp,
13
+ requireCanonicalHumanRequestIdentity,
14
+ } from "@opengeni/core/canonical-human-identities";
15
+ import type { ApiRouteDeps } from "@opengeni/core";
16
+ import {
17
+ acceptOrganizationRecoveryCustody,
18
+ approveOrganizationRecoveryOperation,
19
+ cancelOrganizationRecoveryOperation,
20
+ configureOrganizationRecoveryPolicy,
21
+ disableOrganizationRecoveryPolicy,
22
+ executeOrganizationRecoveryOperation,
23
+ getOrganizationRecoveryOverview,
24
+ OrganizationRecoveryDeniedError,
25
+ OrganizationRecoveryOperationReuseError,
26
+ OrganizationRecoveryRevisionConflictError,
27
+ OrganizationRecoveryUnavailableError,
28
+ startOrganizationRecoveryOperation,
29
+ } from "@opengeni/db";
30
+ import type { Context, Hono } from "hono";
31
+ import { HTTPException } from "hono/http-exception";
32
+ import { z } from "zod";
33
+ import { ApiHttpError } from "../http/api-error";
34
+
35
+ const OrganizationId = z.string().uuid();
36
+ const RecoveryOperationId = z.string().uuid();
37
+
38
+ export type OrganizationRecoveryRouteServices = {
39
+ requireCanonicalHumanRequestIdentity: typeof requireCanonicalHumanRequestIdentity;
40
+ getManagedAuthRequestActorAdmissionStamp: typeof getManagedAuthRequestActorAdmissionStamp;
41
+ getManagedAuthRequestActorLeaseStamp: typeof getManagedAuthRequestActorLeaseStamp;
42
+ getOrganizationRecoveryOverview: typeof getOrganizationRecoveryOverview;
43
+ configureOrganizationRecoveryPolicy: typeof configureOrganizationRecoveryPolicy;
44
+ acceptOrganizationRecoveryCustody: typeof acceptOrganizationRecoveryCustody;
45
+ disableOrganizationRecoveryPolicy: typeof disableOrganizationRecoveryPolicy;
46
+ startOrganizationRecoveryOperation: typeof startOrganizationRecoveryOperation;
47
+ approveOrganizationRecoveryOperation: typeof approveOrganizationRecoveryOperation;
48
+ cancelOrganizationRecoveryOperation: typeof cancelOrganizationRecoveryOperation;
49
+ executeOrganizationRecoveryOperation: typeof executeOrganizationRecoveryOperation;
50
+ };
51
+
52
+ const productionServices: OrganizationRecoveryRouteServices = {
53
+ requireCanonicalHumanRequestIdentity,
54
+ getManagedAuthRequestActorAdmissionStamp,
55
+ getManagedAuthRequestActorLeaseStamp,
56
+ getOrganizationRecoveryOverview,
57
+ configureOrganizationRecoveryPolicy,
58
+ acceptOrganizationRecoveryCustody,
59
+ disableOrganizationRecoveryPolicy,
60
+ startOrganizationRecoveryOperation,
61
+ approveOrganizationRecoveryOperation,
62
+ cancelOrganizationRecoveryOperation,
63
+ executeOrganizationRecoveryOperation,
64
+ };
65
+
66
+ async function requireRecoveryIdentity(
67
+ context: Context,
68
+ deps: ApiRouteDeps,
69
+ services: OrganizationRecoveryRouteServices,
70
+ ) {
71
+ // Recovery is a browser-session ceremony. Never let ambient API, bearer,
72
+ // service, or machine authority become a competing recovery identity.
73
+ if (
74
+ deps.settings.productAccessMode !== "managed" ||
75
+ !deps.managedAuth ||
76
+ !context.req.header("cookie") ||
77
+ context.req.header("authorization")
78
+ ) {
79
+ throw new HTTPException(401, {
80
+ message: "Managed human authentication required",
81
+ });
82
+ }
83
+ const identity = await services.requireCanonicalHumanRequestIdentity(context, {
84
+ db: deps.db,
85
+ managedAuth: deps.managedAuth,
86
+ managedAuthSessionAdapter: deps.managedAuthSessionAdapter,
87
+ managedAuthSessionSetMode: deps.settings.managedAuthSessionSetMode,
88
+ allowRecovery: false,
89
+ });
90
+ return { ...identity, actorSubjectId: `user:${identity.authUserId}` };
91
+ }
92
+
93
+ async function parseBody<S extends z.ZodType>(context: Context, schema: S): Promise<z.infer<S>> {
94
+ const parsed = schema.safeParse(await context.req.json().catch(() => null));
95
+ if (!parsed.success) {
96
+ throw new HTTPException(422, {
97
+ message: "Invalid organization recovery request",
98
+ });
99
+ }
100
+ return parsed.data;
101
+ }
102
+
103
+ function parseId(schema: z.ZodString, value: string, label: string): string {
104
+ const parsed = schema.safeParse(value);
105
+ if (!parsed.success) throw new HTTPException(422, { message: `Invalid ${label}` });
106
+ return parsed.data;
107
+ }
108
+
109
+ function organizationId(context: Context): string {
110
+ return parseId(OrganizationId, context.req.param("organizationId") ?? "", "organization id");
111
+ }
112
+
113
+ function recoveryOperationId(context: Context): string {
114
+ return parseId(
115
+ RecoveryOperationId,
116
+ context.req.param("recoveryOperationId") ?? "",
117
+ "recovery operation id",
118
+ );
119
+ }
120
+
121
+ export function organizationRecoveryHttpError(error: unknown): Error {
122
+ if (error instanceof OrganizationRecoveryRevisionConflictError) {
123
+ return new ApiHttpError(409, {
124
+ code: "conflict",
125
+ message: "Recovery state changed; refresh before submitting a new action.",
126
+ retryable: false,
127
+ outcomeUnknown: false,
128
+ details: { code: error.code },
129
+ });
130
+ }
131
+ if (error instanceof OrganizationRecoveryOperationReuseError) {
132
+ return new ApiHttpError(409, {
133
+ code: "idempotency_conflict",
134
+ message: "Operation id was reused with different input.",
135
+ retryable: false,
136
+ outcomeUnknown: false,
137
+ details: { code: error.code },
138
+ });
139
+ }
140
+ if (error instanceof OrganizationRecoveryUnavailableError) {
141
+ return new ApiHttpError(409, {
142
+ code: "conflict",
143
+ message: "Organization recovery is unavailable.",
144
+ retryable: false,
145
+ outcomeUnknown: false,
146
+ details: { code: error.code },
147
+ });
148
+ }
149
+ if (error instanceof OrganizationRecoveryDeniedError) {
150
+ return new ApiHttpError(404, {
151
+ code: "not_found",
152
+ message: "Organization recovery not found.",
153
+ retryable: false,
154
+ outcomeUnknown: false,
155
+ });
156
+ }
157
+ if (error instanceof Error) return error;
158
+ return new Error("Organization recovery failed");
159
+ }
160
+
161
+ function requireActorFence(
162
+ context: Context,
163
+ deps: ApiRouteDeps,
164
+ services: OrganizationRecoveryRouteServices,
165
+ ) {
166
+ const actorFence = services.getManagedAuthRequestActorLeaseStamp(context.req.raw);
167
+ if (deps.settings.managedAuthSessionSetMode !== "legacy" && !actorFence) {
168
+ throw new HTTPException(409, {
169
+ message: "Managed actor mutation fence is unavailable",
170
+ });
171
+ }
172
+ if (!actorFence) {
173
+ throw new HTTPException(409, {
174
+ message: "Organization recovery requires provider-neutral browser login slots",
175
+ });
176
+ }
177
+ return actorFence;
178
+ }
179
+
180
+ async function mutationContext(
181
+ context: Context,
182
+ deps: ApiRouteDeps,
183
+ services: OrganizationRecoveryRouteServices,
184
+ ) {
185
+ const identity = await requireRecoveryIdentity(context, deps, services);
186
+ return {
187
+ organizationId: organizationId(context),
188
+ actorSubjectId: identity.actorSubjectId,
189
+ actorAuthUserId: identity.authUserId,
190
+ actorAuthSessionId: identity.authSessionId,
191
+ actorFence: requireActorFence(context, deps, services),
192
+ };
193
+ }
194
+
195
+ function mutationResponse(context: Context, value: unknown): Response {
196
+ return context.json(OrganizationRecoveryMutationResponse.parse(value));
197
+ }
198
+
199
+ export function registerOrganizationRecoveryRoutes(
200
+ app: Hono,
201
+ deps: ApiRouteDeps,
202
+ services: OrganizationRecoveryRouteServices = productionServices,
203
+ ): void {
204
+ const base = "/v1/organizations/:organizationId/recovery";
205
+
206
+ app.get(base, async (context) => {
207
+ const identity = await requireRecoveryIdentity(context, deps, services);
208
+ try {
209
+ return context.json(
210
+ OrganizationRecoveryOverview.parse(
211
+ await services.getOrganizationRecoveryOverview(deps.db, {
212
+ organizationId: organizationId(context),
213
+ actorSubjectId: identity.actorSubjectId,
214
+ actorAuthUserId: identity.authUserId,
215
+ actorAuthSessionId: identity.authSessionId,
216
+ actorFence: services.getManagedAuthRequestActorAdmissionStamp(context.req.raw) ?? null,
217
+ }),
218
+ ),
219
+ );
220
+ } catch (error) {
221
+ throw organizationRecoveryHttpError(error);
222
+ }
223
+ });
224
+
225
+ app.put(`${base}/policy`, async (context) => {
226
+ const authority = await mutationContext(context, deps, services);
227
+ const payload = await parseBody(context, ConfigureOrganizationRecoveryPolicyRequest);
228
+ try {
229
+ return mutationResponse(
230
+ context,
231
+ await services.configureOrganizationRecoveryPolicy(deps.db, {
232
+ ...authority,
233
+ operationId: payload.operationId,
234
+ expectedPolicyRevision: payload.expectedPolicyRevision,
235
+ custodianMembershipIds: payload.custodianMembershipIds,
236
+ }),
237
+ );
238
+ } catch (error) {
239
+ throw organizationRecoveryHttpError(error);
240
+ }
241
+ });
242
+
243
+ app.post(`${base}/policy/accept`, async (context) => {
244
+ const authority = await mutationContext(context, deps, services);
245
+ const payload = await parseBody(context, AcceptOrganizationRecoveryCustodyRequest);
246
+ try {
247
+ return mutationResponse(
248
+ context,
249
+ await services.acceptOrganizationRecoveryCustody(deps.db, {
250
+ ...authority,
251
+ operationId: payload.operationId,
252
+ expectedPolicyRevision: payload.expectedPolicyRevision,
253
+ }),
254
+ );
255
+ } catch (error) {
256
+ throw organizationRecoveryHttpError(error);
257
+ }
258
+ });
259
+
260
+ app.post(`${base}/policy/disable`, async (context) => {
261
+ const authority = await mutationContext(context, deps, services);
262
+ const payload = await parseBody(context, DisableOrganizationRecoveryPolicyRequest);
263
+ try {
264
+ return mutationResponse(
265
+ context,
266
+ await services.disableOrganizationRecoveryPolicy(deps.db, {
267
+ ...authority,
268
+ operationId: payload.operationId,
269
+ expectedPolicyRevision: payload.expectedPolicyRevision,
270
+ }),
271
+ );
272
+ } catch (error) {
273
+ throw organizationRecoveryHttpError(error);
274
+ }
275
+ });
276
+
277
+ app.post(`${base}/operations`, async (context) => {
278
+ const authority = await mutationContext(context, deps, services);
279
+ const payload = await parseBody(context, StartOrganizationRecoveryOperationRequest);
280
+ try {
281
+ return mutationResponse(
282
+ context,
283
+ await services.startOrganizationRecoveryOperation(deps.db, {
284
+ ...authority,
285
+ operationId: payload.operationId,
286
+ expectedPolicyRevision: payload.expectedPolicyRevision,
287
+ targetMembershipId: payload.targetMembershipId,
288
+ }),
289
+ );
290
+ } catch (error) {
291
+ throw organizationRecoveryHttpError(error);
292
+ }
293
+ });
294
+
295
+ async function mutateOperation(
296
+ context: Context,
297
+ command: typeof approveOrganizationRecoveryOperation,
298
+ ): Promise<Response> {
299
+ const authority = await mutationContext(context, deps, services);
300
+ const payload = await parseBody(context, OrganizationRecoveryOperationCommandRequest);
301
+ try {
302
+ return mutationResponse(
303
+ context,
304
+ await command(deps.db, {
305
+ ...authority,
306
+ recoveryOperationId: recoveryOperationId(context),
307
+ operationId: payload.operationId,
308
+ expectedOperationRevision: payload.expectedOperationRevision,
309
+ }),
310
+ );
311
+ } catch (error) {
312
+ throw organizationRecoveryHttpError(error);
313
+ }
314
+ }
315
+
316
+ app.post(`${base}/operations/:recoveryOperationId/approve`, async (context) =>
317
+ mutateOperation(context, services.approveOrganizationRecoveryOperation),
318
+ );
319
+ app.post(`${base}/operations/:recoveryOperationId/cancel`, async (context) =>
320
+ mutateOperation(context, services.cancelOrganizationRecoveryOperation),
321
+ );
322
+ app.post(`${base}/operations/:recoveryOperationId/execute`, async (context) =>
323
+ mutateOperation(context, services.executeOrganizationRecoveryOperation),
324
+ );
325
+ }