@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
@@ -1,11 +1,15 @@
1
1
  import {
2
2
  CORE_INTEGRATION_DEFINITIONS,
3
+ INTEGRATION_DEFINITION_PRESENTATIONS,
4
+ autoApprovalForbidden,
3
5
  createPinnedIntegrationTransport,
6
+ integrationDefinitionById,
4
7
  integrationFacetDefinitions,
5
8
  type IntegrationCredentialResolver,
6
9
  } from "@opengeni/capabilities";
7
10
  import {
8
11
  ApiIntegrationPreview,
12
+ OrganizationIntegrationDeniedError,
9
13
  ListIntegrationDefinitionsResponse,
10
14
  ApiIntegrationUninstallPreview,
11
15
  InstallApiIntegrationRequest,
@@ -14,13 +18,21 @@ import {
14
18
  PreviewApiIntegrationRequest,
15
19
  UninstallApiIntegrationRequest,
16
20
  UninstallApiIntegrationResult,
21
+ type AccessGrant,
17
22
  } from "@opengeni/contracts";
18
- import { requireAccessGrant, type ApiRouteDeps } from "@opengeni/core";
19
23
  import {
24
+ requireAccessGrant,
25
+ integrationSourceForOrganizationPolicy,
26
+ type ApiRouteDeps,
27
+ } from "@opengeni/core";
28
+ import { withOrganizationIntegrationPolicyFence } from "@opengeni/db/organization-integration-policy";
29
+ import {
30
+ ApiIntegrationConnectionReferenceError,
20
31
  ApiIntegrationInstallationVersionConflictError,
21
32
  buildConnectionTokenResolver,
22
33
  getApiIntegrationUninstallPreview,
23
34
  getConnectionMetadata,
35
+ getApiIntegrationReconciliationSnapshot,
24
36
  installApiIntegration,
25
37
  IntegrationFacetBindingOwnershipConflictError,
26
38
  IntegrationFacetBindingVersionConflictError,
@@ -36,7 +48,10 @@ import { HTTPException } from "hono/http-exception";
36
48
  import {
37
49
  resolveApiIntegrationPreview,
38
50
  type ApiIntegrationConnectionDescriptor,
51
+ type ResolvedApiIntegrationPreview,
39
52
  } from "../integrations/api-integrations";
53
+ import { ApiHttpError } from "../http/api-error";
54
+ import { parseRequestJson } from "../http/request-body";
40
55
 
41
56
  export type ApiIntegrationRouteOverrides = Readonly<{ fetchImpl?: FetchLike }>;
42
57
 
@@ -45,6 +60,146 @@ export function apiIntegrationRequiresConnection(authScheme: Record<string, unkn
45
60
  return typeof authKind === "string" && authKind !== "none";
46
61
  }
47
62
 
63
+ /** Shared native/embedded install validation. The caller must still authorize
64
+ * capabilities:manage and commit under its own live-authority boundary. */
65
+ export function validatedIntegrationInstallInput(
66
+ grant: AccessGrant,
67
+ workspaceId: string,
68
+ payload: InstallApiIntegrationRequest,
69
+ resolved: ResolvedApiIntegrationPreview,
70
+ ): Parameters<typeof installApiIntegration>[1] {
71
+ if (
72
+ resolved.preview.revisionId !== payload.expectedRevisionId ||
73
+ resolved.preview.contentSha256 !== payload.expectedContentSha256
74
+ ) {
75
+ throw new HTTPException(409, {
76
+ message:
77
+ "The Integration source changed after preview. Review the new tools and permissions before installing.",
78
+ });
79
+ }
80
+ if (resolved.preview.auth.kind !== "none" && !payload.connectionId)
81
+ throw new HTTPException(422, {
82
+ message: "Connect an account before installing this Integration.",
83
+ });
84
+ if (
85
+ payload.ownership &&
86
+ resolved.preview.connectionOwnership &&
87
+ payload.ownership !== resolved.preview.connectionOwnership
88
+ )
89
+ throw new HTTPException(422, {
90
+ message: "The selected Connection ownership does not match this install request.",
91
+ });
92
+ if (payload.ownership === "personal" && !resolved.preview.connectionOwnership)
93
+ throw new HTTPException(422, {
94
+ message: "Choose a Personal Connection before installing for yourself.",
95
+ });
96
+ if (payload.autoApprovedTools?.length) {
97
+ const selected = new Set(payload.allowedTools ?? resolved.preview.tools.map((tool) => tool.id));
98
+ const outside = payload.autoApprovedTools.find((tool) => !selected.has(tool));
99
+ if (outside)
100
+ throw new HTTPException(422, {
101
+ message: `autoApprovedTools must name selected Integration tools: ${outside.slice(0, 200)}`,
102
+ });
103
+ // Curated and custom Integrations share one rule (capabilities:manage plus
104
+ // the organization acquisition recheck in the installer); only a curated
105
+ // definition's reviewed governance can forbid an exemption.
106
+ if (resolved.preview.definitionProvenance === "curated") {
107
+ const definition = integrationDefinitionById(resolved.preview.definitionId);
108
+ const forbidden = resolved.preview.tools.find(
109
+ (tool) =>
110
+ payload.autoApprovedTools!.includes(tool.id) &&
111
+ autoApprovalForbidden(definition, tool.operationKey),
112
+ );
113
+ if (forbidden)
114
+ throw new HTTPException(422, {
115
+ message: `This Integration requires human approval for ${forbidden.id.slice(0, 200)}; it cannot be auto-approved.`,
116
+ });
117
+ }
118
+ }
119
+ return {
120
+ accountId: grant.accountId,
121
+ workspaceId,
122
+ subjectId: grant.subjectId,
123
+ capabilityId: resolved.preview.capabilityId,
124
+ pluginKey: resolved.preview.pluginKey,
125
+ serverId: resolved.preview.serverId,
126
+ name: resolved.preview.name,
127
+ description: resolved.preview.description,
128
+ category: "integrations",
129
+ tags: [resolved.preview.protocol, resolved.preview.provider ?? "custom"],
130
+ definitionId: resolved.preview.definitionId,
131
+ definitionProvenance: resolved.preview.definitionProvenance,
132
+ ...(resolved.provider ? { provider: resolved.provider } : {}),
133
+ providerDomain: resolved.preview.providerDomain,
134
+ protocol: resolved.preview.protocol,
135
+ baseUrl: resolved.preview.baseUrl,
136
+ sourceUrl: resolved.preview.sourceUrl,
137
+ authScheme: resolved.authScheme,
138
+ ...(payload.connectionId ? { connectionId: payload.connectionId } : {}),
139
+ ...(payload.instanceKey ? { instanceKey: payload.instanceKey } : {}),
140
+ ...(payload.displayName ? { displayName: payload.displayName } : {}),
141
+ ...(payload.expectedInstanceVersion !== undefined
142
+ ? { expectedInstanceVersion: payload.expectedInstanceVersion }
143
+ : {}),
144
+ requiredScopes: resolved.requiredScopes,
145
+ ownership: resolved.preview.connectionOwnership === "personal" ? "subject" : "workspace",
146
+ ...(payload.allowedTools
147
+ ? { allowedTools: validatedAllowedToolIds(payload.allowedTools, resolved.revision.tools) }
148
+ : {}),
149
+ ...(payload.autoApprovedTools ? { autoApprovedTools: payload.autoApprovedTools } : {}),
150
+ facetDefinitions: integrationFacetDefinitions(resolved.preview.definitionId),
151
+ revision: resolved.revision,
152
+ };
153
+ }
154
+
155
+ const MAX_REPORTED_TOOL_IDS = 50;
156
+
157
+ /**
158
+ * `allowedTools` names tools by their preview `id`, the stable identity the
159
+ * install persists. Reject anything else as a client error that lists the
160
+ * valid ids; a caller that sent a preview `operationKey` is told which id it
161
+ * maps to rather than having it silently reinterpreted.
162
+ */
163
+ export function validatedAllowedToolIds(
164
+ allowedTools: readonly string[],
165
+ tools: readonly { id: string; operationKey: string }[],
166
+ ): string[] {
167
+ const ids = new Set(tools.map((tool) => tool.id));
168
+ const unknown = [
169
+ ...new Set(allowedTools.map((tool) => tool.trim()).filter((tool) => !ids.has(tool))),
170
+ ];
171
+ if (unknown.length === 0) return [...allowedTools];
172
+ const operationKeyMatches = unknown.flatMap((value) => {
173
+ const tool = tools.find((candidate) => candidate.operationKey === value);
174
+ return tool ? [{ operationKey: value, id: tool.id }] : [];
175
+ });
176
+ const validToolIds = tools.map((tool) => tool.id);
177
+ const shownUnknown = unknown.slice(0, 10);
178
+ const hint =
179
+ operationKeyMatches.length > 0
180
+ ? ` allowedTools takes tool ids, not operationKeys: ${operationKeyMatches
181
+ .slice(0, 5)
182
+ .map((match) => `${match.operationKey} -> ${match.id}`)
183
+ .join(", ")}.`
184
+ : "";
185
+ throw new ApiHttpError(422, {
186
+ code: "validation_failed",
187
+ message: `allowedTools contains unknown tool ids: ${shownUnknown.join(", ")}${
188
+ unknown.length > shownUnknown.length
189
+ ? `, and ${unknown.length - shownUnknown.length} more`
190
+ : ""
191
+ }. Use the \`id\` of each tool in the Integration preview.${hint}`,
192
+ retryable: false,
193
+ details: {
194
+ code: "unknown_integration_tools",
195
+ unknownTools: shownUnknown,
196
+ operationKeyMatches: operationKeyMatches.slice(0, MAX_REPORTED_TOOL_IDS),
197
+ validToolIds: validToolIds.slice(0, MAX_REPORTED_TOOL_IDS),
198
+ validToolIdCount: validToolIds.length,
199
+ },
200
+ });
201
+ }
202
+
48
203
  export function registerApiIntegrationRoutes(
49
204
  app: Hono,
50
205
  deps: ApiRouteDeps,
@@ -52,7 +207,9 @@ export function registerApiIntegrationRoutes(
52
207
  ): void {
53
208
  const transport = createPinnedIntegrationTransport({
54
209
  network: deps.settings,
55
- ...(overrides.fetchImpl ? { fetchImpl: overrides.fetchImpl } : {}),
210
+ ...((overrides.fetchImpl ?? deps.apiIntegrationSourceFetch)
211
+ ? { fetchImpl: overrides.fetchImpl ?? deps.apiIntegrationSourceFetch! }
212
+ : {}),
56
213
  });
57
214
 
58
215
  app.get("/v1/workspaces/:workspaceId/integrations/definitions", async (c) => {
@@ -70,6 +227,9 @@ export function registerApiIntegrationRoutes(
70
227
  kind: definition.authentication.kind,
71
228
  scopes: [...definition.authentication.scopes],
72
229
  },
230
+ ...(INTEGRATION_DEFINITION_PRESENTATIONS[definition.id]
231
+ ? { presentation: INTEGRATION_DEFINITION_PRESENTATIONS[definition.id] }
232
+ : {}),
73
233
  facets: definition.facets.map((facet) => ({
74
234
  facetKey: facet.facetKey,
75
235
  kind: facet.kind,
@@ -131,95 +291,53 @@ export function registerApiIntegrationRoutes(
131
291
  app.post("/v1/workspaces/:workspaceId/integrations/preview", async (c) => {
132
292
  const workspaceId = c.req.param("workspaceId");
133
293
  const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:read");
134
- const payload = PreviewApiIntegrationRequest.parse(await c.req.json());
294
+ const payload = await parseRequestJson(c, PreviewApiIntegrationRequest);
135
295
  const resolved = await resolveForRoute({
136
296
  deps,
137
297
  transport,
298
+ accountId: grant.accountId,
138
299
  workspaceId,
139
300
  subjectId: grant.subjectId,
140
301
  payload,
141
302
  });
142
- return c.json(ApiIntegrationPreview.parse(resolved.preview));
303
+ const credentialWarnings = await connectionCredentialPlacementWarnings(
304
+ deps,
305
+ workspaceId,
306
+ grant.subjectId,
307
+ resolved.preview,
308
+ );
309
+ return c.json(
310
+ ApiIntegrationPreview.parse({
311
+ ...resolved.preview,
312
+ warnings: [...resolved.preview.warnings, ...credentialWarnings].slice(0, 32),
313
+ }),
314
+ );
143
315
  });
144
316
 
145
317
  app.post("/v1/workspaces/:workspaceId/integrations/install", async (c) => {
146
318
  const workspaceId = c.req.param("workspaceId");
147
- const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
148
- const payload = InstallApiIntegrationRequest.parse(await c.req.json());
319
+ const grant = await requireAccessGrant(c, deps, workspaceId, "capabilities:manage");
320
+ const payload = await parseRequestJson(c, InstallApiIntegrationRequest);
149
321
  const resolved = await resolveForRoute({
150
322
  deps,
151
323
  transport,
324
+ accountId: grant.accountId,
152
325
  workspaceId,
153
326
  subjectId: grant.subjectId,
154
327
  payload,
155
328
  });
156
- if (
157
- resolved.preview.revisionId !== payload.expectedRevisionId ||
158
- resolved.preview.contentSha256 !== payload.expectedContentSha256
159
- ) {
160
- throw new HTTPException(409, {
161
- message:
162
- "The Integration source changed after preview. Review the new tools and permissions before installing.",
163
- });
164
- }
165
- if (resolved.preview.auth.kind !== "none" && !payload.connectionId) {
166
- throw new HTTPException(422, {
167
- message: "Connect an account before installing this Integration.",
168
- });
169
- }
170
- if (
171
- payload.ownership &&
172
- resolved.preview.connectionOwnership &&
173
- payload.ownership !== resolved.preview.connectionOwnership
174
- ) {
175
- throw new HTTPException(422, {
176
- message: "The selected Connection ownership does not match this install request.",
177
- });
178
- }
179
- if (payload.ownership === "personal" && !resolved.preview.connectionOwnership) {
180
- throw new HTTPException(422, {
181
- message: "Choose a Personal Connection before installing for yourself.",
182
- });
183
- }
329
+ const installation = validatedIntegrationInstallInput(grant, workspaceId, payload, resolved);
184
330
  try {
185
331
  return c.json(
186
- InstalledApiIntegration.parse(
187
- await installApiIntegration(deps.db, {
188
- accountId: grant.accountId,
189
- workspaceId,
190
- subjectId: grant.subjectId,
191
- capabilityId: resolved.preview.capabilityId,
192
- pluginKey: resolved.preview.pluginKey,
193
- serverId: resolved.preview.serverId,
194
- name: resolved.preview.name,
195
- description: resolved.preview.description,
196
- category: "integrations",
197
- tags: [resolved.preview.protocol, resolved.preview.provider ?? "custom"],
198
- definitionId: resolved.preview.definitionId,
199
- definitionProvenance: resolved.preview.definitionProvenance,
200
- ...(resolved.provider ? { provider: resolved.provider } : {}),
201
- providerDomain: resolved.preview.providerDomain,
202
- protocol: resolved.preview.protocol,
203
- baseUrl: resolved.preview.baseUrl,
204
- sourceUrl: resolved.preview.sourceUrl,
205
- authScheme: resolved.authScheme,
206
- ...(payload.connectionId ? { connectionId: payload.connectionId } : {}),
207
- ...(payload.instanceKey ? { instanceKey: payload.instanceKey } : {}),
208
- ...(payload.displayName ? { displayName: payload.displayName } : {}),
209
- ...(payload.expectedInstanceVersion !== undefined
210
- ? { expectedInstanceVersion: payload.expectedInstanceVersion }
211
- : {}),
212
- requiredScopes: resolved.requiredScopes,
213
- ownership:
214
- resolved.preview.connectionOwnership === "personal" ? "subject" : "workspace",
215
- ...(payload.allowedTools ? { allowedTools: payload.allowedTools } : {}),
216
- facetDefinitions: integrationFacetDefinitions(resolved.preview.definitionId),
217
- revision: resolved.revision,
218
- }),
219
- ),
332
+ InstalledApiIntegration.parse(await installApiIntegration(deps.db, installation)),
220
333
  payload.expectedInstanceVersion === undefined ? 201 : 200,
221
334
  );
222
335
  } catch (error) {
336
+ if (error instanceof ApiIntegrationConnectionReferenceError) {
337
+ throw new HTTPException(error.reason === "not_found" ? 404 : 422, {
338
+ message: error.reason === "not_found" ? "connection not found" : error.message,
339
+ });
340
+ }
223
341
  if (
224
342
  error instanceof IntegrationFacetBindingVersionConflictError ||
225
343
  error instanceof IntegrationFacetBindingVersionRequiredError ||
@@ -257,10 +375,10 @@ export function registerApiIntegrationRoutes(
257
375
  "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey",
258
376
  async (c) => {
259
377
  const workspaceId = c.req.param("workspaceId");
260
- const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
378
+ const grant = await requireAccessGrant(c, deps, workspaceId, "capabilities:manage");
261
379
  const capabilityId = decodeURIComponent(c.req.param("capabilityId"));
262
380
  const instanceKey = decodeURIComponent(c.req.param("instanceKey"));
263
- const payload = UninstallApiIntegrationRequest.parse(await c.req.json());
381
+ const payload = await parseRequestJson(c, UninstallApiIntegrationRequest);
264
382
  try {
265
383
  return c.json(
266
384
  UninstallApiIntegrationResult.parse(
@@ -291,24 +409,48 @@ export function registerApiIntegrationRoutes(
291
409
  );
292
410
  }
293
411
 
294
- async function resolveForRoute(input: {
412
+ export async function resolveForRoute(input: {
295
413
  deps: ApiRouteDeps;
296
414
  transport: ReturnType<typeof createPinnedIntegrationTransport>;
415
+ accountId: string;
297
416
  workspaceId: string;
298
417
  subjectId: string;
299
418
  payload: PreviewApiIntegrationRequest | InstallApiIntegrationRequest;
300
419
  }): ReturnType<typeof resolveApiIntegrationPreview> {
420
+ const payload = structuredClone(input.payload);
421
+ const preparation = await withOrganizationIntegrationPolicyFence(
422
+ input.deps.db,
423
+ input,
424
+ async (tx, policy) => {
425
+ try {
426
+ return { source: integrationSourceForOrganizationPolicy(policy, payload.source) };
427
+ } catch (error) {
428
+ if (!(error instanceof OrganizationIntegrationDeniedError)) throw error;
429
+ const install = InstallApiIntegrationRequest.safeParse(payload);
430
+ if (install.success) {
431
+ const resolved = await storedReconciliationPreview(
432
+ { ...input, deps: { ...input.deps, db: tx } },
433
+ install.data,
434
+ );
435
+ if (resolved) return { resolved };
436
+ }
437
+ throw error;
438
+ }
439
+ },
440
+ );
441
+ if (preparation.resolved) return preparation.resolved;
442
+ const source = preparation.source!;
301
443
  try {
302
- const connection = input.payload.connectionId
444
+ const connection = payload.connectionId
303
445
  ? await requireVisibleConnection(
304
446
  input.deps,
305
447
  input.workspaceId,
306
448
  input.subjectId,
307
- input.payload.connectionId,
449
+ payload.connectionId,
308
450
  )
309
451
  : null;
310
452
  return await resolveApiIntegrationPreview({
311
- source: input.payload.source,
453
+ source,
312
454
  connection: connectionDescriptor(connection),
313
455
  transport: input.transport,
314
456
  authority: {
@@ -339,6 +481,154 @@ async function resolveForRoute(input: {
339
481
  }
340
482
  }
341
483
 
484
+ async function storedReconciliationPreview(
485
+ input: { deps: ApiRouteDeps; accountId: string; workspaceId: string; subjectId: string },
486
+ payload: InstallApiIntegrationRequest,
487
+ ): Promise<ResolvedApiIntegrationPreview | null> {
488
+ const snapshot = await getApiIntegrationReconciliationSnapshot(input.deps.db, {
489
+ accountId: input.accountId,
490
+ workspaceId: input.workspaceId,
491
+ subjectId: input.subjectId,
492
+ source: payload.source,
493
+ expectedRevisionId: payload.expectedRevisionId,
494
+ expectedContentSha256: payload.expectedContentSha256,
495
+ ...(payload.connectionId !== undefined ? { connectionId: payload.connectionId } : {}),
496
+ ...(payload.instanceKey !== undefined ? { instanceKey: payload.instanceKey } : {}),
497
+ ...(payload.allowedTools !== undefined ? { allowedTools: payload.allowedTools } : {}),
498
+ });
499
+ if (!snapshot) return null;
500
+ const { runtime, baseServerId, name, provider, requiredScopes } = snapshot;
501
+ const connection = payload.connectionId
502
+ ? await requireVisibleConnection(
503
+ input.deps,
504
+ input.workspaceId,
505
+ input.subjectId,
506
+ payload.connectionId,
507
+ )
508
+ : null;
509
+ const scheme = runtime.authScheme;
510
+ const auth = !apiIntegrationRequiresConnection(scheme)
511
+ ? { kind: "none" }
512
+ : scheme.kind === "oauth2"
513
+ ? { kind: "oauth2", providerDomain: runtime.providerDomain, scopes: requiredScopes }
514
+ : scheme.kind === "api_key"
515
+ ? {
516
+ kind: "api_key",
517
+ providerDomain: runtime.providerDomain,
518
+ carrier: scheme.carrier,
519
+ name: scheme.name,
520
+ }
521
+ : scheme.kind === "http"
522
+ ? { kind: "http", providerDomain: runtime.providerDomain, scheme: scheme.scheme }
523
+ : null;
524
+ if (!auth) return null;
525
+ return {
526
+ preview: ApiIntegrationPreview.parse({
527
+ source: payload.source,
528
+ definitionId: runtime.definitionId,
529
+ definitionProvenance: runtime.definitionProvenance,
530
+ protocol: runtime.protocol,
531
+ capabilityId: runtime.capabilityId,
532
+ pluginKey: runtime.pluginKey,
533
+ serverId: baseServerId,
534
+ name,
535
+ description: runtime.description,
536
+ provider,
537
+ providerDomain: runtime.providerDomain,
538
+ baseUrl: runtime.baseUrl,
539
+ sourceUrl: runtime.sourceUrl,
540
+ revisionId: runtime.revision.id,
541
+ contentSha256: runtime.revision.contentSha256,
542
+ auth,
543
+ connectionId: connection?.id ?? null,
544
+ connectionOwnership: connection ? (connection.subjectId ? "personal" : "workspace") : null,
545
+ tools: runtime.revision.tools.map((tool) => ({
546
+ id: tool.id,
547
+ operationKey: tool.operationKey,
548
+ name: tool.name,
549
+ description: tool.description,
550
+ safety: tool.safety,
551
+ approvalMode: tool.approvalMode,
552
+ deprecated: tool.deprecated,
553
+ })),
554
+ warnings: [],
555
+ }),
556
+ revision: runtime.revision,
557
+ provider,
558
+ requiredScopes,
559
+ authScheme: runtime.authScheme,
560
+ };
561
+ }
562
+
563
+ /**
564
+ * Advisory preview check that the selected credential Connection delivers
565
+ * its secret where the API description says the provider reads it. Compares
566
+ * carrier and name only; never returns or logs a credential value. Install is
567
+ * unchanged: descriptions are often imprecise, so a mismatch warns instead of
568
+ * refusing a Connection the provider may actually accept.
569
+ */
570
+ async function connectionCredentialPlacementWarnings(
571
+ deps: ApiRouteDeps,
572
+ workspaceId: string,
573
+ subjectId: string,
574
+ preview: ApiIntegrationPreview,
575
+ ): Promise<string[]> {
576
+ if (!preview.connectionId || (preview.auth.kind !== "api_key" && preview.auth.kind !== "http")) {
577
+ return [];
578
+ }
579
+ const connection = await getConnectionMetadata(
580
+ deps.db,
581
+ workspaceId,
582
+ preview.connectionId,
583
+ subjectId,
584
+ );
585
+ if (!connection || connection.kind === "oauth2") return [];
586
+ let result: Awaited<ReturnType<ReturnType<typeof buildConnectionTokenResolver>>>;
587
+ try {
588
+ result = await buildConnectionTokenResolver(
589
+ deps.db,
590
+ deps.settings,
591
+ )({
592
+ workspaceId,
593
+ ...(connection.subjectId ? { subjectId } : {}),
594
+ serverId: `preview_${connection.id}`,
595
+ connectionRef: {
596
+ connectionId: connection.id,
597
+ providerDomain: connection.providerDomain,
598
+ kind: connection.kind,
599
+ subjectScope: connection.subjectId ? "subject" : "workspace",
600
+ },
601
+ destinationUrl: preview.baseUrl,
602
+ credentialTarget: "http_api",
603
+ });
604
+ } catch {
605
+ return [];
606
+ }
607
+ if (result.status === "auth_needed") return [];
608
+ const expected =
609
+ preview.auth.kind === "api_key"
610
+ ? { carrier: preview.auth.carrier, name: preview.auth.name }
611
+ : { carrier: "header" as const, name: "Authorization" };
612
+ const placements =
613
+ result.placements ??
614
+ Object.keys(result.headers).map((name) => ({ carrier: "header" as const, name }));
615
+ const matches = placements.some(
616
+ (placement) =>
617
+ placement.carrier === expected.carrier &&
618
+ (placement.carrier === "header"
619
+ ? placement.name.toLowerCase() === expected.name.toLowerCase()
620
+ : placement.name === expected.name),
621
+ );
622
+ if (matches) return [];
623
+ const actual = placements
624
+ .slice(0, 3)
625
+ .map((placement) => `${placement.carrier} "${placement.name.slice(0, 64)}"`)
626
+ .join(", ");
627
+ return [
628
+ `The API description expects the credential in ${expected.carrier} "${expected.name.slice(0, 64)}", but the selected Connection sends it in ${actual}. Calls may be rejected as unauthenticated.`,
629
+ ];
630
+ }
631
+
342
632
  async function requireVisibleConnection(
343
633
  deps: ApiRouteDeps,
344
634
  workspaceId: string,