@opengeni/api-router 0.30.1 → 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 (436) 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-office-import.d.ts +7 -4
  35. package/dist/editable-artifact-source-session.d.ts +3 -0
  36. package/dist/editable-artifact-websocket.d.ts +10 -18
  37. package/dist/editable-artifact-workspace-files.d.ts +1 -1
  38. package/dist/fatal-process-boundary.d.ts +25 -0
  39. package/dist/github-access.d.ts +31 -2
  40. package/dist/http/acting-person.d.ts +24 -0
  41. package/dist/http/api-contract-compat.d.ts +19 -0
  42. package/dist/http/api-error.d.ts +27 -1
  43. package/dist/http/cors.d.ts +17 -0
  44. package/dist/http/deprecation.d.ts +42 -0
  45. package/dist/http/interaction-control-error.d.ts +13 -0
  46. package/dist/http/keyed-admission.d.ts +12 -0
  47. package/dist/http/local-browser-boundary.d.ts +72 -0
  48. package/dist/http/metrics-listener.d.ts +22 -0
  49. package/dist/http/path-identifier.d.ts +17 -0
  50. package/dist/http/registered-route-label.d.ts +16 -0
  51. package/dist/http/request-body.d.ts +27 -0
  52. package/dist/http/request-source.d.ts +52 -0
  53. package/dist/http/sse.d.ts +17 -6
  54. package/dist/http/unmatched-route.d.ts +18 -0
  55. package/dist/http/user-content.d.ts +36 -0
  56. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  57. package/dist/index.d.ts +10 -3
  58. package/dist/index.js +1129 -166
  59. package/dist/index.js.map +1 -1
  60. package/dist/integration-endpoint-test.d.ts +20 -0
  61. package/dist/integrations/api-integrations.d.ts +2 -2
  62. package/dist/integrations/atlassian.d.ts +29 -3
  63. package/dist/integrations/connect-authority.d.ts +1 -0
  64. package/dist/integrations/connect-callback-return.d.ts +6 -0
  65. package/dist/integrations/fiken.d.ts +16 -2
  66. package/dist/integrations/github-app-connect.d.ts +47 -0
  67. package/dist/integrations/github-installation-proof.d.ts +3 -0
  68. package/dist/integrations/github-lens-connect.d.ts +116 -0
  69. package/dist/integrations/github-skill-source.d.ts +1 -5
  70. package/dist/integrations/google-drive.d.ts +25 -0
  71. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  72. package/dist/integrations/marketplace-plugin.d.ts +2691 -0
  73. package/dist/integrations/oauth-client.d.ts +178 -18
  74. package/dist/integrations/oauth-profiles.d.ts +222 -0
  75. package/dist/integrations/oauth-return-path.d.ts +1 -0
  76. package/dist/integrations/personal-github-repositories.d.ts +84 -0
  77. package/dist/integrations/personal-github.d.ts +42 -0
  78. package/dist/integrations/pr-review-provider.d.ts +22 -0
  79. package/dist/integrations/provider-oauth.d.ts +19 -1
  80. package/dist/integrations/slack-app-home.d.ts +24 -0
  81. package/dist/integrations/slack-bot.d.ts +367 -12
  82. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  83. package/dist/integrations/slack-install.d.ts +20 -0
  84. package/dist/integrations/slack-interactions.d.ts +113 -10
  85. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  86. package/dist/integrations/slack-routing.d.ts +120 -0
  87. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  88. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  89. package/dist/integrations/social-oauth.d.ts +7 -0
  90. package/dist/interaction-agent-access.d.ts +15 -0
  91. package/dist/interaction-frame-proxy.d.ts +68 -0
  92. package/dist/interaction-metrics.d.ts +2 -0
  93. package/dist/mcp/action-catalog-types.d.ts +9 -0
  94. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  95. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  96. package/dist/mcp/child-read-evidence.d.ts +9 -0
  97. package/dist/mcp/command-read.d.ts +24 -0
  98. package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
  99. package/dist/mcp/contract-input.d.ts +11 -0
  100. package/dist/mcp/documents.d.ts +7 -5
  101. package/dist/mcp/files.d.ts +2 -2
  102. package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
  103. package/dist/mcp/knowledge-entries.d.ts +5 -0
  104. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  105. package/dist/mcp/receipts.d.ts +9 -0
  106. package/dist/mcp/request-abort.d.ts +19 -0
  107. package/dist/mcp/scheduled-task-input.d.ts +1189 -0
  108. package/dist/mcp/scheduled-task-view.d.ts +22 -4
  109. package/dist/mcp/server.d.ts +255 -3
  110. package/dist/mcp/session-event-view.d.ts +94 -0
  111. package/dist/mcp/session-view.d.ts +66 -2
  112. package/dist/mcp/session-wait.d.ts +174 -0
  113. package/dist/mcp-oauth.d.ts +52 -0
  114. package/dist/model-catalog.d.ts +11 -31
  115. package/dist/observability.d.ts +3 -1
  116. package/dist/organization-mcp.d.ts +52 -0
  117. package/dist/organization-recovery-notifications.d.ts +41 -0
  118. package/dist/routes/analytics-consent.d.ts +26 -0
  119. package/dist/routes/api-integrations.d.ts +25 -0
  120. package/dist/routes/api-keys.d.ts +17 -0
  121. package/dist/routes/artifact-catalog.d.ts +6 -0
  122. package/dist/routes/automations.d.ts +19 -0
  123. package/dist/routes/billing.d.ts +49 -0
  124. package/dist/routes/browser-sessions.d.ts +71 -3
  125. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  126. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  127. package/dist/routes/client-errors.d.ts +146 -0
  128. package/dist/routes/codex.d.ts +76 -2
  129. package/dist/routes/company-brain.d.ts +3 -0
  130. package/dist/routes/company-profile.d.ts +2 -1
  131. package/dist/routes/computer-sessions.d.ts +14 -0
  132. package/dist/routes/connect.d.ts +5 -0
  133. package/dist/routes/editable-artifacts.d.ts +2 -0
  134. package/dist/routes/external-identity-links.d.ts +6 -0
  135. package/dist/routes/feedback.d.ts +3 -0
  136. package/dist/routes/files.d.ts +4 -0
  137. package/dist/routes/github-browser-pages.d.ts +12 -0
  138. package/dist/routes/github.d.ts +2 -0
  139. package/dist/routes/insights-response-cache.d.ts +10 -0
  140. package/dist/routes/insights-usage.d.ts +12 -0
  141. package/dist/routes/insights.d.ts +30 -1
  142. package/dist/routes/knowledge.d.ts +3 -0
  143. package/dist/routes/managed-auth-session-sets.d.ts +26 -0
  144. package/dist/routes/managed-onboarding.d.ts +29 -0
  145. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  146. package/dist/routes/model-connection-access.d.ts +3 -0
  147. package/dist/routes/organization-integration-policy.d.ts +3 -0
  148. package/dist/routes/organization-integrations.d.ts +6 -0
  149. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  150. package/dist/routes/organization-model-providers.d.ts +3 -0
  151. package/dist/routes/organization-recovery.d.ts +19 -0
  152. package/dist/routes/organization-service-accounts.d.ts +3 -0
  153. package/dist/routes/organization-sessions.d.ts +26 -0
  154. package/dist/routes/personal-github-git-broker.d.ts +29 -0
  155. package/dist/routes/personal-github.d.ts +3 -0
  156. package/dist/routes/pr-review-github.d.ts +3 -0
  157. package/dist/routes/pr-review.d.ts +3 -0
  158. package/dist/routes/session-artifact-associations.d.ts +4 -0
  159. package/dist/routes/session-history-imports.d.ts +9 -0
  160. package/dist/routes/sessions.d.ts +44 -6
  161. package/dist/routes/skill-content.d.ts +4 -0
  162. package/dist/routes/skill-install-authority.d.ts +6 -0
  163. package/dist/routes/subscription-account-pools.d.ts +34 -0
  164. package/dist/routes/subscription-pool-access.d.ts +16 -0
  165. package/dist/routes/supergrok.d.ts +6 -1
  166. package/dist/routes/usage-allowances.d.ts +12 -0
  167. package/dist/routes/user-resource-authorities.d.ts +3 -0
  168. package/dist/routes/workspace-artifacts.d.ts +2 -1
  169. package/dist/routes/workspace-capture.d.ts +10 -2
  170. package/dist/routes/workspace-integrations.d.ts +35 -0
  171. package/dist/routes/workspace-learning.d.ts +3 -0
  172. package/dist/routes/workspace-model-providers.d.ts +4 -0
  173. package/dist/routes/workspaces.d.ts +29 -0
  174. package/dist/sandbox/auth-callout.d.ts +8 -0
  175. package/dist/sandbox/channel-a.d.ts +19 -1
  176. package/dist/sandbox/connection-authority.d.ts +3 -0
  177. package/dist/sandbox/enrollment.d.ts +9 -1
  178. package/dist/sandbox/machines.d.ts +5 -2
  179. package/dist/sandbox/metrics-ingestion.d.ts +28 -20
  180. package/dist/sandbox/rematerialize.d.ts +2 -0
  181. package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
  182. package/dist/sandbox/viewer.d.ts +26 -1
  183. package/dist/sandbox-file-artifacts.d.ts +50 -0
  184. package/dist/scheduled-task-deletion.d.ts +13 -0
  185. package/dist/session-create-observability.d.ts +5 -0
  186. package/dist/session-event-view-MPS2OZD3.js +292 -0
  187. package/dist/session-event-view-MPS2OZD3.js.map +1 -0
  188. package/dist/site-session-origin.d.ts +13 -0
  189. package/dist/site-uploads.d.ts +41 -0
  190. package/dist/slack-reaction-files.d.ts +1 -1
  191. package/dist/temporal-schedule-cleanup.d.ts +1 -0
  192. package/dist/temporal-schedule-sync.d.ts +26 -0
  193. package/dist/transcription/providers/xai-subscription.d.ts +1 -0
  194. package/dist/transcription/service.d.ts +2 -1
  195. package/dist/work-discovery-observability.d.ts +33 -0
  196. package/dist/workspace-artifact-content.d.ts +28 -0
  197. package/dist/workspace-artifact-provenance.d.ts +7 -0
  198. package/dist/workspace-delete-observability.d.ts +10 -0
  199. package/dist/workspace-deletion.d.ts +6 -0
  200. package/dist/workspace-state-projection.d.ts +3 -5
  201. package/dist/workspace-tool-gateway-observability.d.ts +17 -0
  202. package/dist/workspace-tool-gateway.d.ts +123 -0
  203. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  204. package/package.json +23 -19
  205. package/src/access-grant-rls.ts +75 -0
  206. package/src/admission-trace.ts +14 -0
  207. package/src/api-websocket.ts +23 -0
  208. package/src/app.ts +1974 -256
  209. package/src/artifact-catalog-cursor.ts +60 -0
  210. package/src/auth/managed-auth-attempt-context.ts +70 -0
  211. package/src/auth/managed-auth-rate-limits.ts +252 -0
  212. package/src/auth/managed-auth-session-adapter.ts +222 -0
  213. package/src/auth/managed-auth.ts +536 -60
  214. package/src/auth/managed-email.ts +174 -0
  215. package/src/auth/managed-sign-in-notifications.ts +81 -0
  216. package/src/auth/new-signups-gate.ts +49 -0
  217. package/src/auth/organization-user-setup.ts +307 -0
  218. package/src/auth/signup-funnel-metrics.ts +164 -0
  219. package/src/browser-controller-authority.ts +1 -186
  220. package/src/browser-ephemeral.ts +39 -0
  221. package/src/browser-state-authority.ts +1 -236
  222. package/src/claude-subscription-account-conflicts.ts +12 -0
  223. package/src/claude-subscription-account-usage.ts +48 -0
  224. package/src/claude-subscription-oauth.ts +362 -0
  225. package/src/claude-subscription-profile.ts +73 -0
  226. package/src/claude-subscription-usage.ts +97 -0
  227. package/src/claude-workspace-connection.ts +82 -0
  228. package/src/codemode.ts +194 -30
  229. package/src/codex-realtime.ts +8 -2
  230. package/src/company-brain-okf.ts +340 -0
  231. package/src/connected-machine-computer-access.ts +33 -0
  232. package/src/connection-ownership.ts +199 -0
  233. package/src/controller-data-plane.ts +81 -0
  234. package/src/editable-artifact-native-kernel.ts +26 -15
  235. package/src/editable-artifact-office-import.ts +77 -9
  236. package/src/editable-artifact-production.ts +23 -7
  237. package/src/editable-artifact-source-session.ts +123 -0
  238. package/src/editable-artifact-websocket.ts +27 -21
  239. package/src/editable-artifact-workspace-files.ts +31 -6
  240. package/src/fatal-process-boundary.ts +246 -0
  241. package/src/gateway-realtime.ts +1 -1
  242. package/src/github-access.ts +147 -5
  243. package/src/http/acting-person.ts +71 -0
  244. package/src/http/api-contract-compat.ts +49 -0
  245. package/src/http/api-error.ts +115 -1
  246. package/src/http/auth.ts +48 -0
  247. package/src/http/cors.ts +67 -0
  248. package/src/http/deprecation.ts +118 -0
  249. package/src/http/interaction-control-error.ts +164 -0
  250. package/src/http/keyed-admission.ts +29 -0
  251. package/src/http/local-browser-boundary.ts +343 -0
  252. package/src/http/metrics-listener.ts +57 -0
  253. package/src/http/path-identifier.ts +54 -0
  254. package/src/http/registered-route-label.ts +34 -0
  255. package/src/http/request-body.ts +127 -0
  256. package/src/http/request-source.ts +178 -0
  257. package/src/http/sse.ts +486 -132
  258. package/src/http/unmatched-route.ts +60 -0
  259. package/src/http/user-content.ts +158 -0
  260. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  261. package/src/index.ts +157 -52
  262. package/src/integration-endpoint-test.ts +291 -0
  263. package/src/integrations/api-integrations.ts +98 -11
  264. package/src/integrations/atlassian.ts +474 -136
  265. package/src/integrations/connect-authority.ts +2 -0
  266. package/src/integrations/connect-callback-return.ts +86 -0
  267. package/src/integrations/fiken.ts +354 -64
  268. package/src/integrations/github-app-connect.ts +435 -0
  269. package/src/integrations/github-installation-proof.ts +60 -0
  270. package/src/integrations/github-lens-connect.ts +76 -0
  271. package/src/integrations/github-skill-source.ts +2 -142
  272. package/src/integrations/google-drive.ts +820 -222
  273. package/src/integrations/integration-commit-authority.ts +69 -0
  274. package/src/integrations/marketplace-plugin.ts +48 -0
  275. package/src/integrations/oauth-client.ts +1356 -459
  276. package/src/integrations/oauth-profiles.ts +537 -0
  277. package/src/integrations/oauth-return-path.ts +18 -0
  278. package/src/integrations/personal-github-repositories.ts +674 -0
  279. package/src/integrations/personal-github.ts +825 -0
  280. package/src/integrations/pr-review-provider.ts +246 -0
  281. package/src/integrations/provider-oauth.ts +250 -22
  282. package/src/integrations/slack-app-home.ts +300 -0
  283. package/src/integrations/slack-bot.ts +963 -239
  284. package/src/integrations/slack-file-upload-flow.ts +147 -0
  285. package/src/integrations/slack-install.ts +83 -0
  286. package/src/integrations/slack-interactions.ts +3170 -474
  287. package/src/integrations/slack-mrkdwn.ts +193 -0
  288. package/src/integrations/slack-routing.ts +337 -0
  289. package/src/integrations/slack-session-defaults.ts +224 -0
  290. package/src/integrations/slack-task-file-upload.ts +323 -0
  291. package/src/integrations/social-oauth.ts +213 -15
  292. package/src/interaction-agent-access.ts +48 -0
  293. package/src/interaction-frame-proxy.ts +409 -0
  294. package/src/interaction-metrics.ts +30 -0
  295. package/src/mcp/action-catalog-types.ts +9 -0
  296. package/src/mcp/action-catalog.gen.ts +6696 -0
  297. package/src/mcp/capability-account-readiness.ts +17 -0
  298. package/src/mcp/child-read-evidence.ts +19 -0
  299. package/src/mcp/command-read.ts +109 -0
  300. package/src/mcp/company-profile-agent-admin.ts +198 -0
  301. package/src/mcp/contract-input.ts +141 -0
  302. package/src/mcp/documents.ts +65 -377
  303. package/src/mcp/editable-artifacts.ts +12 -6
  304. package/src/mcp/files.ts +80 -38
  305. package/src/mcp/first-party-tool-permissions.ts +305 -0
  306. package/src/mcp/knowledge-entries.ts +322 -0
  307. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  308. package/src/mcp/receipts.ts +34 -0
  309. package/src/mcp/request-abort.ts +44 -0
  310. package/src/mcp/scheduled-task-input.ts +76 -0
  311. package/src/mcp/scheduled-task-view.ts +44 -3
  312. package/src/mcp/server.ts +3030 -1267
  313. package/src/mcp/session-event-view.ts +383 -0
  314. package/src/mcp/session-view.ts +84 -3
  315. package/src/mcp/session-wait.ts +665 -0
  316. package/src/mcp-oauth.ts +1123 -0
  317. package/src/model-catalog.ts +91 -333
  318. package/src/observability.ts +15 -1
  319. package/src/organization-mcp.ts +397 -0
  320. package/src/organization-recovery-notifications.ts +103 -0
  321. package/src/routes/analytics-consent.ts +123 -0
  322. package/src/routes/api-integrations.ts +364 -74
  323. package/src/routes/api-keys.ts +336 -10
  324. package/src/routes/artifact-catalog.ts +279 -0
  325. package/src/routes/automations.ts +768 -0
  326. package/src/routes/billing.ts +461 -46
  327. package/src/routes/browser-sessions.ts +839 -131
  328. package/src/routes/canonical-human-identities.ts +90 -14
  329. package/src/routes/capabilities.ts +107 -6
  330. package/src/routes/channels.ts +20 -3
  331. package/src/routes/claude-subscription-accounts.ts +334 -0
  332. package/src/routes/claude-subscription-oauth.ts +142 -0
  333. package/src/routes/client-errors.ts +362 -0
  334. package/src/routes/codex.ts +833 -116
  335. package/src/routes/company-brain.ts +322 -0
  336. package/src/routes/company-profile.ts +65 -1
  337. package/src/routes/computer-sessions.ts +557 -106
  338. package/src/routes/connect.ts +1938 -0
  339. package/src/routes/connections.ts +1040 -349
  340. package/src/routes/documents.ts +488 -287
  341. package/src/routes/editable-artifacts.ts +79 -9
  342. package/src/routes/enrollments.ts +135 -39
  343. package/src/routes/environments.ts +154 -58
  344. package/src/routes/external-identity-links.ts +201 -0
  345. package/src/routes/feedback.ts +113 -0
  346. package/src/routes/files.ts +337 -39
  347. package/src/routes/github-browser-pages.ts +162 -0
  348. package/src/routes/github.ts +446 -144
  349. package/src/routes/insights-response-cache.ts +83 -0
  350. package/src/routes/insights-usage.ts +345 -0
  351. package/src/routes/insights.ts +153 -19
  352. package/src/routes/install.ts +133 -38
  353. package/src/routes/integration-facets.ts +107 -33
  354. package/src/routes/interaction-resources.ts +30 -3
  355. package/src/routes/knowledge.ts +488 -0
  356. package/src/routes/machines.ts +313 -15
  357. package/src/routes/managed-auth-session-sets.ts +1218 -0
  358. package/src/routes/managed-onboarding.ts +337 -0
  359. package/src/routes/managed-sign-in-methods.ts +433 -0
  360. package/src/routes/memory-slack-publications.ts +3 -2
  361. package/src/routes/model-connection-access.ts +208 -0
  362. package/src/routes/organization-integration-policy.ts +116 -0
  363. package/src/routes/organization-integrations.ts +326 -0
  364. package/src/routes/organization-mcp-connections.ts +178 -0
  365. package/src/routes/organization-memberships.ts +1019 -27
  366. package/src/routes/organization-model-providers.ts +293 -0
  367. package/src/routes/organization-recovery.ts +325 -0
  368. package/src/routes/organization-service-accounts.ts +128 -0
  369. package/src/routes/organization-sessions.ts +350 -0
  370. package/src/routes/personal-github-git-broker.ts +785 -0
  371. package/src/routes/personal-github.ts +370 -0
  372. package/src/routes/plugins.ts +251 -22
  373. package/src/routes/pr-review-github.ts +881 -0
  374. package/src/routes/pr-review.ts +622 -0
  375. package/src/routes/preference-registry.ts +12 -93
  376. package/src/routes/rigs.ts +167 -50
  377. package/src/routes/scheduled-tasks.ts +346 -41
  378. package/src/routes/session-artifact-associations.ts +87 -0
  379. package/src/routes/session-history-imports.ts +280 -0
  380. package/src/routes/sessions.ts +2306 -264
  381. package/src/routes/skill-content.ts +297 -0
  382. package/src/routes/skill-install-authority.ts +64 -0
  383. package/src/routes/skills.ts +62 -9
  384. package/src/routes/social.ts +46 -18
  385. package/src/routes/subscription-account-pools.ts +436 -0
  386. package/src/routes/subscription-pool-access.ts +126 -0
  387. package/src/routes/supergrok.ts +219 -303
  388. package/src/routes/transcription-recordings.ts +38 -3
  389. package/src/routes/transcriptions.ts +4 -0
  390. package/src/routes/usage-allowances.ts +378 -0
  391. package/src/routes/user-resource-authorities.ts +138 -0
  392. package/src/routes/video-generation.ts +14 -10
  393. package/src/routes/workspace-artifacts.ts +275 -69
  394. package/src/routes/workspace-capture.ts +21 -0
  395. package/src/routes/workspace-integrations.ts +576 -0
  396. package/src/routes/workspace-learning.ts +159 -0
  397. package/src/routes/workspace-model-providers.ts +148 -0
  398. package/src/routes/workspace-state.ts +38 -25
  399. package/src/routes/workspaces.ts +1004 -127
  400. package/src/sandbox/auth-callout.ts +96 -19
  401. package/src/sandbox/channel-a.ts +323 -24
  402. package/src/sandbox/connection-authority.ts +3 -0
  403. package/src/sandbox/enrollment.ts +81 -6
  404. package/src/sandbox/machines.ts +218 -76
  405. package/src/sandbox/metrics-ingestion.ts +411 -62
  406. package/src/sandbox/rematerialize.ts +121 -19
  407. package/src/sandbox/session-attach-variable-sets.ts +131 -0
  408. package/src/sandbox/viewer.ts +280 -25
  409. package/src/sandbox-file-artifacts.ts +413 -0
  410. package/src/scheduled-task-deletion.ts +138 -0
  411. package/src/session-create-observability.ts +46 -0
  412. package/src/session-realtime-context.ts +6 -3
  413. package/src/site-session-origin.ts +48 -0
  414. package/src/site-uploads.ts +224 -0
  415. package/src/slack-reaction-files.ts +16 -5
  416. package/src/temporal-schedule-cleanup.ts +13 -0
  417. package/src/temporal-schedule-sync.ts +74 -0
  418. package/src/transcription/providers/codex-subscription.ts +2 -0
  419. package/src/transcription/providers/openai.ts +1 -0
  420. package/src/transcription/providers/xai-subscription.ts +49 -3
  421. package/src/transcription/segmenter.ts +8 -2
  422. package/src/transcription/service.ts +43 -6
  423. package/src/work-discovery-observability.ts +121 -0
  424. package/src/workspace-artifact-content.ts +144 -0
  425. package/src/workspace-artifact-provenance.ts +104 -0
  426. package/src/workspace-delete-observability.ts +75 -0
  427. package/src/workspace-deletion.ts +73 -0
  428. package/src/workspace-state-projection.ts +18 -148
  429. package/src/workspace-tool-gateway-observability.ts +100 -0
  430. package/src/workspace-tool-gateway.ts +870 -0
  431. package/src/workspace-webhook-dispatch.ts +190 -0
  432. package/src/xai-subscription-auth.ts +9 -2
  433. package/dist/chunk-2PQMSRCB.js +0 -49759
  434. package/dist/chunk-2PQMSRCB.js.map +0 -1
  435. package/dist/routes/packs.d.ts +0 -3
  436. 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,