@opengeni/api-router 3.0.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. package/dist/access-grant-rls.d.ts +8 -1
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/app.d.ts +50 -3
  4. package/dist/app.js +10 -1
  5. package/dist/artifact-catalog-cursor.d.ts +1 -0
  6. package/dist/attached-browser-viewer.d.ts +11 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
  10. package/dist/auth/managed-auth.d.ts +72 -5
  11. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  12. package/dist/auth/new-signups-gate.d.ts +23 -0
  13. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  14. package/dist/azure-live.d.ts +28 -0
  15. package/dist/browser-action-fences.d.ts +13 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-lost-runtime-end.d.ts +24 -0
  19. package/dist/browser-state-authority.d.ts +1 -27
  20. package/dist/chunk-OGQDXVXY.js +18 -0
  21. package/dist/chunk-OGQDXVXY.js.map +1 -0
  22. package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
  23. package/dist/chunk-OT56OY4V.js.map +1 -0
  24. package/dist/claude-default-models.d.ts +19 -0
  25. package/dist/claude-subscription-core.d.ts +50 -0
  26. package/dist/claude-subscription-oauth.d.ts +36 -0
  27. package/dist/claude-subscription-profile.d.ts +9 -0
  28. package/dist/claude-subscription-usage.d.ts +6 -0
  29. package/dist/claude-workspace-connection.d.ts +15 -0
  30. package/dist/codemode.d.ts +40 -5
  31. package/dist/codex-realtime.d.ts +29 -3
  32. package/dist/codex-session-pointers.d.ts +19 -0
  33. package/dist/connection-ownership.d.ts +6 -3
  34. package/dist/controller-data-plane.d.ts +16 -0
  35. package/dist/credit-promotion-snapshot.d.ts +6 -0
  36. package/dist/editable-artifact-source-session.d.ts +3 -0
  37. package/dist/editable-artifact-websocket.d.ts +5 -3
  38. package/dist/fatal-process-boundary.d.ts +9 -1
  39. package/dist/github-access.d.ts +7 -1
  40. package/dist/github-browser-flow.d.ts +1 -1
  41. package/dist/http/acting-person.d.ts +36 -0
  42. package/dist/http/api-contract-compat.d.ts +19 -0
  43. package/dist/http/api-error.d.ts +50 -1
  44. package/dist/http/auth.d.ts +8 -1
  45. package/dist/http/cors.d.ts +12 -0
  46. package/dist/http/deprecation.d.ts +42 -0
  47. package/dist/http/keyed-admission.d.ts +12 -0
  48. package/dist/http/local-browser-boundary.d.ts +72 -0
  49. package/dist/http/metrics-listener.d.ts +22 -0
  50. package/dist/http/path-identifier.d.ts +17 -0
  51. package/dist/http/registered-route-label.d.ts +16 -0
  52. package/dist/http/rejection-telemetry.d.ts +34 -0
  53. package/dist/http/request-body.d.ts +27 -0
  54. package/dist/http/request-source.d.ts +41 -3
  55. package/dist/http/sse.d.ts +12 -1
  56. package/dist/http/unmatched-route.d.ts +18 -0
  57. package/dist/http/user-content.d.ts +36 -0
  58. package/dist/http/variable-sets-removed.d.ts +41 -0
  59. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  60. package/dist/index.js +1279 -108
  61. package/dist/index.js.map +1 -1
  62. package/dist/integration-connect-metrics.d.ts +35 -0
  63. package/dist/integration-endpoint-test.d.ts +20 -0
  64. package/dist/integrations/api-integrations.d.ts +2 -2
  65. package/dist/integrations/atlassian.d.ts +8 -3
  66. package/dist/integrations/fiken.d.ts +3 -1
  67. package/dist/integrations/github-lens-connect.d.ts +37 -66
  68. package/dist/integrations/google-drive.d.ts +2 -0
  69. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  70. package/dist/integrations/marketplace-plugin.d.ts +43 -43
  71. package/dist/integrations/oauth-client.d.ts +171 -12
  72. package/dist/integrations/oauth-profiles.d.ts +42 -13
  73. package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
  74. package/dist/integrations/slack-bot.d.ts +285 -7
  75. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  76. package/dist/integrations/slack-interactions.d.ts +89 -10
  77. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  78. package/dist/integrations/slack-routing.d.ts +1 -1
  79. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  80. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  81. package/dist/integrations/slack-tool-review.d.ts +5 -0
  82. package/dist/interaction-agent-access.d.ts +13 -8
  83. package/dist/interaction-agent-version.d.ts +21 -0
  84. package/dist/interaction-holder-heartbeat.d.ts +5 -0
  85. package/dist/interaction-metrics.d.ts +27 -2
  86. package/dist/interaction-route-stages.d.ts +25 -0
  87. package/dist/interaction-secrets-vault.d.ts +20 -0
  88. package/dist/interaction-secrets.d.ts +103 -0
  89. package/dist/mcp/action-catalog-types.d.ts +14 -0
  90. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  91. package/dist/mcp/action-descriptions.d.ts +4 -0
  92. package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
  93. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  94. package/dist/mcp/child-read-evidence.d.ts +9 -0
  95. package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
  96. package/dist/mcp/contract-input.d.ts +13 -0
  97. package/dist/mcp/documents.d.ts +2 -0
  98. package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
  99. package/dist/mcp/notification-tools.d.ts +26 -0
  100. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  101. package/dist/mcp/scheduled-task-input.d.ts +1309 -0
  102. package/dist/mcp/scheduled-task-view.d.ts +217 -3
  103. package/dist/mcp/secret-tools.d.ts +14 -0
  104. package/dist/mcp/server.d.ts +108 -5
  105. package/dist/mcp/session-admin-access-tools.d.ts +33 -0
  106. package/dist/mcp/session-event-errors.d.ts +28 -0
  107. package/dist/mcp/session-event-view.d.ts +62 -0
  108. package/dist/mcp/session-view.d.ts +15 -0
  109. package/dist/mcp/session-wait.d.ts +18 -0
  110. package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
  111. package/dist/mcp/site-data-tools.d.ts +22 -0
  112. package/dist/mcp/site-publication-tools.d.ts +19 -0
  113. package/dist/mcp/site-sql-tools.d.ts +27 -0
  114. package/dist/mcp-oauth.d.ts +37 -4
  115. package/dist/model-calls/chat-completions.d.ts +87 -0
  116. package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
  117. package/dist/model-calls/service.d.ts +36 -0
  118. package/dist/model-catalog.d.ts +9 -3
  119. package/dist/native-push-dispatch.d.ts +69 -0
  120. package/dist/observability.d.ts +3 -1
  121. package/dist/organization-mcp.d.ts +82 -0
  122. package/dist/prepared-mcp-actor.d.ts +77 -0
  123. package/dist/prepared-mcp-permissions.d.ts +8 -0
  124. package/dist/routes/analytics-consent.d.ts +26 -0
  125. package/dist/routes/api-integrations.d.ts +11 -0
  126. package/dist/routes/api-keys.d.ts +7 -7
  127. package/dist/routes/automations.d.ts +2 -0
  128. package/dist/routes/billing.d.ts +59 -0
  129. package/dist/routes/browser-sessions.d.ts +65 -2
  130. package/dist/routes/chat-completions.d.ts +11 -0
  131. package/dist/routes/claude-core-usage.d.ts +20 -0
  132. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  133. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  134. package/dist/routes/client-errors.d.ts +182 -0
  135. package/dist/routes/codex-core.d.ts +401 -0
  136. package/dist/routes/codex.d.ts +64 -2
  137. package/dist/routes/computer-sessions.d.ts +6 -1
  138. package/dist/routes/desktop-distribution.d.ts +32 -0
  139. package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
  140. package/dist/routes/github-browser-pages.d.ts +27 -0
  141. package/dist/routes/inbox.d.ts +13 -0
  142. package/dist/routes/insights-response-cache.d.ts +10 -0
  143. package/dist/routes/insights-usage.d.ts +12 -0
  144. package/dist/routes/insights.d.ts +28 -0
  145. package/dist/routes/interaction-placement-message.d.ts +7 -0
  146. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  147. package/dist/routes/model-account-choice.d.ts +13 -0
  148. package/dist/routes/model-account-settings.d.ts +19 -0
  149. package/dist/routes/native-app-auth.d.ts +12 -0
  150. package/dist/routes/organization-integration-policy.d.ts +8 -0
  151. package/dist/routes/organization-integrations.d.ts +6 -0
  152. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  153. package/dist/routes/organization-model-defaults.d.ts +9 -0
  154. package/dist/routes/organization-service-accounts.d.ts +3 -0
  155. package/dist/routes/personal-api-keys.d.ts +3 -0
  156. package/dist/routes/session-admin-access.d.ts +3 -0
  157. package/dist/routes/session-artifact-associations.d.ts +4 -0
  158. package/dist/routes/session-history-imports.d.ts +20 -0
  159. package/dist/routes/sessions.d.ts +38 -2
  160. package/dist/routes/site-data.d.ts +18 -0
  161. package/dist/routes/site-publishing.d.ts +5 -0
  162. package/dist/routes/site-runtime.d.ts +31 -0
  163. package/dist/routes/site-sql.d.ts +16 -0
  164. package/dist/routes/slack-bot-access.d.ts +3 -0
  165. package/dist/routes/subscription-account-pools.d.ts +21 -0
  166. package/dist/routes/subscription-core-http.d.ts +5 -0
  167. package/dist/routes/subscription-pool-access.d.ts +37 -0
  168. package/dist/routes/subscription-pool-core.d.ts +153 -0
  169. package/dist/routes/supergrok.d.ts +6 -6
  170. package/dist/routes/usage-allowances.d.ts +12 -0
  171. package/dist/routes/variable-sets-removed.d.ts +2 -0
  172. package/dist/routes/vault-providers.d.ts +34 -0
  173. package/dist/routes/vaults.d.ts +3 -0
  174. package/dist/routes/workspace-integrations.d.ts +35 -0
  175. package/dist/routes/workspace-model-providers.d.ts +4 -0
  176. package/dist/routes/workspaces.d.ts +11 -2
  177. package/dist/sandbox/agent-update.d.ts +64 -0
  178. package/dist/sandbox/auth-callout.d.ts +8 -0
  179. package/dist/sandbox/channel-a.d.ts +15 -1
  180. package/dist/sandbox/enrollment.d.ts +26 -4
  181. package/dist/sandbox/machine-audience.d.ts +29 -0
  182. package/dist/sandbox/machines.d.ts +15 -2
  183. package/dist/sandbox/metrics-ingestion.d.ts +6 -2
  184. package/dist/sandbox/screen-control.d.ts +85 -0
  185. package/dist/sandbox/viewer.d.ts +5 -1
  186. package/dist/sandbox-file-artifacts.d.ts +17 -1
  187. package/dist/scheduled-task-blockers.d.ts +39 -0
  188. package/dist/scheduled-task-deletion.d.ts +3 -4
  189. package/dist/scheduled-task-lifecycle.d.ts +14 -0
  190. package/dist/secret-answers.d.ts +40 -0
  191. package/dist/session-create-observability.d.ts +5 -0
  192. package/dist/session-event-view-36GO3IL7.js +528 -0
  193. package/dist/session-event-view-36GO3IL7.js.map +1 -0
  194. package/dist/signed-state-secret.d.ts +18 -0
  195. package/dist/site-agent-guard.d.ts +53 -0
  196. package/dist/site-data/operations.d.ts +103 -0
  197. package/dist/site-data/service.d.ts +203 -0
  198. package/dist/site-frame-guard.d.ts +32 -0
  199. package/dist/site-publishing/agent-data-tools.d.ts +84 -0
  200. package/dist/site-publishing/agent-model.d.ts +58 -0
  201. package/dist/site-publishing/agent-session.d.ts +16 -0
  202. package/dist/site-publishing/content-scanner.d.ts +31 -0
  203. package/dist/site-publishing/edge-sync.d.ts +48 -0
  204. package/dist/site-publishing/gateway-signature.d.ts +56 -0
  205. package/dist/site-publishing/limits.d.ts +63 -0
  206. package/dist/site-publishing/page-tool-authority.d.ts +30 -0
  207. package/dist/site-publishing/platform-usage.d.ts +113 -0
  208. package/dist/site-publishing/platform.d.ts +21 -0
  209. package/dist/site-publishing/readiness.d.ts +62 -0
  210. package/dist/site-publishing/runtime.d.ts +179 -0
  211. package/dist/site-publishing/service.d.ts +264 -0
  212. package/dist/site-publishing/session-events.d.ts +22 -0
  213. package/dist/site-publishing/session-views.d.ts +36 -0
  214. package/dist/site-publishing/viewer.d.ts +40 -0
  215. package/dist/site-session-origin.d.ts +31 -6
  216. package/dist/site-sql/format.d.ts +47 -0
  217. package/dist/site-sql/gateway.d.ts +50 -0
  218. package/dist/site-sql/service.d.ts +213 -0
  219. package/dist/temporal-schedule-sync.d.ts +26 -0
  220. package/dist/transcription/billing-refusal.d.ts +8 -0
  221. package/dist/transcription/normalize.d.ts +23 -0
  222. package/dist/transcription/providers/azure-mai.d.ts +12 -0
  223. package/dist/transcription/providers/azure-openai.d.ts +4 -0
  224. package/dist/transcription/providers/openai.d.ts +16 -0
  225. package/dist/transcription/providers/subscription-core.d.ts +39 -0
  226. package/dist/transcription/service.d.ts +10 -1
  227. package/dist/transcription/wav-duration.d.ts +8 -0
  228. package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
  229. package/dist/workspace-tool-gateway-observability.d.ts +16 -0
  230. package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
  231. package/dist/workspace-tool-gateway.d.ts +102 -6
  232. package/dist/workspace-tool-target-fence.d.ts +116 -0
  233. package/dist/workspace-tool-target.d.ts +225 -0
  234. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  235. package/dist/xai-subscription-core.d.ts +60 -0
  236. package/package.json +25 -20
  237. package/src/access-grant-rls.ts +64 -14
  238. package/src/admission-trace.ts +14 -0
  239. package/src/app.ts +1684 -252
  240. package/src/artifact-catalog-cursor.ts +1 -0
  241. package/src/attached-browser-viewer.ts +26 -0
  242. package/src/auth/managed-auth-attempt-context.ts +9 -0
  243. package/src/auth/managed-auth-rate-limits.ts +252 -0
  244. package/src/auth/managed-auth-session-adapter.ts +64 -29
  245. package/src/auth/managed-auth.ts +303 -35
  246. package/src/auth/managed-email.ts +18 -1
  247. package/src/auth/managed-sign-in-notifications.ts +81 -0
  248. package/src/auth/new-signups-gate.ts +49 -0
  249. package/src/auth/organization-user-setup.ts +3 -3
  250. package/src/auth/signup-funnel-metrics.ts +164 -0
  251. package/src/azure-live.ts +103 -0
  252. package/src/browser-action-fences.ts +45 -0
  253. package/src/browser-controller-authority.ts +1 -186
  254. package/src/browser-ephemeral.ts +39 -0
  255. package/src/browser-lost-runtime-end.ts +71 -0
  256. package/src/browser-state-authority.ts +1 -236
  257. package/src/claude-default-models.ts +37 -0
  258. package/src/claude-subscription-core.ts +154 -0
  259. package/src/claude-subscription-oauth.ts +352 -0
  260. package/src/claude-subscription-profile.ts +73 -0
  261. package/src/claude-subscription-usage.ts +51 -0
  262. package/src/claude-workspace-connection.ts +82 -0
  263. package/src/codemode.ts +236 -39
  264. package/src/codex-realtime.ts +181 -53
  265. package/src/codex-session-pointers.ts +80 -0
  266. package/src/company-brain-okf.ts +1 -1
  267. package/src/connected-machine-computer-access.ts +2 -1
  268. package/src/connection-ownership.ts +19 -13
  269. package/src/controller-data-plane.ts +34 -0
  270. package/src/credit-promotion-snapshot.ts +36 -0
  271. package/src/editable-artifact-production.ts +10 -0
  272. package/src/editable-artifact-source-session.ts +123 -0
  273. package/src/editable-artifact-websocket.ts +16 -3
  274. package/src/fatal-process-boundary.ts +67 -3
  275. package/src/gateway-realtime.ts +12 -8
  276. package/src/github-access.ts +31 -5
  277. package/src/github-browser-flow.ts +1 -1
  278. package/src/http/acting-person.ts +105 -0
  279. package/src/http/api-contract-compat.ts +49 -0
  280. package/src/http/api-error.ts +210 -2
  281. package/src/http/auth.ts +68 -4
  282. package/src/http/cors.ts +37 -5
  283. package/src/http/deprecation.ts +118 -0
  284. package/src/http/keyed-admission.ts +29 -0
  285. package/src/http/local-browser-boundary.ts +343 -0
  286. package/src/http/metrics-listener.ts +57 -0
  287. package/src/http/path-identifier.ts +54 -0
  288. package/src/http/registered-route-label.ts +34 -0
  289. package/src/http/rejection-telemetry.ts +120 -0
  290. package/src/http/request-body.ts +127 -0
  291. package/src/http/request-source.ts +154 -13
  292. package/src/http/sse.ts +88 -28
  293. package/src/http/unmatched-route.ts +60 -0
  294. package/src/http/user-content.ts +158 -0
  295. package/src/http/variable-sets-removed.ts +122 -0
  296. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  297. package/src/index.ts +107 -57
  298. package/src/integration-connect-metrics.ts +228 -0
  299. package/src/integration-endpoint-test.ts +291 -0
  300. package/src/integrations/api-integrations.ts +81 -7
  301. package/src/integrations/atlassian.ts +202 -83
  302. package/src/integrations/fiken.ts +66 -38
  303. package/src/integrations/github-app-connect.ts +64 -18
  304. package/src/integrations/github-lens-connect.ts +8 -29
  305. package/src/integrations/google-drive.ts +448 -152
  306. package/src/integrations/integration-commit-authority.ts +69 -0
  307. package/src/integrations/marketplace-plugin.ts +1 -1
  308. package/src/integrations/oauth-client.ts +733 -193
  309. package/src/integrations/oauth-profiles.ts +116 -45
  310. package/src/integrations/onepassword-vault-provider.ts +16 -0
  311. package/src/integrations/personal-github-repositories.ts +1 -1
  312. package/src/integrations/personal-github.ts +61 -35
  313. package/src/integrations/provider-oauth.ts +67 -85
  314. package/src/integrations/slack-app-home.ts +5 -5
  315. package/src/integrations/slack-bot.ts +893 -201
  316. package/src/integrations/slack-file-upload-flow.ts +147 -0
  317. package/src/integrations/slack-install.ts +7 -7
  318. package/src/integrations/slack-interactions.ts +1589 -299
  319. package/src/integrations/slack-mrkdwn.ts +193 -0
  320. package/src/integrations/slack-routing.ts +2 -2
  321. package/src/integrations/slack-session-defaults.ts +224 -0
  322. package/src/integrations/slack-task-file-upload.ts +323 -0
  323. package/src/integrations/slack-tool-review.ts +65 -0
  324. package/src/integrations/social-oauth.ts +90 -58
  325. package/src/interaction-agent-access.ts +40 -20
  326. package/src/interaction-agent-version.ts +85 -0
  327. package/src/interaction-holder-heartbeat.ts +24 -8
  328. package/src/interaction-metrics.ts +164 -2
  329. package/src/interaction-route-stages.ts +94 -0
  330. package/src/interaction-secrets-vault.ts +213 -0
  331. package/src/interaction-secrets.ts +426 -0
  332. package/src/mcp/action-catalog-types.ts +14 -0
  333. package/src/mcp/action-catalog.gen.ts +8014 -0
  334. package/src/mcp/action-descriptions.ts +299 -0
  335. package/src/mcp/action-schema-imports.gen.ts +304 -0
  336. package/src/mcp/capability-account-readiness.ts +17 -0
  337. package/src/mcp/child-read-evidence.ts +19 -0
  338. package/src/mcp/company-profile-agent-admin.ts +13 -0
  339. package/src/mcp/contract-input.ts +165 -0
  340. package/src/mcp/documents.ts +9 -2
  341. package/src/mcp/editable-artifacts.ts +29 -11
  342. package/src/mcp/files.ts +5 -1
  343. package/src/mcp/first-party-tool-permissions.ts +7 -285
  344. package/src/mcp/knowledge-entries.ts +108 -34
  345. package/src/mcp/notification-tools.ts +480 -0
  346. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  347. package/src/mcp/scheduled-task-input.ts +89 -0
  348. package/src/mcp/scheduled-task-view.ts +63 -3
  349. package/src/mcp/secret-tools.ts +185 -0
  350. package/src/mcp/server.ts +2213 -1116
  351. package/src/mcp/session-admin-access-tools.ts +163 -0
  352. package/src/mcp/session-event-errors.ts +123 -0
  353. package/src/mcp/session-event-view.ts +395 -13
  354. package/src/mcp/session-view.ts +3 -0
  355. package/src/mcp/session-wait.ts +67 -7
  356. package/src/mcp/site-agent-clamp-tools.ts +140 -0
  357. package/src/mcp/site-data-tools.ts +339 -0
  358. package/src/mcp/site-publication-tools.ts +201 -0
  359. package/src/mcp/site-sql-tools.ts +427 -0
  360. package/src/mcp-oauth.ts +635 -45
  361. package/src/model-calls/chat-completions.ts +352 -0
  362. package/src/model-calls/pending-usage-settlements.ts +125 -0
  363. package/src/model-calls/service.ts +694 -0
  364. package/src/model-catalog.ts +68 -17
  365. package/src/native-push-dispatch.ts +457 -0
  366. package/src/observability.ts +15 -1
  367. package/src/organization-mcp.ts +485 -0
  368. package/src/prepared-mcp-actor.ts +154 -0
  369. package/src/prepared-mcp-permissions.ts +38 -0
  370. package/src/routes/analytics-consent.ts +123 -0
  371. package/src/routes/api-integrations.ts +268 -9
  372. package/src/routes/api-keys.ts +164 -25
  373. package/src/routes/artifact-catalog.ts +111 -0
  374. package/src/routes/automations.ts +163 -90
  375. package/src/routes/billing.ts +535 -59
  376. package/src/routes/browser-sessions.ts +966 -342
  377. package/src/routes/canonical-human-identities.ts +61 -0
  378. package/src/routes/capabilities.ts +112 -5
  379. package/src/routes/channels.ts +4 -3
  380. package/src/routes/chat-completions.ts +235 -0
  381. package/src/routes/claude-core-usage.ts +147 -0
  382. package/src/routes/claude-subscription-accounts.ts +233 -0
  383. package/src/routes/claude-subscription-oauth.ts +175 -0
  384. package/src/routes/client-errors.ts +394 -0
  385. package/src/routes/codex-core.ts +687 -0
  386. package/src/routes/codex.ts +1277 -1119
  387. package/src/routes/company-brain.ts +4 -0
  388. package/src/routes/computer-sessions.ts +319 -85
  389. package/src/routes/connect.ts +277 -175
  390. package/src/routes/connections.ts +690 -363
  391. package/src/routes/desktop-distribution.ts +217 -0
  392. package/src/routes/documents.ts +13 -7
  393. package/src/routes/editable-artifacts.ts +74 -4
  394. package/src/routes/enrollments.ts +110 -16
  395. package/src/routes/external-identity-links.ts +13 -12
  396. package/src/routes/files.ts +41 -16
  397. package/src/routes/github-browser-fonts.gen.ts +12 -0
  398. package/src/routes/github-browser-pages.ts +258 -0
  399. package/src/routes/github.ts +200 -75
  400. package/src/routes/inbox.ts +353 -0
  401. package/src/routes/insights-response-cache.ts +83 -0
  402. package/src/routes/insights-usage.ts +345 -0
  403. package/src/routes/insights.ts +103 -8
  404. package/src/routes/install.ts +51 -10
  405. package/src/routes/integration-facets.ts +70 -28
  406. package/src/routes/interaction-placement-message.ts +12 -0
  407. package/src/routes/knowledge.ts +136 -27
  408. package/src/routes/machines.ts +189 -135
  409. package/src/routes/managed-auth-session-sets.ts +43 -10
  410. package/src/routes/managed-onboarding.ts +39 -19
  411. package/src/routes/managed-sign-in-methods.ts +433 -0
  412. package/src/routes/memory-slack-publications.ts +3 -2
  413. package/src/routes/model-account-choice.ts +194 -0
  414. package/src/routes/model-account-settings.ts +235 -0
  415. package/src/routes/model-connection-access.ts +210 -48
  416. package/src/routes/native-app-auth.ts +296 -0
  417. package/src/routes/organization-integration-policy.ts +116 -0
  418. package/src/routes/organization-integrations.ts +326 -0
  419. package/src/routes/organization-mcp-connections.ts +183 -0
  420. package/src/routes/organization-memberships.ts +205 -19
  421. package/src/routes/organization-model-defaults.ts +110 -0
  422. package/src/routes/organization-model-providers.ts +74 -3
  423. package/src/routes/organization-service-accounts.ts +128 -0
  424. package/src/routes/organization-sessions.ts +21 -5
  425. package/src/routes/personal-api-keys.ts +184 -0
  426. package/src/routes/personal-github-git-broker.ts +2 -2
  427. package/src/routes/personal-github.ts +9 -4
  428. package/src/routes/plugins.ts +46 -7
  429. package/src/routes/pr-review-github.ts +105 -118
  430. package/src/routes/pr-review.ts +88 -82
  431. package/src/routes/preference-registry.ts +18 -0
  432. package/src/routes/rigs.ts +48 -13
  433. package/src/routes/scheduled-tasks.ts +347 -27
  434. package/src/routes/session-admin-access.ts +271 -0
  435. package/src/routes/session-artifact-associations.ts +164 -0
  436. package/src/routes/session-history-imports.ts +305 -0
  437. package/src/routes/sessions.ts +1682 -363
  438. package/src/routes/site-data.ts +340 -0
  439. package/src/routes/site-publishing.ts +584 -0
  440. package/src/routes/site-runtime.ts +1944 -0
  441. package/src/routes/site-sql.ts +263 -0
  442. package/src/routes/skill-content.ts +72 -7
  443. package/src/routes/skills.ts +5 -4
  444. package/src/routes/slack-bot-access.ts +108 -0
  445. package/src/routes/social.ts +27 -15
  446. package/src/routes/subscription-account-pools.ts +209 -0
  447. package/src/routes/subscription-core-http.ts +18 -0
  448. package/src/routes/subscription-pool-access.ts +180 -0
  449. package/src/routes/subscription-pool-core.ts +552 -0
  450. package/src/routes/supergrok.ts +174 -655
  451. package/src/routes/transcription-recordings.ts +71 -4
  452. package/src/routes/transcriptions.ts +26 -2
  453. package/src/routes/usage-allowances.ts +381 -0
  454. package/src/routes/variable-sets-removed.ts +19 -0
  455. package/src/routes/vault-providers.ts +782 -0
  456. package/src/routes/vaults.ts +421 -0
  457. package/src/routes/video-generation.ts +30 -12
  458. package/src/routes/workspace-artifacts.ts +165 -53
  459. package/src/routes/workspace-integrations.ts +576 -0
  460. package/src/routes/workspace-model-providers.ts +148 -0
  461. package/src/routes/workspace-state.ts +4 -0
  462. package/src/routes/workspaces.ts +625 -117
  463. package/src/sandbox/agent-update.ts +315 -0
  464. package/src/sandbox/auth-callout.ts +104 -21
  465. package/src/sandbox/channel-a.ts +165 -55
  466. package/src/sandbox/enrollment.ts +131 -22
  467. package/src/sandbox/machine-audience.ts +192 -0
  468. package/src/sandbox/machines.ts +75 -31
  469. package/src/sandbox/metrics-ingestion.ts +133 -2
  470. package/src/sandbox/rematerialize.ts +51 -21
  471. package/src/sandbox/screen-control.ts +289 -0
  472. package/src/sandbox/viewer.ts +33 -58
  473. package/src/sandbox-file-artifacts.ts +53 -27
  474. package/src/scheduled-task-blockers.ts +293 -0
  475. package/src/scheduled-task-deletion.ts +13 -3
  476. package/src/scheduled-task-lifecycle.ts +84 -0
  477. package/src/secret-answers.ts +119 -0
  478. package/src/session-create-observability.ts +46 -0
  479. package/src/session-realtime-context.ts +26 -4
  480. package/src/signed-state-secret.ts +58 -0
  481. package/src/site-agent-guard.ts +261 -0
  482. package/src/site-data/operations.ts +777 -0
  483. package/src/site-data/service.ts +1043 -0
  484. package/src/site-frame-guard.ts +107 -0
  485. package/src/site-publishing/agent-data-tools.ts +250 -0
  486. package/src/site-publishing/agent-model.ts +127 -0
  487. package/src/site-publishing/agent-session.ts +148 -0
  488. package/src/site-publishing/content-scanner.ts +93 -0
  489. package/src/site-publishing/edge-sync.ts +148 -0
  490. package/src/site-publishing/gateway-signature.ts +198 -0
  491. package/src/site-publishing/limits.ts +315 -0
  492. package/src/site-publishing/page-tool-authority.ts +111 -0
  493. package/src/site-publishing/platform-usage.ts +479 -0
  494. package/src/site-publishing/platform.ts +98 -0
  495. package/src/site-publishing/readiness.ts +330 -0
  496. package/src/site-publishing/runtime.ts +831 -0
  497. package/src/site-publishing/service.ts +1282 -0
  498. package/src/site-publishing/session-events.ts +262 -0
  499. package/src/site-publishing/session-views.ts +262 -0
  500. package/src/site-publishing/viewer.ts +75 -0
  501. package/src/site-session-origin.ts +91 -6
  502. package/src/site-sql/format.ts +134 -0
  503. package/src/site-sql/gateway.ts +168 -0
  504. package/src/site-sql/service.ts +1636 -0
  505. package/src/site-uploads.ts +27 -5
  506. package/src/temporal-schedule-sync.ts +74 -0
  507. package/src/transcription/billing-refusal.ts +14 -0
  508. package/src/transcription/normalize.ts +77 -0
  509. package/src/transcription/providers/azure-mai.ts +98 -0
  510. package/src/transcription/providers/azure-openai.ts +16 -7
  511. package/src/transcription/providers/codex-subscription.ts +190 -67
  512. package/src/transcription/providers/openai.ts +79 -5
  513. package/src/transcription/providers/subscription-core.ts +125 -0
  514. package/src/transcription/providers/xai-subscription.ts +81 -83
  515. package/src/transcription/segmenter.ts +7 -1
  516. package/src/transcription/service.ts +239 -10
  517. package/src/transcription/wav-duration.ts +39 -0
  518. package/src/workspace-deletion.ts +25 -1
  519. package/src/workspace-tool-gateway-attestations.ts +133 -0
  520. package/src/workspace-tool-gateway-observability.ts +64 -0
  521. package/src/workspace-tool-gateway-secrets.ts +104 -0
  522. package/src/workspace-tool-gateway.ts +921 -103
  523. package/src/workspace-tool-target-fence.ts +380 -0
  524. package/src/workspace-tool-target.ts +554 -0
  525. package/src/workspace-webhook-dispatch.ts +225 -0
  526. package/src/xai-realtime.ts +85 -81
  527. package/src/xai-subscription-core.ts +172 -0
  528. package/dist/browser-auth-broker.d.ts +0 -20
  529. package/dist/chunk-AJ62T5QN.js.map +0 -1
  530. package/dist/connection-authority-owner.d.ts +0 -59
  531. package/dist/routes/connection-authorities.d.ts +0 -3
  532. package/dist/routes/environments.d.ts +0 -5
  533. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  534. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  535. package/dist/routes/packs.d.ts +0 -3
  536. package/dist/session-event-view-MU3HMNV3.js +0 -264
  537. package/dist/session-event-view-MU3HMNV3.js.map +0 -1
  538. package/dist/xai-subscription-auth.d.ts +0 -23
  539. package/src/browser-auth-broker.ts +0 -155
  540. package/src/connection-authority-owner.ts +0 -61
  541. package/src/routes/connection-authorities.ts +0 -139
  542. package/src/routes/environments.ts +0 -388
  543. package/src/routes/host-mcp-bindings.ts +0 -122
  544. package/src/routes/host-mcp-resolvers.ts +0 -41
  545. package/src/routes/packs.ts +0 -784
  546. package/src/xai-subscription-auth.ts +0 -139
@@ -0,0 +1,213 @@
1
+ /**
2
+ * The vault-backed `InteractionSecretsPort` (design §10B.4, Q-32, D20): the
3
+ * real secret resolver for agent Browser and Computer actions, and passkey
4
+ * items for the session's virtual authenticators.
5
+ */
6
+ import type { VaultProviderRegistry } from "@opengeni/vaults";
7
+ import {
8
+ type BrowserPasskeyCredential,
9
+ type BrowserPasskeyCredentialMaterial,
10
+ PASSKEY_FIELD_NAMES,
11
+ type SecretPrincipal,
12
+ type SecretResolver,
13
+ } from "@opengeni/contracts";
14
+ import { createSecretResolver, createVaultService, type VaultService } from "@opengeni/core";
15
+ import {
16
+ type Database,
17
+ decryptEnvironmentValue,
18
+ getSession,
19
+ getVaultItem,
20
+ isVaultError,
21
+ leaseVaultPasskeys,
22
+ readVaultFieldCiphertext,
23
+ releaseVaultPasskeyLeases,
24
+ updatePasskeySignCount,
25
+ type VaultItemRow,
26
+ } from "@opengeni/db";
27
+ import type {
28
+ AttemptSecretPrincipal,
29
+ InteractionPasskeyStore,
30
+ InteractionSecretsPort,
31
+ } from "./interaction-secrets";
32
+
33
+ const CAPABILITY_CACHE_MS = 30_000;
34
+ const CAPABILITY_CACHE_LIMIT = 512;
35
+ const HOLDER_PRINCIPALS_LIMIT = 1_024;
36
+
37
+ type PasskeyFieldName = (typeof PASSKEY_FIELD_NAMES)[number];
38
+
39
+ function fieldKey(name: string): string {
40
+ return name.toLowerCase();
41
+ }
42
+
43
+ /** `/`, `{`, `}`, `#` and `\` are not allowed in vault names. */
44
+ function safeName(value: string): string {
45
+ return value.replace(/[/{}#\\\p{Cc}]/gu, "-").trim();
46
+ }
47
+
48
+ export function passkeyItemName(credential: BrowserPasskeyCredentialMaterial): string {
49
+ const user = credential.userName?.trim() || credential.userDisplayName?.trim() || null;
50
+ return safeName(
51
+ user ? `${credential.rpId} passkey for ${user}` : `${credential.rpId} passkey`,
52
+ ).slice(0, 180);
53
+ }
54
+
55
+ export function createVaultInteractionSecretsPort(deps: {
56
+ db: Database;
57
+ /** The variable-set envelope key; null fails value reads like the vault API. */
58
+ encryptionKey: Uint8Array | null;
59
+ /** Defaults to a service over the same database and key. */
60
+ vaultService?: VaultService;
61
+ /** Connected vaults (1Password, host) for a workspace's acting subject. */
62
+ providersFor?: (workspaceId: string, subjectId: string | null) => VaultProviderRegistry;
63
+ }): InteractionSecretsPort {
64
+ const encryptionKey = deps.encryptionKey;
65
+ let service = deps.vaultService ?? null;
66
+ const vaults = (): VaultService =>
67
+ (service ??= createVaultService({ db: deps.db, encryptionKey }));
68
+ const capabilities = new Map<string, { enabled: boolean; at: number }>();
69
+ /** Lease holders to the principal that leased, so a release can be scoped. */
70
+ const holders = new Map<string, AttemptSecretPrincipal>();
71
+
72
+ async function secretsEnabled(principal: AttemptSecretPrincipal): Promise<boolean> {
73
+ const cached = capabilities.get(principal.sessionId);
74
+ if (cached && Date.now() - cached.at < CAPABILITY_CACHE_MS) return cached.enabled;
75
+ const session = await getSession(deps.db, principal.workspaceId, principal.sessionId);
76
+ const enabled = session?.agent?.capabilities.secrets ?? true;
77
+ capabilities.delete(principal.sessionId);
78
+ capabilities.set(principal.sessionId, { enabled, at: Date.now() });
79
+ while (capabilities.size > CAPABILITY_CACHE_LIMIT) {
80
+ capabilities.delete(capabilities.keys().next().value!);
81
+ }
82
+ return enabled;
83
+ }
84
+
85
+ function context(principal: SecretPrincipal) {
86
+ return { kind: "principal" as const, principal };
87
+ }
88
+
89
+ function requireKey(): Uint8Array {
90
+ if (!encryptionKey) throw new Error("vault encryption key is not configured");
91
+ return encryptionKey;
92
+ }
93
+
94
+ async function credentialFromItem(
95
+ principal: AttemptSecretPrincipal,
96
+ row: VaultItemRow,
97
+ ): Promise<BrowserPasskeyCredential | null> {
98
+ const values = new Map<PasskeyFieldName, string>();
99
+ for (const name of PASSKEY_FIELD_NAMES) {
100
+ const field = row.fields.find((candidate) => fieldKey(candidate.name) === fieldKey(name));
101
+ if (!field) continue;
102
+ let stored = field.valueEncrypted ?? null;
103
+ if (stored === null) {
104
+ stored = (
105
+ await readVaultFieldCiphertext(deps.db, context(principal), {
106
+ fieldId: field.id,
107
+ purpose: "internal",
108
+ metadata: { surface: "browser", use: "passkey_load" },
109
+ })
110
+ ).valueEncrypted;
111
+ }
112
+ if (stored !== null) values.set(name, decryptEnvironmentValue(requireKey(), stored));
113
+ }
114
+ const rpId = values.get("rpId");
115
+ const credentialId = values.get("credentialId");
116
+ const privateKey = values.get("privateKey");
117
+ if (!rpId || !credentialId || !privateKey) return null;
118
+ return {
119
+ itemId: row.id,
120
+ rpId,
121
+ credentialId,
122
+ userHandle: values.get("userHandle") || null,
123
+ userName: values.get("userName") || null,
124
+ userDisplayName: null,
125
+ privateKey,
126
+ signCount: Math.max(0, Math.min(0xffff_ffff, Number(row.passkeySignCount ?? 0))),
127
+ };
128
+ }
129
+
130
+ const passkeys: InteractionPasskeyStore = {
131
+ async lease(principal, holder, ttlSeconds) {
132
+ holders.delete(holder);
133
+ holders.set(holder, principal);
134
+ while (holders.size > HOLDER_PRINCIPALS_LIMIT) holders.delete(holders.keys().next().value!);
135
+ const itemIds = await leaseVaultPasskeys(deps.db, context(principal), {
136
+ holder,
137
+ ttlSeconds,
138
+ });
139
+ const credentials: BrowserPasskeyCredential[] = [];
140
+ for (const itemId of itemIds) {
141
+ const row = await getVaultItem(deps.db, context(principal), { itemId });
142
+ const credential = await credentialFromItem(principal, row);
143
+ if (credential) credentials.push(credential);
144
+ }
145
+ return credentials;
146
+ },
147
+ async saveRegistered(principal, { credential, origin }) {
148
+ const fields = [
149
+ { name: "rpId", kind: "text" as const, value: credential.rpId },
150
+ { name: "credentialId", kind: "text" as const, value: credential.credentialId },
151
+ ...(credential.userHandle
152
+ ? [{ name: "userHandle", kind: "text" as const, value: credential.userHandle }]
153
+ : []),
154
+ ...(credential.userName
155
+ ? [{ name: "userName", kind: "text" as const, value: credential.userName }]
156
+ : []),
157
+ { name: "privateKey", kind: "concealed" as const, value: credential.privateKey },
158
+ ];
159
+ const base = passkeyItemName(credential);
160
+ let saved: Awaited<ReturnType<VaultService["saveForAgent"]>> | null = null;
161
+ for (const item of [base, `${base} ${credential.credentialId.slice(-6)}`]) {
162
+ try {
163
+ saved = await vaults().saveForAgent(principal, {
164
+ item: safeName(item),
165
+ type: "passkey",
166
+ websites: origin ? [origin] : [`https://${credential.rpId}`],
167
+ fields,
168
+ mode: "create",
169
+ });
170
+ break;
171
+ } catch (error) {
172
+ if (isVaultError(error) && error.code === "vault_item_name_conflict") continue;
173
+ throw error;
174
+ }
175
+ }
176
+ if (!saved) throw new Error("could not name the new passkey item");
177
+ if (credential.signCount > 0) {
178
+ await updatePasskeySignCount(deps.db, context(principal), {
179
+ itemId: saved.item.id,
180
+ count: credential.signCount,
181
+ });
182
+ }
183
+ return { itemId: saved.item.id };
184
+ },
185
+ async updateSignCount(principal, itemId, signCount) {
186
+ await updatePasskeySignCount(deps.db, context(principal), { itemId, count: signCount });
187
+ },
188
+ async release(holder) {
189
+ const principal = holders.get(holder);
190
+ // Without the leasing principal (another API replica or a restart) the
191
+ // lease simply expires after its TTL.
192
+ if (!principal) return;
193
+ holders.delete(holder);
194
+ await releaseVaultPasskeyLeases(deps.db, context(principal), { holder });
195
+ },
196
+ };
197
+
198
+ return {
199
+ async resolverFor(principal): Promise<SecretResolver | null> {
200
+ const providersFor = deps.providersFor;
201
+ return createSecretResolver({ db: deps.db, encryptionKey }, principal, {
202
+ capabilityEnabled: await secretsEnabled(principal),
203
+ ...(providersFor
204
+ ? {
205
+ providersForSubject: (subjectId: string | null) =>
206
+ providersFor(principal.workspaceId, subjectId),
207
+ }
208
+ : {}),
209
+ });
210
+ },
211
+ passkeys,
212
+ };
213
+ }
@@ -0,0 +1,426 @@
1
+ /**
2
+ * `{{secret:…}}` references in Browser and Computer actions (design §10B.4,
3
+ * BR-1..3). Only agent attempts resolve: the API resolves the references in
4
+ * the secret-bearing fields of an action right before dispatch and sends the
5
+ * plaintext to the controller in the private `secretValues` side map. Human
6
+ * and service callers' text is always typed literally. Agent-owned passkeys
7
+ * ride the same seam: around every agent browser action the API loads the
8
+ * principal's leased passkeys into browserd and pulls registration and
9
+ * assertion events back into the vault.
10
+ */
11
+ import {
12
+ type AccessGrant,
13
+ type BrowserPasskeyCredential,
14
+ type BrowserPasskeyCredentialMaterial,
15
+ type BrowserPasskeyEvent,
16
+ type BrowserPasskeySyncRequest,
17
+ type BrowserPasskeySyncResponse,
18
+ buildMissingSecretAskCard,
19
+ containsSecretReference,
20
+ findInvalidSecretReferences,
21
+ findSecretReferences,
22
+ type InteractionSecretValues,
23
+ INTERACTION_PROTOCOL_VERSION,
24
+ isSecretReferenceError,
25
+ referenceKey,
26
+ type SecretClock,
27
+ SecretReferenceError,
28
+ type SecretReferenceFailure,
29
+ type SecretPrincipal,
30
+ type SecretResolver,
31
+ type SecretUseContext,
32
+ secretValueAtDispatch,
33
+ } from "@opengeni/contracts";
34
+ import { ApiHttpError } from "./http/api-error";
35
+
36
+ export type AttemptSecretPrincipal = Extract<SecretPrincipal, { kind: "attempt" }>;
37
+
38
+ /** Vault storage for agent-owned passkeys (F2: `lease_vault_passkeys`,
39
+ * `update_passkey_sign_count`, `release_vault_passkey_leases`). */
40
+ export interface InteractionPasskeyStore {
41
+ /** Lease every passkey item the principal may use and no other holder holds. */
42
+ lease(
43
+ principal: AttemptSecretPrincipal,
44
+ holder: string,
45
+ ttlSeconds: number,
46
+ ): Promise<BrowserPasskeyCredential[]>;
47
+ /** Save a passkey the agent just registered; returns the new item. */
48
+ saveRegistered(
49
+ principal: AttemptSecretPrincipal,
50
+ input: { credential: BrowserPasskeyCredentialMaterial; origin: string | null },
51
+ ): Promise<{ itemId: string }>;
52
+ /** Monotonic write-back (`greatest(existing, new)`). */
53
+ updateSignCount(
54
+ principal: AttemptSecretPrincipal,
55
+ itemId: string,
56
+ signCount: number,
57
+ ): Promise<void>;
58
+ release(holder: string): Promise<void>;
59
+ }
60
+
61
+ export interface InteractionSecretsPort {
62
+ /** The principal's resolver, or null when secrets are unavailable here.
63
+ * A resolver with `enabled: false` (capability off) also passes text through
64
+ * literally (Q-35). */
65
+ resolverFor(principal: AttemptSecretPrincipal): Promise<SecretResolver | null>;
66
+ passkeys: InteractionPasskeyStore | null;
67
+ clock?: SecretClock;
68
+ }
69
+
70
+ export type InteractionSecretsLog = (event: string, fields: Record<string, unknown>) => void;
71
+
72
+ /** The attempt principal of an agent grant. Human, service and incomplete
73
+ * grants have none, so their text is never resolved (BR-1). */
74
+ export function attemptSecretPrincipal(grant: AccessGrant): AttemptSecretPrincipal | null {
75
+ if (grant.principalKind !== "agent_attempt") return null;
76
+ const metadata = grant.metadata ?? {};
77
+ const sessionId = metadata["sessionId"];
78
+ const turnId = metadata["turnId"];
79
+ const attemptId = metadata["attemptId"];
80
+ const executionGeneration = metadata["executionGeneration"];
81
+ if (
82
+ typeof sessionId !== "string" ||
83
+ typeof turnId !== "string" ||
84
+ typeof attemptId !== "string" ||
85
+ typeof executionGeneration !== "number" ||
86
+ !Number.isSafeInteger(executionGeneration)
87
+ ) {
88
+ return null;
89
+ }
90
+ return {
91
+ kind: "attempt",
92
+ accountId: grant.accountId,
93
+ workspaceId: grant.workspaceId,
94
+ sessionId,
95
+ turnId,
96
+ attemptId,
97
+ executionGeneration,
98
+ };
99
+ }
100
+
101
+ /** The public failure: nothing was dispatched. `details.secretReference` is
102
+ * the model-facing `{error, failures, askCard, hint}` object; it never
103
+ * contains values. */
104
+ export function secretReferenceHttpError(error: SecretReferenceError): ApiHttpError {
105
+ const output = JSON.parse(error.toModelOutput()) as Record<string, unknown>;
106
+ return new ApiHttpError(422, {
107
+ code: "validation_failed",
108
+ message: `${error.message}. ${String(output["hint"] ?? "")}`.trim(),
109
+ retryable: false,
110
+ outcomeUnknown: false,
111
+ details: { reason: "secret_reference_error", secretReference: output },
112
+ });
113
+ }
114
+
115
+ function referenceFailure(
116
+ raw: string,
117
+ code: SecretReferenceFailure["code"],
118
+ message: string,
119
+ ): SecretReferenceFailure {
120
+ return { raw, code, message };
121
+ }
122
+
123
+ /** Every string in a JSON-like value (native desktop call arguments). */
124
+ export function collectStringsDeep(value: unknown, out: string[] = [], depth = 0): string[] {
125
+ if (depth > 32) return out;
126
+ if (typeof value === "string") out.push(value);
127
+ else if (Array.isArray(value))
128
+ for (const entry of value) collectStringsDeep(entry, out, depth + 1);
129
+ else if (value !== null && typeof value === "object") {
130
+ for (const entry of Object.values(value)) collectStringsDeep(entry, out, depth + 1);
131
+ }
132
+ return out;
133
+ }
134
+
135
+ /**
136
+ * Resolve the references in `texts` for an agent grant. Returns undefined
137
+ * when the text must be dispatched literally (non-agent caller, no marker,
138
+ * secrets unavailable or off). Returns a (possibly empty) side map otherwise;
139
+ * an empty map still tells the controller to remove `\{{secret:…}}` escapes.
140
+ * TOTP codes are computed last, at dispatch (Q-33). Throws ApiHttpError(422)
141
+ * before anything is dispatched when any reference fails (I2).
142
+ */
143
+ export async function resolveInteractionSecretValues(input: {
144
+ port: InteractionSecretsPort | null | undefined;
145
+ grant: AccessGrant;
146
+ texts: readonly string[];
147
+ use: SecretUseContext;
148
+ /** Runs once the text is known to carry references for an agent with
149
+ * secrets enabled, before anything resolves: a controller that cannot
150
+ * accept secret values refuses here, with nothing used or dispatched. */
151
+ beforeResolve?: () => Promise<void>;
152
+ }): Promise<InteractionSecretValues | undefined> {
153
+ const { port, grant, texts, use, beforeResolve } = input;
154
+ if (!port) return undefined;
155
+ if (!texts.some((text) => containsSecretReference(text))) return undefined;
156
+ const principal = attemptSecretPrincipal(grant);
157
+ if (!principal) return undefined;
158
+ const resolver = await port.resolverFor(principal);
159
+ if (!resolver || !resolver.enabled) return undefined;
160
+ await beforeResolve?.();
161
+ const failures: SecretReferenceFailure[] = [];
162
+ for (const text of texts) {
163
+ for (const invalid of findInvalidSecretReferences(text)) {
164
+ failures.push(
165
+ referenceFailure(invalid.raw, "invalid_reference", `invalid reference: ${invalid.reason}`),
166
+ );
167
+ }
168
+ }
169
+ const references = texts.flatMap((text) => findSecretReferences(text));
170
+ for (const reference of references) {
171
+ if (reference.kind === "secretfile") {
172
+ failures.push(
173
+ referenceFailure(
174
+ reference.raw,
175
+ "secretfile_not_allowed",
176
+ "{{secretfile:…}} is for commands that read a file path; type the value with {{secret:…}}",
177
+ ),
178
+ );
179
+ }
180
+ }
181
+ if (failures.length > 0) throw secretReferenceHttpError(new SecretReferenceError(failures));
182
+ if (references.length === 0) return {};
183
+ let resolved;
184
+ try {
185
+ resolved = await resolver.resolve(references, use);
186
+ } catch (error) {
187
+ if (isSecretReferenceError(error)) {
188
+ if (error instanceof SecretReferenceError) throw secretReferenceHttpError(error);
189
+ // A structurally equal error from another copy of the contracts module.
190
+ const foreign = error as unknown as {
191
+ failures: SecretReferenceFailure[];
192
+ askCard?: SecretReferenceError["askCard"];
193
+ };
194
+ throw secretReferenceHttpError(
195
+ new SecretReferenceError(
196
+ foreign.failures,
197
+ foreign.askCard ?? buildMissingSecretAskCard(foreign.failures, { hasActingHuman: false }),
198
+ ),
199
+ );
200
+ }
201
+ throw error;
202
+ }
203
+ const values: InteractionSecretValues = {};
204
+ const ordered = [...resolved.values()].sort(
205
+ (left, right) => Number(left.material.type === "totp") - Number(right.material.type === "totp"),
206
+ );
207
+ for (const value of ordered) {
208
+ const material = await secretValueAtDispatch(value, port.clock);
209
+ if (typeof material !== "string") {
210
+ failures.push(
211
+ referenceFailure(
212
+ value.reference.raw,
213
+ "binary_value",
214
+ "this field holds a file; browsers and desktops can only type text",
215
+ ),
216
+ );
217
+ continue;
218
+ }
219
+ values[value.key] = material;
220
+ }
221
+ if (failures.length > 0) throw secretReferenceHttpError(new SecretReferenceError(failures));
222
+ for (const reference of references) {
223
+ if (values[referenceKey(reference)] === undefined) {
224
+ throw secretReferenceHttpError(
225
+ new SecretReferenceError([
226
+ referenceFailure(reference.raw, "not_found", "the reference did not resolve"),
227
+ ]),
228
+ );
229
+ }
230
+ }
231
+ return values;
232
+ }
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // Passkeys
236
+ // ---------------------------------------------------------------------------
237
+
238
+ export const PASSKEY_LEASE_TTL_SECONDS = 600;
239
+ const PASSKEY_LEASE_RENEW_MS = 60_000;
240
+ const PASSKEY_SESSION_CACHE_LIMIT = 2_048;
241
+
242
+ type PasskeySessionState = {
243
+ leasedAtMs: number;
244
+ credentials: BrowserPasskeyCredential[];
245
+ unsupported: boolean;
246
+ };
247
+
248
+ /** Per-process lease cache: renew at most once a minute per browser session
249
+ * (leases last ten minutes and renew on use, Q-32). */
250
+ const passkeySessions = new Map<string, PasskeySessionState>();
251
+
252
+ /** The latest pending sync per BrowserSession; later syncs chain after it. */
253
+ const passkeySyncTails = new Map<string, Promise<void>>();
254
+
255
+ export function resetPasskeySessionCacheForTests(): void {
256
+ passkeySessions.clear();
257
+ passkeySyncTails.clear();
258
+ }
259
+
260
+ /** One lease holder per BrowserSession: every target in it shares the set. */
261
+ export function passkeyLeaseHolder(browserSessionId: string): string {
262
+ return browserSessionId;
263
+ }
264
+
265
+ export type PasskeySyncClient = {
266
+ passkeySync(request: BrowserPasskeySyncRequest): Promise<BrowserPasskeySyncResponse>;
267
+ };
268
+
269
+ function isUnsupportedSync(error: unknown): boolean {
270
+ const status = (error as { status?: unknown } | null)?.status;
271
+ const name = (error as { name?: unknown } | null)?.name;
272
+ return status === 404 || status === 405 || name === "BrowserControlUnsupportedError";
273
+ }
274
+
275
+ /**
276
+ * Load the principal's passkeys into the BrowserSession and write back what
277
+ * happened since the last sync. Best effort: a failure is logged and never
278
+ * fails the surrounding action. Unacknowledged events stay in browserd and
279
+ * are retried on the next sync.
280
+ *
281
+ * Syncs for one BrowserSession run one at a time, in call order, so a caller
282
+ * may start the write-back after an action without awaiting it: the next
283
+ * action's sync waits for it instead of racing it on the same events.
284
+ */
285
+ export function syncBrowserPasskeys(input: PasskeySyncInput): Promise<PasskeySyncResult> {
286
+ const previous = passkeySyncTails.get(input.browserSessionId);
287
+ const run = (previous ?? Promise.resolve()).then(() => syncBrowserPasskeysNow(input));
288
+ const tail = run.then(
289
+ () => undefined,
290
+ () => undefined,
291
+ );
292
+ passkeySyncTails.set(input.browserSessionId, tail);
293
+ void tail.then(() => {
294
+ if (passkeySyncTails.get(input.browserSessionId) === tail) {
295
+ passkeySyncTails.delete(input.browserSessionId);
296
+ }
297
+ });
298
+ return run;
299
+ }
300
+
301
+ type PasskeySyncResult = { saved: number; asserted: number } | null;
302
+
303
+ type PasskeySyncInput = {
304
+ port: InteractionSecretsPort | null | undefined;
305
+ grant: AccessGrant;
306
+ browserSessionId: string;
307
+ controllerGeneration: string;
308
+ client: PasskeySyncClient;
309
+ /** Lease again now (right before an action), taking over from any other browser. */
310
+ refresh?: boolean;
311
+ now?: () => number;
312
+ log?: InteractionSecretsLog;
313
+ };
314
+
315
+ async function syncBrowserPasskeysNow(input: PasskeySyncInput): Promise<PasskeySyncResult> {
316
+ const store = input.port?.passkeys;
317
+ if (!store) return null;
318
+ const principal = attemptSecretPrincipal(input.grant);
319
+ if (!principal) return null;
320
+ const now = input.now ?? Date.now;
321
+ const holder = passkeyLeaseHolder(input.browserSessionId);
322
+ // Per attempt: a later turn may act for another person, so it leases (and
323
+ // replaces browserd's credential set with) its own passkeys first.
324
+ const cacheKey = `${input.browserSessionId}:${input.controllerGeneration}:${principal.attemptId}`;
325
+ let state = passkeySessions.get(cacheKey);
326
+ if (state?.unsupported) return null;
327
+ const lease = async (): Promise<BrowserPasskeyCredential[]> => {
328
+ const credentials = await store.lease(principal, holder, PASSKEY_LEASE_TTL_SECONDS);
329
+ state = { leasedAtMs: now(), credentials, unsupported: false };
330
+ passkeySessions.delete(cacheKey);
331
+ passkeySessions.set(cacheKey, state);
332
+ while (passkeySessions.size > PASSKEY_SESSION_CACHE_LIMIT) {
333
+ passkeySessions.delete(passkeySessions.keys().next().value!);
334
+ }
335
+ return credentials;
336
+ };
337
+ const request = (
338
+ credentials: BrowserPasskeyCredential[] | null,
339
+ acknowledgeEventIds: string[],
340
+ ): BrowserPasskeySyncRequest => ({
341
+ protocolVersion: INTERACTION_PROTOCOL_VERSION,
342
+ browserSessionId: input.browserSessionId,
343
+ controllerGeneration: input.controllerGeneration,
344
+ credentials,
345
+ acknowledgeEventIds,
346
+ });
347
+ try {
348
+ const due =
349
+ input.refresh === true || !state || now() - state.leasedAtMs >= PASSKEY_LEASE_RENEW_MS;
350
+ const credentials = due ? await lease() : null;
351
+ let response: BrowserPasskeySyncResponse;
352
+ try {
353
+ response = await input.client.passkeySync(request(credentials, []));
354
+ } catch (error) {
355
+ if (isUnsupportedSync(error)) {
356
+ passkeySessions.set(cacheKey, {
357
+ leasedAtMs: now(),
358
+ credentials: [],
359
+ unsupported: true,
360
+ });
361
+ await store.release(holder).catch(() => undefined);
362
+ return null;
363
+ }
364
+ throw error;
365
+ }
366
+ if (response.events.length === 0) return { saved: 0, asserted: 0 };
367
+ const processed: string[] = [];
368
+ const itemByCredential = new Map(
369
+ (state?.credentials ?? []).map((credential) => [credential.credentialId, credential.itemId]),
370
+ );
371
+ let saved = 0;
372
+ let asserted = 0;
373
+ for (const event of response.events as BrowserPasskeyEvent[]) {
374
+ try {
375
+ if (event.type === "registered") {
376
+ const existing = itemByCredential.get(event.credential.credentialId);
377
+ if (existing === undefined) {
378
+ const result = await store.saveRegistered(principal, {
379
+ credential: event.credential,
380
+ origin: event.origin,
381
+ });
382
+ itemByCredential.set(event.credential.credentialId, result.itemId);
383
+ saved += 1;
384
+ }
385
+ } else {
386
+ const itemId = event.itemId ?? itemByCredential.get(event.credentialId) ?? null;
387
+ if (itemId !== null) {
388
+ await store.updateSignCount(principal, itemId, event.signCount);
389
+ asserted += 1;
390
+ } else {
391
+ input.log?.("browser.passkey.assertion_unmatched", { rpId: event.rpId });
392
+ }
393
+ }
394
+ processed.push(event.eventId);
395
+ } catch (error) {
396
+ input.log?.("browser.passkey.event_failed", {
397
+ type: event.type,
398
+ message: error instanceof Error ? error.message : String(error),
399
+ });
400
+ }
401
+ }
402
+ // New items are loaded with their item IDs so later assertions write back.
403
+ const refreshed = saved > 0 ? await lease() : null;
404
+ await input.client.passkeySync(request(refreshed, processed));
405
+ if (saved > 0 || asserted > 0) {
406
+ input.log?.("browser.passkey.synced", { saved, asserted });
407
+ }
408
+ return { saved, asserted };
409
+ } catch (error) {
410
+ input.log?.("browser.passkey.sync_failed", {
411
+ message: error instanceof Error ? error.message : String(error),
412
+ });
413
+ return null;
414
+ }
415
+ }
416
+
417
+ /** Release the BrowserSession's passkey leases (session end). Best effort. */
418
+ export async function releaseBrowserPasskeys(
419
+ port: InteractionSecretsPort | null | undefined,
420
+ browserSessionId: string,
421
+ ): Promise<void> {
422
+ for (const key of [...passkeySessions.keys()]) {
423
+ if (key.startsWith(`${browserSessionId}:`)) passkeySessions.delete(key);
424
+ }
425
+ await port?.passkeys?.release(passkeyLeaseHolder(browserSessionId)).catch(() => undefined);
426
+ }
@@ -0,0 +1,14 @@
1
+ export type ActionCatalogEntry = {
2
+ /** Stable name an agent calls: the SDK method ("listSessions"), else "METHOD /path". */
3
+ id: string;
4
+ method: string;
5
+ path: string;
6
+ /** Contract schema names for the JSON body and response, when known. */
7
+ request: string[];
8
+ response: string[];
9
+ /**
10
+ * Why no MCP caller can complete this action: it needs the person's own
11
+ * Opengeni browser session. Set only on such actions; the server hides them.
12
+ */
13
+ browserOnly?: string;
14
+ };