@opengeni/api-router 0.30.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/dist/access-grant-rls.d.ts +3 -0
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/api-websocket.d.ts +18 -0
  4. package/dist/app.d.ts +50 -2
  5. package/dist/app.js +12 -1
  6. package/dist/artifact-catalog-cursor.d.ts +27 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +10 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +6 -0
  10. package/dist/auth/managed-auth.d.ts +102 -3
  11. package/dist/auth/managed-email.d.ts +29 -0
  12. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  13. package/dist/auth/new-signups-gate.d.ts +23 -0
  14. package/dist/auth/organization-user-setup.d.ts +80 -0
  15. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-state-authority.d.ts +1 -27
  19. package/dist/chunk-6TZ5LG3O.js +123948 -0
  20. package/dist/chunk-6TZ5LG3O.js.map +1 -0
  21. package/dist/chunk-OGQDXVXY.js +18 -0
  22. package/dist/chunk-OGQDXVXY.js.map +1 -0
  23. package/dist/claude-subscription-account-conflicts.d.ts +1 -0
  24. package/dist/claude-subscription-account-usage.d.ts +39 -0
  25. package/dist/claude-subscription-oauth.d.ts +25 -0
  26. package/dist/claude-subscription-profile.d.ts +9 -0
  27. package/dist/claude-subscription-usage.d.ts +44 -0
  28. package/dist/claude-workspace-connection.d.ts +15 -0
  29. package/dist/codemode.d.ts +32 -1
  30. package/dist/company-brain-okf.d.ts +24 -0
  31. package/dist/connected-machine-computer-access.d.ts +11 -0
  32. package/dist/connection-ownership.d.ts +54 -0
  33. package/dist/controller-data-plane.d.ts +32 -0
  34. package/dist/editable-artifact-source-session.d.ts +3 -0
  35. package/dist/editable-artifact-websocket.d.ts +10 -18
  36. package/dist/editable-artifact-workspace-files.d.ts +1 -1
  37. package/dist/fatal-process-boundary.d.ts +25 -0
  38. package/dist/github-access.d.ts +31 -2
  39. package/dist/http/acting-person.d.ts +24 -0
  40. package/dist/http/api-contract-compat.d.ts +19 -0
  41. package/dist/http/api-error.d.ts +27 -1
  42. package/dist/http/cors.d.ts +17 -0
  43. package/dist/http/deprecation.d.ts +42 -0
  44. package/dist/http/interaction-control-error.d.ts +13 -0
  45. package/dist/http/keyed-admission.d.ts +12 -0
  46. package/dist/http/local-browser-boundary.d.ts +72 -0
  47. package/dist/http/metrics-listener.d.ts +22 -0
  48. package/dist/http/path-identifier.d.ts +17 -0
  49. package/dist/http/registered-route-label.d.ts +16 -0
  50. package/dist/http/request-body.d.ts +27 -0
  51. package/dist/http/request-source.d.ts +52 -0
  52. package/dist/http/sse.d.ts +17 -6
  53. package/dist/http/unmatched-route.d.ts +18 -0
  54. package/dist/http/user-content.d.ts +36 -0
  55. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  56. package/dist/index.d.ts +10 -3
  57. package/dist/index.js +1091 -162
  58. package/dist/index.js.map +1 -1
  59. package/dist/integration-endpoint-test.d.ts +20 -0
  60. package/dist/integrations/api-integrations.d.ts +2 -2
  61. package/dist/integrations/atlassian.d.ts +29 -3
  62. package/dist/integrations/connect-authority.d.ts +1 -0
  63. package/dist/integrations/connect-callback-return.d.ts +6 -0
  64. package/dist/integrations/fiken.d.ts +16 -2
  65. package/dist/integrations/github-app-connect.d.ts +47 -0
  66. package/dist/integrations/github-installation-proof.d.ts +3 -0
  67. package/dist/integrations/github-lens-connect.d.ts +116 -0
  68. package/dist/integrations/github-skill-source.d.ts +1 -5
  69. package/dist/integrations/google-drive.d.ts +24 -0
  70. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  71. package/dist/integrations/marketplace-plugin.d.ts +2691 -0
  72. package/dist/integrations/oauth-client.d.ts +178 -18
  73. package/dist/integrations/oauth-profiles.d.ts +222 -0
  74. package/dist/integrations/oauth-return-path.d.ts +1 -0
  75. package/dist/integrations/personal-github-repositories.d.ts +84 -0
  76. package/dist/integrations/personal-github.d.ts +42 -0
  77. package/dist/integrations/pr-review-provider.d.ts +22 -0
  78. package/dist/integrations/provider-oauth.d.ts +19 -1
  79. package/dist/integrations/slack-app-home.d.ts +24 -0
  80. package/dist/integrations/slack-bot.d.ts +367 -12
  81. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  82. package/dist/integrations/slack-install.d.ts +20 -0
  83. package/dist/integrations/slack-interactions.d.ts +107 -9
  84. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  85. package/dist/integrations/slack-routing.d.ts +120 -0
  86. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  87. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  88. package/dist/integrations/social-oauth.d.ts +7 -0
  89. package/dist/interaction-agent-access.d.ts +15 -0
  90. package/dist/interaction-frame-proxy.d.ts +68 -0
  91. package/dist/interaction-metrics.d.ts +2 -0
  92. package/dist/mcp/action-catalog-types.d.ts +9 -0
  93. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  94. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  95. package/dist/mcp/child-read-evidence.d.ts +9 -0
  96. package/dist/mcp/command-read.d.ts +24 -0
  97. package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
  98. package/dist/mcp/contract-input.d.ts +11 -0
  99. package/dist/mcp/documents.d.ts +7 -5
  100. package/dist/mcp/files.d.ts +2 -2
  101. package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
  102. package/dist/mcp/knowledge-entries.d.ts +5 -0
  103. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  104. package/dist/mcp/receipts.d.ts +9 -0
  105. package/dist/mcp/request-abort.d.ts +19 -0
  106. package/dist/mcp/scheduled-task-input.d.ts +1189 -0
  107. package/dist/mcp/scheduled-task-view.d.ts +22 -4
  108. package/dist/mcp/server.d.ts +255 -3
  109. package/dist/mcp/session-event-view.d.ts +94 -0
  110. package/dist/mcp/session-view.d.ts +66 -2
  111. package/dist/mcp/session-wait.d.ts +174 -0
  112. package/dist/mcp-oauth.d.ts +52 -0
  113. package/dist/model-catalog.d.ts +11 -31
  114. package/dist/observability.d.ts +3 -1
  115. package/dist/organization-mcp.d.ts +52 -0
  116. package/dist/organization-recovery-notifications.d.ts +41 -0
  117. package/dist/routes/analytics-consent.d.ts +26 -0
  118. package/dist/routes/api-integrations.d.ts +25 -0
  119. package/dist/routes/api-keys.d.ts +17 -0
  120. package/dist/routes/artifact-catalog.d.ts +6 -0
  121. package/dist/routes/automations.d.ts +19 -0
  122. package/dist/routes/billing.d.ts +49 -0
  123. package/dist/routes/browser-sessions.d.ts +59 -2
  124. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  125. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  126. package/dist/routes/client-errors.d.ts +146 -0
  127. package/dist/routes/codex.d.ts +76 -2
  128. package/dist/routes/company-brain.d.ts +3 -0
  129. package/dist/routes/company-profile.d.ts +2 -1
  130. package/dist/routes/computer-sessions.d.ts +14 -0
  131. package/dist/routes/connect.d.ts +5 -0
  132. package/dist/routes/editable-artifacts.d.ts +2 -0
  133. package/dist/routes/external-identity-links.d.ts +6 -0
  134. package/dist/routes/feedback.d.ts +3 -0
  135. package/dist/routes/github-browser-pages.d.ts +12 -0
  136. package/dist/routes/github.d.ts +2 -0
  137. package/dist/routes/insights-response-cache.d.ts +10 -0
  138. package/dist/routes/insights-usage.d.ts +12 -0
  139. package/dist/routes/insights.d.ts +30 -1
  140. package/dist/routes/knowledge.d.ts +3 -0
  141. package/dist/routes/managed-auth-session-sets.d.ts +26 -0
  142. package/dist/routes/managed-onboarding.d.ts +29 -0
  143. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  144. package/dist/routes/model-connection-access.d.ts +3 -0
  145. package/dist/routes/organization-integration-policy.d.ts +3 -0
  146. package/dist/routes/organization-integrations.d.ts +6 -0
  147. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  148. package/dist/routes/organization-model-providers.d.ts +3 -0
  149. package/dist/routes/organization-recovery.d.ts +19 -0
  150. package/dist/routes/organization-service-accounts.d.ts +3 -0
  151. package/dist/routes/organization-sessions.d.ts +26 -0
  152. package/dist/routes/personal-github-git-broker.d.ts +29 -0
  153. package/dist/routes/personal-github.d.ts +3 -0
  154. package/dist/routes/pr-review-github.d.ts +3 -0
  155. package/dist/routes/pr-review.d.ts +3 -0
  156. package/dist/routes/session-artifact-associations.d.ts +4 -0
  157. package/dist/routes/session-history-imports.d.ts +9 -0
  158. package/dist/routes/sessions.d.ts +44 -6
  159. package/dist/routes/skill-content.d.ts +4 -0
  160. package/dist/routes/skill-install-authority.d.ts +6 -0
  161. package/dist/routes/subscription-account-pools.d.ts +34 -0
  162. package/dist/routes/subscription-pool-access.d.ts +16 -0
  163. package/dist/routes/supergrok.d.ts +6 -1
  164. package/dist/routes/usage-allowances.d.ts +12 -0
  165. package/dist/routes/user-resource-authorities.d.ts +3 -0
  166. package/dist/routes/workspace-artifacts.d.ts +2 -1
  167. package/dist/routes/workspace-capture.d.ts +10 -2
  168. package/dist/routes/workspace-integrations.d.ts +35 -0
  169. package/dist/routes/workspace-learning.d.ts +3 -0
  170. package/dist/routes/workspace-model-providers.d.ts +4 -0
  171. package/dist/routes/workspaces.d.ts +29 -0
  172. package/dist/sandbox/auth-callout.d.ts +8 -0
  173. package/dist/sandbox/channel-a.d.ts +19 -1
  174. package/dist/sandbox/connection-authority.d.ts +3 -0
  175. package/dist/sandbox/enrollment.d.ts +9 -1
  176. package/dist/sandbox/machines.d.ts +5 -2
  177. package/dist/sandbox/metrics-ingestion.d.ts +28 -20
  178. package/dist/sandbox/rematerialize.d.ts +2 -0
  179. package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
  180. package/dist/sandbox/viewer.d.ts +26 -1
  181. package/dist/sandbox-file-artifacts.d.ts +50 -0
  182. package/dist/scheduled-task-deletion.d.ts +13 -0
  183. package/dist/session-create-observability.d.ts +5 -0
  184. package/dist/session-event-view-MPS2OZD3.js +292 -0
  185. package/dist/session-event-view-MPS2OZD3.js.map +1 -0
  186. package/dist/site-session-origin.d.ts +13 -0
  187. package/dist/site-uploads.d.ts +41 -0
  188. package/dist/slack-reaction-files.d.ts +1 -1
  189. package/dist/temporal-schedule-cleanup.d.ts +1 -0
  190. package/dist/temporal-schedule-sync.d.ts +26 -0
  191. package/dist/transcription/providers/xai-subscription.d.ts +1 -0
  192. package/dist/transcription/service.d.ts +2 -1
  193. package/dist/work-discovery-observability.d.ts +33 -0
  194. package/dist/workspace-artifact-content.d.ts +28 -0
  195. package/dist/workspace-artifact-provenance.d.ts +7 -0
  196. package/dist/workspace-delete-observability.d.ts +10 -0
  197. package/dist/workspace-deletion.d.ts +6 -0
  198. package/dist/workspace-state-projection.d.ts +3 -5
  199. package/dist/workspace-tool-gateway-observability.d.ts +17 -0
  200. package/dist/workspace-tool-gateway.d.ts +123 -0
  201. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  202. package/package.json +23 -19
  203. package/src/access-grant-rls.ts +75 -0
  204. package/src/admission-trace.ts +14 -0
  205. package/src/api-websocket.ts +23 -0
  206. package/src/app.ts +1967 -252
  207. package/src/artifact-catalog-cursor.ts +60 -0
  208. package/src/auth/managed-auth-attempt-context.ts +70 -0
  209. package/src/auth/managed-auth-rate-limits.ts +252 -0
  210. package/src/auth/managed-auth-session-adapter.ts +222 -0
  211. package/src/auth/managed-auth.ts +536 -60
  212. package/src/auth/managed-email.ts +174 -0
  213. package/src/auth/managed-sign-in-notifications.ts +81 -0
  214. package/src/auth/new-signups-gate.ts +49 -0
  215. package/src/auth/organization-user-setup.ts +307 -0
  216. package/src/auth/signup-funnel-metrics.ts +164 -0
  217. package/src/browser-controller-authority.ts +1 -186
  218. package/src/browser-ephemeral.ts +39 -0
  219. package/src/browser-state-authority.ts +1 -236
  220. package/src/claude-subscription-account-conflicts.ts +12 -0
  221. package/src/claude-subscription-account-usage.ts +48 -0
  222. package/src/claude-subscription-oauth.ts +362 -0
  223. package/src/claude-subscription-profile.ts +73 -0
  224. package/src/claude-subscription-usage.ts +97 -0
  225. package/src/claude-workspace-connection.ts +82 -0
  226. package/src/codemode.ts +194 -30
  227. package/src/codex-realtime.ts +8 -2
  228. package/src/company-brain-okf.ts +340 -0
  229. package/src/connected-machine-computer-access.ts +33 -0
  230. package/src/connection-ownership.ts +199 -0
  231. package/src/controller-data-plane.ts +81 -0
  232. package/src/editable-artifact-native-kernel.ts +26 -15
  233. package/src/editable-artifact-office-import.ts +28 -3
  234. package/src/editable-artifact-production.ts +23 -7
  235. package/src/editable-artifact-source-session.ts +123 -0
  236. package/src/editable-artifact-websocket.ts +27 -21
  237. package/src/editable-artifact-workspace-files.ts +31 -6
  238. package/src/fatal-process-boundary.ts +246 -0
  239. package/src/gateway-realtime.ts +1 -1
  240. package/src/github-access.ts +147 -5
  241. package/src/http/acting-person.ts +71 -0
  242. package/src/http/api-contract-compat.ts +49 -0
  243. package/src/http/api-error.ts +115 -1
  244. package/src/http/auth.ts +48 -0
  245. package/src/http/cors.ts +67 -0
  246. package/src/http/deprecation.ts +118 -0
  247. package/src/http/interaction-control-error.ts +164 -0
  248. package/src/http/keyed-admission.ts +29 -0
  249. package/src/http/local-browser-boundary.ts +343 -0
  250. package/src/http/metrics-listener.ts +57 -0
  251. package/src/http/path-identifier.ts +54 -0
  252. package/src/http/registered-route-label.ts +34 -0
  253. package/src/http/request-body.ts +127 -0
  254. package/src/http/request-source.ts +178 -0
  255. package/src/http/sse.ts +486 -132
  256. package/src/http/unmatched-route.ts +60 -0
  257. package/src/http/user-content.ts +158 -0
  258. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  259. package/src/index.ts +157 -52
  260. package/src/integration-endpoint-test.ts +291 -0
  261. package/src/integrations/api-integrations.ts +98 -11
  262. package/src/integrations/atlassian.ts +474 -136
  263. package/src/integrations/connect-authority.ts +2 -0
  264. package/src/integrations/connect-callback-return.ts +86 -0
  265. package/src/integrations/fiken.ts +354 -64
  266. package/src/integrations/github-app-connect.ts +435 -0
  267. package/src/integrations/github-installation-proof.ts +60 -0
  268. package/src/integrations/github-lens-connect.ts +76 -0
  269. package/src/integrations/github-skill-source.ts +2 -142
  270. package/src/integrations/google-drive.ts +717 -225
  271. package/src/integrations/integration-commit-authority.ts +69 -0
  272. package/src/integrations/marketplace-plugin.ts +48 -0
  273. package/src/integrations/oauth-client.ts +1356 -459
  274. package/src/integrations/oauth-profiles.ts +537 -0
  275. package/src/integrations/oauth-return-path.ts +18 -0
  276. package/src/integrations/personal-github-repositories.ts +674 -0
  277. package/src/integrations/personal-github.ts +825 -0
  278. package/src/integrations/pr-review-provider.ts +246 -0
  279. package/src/integrations/provider-oauth.ts +250 -22
  280. package/src/integrations/slack-app-home.ts +300 -0
  281. package/src/integrations/slack-bot.ts +963 -239
  282. package/src/integrations/slack-file-upload-flow.ts +147 -0
  283. package/src/integrations/slack-install.ts +83 -0
  284. package/src/integrations/slack-interactions.ts +3167 -474
  285. package/src/integrations/slack-mrkdwn.ts +193 -0
  286. package/src/integrations/slack-routing.ts +337 -0
  287. package/src/integrations/slack-session-defaults.ts +224 -0
  288. package/src/integrations/slack-task-file-upload.ts +323 -0
  289. package/src/integrations/social-oauth.ts +213 -15
  290. package/src/interaction-agent-access.ts +48 -0
  291. package/src/interaction-frame-proxy.ts +409 -0
  292. package/src/interaction-metrics.ts +30 -0
  293. package/src/mcp/action-catalog-types.ts +9 -0
  294. package/src/mcp/action-catalog.gen.ts +6696 -0
  295. package/src/mcp/capability-account-readiness.ts +17 -0
  296. package/src/mcp/child-read-evidence.ts +19 -0
  297. package/src/mcp/command-read.ts +109 -0
  298. package/src/mcp/company-profile-agent-admin.ts +198 -0
  299. package/src/mcp/contract-input.ts +141 -0
  300. package/src/mcp/documents.ts +65 -377
  301. package/src/mcp/editable-artifacts.ts +12 -6
  302. package/src/mcp/files.ts +80 -43
  303. package/src/mcp/first-party-tool-permissions.ts +305 -0
  304. package/src/mcp/knowledge-entries.ts +322 -0
  305. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  306. package/src/mcp/receipts.ts +34 -0
  307. package/src/mcp/request-abort.ts +44 -0
  308. package/src/mcp/scheduled-task-input.ts +76 -0
  309. package/src/mcp/scheduled-task-view.ts +44 -3
  310. package/src/mcp/server.ts +3030 -1267
  311. package/src/mcp/session-event-view.ts +383 -0
  312. package/src/mcp/session-view.ts +84 -3
  313. package/src/mcp/session-wait.ts +665 -0
  314. package/src/mcp-oauth.ts +1123 -0
  315. package/src/model-catalog.ts +91 -333
  316. package/src/observability.ts +15 -1
  317. package/src/organization-mcp.ts +397 -0
  318. package/src/organization-recovery-notifications.ts +103 -0
  319. package/src/routes/analytics-consent.ts +123 -0
  320. package/src/routes/api-integrations.ts +364 -74
  321. package/src/routes/api-keys.ts +336 -10
  322. package/src/routes/artifact-catalog.ts +279 -0
  323. package/src/routes/automations.ts +768 -0
  324. package/src/routes/billing.ts +461 -46
  325. package/src/routes/browser-sessions.ts +780 -112
  326. package/src/routes/canonical-human-identities.ts +90 -14
  327. package/src/routes/capabilities.ts +107 -6
  328. package/src/routes/channels.ts +20 -3
  329. package/src/routes/claude-subscription-accounts.ts +334 -0
  330. package/src/routes/claude-subscription-oauth.ts +142 -0
  331. package/src/routes/client-errors.ts +362 -0
  332. package/src/routes/codex.ts +833 -116
  333. package/src/routes/company-brain.ts +322 -0
  334. package/src/routes/company-profile.ts +65 -1
  335. package/src/routes/computer-sessions.ts +557 -106
  336. package/src/routes/connect.ts +1938 -0
  337. package/src/routes/connections.ts +1039 -349
  338. package/src/routes/documents.ts +488 -287
  339. package/src/routes/editable-artifacts.ts +79 -9
  340. package/src/routes/enrollments.ts +135 -39
  341. package/src/routes/environments.ts +154 -58
  342. package/src/routes/external-identity-links.ts +201 -0
  343. package/src/routes/feedback.ts +113 -0
  344. package/src/routes/files.ts +267 -33
  345. package/src/routes/github-browser-pages.ts +162 -0
  346. package/src/routes/github.ts +446 -144
  347. package/src/routes/insights-response-cache.ts +83 -0
  348. package/src/routes/insights-usage.ts +345 -0
  349. package/src/routes/insights.ts +153 -19
  350. package/src/routes/install.ts +133 -38
  351. package/src/routes/integration-facets.ts +107 -33
  352. package/src/routes/interaction-resources.ts +30 -3
  353. package/src/routes/knowledge.ts +488 -0
  354. package/src/routes/machines.ts +313 -15
  355. package/src/routes/managed-auth-session-sets.ts +1218 -0
  356. package/src/routes/managed-onboarding.ts +337 -0
  357. package/src/routes/managed-sign-in-methods.ts +433 -0
  358. package/src/routes/memory-slack-publications.ts +3 -2
  359. package/src/routes/model-connection-access.ts +208 -0
  360. package/src/routes/organization-integration-policy.ts +116 -0
  361. package/src/routes/organization-integrations.ts +326 -0
  362. package/src/routes/organization-mcp-connections.ts +178 -0
  363. package/src/routes/organization-memberships.ts +1019 -27
  364. package/src/routes/organization-model-providers.ts +293 -0
  365. package/src/routes/organization-recovery.ts +325 -0
  366. package/src/routes/organization-service-accounts.ts +128 -0
  367. package/src/routes/organization-sessions.ts +350 -0
  368. package/src/routes/personal-github-git-broker.ts +785 -0
  369. package/src/routes/personal-github.ts +370 -0
  370. package/src/routes/plugins.ts +251 -22
  371. package/src/routes/pr-review-github.ts +881 -0
  372. package/src/routes/pr-review.ts +622 -0
  373. package/src/routes/preference-registry.ts +12 -93
  374. package/src/routes/rigs.ts +167 -50
  375. package/src/routes/scheduled-tasks.ts +346 -41
  376. package/src/routes/session-artifact-associations.ts +87 -0
  377. package/src/routes/session-history-imports.ts +280 -0
  378. package/src/routes/sessions.ts +2306 -264
  379. package/src/routes/skill-content.ts +297 -0
  380. package/src/routes/skill-install-authority.ts +64 -0
  381. package/src/routes/skills.ts +62 -9
  382. package/src/routes/social.ts +46 -18
  383. package/src/routes/subscription-account-pools.ts +436 -0
  384. package/src/routes/subscription-pool-access.ts +126 -0
  385. package/src/routes/supergrok.ts +219 -303
  386. package/src/routes/transcription-recordings.ts +38 -3
  387. package/src/routes/transcriptions.ts +4 -0
  388. package/src/routes/usage-allowances.ts +378 -0
  389. package/src/routes/user-resource-authorities.ts +138 -0
  390. package/src/routes/video-generation.ts +14 -10
  391. package/src/routes/workspace-artifacts.ts +275 -69
  392. package/src/routes/workspace-capture.ts +21 -0
  393. package/src/routes/workspace-integrations.ts +576 -0
  394. package/src/routes/workspace-learning.ts +159 -0
  395. package/src/routes/workspace-model-providers.ts +148 -0
  396. package/src/routes/workspace-state.ts +38 -25
  397. package/src/routes/workspaces.ts +1004 -127
  398. package/src/sandbox/auth-callout.ts +96 -19
  399. package/src/sandbox/channel-a.ts +323 -24
  400. package/src/sandbox/connection-authority.ts +3 -0
  401. package/src/sandbox/enrollment.ts +81 -6
  402. package/src/sandbox/machines.ts +218 -76
  403. package/src/sandbox/metrics-ingestion.ts +411 -62
  404. package/src/sandbox/rematerialize.ts +121 -19
  405. package/src/sandbox/session-attach-variable-sets.ts +131 -0
  406. package/src/sandbox/viewer.ts +280 -25
  407. package/src/sandbox-file-artifacts.ts +413 -0
  408. package/src/scheduled-task-deletion.ts +138 -0
  409. package/src/session-create-observability.ts +46 -0
  410. package/src/session-realtime-context.ts +6 -3
  411. package/src/site-session-origin.ts +48 -0
  412. package/src/site-uploads.ts +224 -0
  413. package/src/slack-reaction-files.ts +16 -5
  414. package/src/temporal-schedule-cleanup.ts +13 -0
  415. package/src/temporal-schedule-sync.ts +74 -0
  416. package/src/transcription/providers/codex-subscription.ts +2 -0
  417. package/src/transcription/providers/openai.ts +1 -0
  418. package/src/transcription/providers/xai-subscription.ts +49 -3
  419. package/src/transcription/segmenter.ts +8 -2
  420. package/src/transcription/service.ts +43 -6
  421. package/src/work-discovery-observability.ts +121 -0
  422. package/src/workspace-artifact-content.ts +144 -0
  423. package/src/workspace-artifact-provenance.ts +104 -0
  424. package/src/workspace-delete-observability.ts +75 -0
  425. package/src/workspace-deletion.ts +73 -0
  426. package/src/workspace-state-projection.ts +18 -148
  427. package/src/workspace-tool-gateway-observability.ts +100 -0
  428. package/src/workspace-tool-gateway.ts +870 -0
  429. package/src/workspace-webhook-dispatch.ts +190 -0
  430. package/src/xai-subscription-auth.ts +9 -2
  431. package/dist/chunk-WCXHI3FF.js +0 -49920
  432. package/dist/chunk-WCXHI3FF.js.map +0 -1
  433. package/dist/routes/packs.d.ts +0 -3
  434. package/src/routes/packs.ts +0 -729
package/src/codemode.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { siteRequestHeaders } from "@opengeni/contracts/site-session-http";
1
2
  import {
2
3
  codemodeDispatchSubject,
3
4
  decodeCodemodeDispatchAck,
@@ -13,13 +14,113 @@ import {
13
14
  type CodemodeOperation,
14
15
  } from "@opengeni/contracts";
15
16
  import type { ApiRouteDeps } from "@opengeni/core";
16
- import { hasPermission, requireSessionAuthorization } from "@opengeni/core";
17
+ import { hasPermission, isDeveloperSetupGrant, requireSessionAuthorization } from "@opengeni/core";
17
18
  import {
18
19
  getActiveSessionTurnForExecution,
19
20
  getAttemptToolCatalog,
20
21
  getCodemodeOperation,
21
22
  submitCodemodeOperation,
23
+ type SessionTurnForExecution,
22
24
  } from "@opengeni/db";
25
+ import { getSession } from "@opengeni/db";
26
+ import {
27
+ allowedFirstPartyMcpToolsForSession,
28
+ resolveFirstPartyDelegationSecret,
29
+ type Settings,
30
+ } from "@opengeni/config";
31
+ import {
32
+ DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
33
+ signDelegatedAccessToken,
34
+ readTurnExecutionPolicyV1,
35
+ siteSessionPath,
36
+ OPENGENI_API_CONTRACT_HEADER,
37
+ OPENGENI_API_CONTRACT_REVISION,
38
+ type Permission,
39
+ type Session,
40
+ } from "@opengeni/contracts";
41
+ import { permissionsRequiredByFirstPartyTools } from "./mcp/first-party-tool-permissions";
42
+
43
+ /** The REST authority a Codemode SDK proxy token may ever carry. */
44
+ export const CODEMODE_SESSION_PROXY_PERMISSION_CEILING = [
45
+ "workspace:read",
46
+ "sessions:read",
47
+ "sessions:create",
48
+ "sessions:control",
49
+ ] as const satisfies readonly Permission[];
50
+
51
+ /**
52
+ * Proxy permissions = the session's effective first-party permissions, cut
53
+ * down to what its exact model-visible tool selection could actually
54
+ * exercise (plus workspace:read for the context routes), under the fixed
55
+ * ceiling above. A session whose selection has no session_* tool therefore
56
+ * gets only workspace:read and every proxied /sessions handler refuses it,
57
+ * exactly as its MCP surface would.
58
+ */
59
+ export function codemodeSessionProxyPermissions(
60
+ settings: Pick<Settings, "defaultFirstPartyMcpTools" | "allowedFirstPartyMcpTools">,
61
+ session: Pick<Session, "firstPartyMcpTools" | "firstPartyMcpPermissions">,
62
+ ): Permission[] {
63
+ const sessionPermissions = session.firstPartyMcpPermissions ?? [
64
+ ...DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
65
+ ];
66
+ const selection = allowedFirstPartyMcpToolsForSession(settings, session.firstPartyMcpTools);
67
+ const requiredBySelection = new Set<Permission>([
68
+ "workspace:read",
69
+ ...permissionsRequiredByFirstPartyTools(selection),
70
+ ]);
71
+ return CODEMODE_SESSION_PROXY_PERMISSION_CEILING.filter(
72
+ (permission) => requiredBySelection.has(permission) && sessionPermissions.includes(permission),
73
+ );
74
+ }
75
+
76
+ /** Reuse normal REST handlers, including their resource/command authorization.
77
+ * The exact attempt is checked before issuing this internal-only credential. */
78
+ export async function codemodeSessionRequest(
79
+ deps: ApiRouteDeps,
80
+ grant: AccessGrant,
81
+ request: Request,
82
+ path: string,
83
+ resolveProxySettings?: (
84
+ session: Session,
85
+ ) => Pick<Settings, "defaultFirstPartyMcpTools" | "allowedFirstPartyMcpTools">,
86
+ ): Promise<Request> {
87
+ siteSessionPath(path, grant.workspaceId, request.method);
88
+ const { authority, turn } = await requireActiveCodemodeCatalog(deps, grant);
89
+ const session = await getSession(deps.db, authority.workspaceId, authority.sessionId);
90
+ const secret = resolveFirstPartyDelegationSecret(deps.settings);
91
+ if (!session || !secret) throw new CodemodeAuthorityError("invalid_grant");
92
+ const permissions = codemodeSessionProxyPermissions(
93
+ resolveProxySettings?.(session) ?? deps.settings,
94
+ session,
95
+ );
96
+ const turnPolicy = readTurnExecutionPolicyV1(turn.metadata);
97
+ const initialPolicy = readTurnExecutionPolicyV1(session.metadata);
98
+ const restricted =
99
+ isDeveloperSetupGrant(grant) ||
100
+ (turnPolicy.kind === "valid" &&
101
+ turnPolicy.policy.credentialRestriction === "developer_setup") ||
102
+ (initialPolicy.kind === "valid" &&
103
+ initialPolicy.policy.credentialRestriction === "developer_setup");
104
+ const token = await signDelegatedAccessToken(secret, {
105
+ ...authority,
106
+ permissions,
107
+ principalKind: "agent_attempt",
108
+ ...(restricted ? { credentialRestriction: "developer_setup" as const } : {}),
109
+ exp: Math.floor(Date.now() / 1000) + 60,
110
+ });
111
+ const target = new URL(request.url);
112
+ const rewritten = siteSessionPath(path, authority.workspaceId, request.method);
113
+ const url = new URL(rewritten, target.origin);
114
+ const headers = siteRequestHeaders(request.headers);
115
+ headers.set("authorization", `Bearer ${token}`);
116
+ headers.set(OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION);
117
+ return new Request(url, {
118
+ method: request.method,
119
+ headers,
120
+ signal: request.signal,
121
+ ...(request.body ? { body: await request.text() } : {}),
122
+ });
123
+ }
23
124
 
24
125
  export type CodemodeGrantAuthority = {
25
126
  accountId: string;
@@ -31,12 +132,42 @@ export type CodemodeGrantAuthority = {
31
132
  subjectId: string;
32
133
  };
33
134
 
135
+ export type CodemodeAuthorityFailureReason =
136
+ | "invalid_grant"
137
+ | "inactive_attempt"
138
+ | "catalog_mismatch";
139
+
140
+ const CODEMODE_AUTHORITY_FAILURE_MESSAGES: Record<CodemodeAuthorityFailureReason, string> = {
141
+ invalid_grant: "Codemode bearer does not carry valid execution-attempt authority",
142
+ inactive_attempt: "Codemode execution attempt is no longer active",
143
+ catalog_mismatch: "Codemode tool catalog does not match the active execution attempt",
144
+ };
145
+
34
146
  export class CodemodeAuthorityError extends Error {
35
- readonly code = "codemode_authority_invalid";
147
+ readonly code: `codemode_${CodemodeAuthorityFailureReason}`;
36
148
 
37
- constructor() {
38
- super("Codemode bearer is not bound to an active execution attempt");
149
+ constructor(readonly reason: CodemodeAuthorityFailureReason) {
150
+ super(CODEMODE_AUTHORITY_FAILURE_MESSAGES[reason]);
39
151
  this.name = "CodemodeAuthorityError";
152
+ this.code = `codemode_${reason}`;
153
+ }
154
+ }
155
+
156
+ export class CodemodeCatalogNotReadyError extends Error {
157
+ readonly code = "codemode_catalog_not_ready";
158
+
159
+ constructor() {
160
+ super("Codemode tool catalog is not ready for the active execution attempt");
161
+ this.name = "CodemodeCatalogNotReadyError";
162
+ }
163
+ }
164
+
165
+ export class CodemodeCatalogStaleError extends Error {
166
+ readonly code = "codemode_catalog_stale";
167
+
168
+ constructor() {
169
+ super("Codemode tool catalog is stale for the active execution attempt");
170
+ this.name = "CodemodeCatalogStaleError";
40
171
  }
41
172
  }
42
173
 
@@ -71,11 +202,33 @@ export function isCodemodeGrant(grant: AccessGrant): boolean {
71
202
  );
72
203
  }
73
204
 
205
+ export function requireMatchingCodemodeCatalog(
206
+ authority: CodemodeGrantAuthority,
207
+ catalog: AttemptToolCatalog | null,
208
+ ): AttemptToolCatalog {
209
+ if (!catalog) throw new CodemodeCatalogNotReadyError();
210
+ if (
211
+ catalog.accountId !== authority.accountId ||
212
+ catalog.workspaceId !== authority.workspaceId ||
213
+ catalog.sessionId !== authority.sessionId ||
214
+ catalog.turnId !== authority.turnId ||
215
+ catalog.attemptId !== authority.attemptId ||
216
+ catalog.executionGeneration !== authority.executionGeneration
217
+ ) {
218
+ throw new CodemodeAuthorityError("catalog_mismatch");
219
+ }
220
+ return catalog;
221
+ }
222
+
74
223
  export async function requireActiveCodemodeCatalog(
75
224
  deps: ApiRouteDeps,
76
225
  grant: AccessGrant,
77
- ): Promise<{ authority: CodemodeGrantAuthority; catalog: AttemptToolCatalog }> {
78
- if (!isCodemodeGrant(grant)) throw new CodemodeAuthorityError();
226
+ ): Promise<{
227
+ authority: CodemodeGrantAuthority;
228
+ catalog: AttemptToolCatalog;
229
+ turn: SessionTurnForExecution;
230
+ }> {
231
+ if (!isCodemodeGrant(grant)) throw new CodemodeAuthorityError("invalid_grant");
79
232
  const authority = codemodeAuthorityForGrant(grant)!;
80
233
  await requireSessionAuthorization(deps, grant, {
81
234
  sessionId: authority.sessionId,
@@ -94,25 +247,17 @@ export async function requireActiveCodemodeCatalog(
94
247
  active.activeAttemptId !== authority.attemptId ||
95
248
  active.executionGeneration !== authority.executionGeneration
96
249
  ) {
97
- throw new CodemodeAuthorityError();
250
+ throw new CodemodeAuthorityError("inactive_attempt");
98
251
  }
99
- const catalog = await getAttemptToolCatalog(deps.db, {
100
- accountId: authority.accountId,
101
- workspaceId: authority.workspaceId,
102
- attemptId: authority.attemptId,
103
- });
104
- if (
105
- !catalog ||
106
- catalog.accountId !== authority.accountId ||
107
- catalog.workspaceId !== authority.workspaceId ||
108
- catalog.sessionId !== authority.sessionId ||
109
- catalog.turnId !== authority.turnId ||
110
- catalog.attemptId !== authority.attemptId ||
111
- catalog.executionGeneration !== authority.executionGeneration
112
- ) {
113
- throw new CodemodeAuthorityError();
114
- }
115
- return { authority, catalog };
252
+ const catalog = requireMatchingCodemodeCatalog(
253
+ authority,
254
+ await getAttemptToolCatalog(deps.db, {
255
+ accountId: authority.accountId,
256
+ workspaceId: authority.workspaceId,
257
+ attemptId: authority.attemptId,
258
+ }),
259
+ );
260
+ return { authority, catalog, turn: active };
116
261
  }
117
262
 
118
263
  export async function submitAndDispatchCodemodeCall(
@@ -122,13 +267,13 @@ export async function submitAndDispatchCodemodeCall(
122
267
  ): Promise<CodemodeCallSubmissionValue> {
123
268
  const request = CodemodeCallRequest.parse(rawRequest);
124
269
  const { authority, catalog } = await requireActiveCodemodeCatalog(deps, grant);
270
+ if (request.catalogDigest !== catalog.digest) throw new CodemodeCatalogStaleError();
125
271
  const submitted = await submitCodemodeOperation(deps.db, {
126
272
  ...authority,
127
273
  call: {
128
274
  ...request,
129
275
  caller: { kind: "codemode", subjectId: authority.subjectId },
130
276
  },
131
- callLimit: deps.settings.codemodeMaxCallsPerTurn,
132
277
  });
133
278
  let operation = submitted.operation;
134
279
  let dispatch: CodemodeCallSubmissionValue["dispatch"] = terminal(operation)
@@ -136,7 +281,7 @@ export async function submitAndDispatchCodemodeCall(
136
281
  : operation.state === "running"
137
282
  ? "already_running"
138
283
  : "unavailable";
139
- if (operation.state === "queued") {
284
+ if (codemodeOperationNeedsDispatch(operation)) {
140
285
  try {
141
286
  const reply = await deps.bus.request(
142
287
  codemodeDispatchSubject(authority.workspaceId, authority.attemptId),
@@ -151,13 +296,14 @@ export async function submitAndDispatchCodemodeCall(
151
296
  } catch {
152
297
  dispatch = "unavailable";
153
298
  }
154
- operation =
155
- (await getCodemodeOperation(deps.db, {
299
+ operation = await refreshAdmittedCodemodeOperation(operation, () =>
300
+ getCodemodeOperation(deps.db, {
156
301
  accountId: authority.accountId,
157
302
  workspaceId: authority.workspaceId,
158
303
  attemptId: authority.attemptId,
159
304
  operationId: operation.operationId,
160
- })) ?? operation;
305
+ }),
306
+ );
161
307
  if (terminal(operation)) dispatch = "terminal";
162
308
  else if (operation.state === "running" && dispatch === "unavailable") {
163
309
  dispatch = "already_running";
@@ -166,12 +312,16 @@ export async function submitAndDispatchCodemodeCall(
166
312
  return CodemodeCallSubmission.parse({ operation, dispatch });
167
313
  }
168
314
 
315
+ export function codemodeOperationNeedsDispatch(operation: CodemodeOperation): boolean {
316
+ return operation.state === "queued" || operation.state === "running";
317
+ }
318
+
169
319
  export async function readCodemodeOperation(
170
320
  deps: ApiRouteDeps,
171
321
  grant: AccessGrant,
172
322
  operationId: string,
173
323
  ): Promise<CodemodeOperation | null> {
174
- if (!isCodemodeGrant(grant)) throw new CodemodeAuthorityError();
324
+ if (!isCodemodeGrant(grant)) throw new CodemodeAuthorityError("invalid_grant");
175
325
  const authority = codemodeAuthorityForGrant(grant)!;
176
326
  return await getCodemodeOperation(deps.db, {
177
327
  accountId: authority.accountId,
@@ -184,3 +334,17 @@ export async function readCodemodeOperation(
184
334
  function terminal(operation: CodemodeOperation): boolean {
185
335
  return ["completed", "failed", "outcome_unknown", "cancelled"].includes(operation.state);
186
336
  }
337
+
338
+ export async function refreshAdmittedCodemodeOperation(
339
+ admitted: CodemodeOperation,
340
+ read: () => Promise<CodemodeOperation | null>,
341
+ ): Promise<CodemodeOperation> {
342
+ try {
343
+ return (await read()) ?? admitted;
344
+ } catch {
345
+ // Admission is already durable. Returning the known row lets the client
346
+ // continue with the same operation id instead of turning a refresh outage
347
+ // into an unmarked post-commit failure.
348
+ return admitted;
349
+ }
350
+ }
@@ -5,6 +5,7 @@ import {
5
5
  CodexRealtimeError,
6
6
  CodexReloginRequired,
7
7
  createCodexRealtimeCall,
8
+ fetchCodexRealtimeProviderConfig,
8
9
  selectCodexCredentialId,
9
10
  type CodexAuthHeaders,
10
11
  type CodexFetch,
@@ -295,8 +296,13 @@ export function buildSessionCodexRealtimeBroker(
295
296
  },
296
297
  tokenResolver: (credentialId) =>
297
298
  buildCodexTokenResolver(db, settings, workspaceId, credentialId),
298
- createCall: async (auth, callInput, options) =>
299
- await createCodexRealtimeCall(auth, callInput, fetchImpl, options),
299
+ createCall: async (auth, callInput, options) => {
300
+ const providerConfig = await fetchCodexRealtimeProviderConfig(auth, fetchImpl, options);
301
+ return await createCodexRealtimeCall(auth, callInput, fetchImpl, {
302
+ ...options,
303
+ providerConfig,
304
+ });
305
+ },
300
306
  },
301
307
  { ...input, sessionId },
302
308
  );
@@ -0,0 +1,340 @@
1
+ import {
2
+ COMPANY_BRAIN_GUIDANCE_MAX_CONTENT_BYTES,
3
+ COMPANY_BRAIN_GUIDANCE_MAX_ENTRIES,
4
+ CompanyBrainOkfPackage,
5
+ type CompanyBrainGuidanceEntry,
6
+ type CompanyBrainGuidanceTruncationReason,
7
+ type CompanyBrainOkfPackage as CompanyBrainOkfPackageType,
8
+ type CompanyProfileListResponse,
9
+ type WorkspaceInstructionPolicyListResponse,
10
+ type WorkspaceInstructionPolicyRevision,
11
+ type WorkspaceStateKnowledge,
12
+ } from "@opengeni/contracts";
13
+ import type { CompanyBrainPreferenceGuidancePage } from "@opengeni/db";
14
+
15
+ const OKF_MARKER = "<!-- opengeni-company-brain-okf-v1 -->";
16
+
17
+ function canonicalize(value: unknown): unknown {
18
+ if (Array.isArray(value)) return value.map(canonicalize);
19
+ if (value === null || typeof value !== "object") return value;
20
+ return Object.fromEntries(
21
+ Object.entries(value as Record<string, unknown>)
22
+ .sort(([left], [right]) => left.localeCompare(right))
23
+ .map(([key, nested]) => [key, canonicalize(nested)]),
24
+ );
25
+ }
26
+
27
+ function canonicalJson(value: unknown): string {
28
+ return `${JSON.stringify(canonicalize(value), null, 2)}\n`;
29
+ }
30
+
31
+ function companyProfileEntries(profile: CompanyProfileListResponse): {
32
+ entries: CompanyBrainGuidanceEntry[];
33
+ truncated: boolean;
34
+ } {
35
+ const activeRevisionId = profile.current?.revisionId ?? null;
36
+ const byId = new Map(profile.revisions.map((revision) => [revision.id, revision] as const));
37
+ if (profile.activeRevision) byId.set(profile.activeRevision.id, profile.activeRevision);
38
+ return {
39
+ entries: [...byId.values()].map((revision) => {
40
+ const active = revision.id === activeRevisionId;
41
+ return {
42
+ id: "company-profile",
43
+ revisionId: revision.id,
44
+ path: "company/profile",
45
+ scope: "organization",
46
+ classification: "company_profile",
47
+ title: "Company profile",
48
+ description: "Company identity, mission, products, customers, goals, and constraints.",
49
+ // Company-profile hashes cover this exact canonical field order.
50
+ content: JSON.stringify(revision.profile),
51
+ contentHash: revision.contentHash,
52
+ revision: revision.revision,
53
+ active,
54
+ lifecycle: active ? "active" : revision.intent === "proposal" ? "proposal" : "historical",
55
+ provenance: {
56
+ source: revision.provenance.source,
57
+ sourceId: revision.provenance.sourceId,
58
+ trust: revision.intent === "proposal" ? "untrusted_proposal" : "organization_managed",
59
+ },
60
+ relationships:
61
+ revision.supersedesRevisionId && byId.has(revision.supersedesRevisionId)
62
+ ? [{ type: "supersedes" as const, targetId: revision.supersedesRevisionId }]
63
+ : [],
64
+ createdAt: revision.createdAt,
65
+ } satisfies CompanyBrainGuidanceEntry;
66
+ }),
67
+ truncated: profile.nextAfterRevision !== null,
68
+ };
69
+ }
70
+
71
+ function instructionPolicyEntries(
72
+ policies: WorkspaceInstructionPolicyListResponse,
73
+ activeRevisions: WorkspaceInstructionPolicyRevision[],
74
+ activatedRevisionIds: string[],
75
+ ): { entries: CompanyBrainGuidanceEntry[]; truncated: boolean } {
76
+ const byId = new Map(policies.revisions.map((revision) => [revision.id, revision] as const));
77
+ for (const revision of activeRevisions) byId.set(revision.id, revision);
78
+ const activeIds = new Set(policies.activeHeads.map((head) => head.revisionId));
79
+ const activatedIds = new Set(activatedRevisionIds);
80
+ return {
81
+ entries: [...byId.values()].map((revision) => {
82
+ const roleSegment = revision.roleKey ?? "all";
83
+ const active = activeIds.has(revision.id);
84
+ const lifecycle = active
85
+ ? "active"
86
+ : activatedIds.has(revision.id)
87
+ ? "historical"
88
+ : revision.provenance.source === "onboarding" ||
89
+ revision.provenance.source === "knowledge_proposal"
90
+ ? "proposal"
91
+ : "inactive";
92
+ return {
93
+ id: `instruction-policy:${revision.kind}:${revision.scope}:${roleSegment}`,
94
+ revisionId: revision.id,
95
+ path: `ways-of-working/rules/${revision.kind}/${revision.scope}/${roleSegment}`,
96
+ scope: "workspace",
97
+ classification: "mandatory_rule",
98
+ title:
99
+ revision.kind === "charter"
100
+ ? "Workspace charter"
101
+ : revision.scope === "role"
102
+ ? `Role policy: ${roleSegment}`
103
+ : "Workspace policy",
104
+ description: active ? "Mandatory context included for applicable agents." : null,
105
+ content: revision.content,
106
+ contentHash: revision.contentHash,
107
+ revision: revision.revision,
108
+ active,
109
+ lifecycle,
110
+ provenance: {
111
+ source: revision.provenance.source,
112
+ sourceId: revision.provenance.sourceId,
113
+ trust:
114
+ revision.provenance.source === "human"
115
+ ? "workspace_managed"
116
+ : revision.provenance.source === "legacy_import"
117
+ ? "migrated"
118
+ : "untrusted_proposal",
119
+ },
120
+ relationships:
121
+ revision.supersedesRevisionId && byId.has(revision.supersedesRevisionId)
122
+ ? [{ type: "supersedes" as const, targetId: revision.supersedesRevisionId }]
123
+ : [],
124
+ createdAt: revision.createdAt,
125
+ } satisfies CompanyBrainGuidanceEntry;
126
+ }),
127
+ truncated: policies.nextAfterRevision !== null,
128
+ };
129
+ }
130
+
131
+ function preferenceLifecycle(
132
+ row: CompanyBrainPreferenceGuidancePage["rows"][number],
133
+ generatedAt: string,
134
+ ): CompanyBrainGuidanceEntry["lifecycle"] {
135
+ if (row.active && row.expiresAt && row.expiresAt.getTime() <= Date.parse(generatedAt)) {
136
+ return "expired";
137
+ }
138
+ if (row.active && row.status === "active") return "active";
139
+ if (row.status === "proposed") return "proposal";
140
+ if (row.status === "inactive") return "inactive";
141
+ if (row.status === "rejected") return "rejected";
142
+ if (row.status === "superseded") return "superseded";
143
+ return "historical";
144
+ }
145
+
146
+ function preferenceEntries(
147
+ page: CompanyBrainPreferenceGuidancePage,
148
+ generatedAt: string,
149
+ ): CompanyBrainGuidanceEntry[] {
150
+ const visibleRevisionIds = new Set(page.rows.map((row) => row.revisionId));
151
+ const visiblePreferenceIds = new Set(page.rows.map((row) => row.preferenceId));
152
+ return page.rows.map((row) => {
153
+ const scope =
154
+ row.scope === "organization"
155
+ ? "organization"
156
+ : row.scope === "user"
157
+ ? "personal"
158
+ : "workspace";
159
+ const lifecycle = preferenceLifecycle(row, generatedAt);
160
+ const relationships: CompanyBrainGuidanceEntry["relationships"] = [];
161
+ if (row.correctsRevisionId && visibleRevisionIds.has(row.correctsRevisionId)) {
162
+ relationships.push({ type: "corrects", targetId: row.correctsRevisionId });
163
+ }
164
+ if (row.supersededByPreferenceId && visiblePreferenceIds.has(row.supersededByPreferenceId)) {
165
+ relationships.push({
166
+ type: "superseded_by",
167
+ targetId: `preference:${row.supersededByPreferenceId}`,
168
+ });
169
+ }
170
+ return {
171
+ id: `preference:${row.preferenceId}`,
172
+ revisionId: row.revisionId,
173
+ path: `ways-of-working/guides/${scope}/${row.stableKey}`,
174
+ scope,
175
+ classification: "guide",
176
+ title: row.title,
177
+ description: row.description,
178
+ content: row.content,
179
+ contentHash: row.contentHash,
180
+ revision: row.revision,
181
+ active: lifecycle === "active",
182
+ lifecycle,
183
+ provenance: {
184
+ source: row.provenanceSource,
185
+ sourceId: row.provenanceSourceId,
186
+ trust: row.trust,
187
+ },
188
+ relationships,
189
+ createdAt: row.createdAt.toISOString(),
190
+ } satisfies CompanyBrainGuidanceEntry;
191
+ });
192
+ }
193
+
194
+ function guidanceEntryOrder(
195
+ left: CompanyBrainGuidanceEntry,
196
+ right: CompanyBrainGuidanceEntry,
197
+ ): number {
198
+ return (
199
+ left.classification.localeCompare(right.classification) ||
200
+ left.path.localeCompare(right.path) ||
201
+ right.revision - left.revision ||
202
+ left.revisionId.localeCompare(right.revisionId)
203
+ );
204
+ }
205
+
206
+ function relationshipTargetKeys(entry: CompanyBrainGuidanceEntry): string[] {
207
+ return [entry.id, entry.revisionId];
208
+ }
209
+
210
+ export function boundCompanyBrainGuidanceEntries(entries: CompanyBrainGuidanceEntry[]): {
211
+ entries: CompanyBrainGuidanceEntry[];
212
+ itemCountTruncated: boolean;
213
+ contentBytesTruncated: boolean;
214
+ } {
215
+ const prioritized = [...entries].sort(
216
+ (left, right) => Number(right.active) - Number(left.active) || guidanceEntryOrder(left, right),
217
+ );
218
+ const selected: CompanyBrainGuidanceEntry[] = [];
219
+ let contentBytes = 0;
220
+ let itemCountTruncated = false;
221
+ let contentBytesTruncated = false;
222
+ for (const entry of prioritized) {
223
+ if (selected.length >= COMPANY_BRAIN_GUIDANCE_MAX_ENTRIES) {
224
+ itemCountTruncated = true;
225
+ continue;
226
+ }
227
+ const entryBytes = new TextEncoder().encode(entry.content).byteLength;
228
+ if (contentBytes + entryBytes > COMPANY_BRAIN_GUIDANCE_MAX_CONTENT_BYTES) {
229
+ contentBytesTruncated = true;
230
+ continue;
231
+ }
232
+ selected.push(entry);
233
+ contentBytes += entryBytes;
234
+ }
235
+ const visibleTargets = new Set(selected.flatMap(relationshipTargetKeys));
236
+ return {
237
+ entries: selected
238
+ .map((entry) => ({
239
+ ...entry,
240
+ relationships: entry.relationships.filter((relationship) =>
241
+ visibleTargets.has(relationship.targetId),
242
+ ),
243
+ }))
244
+ .sort(guidanceEntryOrder),
245
+ itemCountTruncated,
246
+ contentBytesTruncated,
247
+ };
248
+ }
249
+
250
+ export function createCompanyBrainOkfPackage(input: {
251
+ workspaceId: string;
252
+ generatedAt: string;
253
+ companyProfile: CompanyProfileListResponse;
254
+ instructionPolicies: WorkspaceInstructionPolicyListResponse;
255
+ activeInstructionPolicyRevisions: WorkspaceInstructionPolicyRevision[];
256
+ activatedInstructionPolicyRevisionIds: string[];
257
+ preferences: CompanyBrainPreferenceGuidancePage;
258
+ knowledge: WorkspaceStateKnowledge;
259
+ }): CompanyBrainOkfPackageType {
260
+ const company = companyProfileEntries(input.companyProfile);
261
+ const policies = instructionPolicyEntries(
262
+ input.instructionPolicies,
263
+ input.activeInstructionPolicyRevisions,
264
+ input.activatedInstructionPolicyRevisionIds,
265
+ );
266
+ const preferences = preferenceEntries(input.preferences, input.generatedAt);
267
+ const truncationReasons: CompanyBrainGuidanceTruncationReason[] = [];
268
+ if (company.truncated) truncationReasons.push("company_profile_history");
269
+ if (policies.truncated) truncationReasons.push("instruction_policy_history");
270
+ if (input.preferences.preferenceCountTruncated) truncationReasons.push("preference_count");
271
+ if (input.preferences.revisionCountTruncated) truncationReasons.push("preference_history");
272
+ if (input.preferences.contentBytesTruncated) truncationReasons.push("aggregate_content_bytes");
273
+
274
+ const bounded = boundCompanyBrainGuidanceEntries([
275
+ ...company.entries,
276
+ ...policies.entries,
277
+ ...preferences,
278
+ ]);
279
+ if (bounded.itemCountTruncated) truncationReasons.push("aggregate_item_count");
280
+ if (bounded.contentBytesTruncated && !truncationReasons.includes("aggregate_content_bytes")) {
281
+ truncationReasons.push("aggregate_content_bytes");
282
+ }
283
+ const knowledgeAvailable = input.knowledge.availability === "available";
284
+ return CompanyBrainOkfPackage.parse({
285
+ kind: "opengeni.company_brain.okf",
286
+ schemaVersion: 1,
287
+ workspaceId: input.workspaceId,
288
+ generatedAt: input.generatedAt,
289
+ permissions: {
290
+ guidance: "available",
291
+ knowledge: knowledgeAvailable ? "available" : "unavailable",
292
+ },
293
+ guidance: {
294
+ entries: bounded.entries,
295
+ truncated: truncationReasons.length > 0,
296
+ truncationReasons,
297
+ },
298
+ knowledge: input.knowledge,
299
+ omissions: [
300
+ ...(knowledgeAvailable ? [] : (["inaccessible_knowledge"] as const)),
301
+ "document_bodies_use_documents_export",
302
+ "memory_bodies_and_provenance",
303
+ "secret_values_and_credentials",
304
+ "session_messages_and_task_notes",
305
+ "policy_and_preference_actor_identifiers",
306
+ ],
307
+ });
308
+ }
309
+
310
+ /**
311
+ * JSON is a strict subset of YAML 1.2. Keeping the payload in one fenced YAML
312
+ * block gives humans a readable Markdown package while making arbitrary
313
+ * guidance Markdown structurally inert and exactly round-trippable.
314
+ */
315
+ export function serializeCompanyBrainOkf(value: CompanyBrainOkfPackageType): string {
316
+ const parsed = CompanyBrainOkfPackage.parse(value);
317
+ return [
318
+ OKF_MARKER,
319
+ "# Opengeni Company Brain",
320
+ "",
321
+ "This permission-filtered package is portable evidence. Postgres remains canonical.",
322
+ "",
323
+ "```yaml",
324
+ canonicalJson(parsed).trimEnd(),
325
+ "```",
326
+ "",
327
+ ].join("\n");
328
+ }
329
+
330
+ export function parseCompanyBrainOkf(markdown: string): CompanyBrainOkfPackageType {
331
+ if (!markdown.startsWith(`${OKF_MARKER}\n`)) throw new Error("Invalid Company Brain OKF marker");
332
+ const opening = markdown.indexOf("```yaml\n");
333
+ if (opening < 0) throw new Error("Company Brain OKF payload is missing");
334
+ const payloadStart = opening + "```yaml\n".length;
335
+ const closing = markdown.indexOf("\n```", payloadStart);
336
+ if (closing < 0) throw new Error("Company Brain OKF payload is incomplete");
337
+ const trailing = markdown.slice(closing + "\n```".length).trim();
338
+ if (trailing.length > 0) throw new Error("Company Brain OKF has unexpected trailing content");
339
+ return CompanyBrainOkfPackage.parse(JSON.parse(markdown.slice(payloadStart, closing)));
340
+ }