@agent-native/core 0.113.0 → 0.114.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 (1508) hide show
  1. package/agent-native.eject.json +164 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +11 -0
  4. package/corpus/core/README.md +61 -174
  5. package/corpus/core/agent-native.eject.json +164 -0
  6. package/corpus/core/docs/content/agent-native-toolkit.mdx +38 -0
  7. package/corpus/core/docs/content/package-lifecycle.mdx +54 -4
  8. package/corpus/core/package.json +15 -2
  9. package/corpus/core/src/cli/eject.ts +1594 -0
  10. package/corpus/core/src/cli/index.ts +16 -0
  11. package/corpus/core/src/client/index.ts +4 -0
  12. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +8 -2
  13. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +7 -2
  14. package/corpus/core/src/client/resources/ResourcesPanel.tsx +17 -3
  15. package/corpus/core/src/client/resources/index.ts +19 -0
  16. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +9 -1
  17. package/corpus/core/src/client/resources/runtime.ts +1 -0
  18. package/corpus/core/src/client/setup-connections/catalog.ts +6 -0
  19. package/corpus/core/src/client/setup-connections/index.ts +1 -0
  20. package/corpus/core/src/client/setup-connections/runtime.ts +1 -0
  21. package/corpus/core/src/connections/catalog.ts +41 -24
  22. package/corpus/core/src/connections/index.ts +1 -0
  23. package/corpus/core/src/connections/runtime.ts +1 -0
  24. package/corpus/core/src/eject/provider-api-definitions.ts +193 -0
  25. package/corpus/core/src/eject/remote-mcp-presets.ts +137 -0
  26. package/corpus/core/src/eject/setup-readiness-ui.tsx +29 -0
  27. package/corpus/core/src/eject/workspace-connections.ts +92 -0
  28. package/corpus/core/src/index.ts +1 -0
  29. package/corpus/core/src/integrations/adapter-overrides.ts +12 -0
  30. package/corpus/core/src/integrations/eject/messaging-adapters.ts +85 -0
  31. package/corpus/core/src/integrations/index.ts +5 -1
  32. package/corpus/core/src/integrations/plugin.ts +34 -12
  33. package/corpus/core/src/integrations/runtime.ts +1 -0
  34. package/corpus/core/src/integrations/types.ts +3 -1
  35. package/corpus/core/src/package-lifecycle/eject-manifest.ts +345 -0
  36. package/corpus/core/src/package-lifecycle/index.ts +1 -0
  37. package/corpus/core/src/provider-api/index.ts +46 -12
  38. package/corpus/core/src/provider-api/runtime.ts +1 -0
  39. package/corpus/core/src/setup-connections/index.ts +1 -0
  40. package/corpus/core/src/shared/merge-by-id.ts +14 -0
  41. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
  42. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  43. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
  44. package/corpus/core/src/templates/default/AGENTS.md +6 -5
  45. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
  46. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  47. package/corpus/core/src/templates/headless/AGENTS.md +5 -4
  48. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
  49. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
  50. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  51. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
  52. package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -4
  53. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -4
  54. package/corpus/core/src/vite/client.ts +25 -2
  55. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  56. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +9 -6
  57. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  58. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +9 -6
  59. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  60. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +9 -6
  61. package/corpus/templates/brain/actions/remediate-legacy-capture-audiences.ts +167 -0
  62. package/corpus/templates/brain/app/lib/brain-chat-readiness.ts +6 -0
  63. package/corpus/templates/brain/app/routes/_index.tsx +8 -0
  64. package/corpus/templates/brain/app/routes.ts +1 -0
  65. package/corpus/templates/brain/changelog/2026-07-19-ask-starts-immediately-when-builder-s-managed-ai-connection-.md +6 -0
  66. package/corpus/templates/brain/changelog/2026-07-19-slack-and-granola-backfills-now-process-captures-concurrentl.md +6 -0
  67. package/corpus/templates/brain/changelog/2026-07-19-source-review-settings-now-control-knowledge-approval.md +6 -0
  68. package/corpus/templates/brain/changelog/2026-07-19-the-manage-agent-page-now-opens-correctly-from-brain-navigat.md +6 -0
  69. package/corpus/templates/brain/server/db/schema.ts +3 -0
  70. package/corpus/templates/brain/server/lib/brain.ts +41 -2
  71. package/corpus/templates/brain/server/lib/connectors.ts +379 -113
  72. package/corpus/templates/brain/server/lib/meeting-audience.ts +38 -0
  73. package/corpus/templates/brain/server/plugins/db.ts +10 -0
  74. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +6 -4
  75. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  76. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +9 -6
  77. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
  78. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  79. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
  80. package/corpus/templates/chat/AGENTS.md +3 -2
  81. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  82. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +9 -6
  83. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  84. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +9 -6
  85. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  86. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +9 -6
  87. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  88. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +9 -6
  89. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  90. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +9 -6
  91. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  92. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  93. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +9 -6
  94. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  95. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +9 -6
  96. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  97. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +9 -6
  98. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +15 -13
  99. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  100. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +9 -6
  101. package/corpus/toolkit/CHANGELOG.md +6 -0
  102. package/corpus/toolkit/agent-native.eject.json +411 -0
  103. package/corpus/toolkit/package.json +5 -2
  104. package/dist/cli/eject.d.ts +21 -0
  105. package/dist/cli/eject.d.ts.map +1 -0
  106. package/dist/cli/eject.js +1145 -0
  107. package/dist/cli/eject.js.map +1 -0
  108. package/dist/cli/index.js +15 -0
  109. package/dist/cli/index.js.map +1 -1
  110. package/dist/client/index.d.ts +1 -1
  111. package/dist/client/index.d.ts.map +1 -1
  112. package/dist/client/index.js +1 -1
  113. package/dist/client/index.js.map +1 -1
  114. package/dist/client/resources/McpConnectionSuggestion.d.ts +4 -3
  115. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  116. package/dist/client/resources/McpConnectionSuggestion.js +3 -3
  117. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  118. package/dist/client/resources/McpIntegrationDialog.d.ts +4 -3
  119. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  120. package/dist/client/resources/McpIntegrationDialog.js +2 -2
  121. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  122. package/dist/client/resources/ResourcesPanel.d.ts +4 -1
  123. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  124. package/dist/client/resources/ResourcesPanel.js +9 -7
  125. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  126. package/dist/client/resources/index.d.ts +3 -0
  127. package/dist/client/resources/index.d.ts.map +1 -1
  128. package/dist/client/resources/index.js +3 -0
  129. package/dist/client/resources/index.js.map +1 -1
  130. package/dist/client/resources/mcp-integration-catalog.d.ts +2 -1
  131. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  132. package/dist/client/resources/mcp-integration-catalog.js +6 -2
  133. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  134. package/dist/client/resources/runtime.d.ts +2 -0
  135. package/dist/client/resources/runtime.d.ts.map +1 -0
  136. package/dist/client/resources/runtime.js +2 -0
  137. package/dist/client/resources/runtime.js.map +1 -0
  138. package/dist/client/setup-connections/catalog.d.ts +2 -0
  139. package/dist/client/setup-connections/catalog.d.ts.map +1 -0
  140. package/dist/client/setup-connections/catalog.js +7 -0
  141. package/dist/client/setup-connections/catalog.js.map +1 -0
  142. package/dist/client/setup-connections/index.d.ts +1 -0
  143. package/dist/client/setup-connections/index.d.ts.map +1 -1
  144. package/dist/client/setup-connections/index.js +1 -0
  145. package/dist/client/setup-connections/index.js.map +1 -1
  146. package/dist/client/setup-connections/runtime.d.ts +2 -0
  147. package/dist/client/setup-connections/runtime.d.ts.map +1 -0
  148. package/dist/client/setup-connections/runtime.js +2 -0
  149. package/dist/client/setup-connections/runtime.js.map +1 -0
  150. package/dist/collab/awareness.d.ts +2 -2
  151. package/dist/collab/awareness.d.ts.map +1 -1
  152. package/dist/collab/routes.d.ts +1 -1
  153. package/dist/connections/catalog.d.ts +5 -3
  154. package/dist/connections/catalog.d.ts.map +1 -1
  155. package/dist/connections/catalog.js +16 -8
  156. package/dist/connections/catalog.js.map +1 -1
  157. package/dist/connections/index.d.ts +1 -1
  158. package/dist/connections/index.d.ts.map +1 -1
  159. package/dist/connections/index.js +1 -1
  160. package/dist/connections/index.js.map +1 -1
  161. package/dist/connections/runtime.d.ts +2 -0
  162. package/dist/connections/runtime.d.ts.map +1 -0
  163. package/dist/connections/runtime.js +2 -0
  164. package/dist/connections/runtime.js.map +1 -0
  165. package/dist/eject/provider-api-definitions.d.ts +34 -0
  166. package/dist/eject/provider-api-definitions.d.ts.map +1 -0
  167. package/dist/eject/provider-api-definitions.js +88 -0
  168. package/dist/eject/provider-api-definitions.js.map +1 -0
  169. package/dist/eject/remote-mcp-presets.d.ts +17 -0
  170. package/dist/eject/remote-mcp-presets.d.ts.map +1 -0
  171. package/dist/eject/remote-mcp-presets.js +81 -0
  172. package/dist/eject/remote-mcp-presets.js.map +1 -0
  173. package/dist/eject/setup-readiness-ui.d.ts +7 -0
  174. package/dist/eject/setup-readiness-ui.d.ts.map +1 -0
  175. package/dist/eject/setup-readiness-ui.js +13 -0
  176. package/dist/eject/setup-readiness-ui.js.map +1 -0
  177. package/dist/eject/workspace-connections.d.ts +11 -0
  178. package/dist/eject/workspace-connections.d.ts.map +1 -0
  179. package/dist/eject/workspace-connections.js +47 -0
  180. package/dist/eject/workspace-connections.js.map +1 -0
  181. package/dist/index.d.ts +1 -1
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js +1 -1
  184. package/dist/index.js.map +1 -1
  185. package/dist/integrations/adapter-overrides.d.ts +3 -0
  186. package/dist/integrations/adapter-overrides.d.ts.map +1 -0
  187. package/dist/integrations/adapter-overrides.js +7 -0
  188. package/dist/integrations/adapter-overrides.js.map +1 -0
  189. package/dist/integrations/eject/messaging-adapters.d.ts +12 -0
  190. package/dist/integrations/eject/messaging-adapters.d.ts.map +1 -0
  191. package/dist/integrations/eject/messaging-adapters.js +49 -0
  192. package/dist/integrations/eject/messaging-adapters.js.map +1 -0
  193. package/dist/integrations/index.d.ts +3 -2
  194. package/dist/integrations/index.d.ts.map +1 -1
  195. package/dist/integrations/index.js +2 -1
  196. package/dist/integrations/index.js.map +1 -1
  197. package/dist/integrations/plugin.d.ts +32 -1
  198. package/dist/integrations/plugin.d.ts.map +1 -1
  199. package/dist/integrations/plugin.js +19 -12
  200. package/dist/integrations/plugin.js.map +1 -1
  201. package/dist/integrations/runtime.d.ts +2 -0
  202. package/dist/integrations/runtime.d.ts.map +1 -0
  203. package/dist/integrations/runtime.js +2 -0
  204. package/dist/integrations/runtime.js.map +1 -0
  205. package/dist/integrations/types.d.ts +3 -1
  206. package/dist/integrations/types.d.ts.map +1 -1
  207. package/dist/integrations/types.js.map +1 -1
  208. package/dist/notifications/routes.d.ts +3 -3
  209. package/dist/package-lifecycle/eject-manifest.d.ts +43 -0
  210. package/dist/package-lifecycle/eject-manifest.d.ts.map +1 -0
  211. package/dist/package-lifecycle/eject-manifest.js +219 -0
  212. package/dist/package-lifecycle/eject-manifest.js.map +1 -0
  213. package/dist/package-lifecycle/index.d.ts +1 -0
  214. package/dist/package-lifecycle/index.d.ts.map +1 -1
  215. package/dist/package-lifecycle/index.js +1 -0
  216. package/dist/package-lifecycle/index.js.map +1 -1
  217. package/dist/progress/routes.d.ts +1 -1
  218. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  219. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  220. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  221. package/dist/provider-api/index.d.ts +6 -2
  222. package/dist/provider-api/index.d.ts.map +1 -1
  223. package/dist/provider-api/index.js +25 -12
  224. package/dist/provider-api/index.js.map +1 -1
  225. package/dist/provider-api/runtime.d.ts +2 -0
  226. package/dist/provider-api/runtime.d.ts.map +1 -0
  227. package/dist/provider-api/runtime.js +2 -0
  228. package/dist/provider-api/runtime.js.map +1 -0
  229. package/dist/secrets/routes.d.ts +9 -9
  230. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  231. package/dist/server/transcribe-voice.d.ts +1 -1
  232. package/dist/setup-connections/index.d.ts +1 -1
  233. package/dist/setup-connections/index.d.ts.map +1 -1
  234. package/dist/setup-connections/index.js +1 -1
  235. package/dist/setup-connections/index.js.map +1 -1
  236. package/dist/shared/merge-by-id.d.ts +5 -0
  237. package/dist/shared/merge-by-id.d.ts.map +1 -0
  238. package/dist/shared/merge-by-id.js +7 -0
  239. package/dist/shared/merge-by-id.js.map +1 -0
  240. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
  241. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  242. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
  243. package/dist/templates/chat/AGENTS.md +3 -2
  244. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
  245. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  246. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
  247. package/dist/templates/default/AGENTS.md +6 -5
  248. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
  249. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  250. package/dist/templates/headless/AGENTS.md +5 -4
  251. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
  252. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
  253. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  254. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
  255. package/dist/templates/workspace-core/AGENTS.md +4 -4
  256. package/dist/templates/workspace-root/AGENTS.md +4 -4
  257. package/dist/vite/client.d.ts.map +1 -1
  258. package/dist/vite/client.js +22 -2
  259. package/dist/vite/client.js.map +1 -1
  260. package/docs/content/agent-native-toolkit.mdx +38 -0
  261. package/docs/content/package-lifecycle.mdx +54 -4
  262. package/package.json +15 -2
  263. package/src/a2a/agent-card.ts +83 -0
  264. package/src/a2a/artifact-response.ts +1648 -0
  265. package/src/a2a/auth-policy.ts +66 -0
  266. package/src/a2a/caller-auth.ts +102 -0
  267. package/src/a2a/client.ts +876 -0
  268. package/src/a2a/correlation.ts +50 -0
  269. package/src/a2a/handlers.ts +1285 -0
  270. package/src/a2a/index.ts +50 -0
  271. package/src/a2a/invoke.ts +348 -0
  272. package/src/a2a/response-text.ts +53 -0
  273. package/src/a2a/server.ts +586 -0
  274. package/src/a2a/task-store.ts +917 -0
  275. package/src/a2a/types.ts +221 -0
  276. package/src/a2a-claims.ts +52 -0
  277. package/src/action-change-marker.ts +74 -0
  278. package/src/action-ui.ts +38 -0
  279. package/src/action.ts +1406 -0
  280. package/src/adapters/cli/index.ts +6 -0
  281. package/src/adapters/cli/registry.ts +73 -0
  282. package/src/adapters/cli/shell-adapter.ts +92 -0
  283. package/src/adapters/cli/types.ts +27 -0
  284. package/src/agent/action-continuation-guidance.ts +38 -0
  285. package/src/agent/app-model-defaults.ts +201 -0
  286. package/src/agent/context-xray/actions/context-evict.ts +56 -0
  287. package/src/agent/context-xray/actions/context-manifest-get.ts +75 -0
  288. package/src/agent/context-xray/actions/context-pin.ts +56 -0
  289. package/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  290. package/src/agent/context-xray/actions/context-report.ts +75 -0
  291. package/src/agent/context-xray/actions/context-restore.ts +51 -0
  292. package/src/agent/context-xray/actions/errors.ts +40 -0
  293. package/src/agent/context-xray/apply-directives.ts +137 -0
  294. package/src/agent/context-xray/directives-store.ts +178 -0
  295. package/src/agent/context-xray/identity.ts +37 -0
  296. package/src/agent/context-xray/manifest.ts +284 -0
  297. package/src/agent/context-xray/migrations.ts +32 -0
  298. package/src/agent/context-xray/plugin.ts +23 -0
  299. package/src/agent/context-xray/schema.ts +17 -0
  300. package/src/agent/context-xray/segments.ts +194 -0
  301. package/src/agent/context-xray/tokenize.ts +93 -0
  302. package/src/agent/default-model.ts +5 -0
  303. package/src/agent/durable-background.ts +547 -0
  304. package/src/agent/engine/ai-sdk-engine.ts +565 -0
  305. package/src/agent/engine/anthropic-engine.ts +320 -0
  306. package/src/agent/engine/builder-engine.ts +1110 -0
  307. package/src/agent/engine/builder-gateway-headers.ts +44 -0
  308. package/src/agent/engine/builtin.ts +122 -0
  309. package/src/agent/engine/context-directives-transform.ts +73 -0
  310. package/src/agent/engine/continuation-dispatch-retry.ts +168 -0
  311. package/src/agent/engine/credential-errors.ts +69 -0
  312. package/src/agent/engine/index.ts +54 -0
  313. package/src/agent/engine/openai-compatible-endpoint.ts +25 -0
  314. package/src/agent/engine/output-tokens.ts +181 -0
  315. package/src/agent/engine/provider-env-vars.ts +69 -0
  316. package/src/agent/engine/registry.ts +853 -0
  317. package/src/agent/engine/tool-call-journal-seed.ts +85 -0
  318. package/src/agent/engine/translate-ai-sdk.ts +407 -0
  319. package/src/agent/engine/translate-anthropic.ts +611 -0
  320. package/src/agent/engine/types.ts +310 -0
  321. package/src/agent/harness/acp-adapter.ts +893 -0
  322. package/src/agent/harness/acp-builtin.ts +70 -0
  323. package/src/agent/harness/ai-sdk-adapter.ts +509 -0
  324. package/src/agent/harness/background.ts +365 -0
  325. package/src/agent/harness/builtin.ts +50 -0
  326. package/src/agent/harness/index.ts +86 -0
  327. package/src/agent/harness/lifecycle.ts +498 -0
  328. package/src/agent/harness/registry.ts +97 -0
  329. package/src/agent/harness/runner.ts +182 -0
  330. package/src/agent/harness/store.ts +466 -0
  331. package/src/agent/harness/translate.ts +130 -0
  332. package/src/agent/harness/types.ts +129 -0
  333. package/src/agent/index.ts +32 -0
  334. package/src/agent/loop-settings.ts +186 -0
  335. package/src/agent/model-config.ts +363 -0
  336. package/src/agent/observational-memory/compactor.ts +78 -0
  337. package/src/agent/observational-memory/config.ts +78 -0
  338. package/src/agent/observational-memory/index.ts +79 -0
  339. package/src/agent/observational-memory/internal-run.ts +89 -0
  340. package/src/agent/observational-memory/message-text.ts +49 -0
  341. package/src/agent/observational-memory/migrations.ts +44 -0
  342. package/src/agent/observational-memory/observer.ts +128 -0
  343. package/src/agent/observational-memory/plugin.ts +35 -0
  344. package/src/agent/observational-memory/prompts.ts +53 -0
  345. package/src/agent/observational-memory/read.ts +131 -0
  346. package/src/agent/observational-memory/reflector.ts +119 -0
  347. package/src/agent/observational-memory/schema.ts +48 -0
  348. package/src/agent/observational-memory/store.ts +275 -0
  349. package/src/agent/observational-memory/types.ts +65 -0
  350. package/src/agent/processors.ts +209 -0
  351. package/src/agent/production-agent.ts +8254 -0
  352. package/src/agent/run-loop-with-resume.ts +394 -0
  353. package/src/agent/run-manager.ts +1825 -0
  354. package/src/agent/run-ownership.ts +75 -0
  355. package/src/agent/run-store.ts +2601 -0
  356. package/src/agent/runtime-context.ts +169 -0
  357. package/src/agent/thread-data-builder.ts +1584 -0
  358. package/src/agent/tool-call-journal.ts +368 -0
  359. package/src/agent/tool-error-redaction.ts +52 -0
  360. package/src/agent/tool-result-images.ts +178 -0
  361. package/src/agent/tool-search.ts +376 -0
  362. package/src/agent/types.ts +372 -0
  363. package/src/agent-native/index.ts +198 -0
  364. package/src/agent-web/config.ts +253 -0
  365. package/src/agent-web/generator.ts +382 -0
  366. package/src/agent-web/index.ts +36 -0
  367. package/src/appearance/actions/change-appearance.ts +35 -0
  368. package/src/application-state/emitter.ts +81 -0
  369. package/src/application-state/handlers.ts +121 -0
  370. package/src/application-state/index.ts +44 -0
  371. package/src/application-state/script-helpers.ts +155 -0
  372. package/src/application-state/store.ts +274 -0
  373. package/src/assets/branding/agent-native.icon/Assets/background.svg +3 -0
  374. package/src/assets/branding/agent-native.icon/Assets/foreground.svg +12 -0
  375. package/src/assets/branding/agent-native.icon/icon.json +49 -0
  376. package/src/assets/branding/favicon.png +0 -0
  377. package/src/assets/branding/favicon.svg +1 -0
  378. package/src/assets/branding/icon-on-dark.svg +10 -0
  379. package/src/assets/branding/icon-on-light.svg +10 -0
  380. package/src/assets/branding/mac-app-icon.svg +1 -0
  381. package/src/assets/branding/slack-bot/agent-native-1024.png +0 -0
  382. package/src/assets/branding/slack-bot/agent-native-512.png +0 -0
  383. package/src/assets/branding/tray-icon.svg +6 -0
  384. package/src/assets/branding/wordmark-on-dark.svg +21 -0
  385. package/src/assets/branding/wordmark-on-light.svg +21 -0
  386. package/src/assets/fonts/LICENSE_LIBERATION +96 -0
  387. package/src/assets/fonts/LICENSE_NOTO_NASKH_ARABIC +93 -0
  388. package/src/assets/fonts/LiberationSans-Bold.ttf +0 -0
  389. package/src/assets/fonts/LiberationSans-Regular.ttf +0 -0
  390. package/src/assets/fonts/NotoNaskhArabic-Variable.ttf +0 -0
  391. package/src/audit/actions/export-audit-events.ts +162 -0
  392. package/src/audit/actions/get-audit-event.ts +24 -0
  393. package/src/audit/actions/list-audit-events.ts +66 -0
  394. package/src/audit/cleanup-job.ts +100 -0
  395. package/src/audit/config.ts +90 -0
  396. package/src/audit/index.ts +43 -0
  397. package/src/audit/record.ts +180 -0
  398. package/src/audit/redact.ts +109 -0
  399. package/src/audit/store.ts +346 -0
  400. package/src/audit/types.ts +141 -0
  401. package/src/automation/index.ts +802 -0
  402. package/src/brand-kit/brand-signals.ts +124 -0
  403. package/src/brand-kit/fig/index.ts +64 -0
  404. package/src/brand-kit/index.ts +72 -0
  405. package/src/brand-kit/types.ts +113 -0
  406. package/src/browser-sessions/actions.ts +302 -0
  407. package/src/browser-sessions/routes.ts +234 -0
  408. package/src/browser-sessions/store.ts +679 -0
  409. package/src/browser-sessions/types.ts +84 -0
  410. package/src/changelog/parse.ts +328 -0
  411. package/src/chat-threads/emitter.ts +22 -0
  412. package/src/chat-threads/schema.ts +43 -0
  413. package/src/chat-threads/store.ts +1311 -0
  414. package/src/checkpoints/index.ts +15 -0
  415. package/src/checkpoints/service.ts +142 -0
  416. package/src/checkpoints/store.ts +153 -0
  417. package/src/cli/add.ts +425 -0
  418. package/src/cli/agent.ts +424 -0
  419. package/src/cli/agents.ts +122 -0
  420. package/src/cli/app-skill.ts +1455 -0
  421. package/src/cli/atomic-json-file.ts +324 -0
  422. package/src/cli/audit-agent-web.ts +324 -0
  423. package/src/cli/changelog.ts +199 -0
  424. package/src/cli/claude-code-participant.ts +515 -0
  425. package/src/cli/code-agent-commands.ts +270 -0
  426. package/src/cli/code-agent-connector.ts +1109 -0
  427. package/src/cli/code-agent-executor.ts +1970 -0
  428. package/src/cli/code-agent-output-smoother.ts +140 -0
  429. package/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  430. package/src/cli/code-agent-runs.ts +548 -0
  431. package/src/cli/code.ts +1805 -0
  432. package/src/cli/codex-cli-participant.ts +496 -0
  433. package/src/cli/connect.ts +2714 -0
  434. package/src/cli/content-local.ts +442 -0
  435. package/src/cli/context-xray-local.ts +2193 -0
  436. package/src/cli/create-workspace.ts +30 -0
  437. package/src/cli/create.ts +2247 -0
  438. package/src/cli/deploy-build.ts +50 -0
  439. package/src/cli/design-connect.ts +3187 -0
  440. package/src/cli/doctor.ts +472 -0
  441. package/src/cli/eject.ts +1594 -0
  442. package/src/cli/eval.ts +134 -0
  443. package/src/cli/gateway-helpers.ts +70 -0
  444. package/src/cli/index.ts +1217 -0
  445. package/src/cli/info.ts +105 -0
  446. package/src/cli/invoke.ts +288 -0
  447. package/src/cli/mcp-config-writers.ts +857 -0
  448. package/src/cli/mcp.ts +594 -0
  449. package/src/cli/migrate.ts +1813 -0
  450. package/src/cli/migration-codemod.ts +646 -0
  451. package/src/cli/multi-frontier-runs.ts +1952 -0
  452. package/src/cli/package-lifecycle.ts +823 -0
  453. package/src/cli/plan-blocks.ts +143 -0
  454. package/src/cli/plan-local.ts +3189 -0
  455. package/src/cli/plan-publish-store.ts +138 -0
  456. package/src/cli/pr-visual-recap-workflow.ts +2 -0
  457. package/src/cli/recap.ts +5 -0
  458. package/src/cli/setup-agents.ts +120 -0
  459. package/src/cli/skills-content/assets-skill.ts +83 -0
  460. package/src/cli/skills-content/canvas.ts +153 -0
  461. package/src/cli/skills-content/connection.ts +52 -0
  462. package/src/cli/skills-content/content-skill.ts +120 -0
  463. package/src/cli/skills-content/design-exploration-skill.ts +118 -0
  464. package/src/cli/skills-content/design-visual-edit-skill.ts +228 -0
  465. package/src/cli/skills-content/document-quality.ts +196 -0
  466. package/src/cli/skills-content/exemplar.ts +69 -0
  467. package/src/cli/skills-content/help.ts +77 -0
  468. package/src/cli/skills-content/index.ts +22 -0
  469. package/src/cli/skills-content/local-files.ts +100 -0
  470. package/src/cli/skills-content/plan-setup-auth.ts +80 -0
  471. package/src/cli/skills-content/visual-plan-skill.ts +493 -0
  472. package/src/cli/skills-content/visual-recap-skill.ts +553 -0
  473. package/src/cli/skills-content/visualize-repo-skill.ts +93 -0
  474. package/src/cli/skills-content/wireframe.ts +349 -0
  475. package/src/cli/skills.ts +4340 -0
  476. package/src/cli/sync-builder-starter-manifest.ts +631 -0
  477. package/src/cli/telemetry.ts +136 -0
  478. package/src/cli/templates-meta.ts +269 -0
  479. package/src/cli/upgrade.ts +956 -0
  480. package/src/cli/visualize-repo.ts +715 -0
  481. package/src/cli/workspace-dev.ts +1486 -0
  482. package/src/cli/workspacify.ts +258 -0
  483. package/src/client/AgentAskPopover.tsx +89 -0
  484. package/src/client/AgentChatHome.tsx +66 -0
  485. package/src/client/AgentNative.tsx +161 -0
  486. package/src/client/AgentNativeEmbedded.tsx +288 -0
  487. package/src/client/AgentNativeFrame.tsx +151 -0
  488. package/src/client/AgentPanel.tsx +3437 -0
  489. package/src/client/AgentTaskCard.tsx +273 -0
  490. package/src/client/AppearancePicker.tsx +79 -0
  491. package/src/client/AssistantChat.tsx +5793 -0
  492. package/src/client/ClientOnly.tsx +22 -0
  493. package/src/client/CommandMenu.tsx +726 -0
  494. package/src/client/ConnectBuilderCard.tsx +390 -0
  495. package/src/client/DefaultSpinner.tsx +47 -0
  496. package/src/client/ErrorBoundary.tsx +359 -0
  497. package/src/client/ErrorReportActions.tsx +69 -0
  498. package/src/client/FeedbackButton.tsx +553 -0
  499. package/src/client/HighlightedCodeBlock.tsx +173 -0
  500. package/src/client/IframeEmbed.tsx +151 -0
  501. package/src/client/KeepTabOpenNotice.tsx +181 -0
  502. package/src/client/MultiTabAssistantChat.tsx +2576 -0
  503. package/src/client/NewWorkspaceAppFlow.tsx +525 -0
  504. package/src/client/PoweredByBadge.tsx +284 -0
  505. package/src/client/RunStuckBanner.tsx +431 -0
  506. package/src/client/StarfieldBackground.tsx +466 -0
  507. package/src/client/Turnstile.tsx +125 -0
  508. package/src/client/active-run-state.ts +139 -0
  509. package/src/client/agent-chat/index.ts +279 -0
  510. package/src/client/agent-chat-adapter.ts +3692 -0
  511. package/src/client/agent-chat.ts +1233 -0
  512. package/src/client/agent-engine-key.ts +122 -0
  513. package/src/client/agent-page/AgentContextTab.tsx +487 -0
  514. package/src/client/agent-page/AgentEmptyState.tsx +44 -0
  515. package/src/client/agent-page/AgentJobsTab.tsx +441 -0
  516. package/src/client/agent-page/AgentTabFrame.tsx +39 -0
  517. package/src/client/agent-page/AgentTabsPage.tsx +1096 -0
  518. package/src/client/agent-page/types.ts +18 -0
  519. package/src/client/agent-page/use-jobs.ts +150 -0
  520. package/src/client/agent-sidebar-state.ts +166 -0
  521. package/src/client/analytics/index.ts +40 -0
  522. package/src/client/analytics-session.ts +70 -0
  523. package/src/client/analytics.ts +1757 -0
  524. package/src/client/api-path.ts +124 -0
  525. package/src/client/app-providers.tsx +230 -0
  526. package/src/client/appearance.ts +130 -0
  527. package/src/client/application-state.ts +154 -0
  528. package/src/client/assistant-ui-recovery.tsx +205 -0
  529. package/src/client/automation/index.ts +4 -0
  530. package/src/client/automation.ts +22 -0
  531. package/src/client/blocks/AiEditableField.tsx +30 -0
  532. package/src/client/blocks/BlockView.tsx +145 -0
  533. package/src/client/blocks/RegistryBlockDataProvider.tsx +121 -0
  534. package/src/client/blocks/SchemaBlockEditor.tsx +457 -0
  535. package/src/client/blocks/agent.ts +95 -0
  536. package/src/client/blocks/code-block-direction.ts +21 -0
  537. package/src/client/blocks/index.ts +308 -0
  538. package/src/client/blocks/library/AnnotatedCodeBlock.tsx +710 -0
  539. package/src/client/blocks/library/ApiEndpointBlock.tsx +1120 -0
  540. package/src/client/blocks/library/DataModelBlock.tsx +775 -0
  541. package/src/client/blocks/library/DiffBlock.tsx +1854 -0
  542. package/src/client/blocks/library/FileTreeBlock.tsx +868 -0
  543. package/src/client/blocks/library/HighlightedCode.tsx +260 -0
  544. package/src/client/blocks/library/JsonExplorerBlock.tsx +608 -0
  545. package/src/client/blocks/library/MermaidBlock.tsx +362 -0
  546. package/src/client/blocks/library/OpenApiSpecBlock.tsx +998 -0
  547. package/src/client/blocks/library/annotated-code.config.ts +101 -0
  548. package/src/client/blocks/library/annotation-rail.tsx +1020 -0
  549. package/src/client/blocks/library/api-endpoint.config.ts +207 -0
  550. package/src/client/blocks/library/block-copy.ts +399 -0
  551. package/src/client/blocks/library/callout.config.ts +57 -0
  552. package/src/client/blocks/library/callout.tsx +149 -0
  553. package/src/client/blocks/library/checklist.config.ts +56 -0
  554. package/src/client/blocks/library/checklist.tsx +208 -0
  555. package/src/client/blocks/library/code-filename-label.tsx +59 -0
  556. package/src/client/blocks/library/code-highlight.tsx +178 -0
  557. package/src/client/blocks/library/code-tabs.config.ts +70 -0
  558. package/src/client/blocks/library/code-tabs.tsx +606 -0
  559. package/src/client/blocks/library/code.config.ts +69 -0
  560. package/src/client/blocks/library/code.tsx +440 -0
  561. package/src/client/blocks/library/columns.config.ts +85 -0
  562. package/src/client/blocks/library/columns.tsx +334 -0
  563. package/src/client/blocks/library/data-model.config.ts +152 -0
  564. package/src/client/blocks/library/dev-doc-ui.tsx +191 -0
  565. package/src/client/blocks/library/diagram.config.ts +222 -0
  566. package/src/client/blocks/library/diagram.tsx +958 -0
  567. package/src/client/blocks/library/diff.config.ts +115 -0
  568. package/src/client/blocks/library/file-tree.config.ts +92 -0
  569. package/src/client/blocks/library/html.config.ts +79 -0
  570. package/src/client/blocks/library/html.tsx +258 -0
  571. package/src/client/blocks/library/json-explorer.config.ts +74 -0
  572. package/src/client/blocks/library/mermaid.config.ts +49 -0
  573. package/src/client/blocks/library/narrow-container.tsx +37 -0
  574. package/src/client/blocks/library/openapi-spec.config.ts +66 -0
  575. package/src/client/blocks/library/question-form.config.ts +127 -0
  576. package/src/client/blocks/library/question-form.tsx +944 -0
  577. package/src/client/blocks/library/sanitize-html.ts +343 -0
  578. package/src/client/blocks/library/server-specs.ts +338 -0
  579. package/src/client/blocks/library/specs.tsx +308 -0
  580. package/src/client/blocks/library/table.config.ts +61 -0
  581. package/src/client/blocks/library/table.tsx +449 -0
  582. package/src/client/blocks/library/tabs.config.ts +96 -0
  583. package/src/client/blocks/library/tabs.tsx +665 -0
  584. package/src/client/blocks/library/wireframe-icons.ts +210 -0
  585. package/src/client/blocks/library/wireframe-kit.tsx +1850 -0
  586. package/src/client/blocks/library/wireframe.config.ts +539 -0
  587. package/src/client/blocks/library/wireframe.tsx +535 -0
  588. package/src/client/blocks/mdx.ts +364 -0
  589. package/src/client/blocks/provider.tsx +51 -0
  590. package/src/client/blocks/registry.ts +83 -0
  591. package/src/client/blocks/schema-form/introspect.ts +201 -0
  592. package/src/client/blocks/server.ts +170 -0
  593. package/src/client/blocks/types.ts +415 -0
  594. package/src/client/browser-session-bridge.ts +548 -0
  595. package/src/client/browser-tab-id.ts +36 -0
  596. package/src/client/builder-frame.ts +194 -0
  597. package/src/client/builder-mark.tsx +21 -0
  598. package/src/client/changelog/Changelog.tsx +333 -0
  599. package/src/client/changelog/index.ts +1 -0
  600. package/src/client/chat/ChatHistoryList.tsx +7 -0
  601. package/src/client/chat/attachment-adapters.ts +426 -0
  602. package/src/client/chat/connectors.ts +1579 -0
  603. package/src/client/chat/index.ts +160 -0
  604. package/src/client/chat/markdown-renderer.tsx +693 -0
  605. package/src/client/chat/message-components.tsx +1326 -0
  606. package/src/client/chat/repo-helpers.ts +281 -0
  607. package/src/client/chat/run-recovery.tsx +994 -0
  608. package/src/client/chat/runtime.ts +1810 -0
  609. package/src/client/chat/tool-call-display.tsx +1270 -0
  610. package/src/client/chat/tool-render-registry.tsx +144 -0
  611. package/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  612. package/src/client/chat/use-reconnect-reader-owner.ts +28 -0
  613. package/src/client/chat/widgets/DataChartRenderer.tsx +242 -0
  614. package/src/client/chat/widgets/DataChartWidget.tsx +51 -0
  615. package/src/client/chat/widgets/DataInsightsWidget.tsx +59 -0
  616. package/src/client/chat/widgets/DataTableWidget.tsx +240 -0
  617. package/src/client/chat/widgets/InlineExtensionWidget.tsx +60 -0
  618. package/src/client/chat/widgets/builtin-tool-renderers.tsx +213 -0
  619. package/src/client/chat/widgets/data-widget-types.ts +1 -0
  620. package/src/client/chat/widgets/inline-extension-result.ts +86 -0
  621. package/src/client/chat-model-groups.ts +171 -0
  622. package/src/client/chat-thread-url.ts +11 -0
  623. package/src/client/chat-view-transition.ts +213 -0
  624. package/src/client/client-action.ts +21 -0
  625. package/src/client/client-bootstrap.ts +7 -0
  626. package/src/client/client-surface.ts +41 -0
  627. package/src/client/clipboard.ts +89 -0
  628. package/src/client/code-agent-chat-adapter.ts +537 -0
  629. package/src/client/collab/index.ts +60 -0
  630. package/src/client/command-navigation/index.ts +15 -0
  631. package/src/client/comments-review/index.ts +1 -0
  632. package/src/client/components/AgentPresenceChip.tsx +4 -0
  633. package/src/client/components/ApiKeySettings.tsx +309 -0
  634. package/src/client/components/CodeAgentIndicator.tsx +59 -0
  635. package/src/client/components/CodeRequiredDialog.tsx +470 -0
  636. package/src/client/components/LiveCursorOverlay.tsx +5 -0
  637. package/src/client/components/MissingKeyCard.tsx +61 -0
  638. package/src/client/components/PresenceBar.tsx +4 -0
  639. package/src/client/components/RecentEditHighlights.tsx +4 -0
  640. package/src/client/components/RemoteSelectionRings.tsx +5 -0
  641. package/src/client/components/icons/AgentNativeIcon.tsx +46 -0
  642. package/src/client/components/ui/dialog.tsx +1 -0
  643. package/src/client/components/ui/dropdown-menu.tsx +1 -0
  644. package/src/client/components/ui/hover-card.tsx +1 -0
  645. package/src/client/components/ui/message-scroller.tsx +131 -0
  646. package/src/client/components/ui/popover.tsx +1 -0
  647. package/src/client/components/ui/sheet.tsx +1 -0
  648. package/src/client/components/ui/tooltip.tsx +1 -0
  649. package/src/client/composer/index.ts +11 -0
  650. package/src/client/composer/runtime-adapters.tsx +123 -0
  651. package/src/client/composer/use-mention-search.ts +7 -0
  652. package/src/client/composer/wired-components.tsx +53 -0
  653. package/src/client/context-xray/ContextMeter.tsx +124 -0
  654. package/src/client/context-xray/ContextSegmentRow.tsx +27 -0
  655. package/src/client/context-xray/ContextTreemap.tsx +24 -0
  656. package/src/client/context-xray/ContextXRayPanel.tsx +59 -0
  657. package/src/client/context-xray/SegmentProvenancePopover.tsx +18 -0
  658. package/src/client/context-xray/format.ts +27 -0
  659. package/src/client/conversation/AgentConversation.tsx +555 -0
  660. package/src/client/conversation/code-agent-transcript.ts +283 -0
  661. package/src/client/conversation/index.ts +22 -0
  662. package/src/client/conversation/types.ts +85 -0
  663. package/src/client/conversation/use-near-bottom-autoscroll.ts +278 -0
  664. package/src/client/create-query-client.ts +86 -0
  665. package/src/client/db-admin/DataGrid.tsx +551 -0
  666. package/src/client/db-admin/DbAdminPage.tsx +218 -0
  667. package/src/client/db-admin/DevDatabaseLink.tsx +16 -0
  668. package/src/client/db-admin/EditableCell.tsx +451 -0
  669. package/src/client/db-admin/FilterBar.tsx +203 -0
  670. package/src/client/db-admin/ResultsGrid.tsx +114 -0
  671. package/src/client/db-admin/RowSidePanel.tsx +337 -0
  672. package/src/client/db-admin/SqlEditor.tsx +840 -0
  673. package/src/client/db-admin/TableBrowser.tsx +212 -0
  674. package/src/client/db-admin/TableEditor.tsx +760 -0
  675. package/src/client/db-admin/cell-format.ts +246 -0
  676. package/src/client/db-admin/changeset.ts +296 -0
  677. package/src/client/db-admin/export-utils.ts +78 -0
  678. package/src/client/db-admin/index.ts +33 -0
  679. package/src/client/db-admin/sql-storage.ts +134 -0
  680. package/src/client/db-admin/storage.ts +68 -0
  681. package/src/client/db-admin/useAgentSync.ts +226 -0
  682. package/src/client/db-admin/useDbAdmin.ts +294 -0
  683. package/src/client/dev-overlay/DevOverlay.tsx +576 -0
  684. package/src/client/dev-overlay/builtins.ts +40 -0
  685. package/src/client/dev-overlay/index.ts +23 -0
  686. package/src/client/dev-overlay/registry.ts +67 -0
  687. package/src/client/dev-overlay/types.ts +64 -0
  688. package/src/client/dev-overlay/use-dev-option.ts +78 -0
  689. package/src/client/dev-overlay/use-dev-overlay-shortcut.ts +31 -0
  690. package/src/client/dynamic-suggestions.ts +455 -0
  691. package/src/client/embed-auth.ts +544 -0
  692. package/src/client/embed.ts +54 -0
  693. package/src/client/error-capture.ts +690 -0
  694. package/src/client/error-format.ts +211 -0
  695. package/src/client/error-reporting.ts +100 -0
  696. package/src/client/extensions/AgentNativeExtensionFrame.e2e-host.tsx +136 -0
  697. package/src/client/extensions/AgentNativeExtensionFrame.tsx +708 -0
  698. package/src/client/extensions/EmbeddedExtension.tsx +604 -0
  699. package/src/client/extensions/ExtensionEditor.tsx +450 -0
  700. package/src/client/extensions/ExtensionQueryErrorState.tsx +47 -0
  701. package/src/client/extensions/ExtensionSlot.tsx +345 -0
  702. package/src/client/extensions/ExtensionViewer.tsx +1502 -0
  703. package/src/client/extensions/ExtensionViewerPage.tsx +32 -0
  704. package/src/client/extensions/ExtensionsListPage.tsx +432 -0
  705. package/src/client/extensions/ExtensionsSidebarSection.tsx +1259 -0
  706. package/src/client/extensions/InlineExtensionFrame.tsx +660 -0
  707. package/src/client/extensions/agent-native-extension-runtime.ts +495 -0
  708. package/src/client/extensions/delete-extension.ts +76 -0
  709. package/src/client/extensions/extension-load-error.ts +26 -0
  710. package/src/client/extensions/extension-order.ts +49 -0
  711. package/src/client/extensions/extension-popularity.ts +61 -0
  712. package/src/client/extensions/iframe-bridge.ts +377 -0
  713. package/src/client/extensions/index.ts +84 -0
  714. package/src/client/extensions/portable-extension.ts +712 -0
  715. package/src/client/feature-flags/FeatureFlagsPanel.tsx +519 -0
  716. package/src/client/feature-flags/helpers.ts +77 -0
  717. package/src/client/feature-flags/index.ts +13 -0
  718. package/src/client/feature-flags/types.ts +29 -0
  719. package/src/client/feature-flags/use-feature-flag.ts +26 -0
  720. package/src/client/feedback-context.ts +90 -0
  721. package/src/client/frame-protocol.ts +168 -0
  722. package/src/client/frame.ts +329 -0
  723. package/src/client/guided-questions.tsx +1152 -0
  724. package/src/client/history/VersionHistoryPanel.tsx +175 -0
  725. package/src/client/history/index.ts +21 -0
  726. package/src/client/history/use-history.ts +114 -0
  727. package/src/client/hooks/index.ts +46 -0
  728. package/src/client/host/index.ts +170 -0
  729. package/src/client/host-bridge.ts +1272 -0
  730. package/src/client/host-tools.ts +190 -0
  731. package/src/client/i18n.tsx +798 -0
  732. package/src/client/index.ts +370 -0
  733. package/src/client/integrations/IntegrationCard.tsx +186 -0
  734. package/src/client/integrations/IntegrationsPanel.tsx +633 -0
  735. package/src/client/integrations/api.ts +295 -0
  736. package/src/client/integrations/index.ts +29 -0
  737. package/src/client/integrations/useIntegrationStatus.ts +52 -0
  738. package/src/client/mcp-app-host.ts +720 -0
  739. package/src/client/mcp-apps/McpAppRenderer.tsx +760 -0
  740. package/src/client/navigation/index.ts +54 -0
  741. package/src/client/notifications/NotificationsBell.tsx +383 -0
  742. package/src/client/notifications/index.ts +1 -0
  743. package/src/client/observability/ObservabilityDashboard.tsx +890 -0
  744. package/src/client/observability/ThumbsFeedback.tsx +160 -0
  745. package/src/client/observability/index.ts +20 -0
  746. package/src/client/observability/useObservability.ts +266 -0
  747. package/src/client/onboarding/OnboardingBanner.tsx +73 -0
  748. package/src/client/onboarding/OnboardingPanel.tsx +1036 -0
  749. package/src/client/onboarding/SetupButton.tsx +64 -0
  750. package/src/client/onboarding/index.ts +25 -0
  751. package/src/client/onboarding/use-onboarding.ts +164 -0
  752. package/src/client/onboarding/use-preview-mode.ts +40 -0
  753. package/src/client/org/InvitationBanner.tsx +148 -0
  754. package/src/client/org/OrgSwitcher.tsx +754 -0
  755. package/src/client/org/RequireActiveOrg.tsx +337 -0
  756. package/src/client/org/TeamPage.tsx +1432 -0
  757. package/src/client/org/hooks.ts +359 -0
  758. package/src/client/org/index.ts +70 -0
  759. package/src/client/org/workspace-app-links.ts +367 -0
  760. package/src/client/org-team/index.ts +1 -0
  761. package/src/client/progress/RunsTray.tsx +680 -0
  762. package/src/client/progress/index.ts +1 -0
  763. package/src/client/require-session.tsx +142 -0
  764. package/src/client/resources/BuiltinCapabilityDetail.tsx +258 -0
  765. package/src/client/resources/McpConnectionSuggestion.tsx +276 -0
  766. package/src/client/resources/McpIntegrationDialog.tsx +808 -0
  767. package/src/client/resources/McpServerDetail.tsx +230 -0
  768. package/src/client/resources/ResourceEditor.tsx +872 -0
  769. package/src/client/resources/ResourceTree.tsx +860 -0
  770. package/src/client/resources/ResourcesPanel.tsx +1960 -0
  771. package/src/client/resources/index.ts +25 -0
  772. package/src/client/resources/mcp-integration-catalog.ts +771 -0
  773. package/src/client/resources/mcp-integration-logos.ts +108 -0
  774. package/src/client/resources/runtime.ts +1 -0
  775. package/src/client/resources/use-builtin-capabilities.ts +113 -0
  776. package/src/client/resources/use-mcp-servers.ts +217 -0
  777. package/src/client/resources/use-resources.ts +402 -0
  778. package/src/client/review/ReviewCommentComposer.tsx +123 -0
  779. package/src/client/review/ReviewStatusBadge.tsx +39 -0
  780. package/src/client/review/ReviewThreadPanel.tsx +625 -0
  781. package/src/client/review/index.ts +38 -0
  782. package/src/client/review/use-review.ts +186 -0
  783. package/src/client/route-chunk-recovery/index.ts +1 -0
  784. package/src/client/route-chunk-recovery.ts +331 -0
  785. package/src/client/route-state.ts +455 -0
  786. package/src/client/route-warmup.tsx +543 -0
  787. package/src/client/session-replay-iframe.e2e-host.tsx +100 -0
  788. package/src/client/session-replay.ts +3417 -0
  789. package/src/client/settings/AgentsSection.tsx +441 -0
  790. package/src/client/settings/AutomationsSection.tsx +516 -0
  791. package/src/client/settings/BackgroundAgentSection.tsx +189 -0
  792. package/src/client/settings/BrowserSection.tsx +110 -0
  793. package/src/client/settings/DemoModeSection.tsx +48 -0
  794. package/src/client/settings/SecretsSection.tsx +875 -0
  795. package/src/client/settings/SettingsPanel.tsx +3162 -0
  796. package/src/client/settings/SettingsSection.tsx +283 -0
  797. package/src/client/settings/SettingsTabsPage.tsx +592 -0
  798. package/src/client/settings/UsageSection.tsx +401 -0
  799. package/src/client/settings/VoiceTranscriptionSection.tsx +960 -0
  800. package/src/client/settings/agent-settings-search.ts +220 -0
  801. package/src/client/settings/index.ts +27 -0
  802. package/src/client/settings/useBuilderStatus.ts +1055 -0
  803. package/src/client/setup-connections/BuilderConnectCard.tsx +89 -0
  804. package/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  805. package/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  806. package/src/client/setup-connections/catalog.ts +6 -0
  807. package/src/client/setup-connections/index.ts +47 -0
  808. package/src/client/setup-connections/runtime.ts +1 -0
  809. package/src/client/sharing/ShareButton.tsx +1748 -0
  810. package/src/client/sharing/ShareDialog.tsx +846 -0
  811. package/src/client/sharing/VisibilityBadge.tsx +4 -0
  812. package/src/client/sharing/index.ts +2 -0
  813. package/src/client/sse-event-processor.ts +2002 -0
  814. package/src/client/terminal/AgentTerminal.tsx +488 -0
  815. package/src/client/terminal/index.ts +7 -0
  816. package/src/client/theme.ts +27 -0
  817. package/src/client/tombstone/agent-presence-chip.ts +17 -0
  818. package/src/client/tombstone/editor.ts +265 -0
  819. package/src/client/tombstone/live-cursor-overlay.ts +21 -0
  820. package/src/client/tombstone/presence-bar.ts +17 -0
  821. package/src/client/tombstone/recent-edit-highlights.ts +17 -0
  822. package/src/client/tombstone/remote-selection-rings.ts +21 -0
  823. package/src/client/tombstone/rich-markdown-editor.ts +265 -0
  824. package/src/client/tombstone/ui-dialog.ts +49 -0
  825. package/src/client/tombstone/ui-dropdown-menu.ts +69 -0
  826. package/src/client/tombstone/ui-hover-card.ts +21 -0
  827. package/src/client/tombstone/ui-popover.ts +25 -0
  828. package/src/client/tombstone/ui-sheet.ts +49 -0
  829. package/src/client/tombstone/ui-tooltip.ts +29 -0
  830. package/src/client/tombstone/visual-style-controls.ts +61 -0
  831. package/src/client/tool-cells/BashCell.tsx +164 -0
  832. package/src/client/tool-cells/EditCell.tsx +303 -0
  833. package/src/client/tool-cells/FilesChangedSummary.tsx +208 -0
  834. package/src/client/tool-cells/WriteCell.tsx +145 -0
  835. package/src/client/tool-cells/index.ts +7 -0
  836. package/src/client/tool-display.ts +41 -0
  837. package/src/client/track.ts +57 -0
  838. package/src/client/transcription/BuilderTranscriptionCta.tsx +120 -0
  839. package/src/client/transcription/use-live-transcription.ts +292 -0
  840. package/src/client/ui/index.ts +55 -0
  841. package/src/client/uploads/index.ts +6 -0
  842. package/src/client/uploads/upload-editor-image.ts +79 -0
  843. package/src/client/uploads/use-upload-resource.ts +24 -0
  844. package/src/client/url-scrub.ts +51 -0
  845. package/src/client/use-action.ts +766 -0
  846. package/src/client/use-agent-chat-context.ts +63 -0
  847. package/src/client/use-agent-chat-home-handoff.ts +207 -0
  848. package/src/client/use-agent-chat.ts +53 -0
  849. package/src/client/use-agent-engine-configured.ts +211 -0
  850. package/src/client/use-avatar.ts +127 -0
  851. package/src/client/use-change-version.ts +150 -0
  852. package/src/client/use-chat-models.ts +252 -0
  853. package/src/client/use-chat-threads.ts +1262 -0
  854. package/src/client/use-db-sync.ts +1112 -0
  855. package/src/client/use-demo-mode-status.ts +30 -0
  856. package/src/client/use-dev-mode.ts +177 -0
  857. package/src/client/use-external-value.ts +40 -0
  858. package/src/client/use-pausing-interval.ts +65 -0
  859. package/src/client/use-pinch-zoom.ts +202 -0
  860. package/src/client/use-run-stuck-detection.ts +427 -0
  861. package/src/client/use-send-to-agent-chat.ts +85 -0
  862. package/src/client/use-session.ts +114 -0
  863. package/src/client/utils.ts +7 -0
  864. package/src/client/visual-style-controls.tsx +1 -0
  865. package/src/client/vite-dev-recovery-script.ts +226 -0
  866. package/src/client/voice-provider-status.ts +44 -0
  867. package/src/client/widgets/index.ts +41 -0
  868. package/src/code-agents/background-controller.ts +398 -0
  869. package/src/code-agents/background-run.ts +156 -0
  870. package/src/code-agents/index.ts +95 -0
  871. package/src/code-agents/prompt-attachments.ts +39 -0
  872. package/src/code-agents/transcript-normalizer.ts +750 -0
  873. package/src/code-agents/transcript-order.ts +73 -0
  874. package/src/coding-tools/index.ts +742 -0
  875. package/src/coding-tools/run-code.ts +1662 -0
  876. package/src/coding-tools/sandbox/adapter.ts +82 -0
  877. package/src/coding-tools/sandbox/background.ts +406 -0
  878. package/src/coding-tools/sandbox/executions-store.ts +517 -0
  879. package/src/coding-tools/sandbox/index.ts +132 -0
  880. package/src/coding-tools/sandbox/local-child-process-adapter.ts +217 -0
  881. package/src/collab/agent-identity.ts +5 -0
  882. package/src/collab/agent-presence.ts +341 -0
  883. package/src/collab/awareness-store.ts +196 -0
  884. package/src/collab/awareness.ts +317 -0
  885. package/src/collab/client-struct.ts +366 -0
  886. package/src/collab/client.ts +1205 -0
  887. package/src/collab/emitter.ts +31 -0
  888. package/src/collab/follow-mode.ts +107 -0
  889. package/src/collab/index.ts +151 -0
  890. package/src/collab/json-to-yjs.ts +504 -0
  891. package/src/collab/presence.ts +207 -0
  892. package/src/collab/recent-edits.ts +215 -0
  893. package/src/collab/routes.ts +191 -0
  894. package/src/collab/storage.ts +228 -0
  895. package/src/collab/struct-routes.ts +133 -0
  896. package/src/collab/text-to-yjs.ts +79 -0
  897. package/src/collab/undo.ts +432 -0
  898. package/src/collab/xml-ops.ts +68 -0
  899. package/src/collab/ydoc-manager.ts +544 -0
  900. package/src/command-navigation/actions.ts +100 -0
  901. package/src/command-navigation/index.ts +12 -0
  902. package/src/comments-review/index.ts +1 -0
  903. package/src/connections/catalog.ts +451 -0
  904. package/src/connections/index.ts +48 -0
  905. package/src/connections/reader.ts +911 -0
  906. package/src/connections/runtime.ts +1 -0
  907. package/src/credentials/index.ts +187 -0
  908. package/src/data-programs/actions.ts +335 -0
  909. package/src/data-programs/contract.ts +284 -0
  910. package/src/data-programs/execute.ts +693 -0
  911. package/src/data-programs/index.ts +72 -0
  912. package/src/data-programs/schema.ts +148 -0
  913. package/src/data-programs/store.ts +755 -0
  914. package/src/data-widgets/index.ts +376 -0
  915. package/src/db/client.ts +1627 -0
  916. package/src/db/create-get-db.ts +579 -0
  917. package/src/db/ddl-guard.ts +302 -0
  918. package/src/db/drizzle-config.ts +190 -0
  919. package/src/db/ensure-additive-columns.ts +430 -0
  920. package/src/db/index.ts +57 -0
  921. package/src/db/migrations.ts +691 -0
  922. package/src/db/request-telemetry.ts +154 -0
  923. package/src/db/runtime-diagnostics.ts +331 -0
  924. package/src/db/schema.ts +121 -0
  925. package/src/db/widen-columns.ts +75 -0
  926. package/src/db-admin/agent-tools.ts +202 -0
  927. package/src/db-admin/index.ts +26 -0
  928. package/src/db-admin/operations.ts +803 -0
  929. package/src/db-admin/routes.ts +174 -0
  930. package/src/db-admin/types.ts +110 -0
  931. package/src/demo/browser-state.ts +47 -0
  932. package/src/demo/fetch-interceptor.ts +175 -0
  933. package/src/demo/redact.ts +575 -0
  934. package/src/deploy/build.ts +3935 -0
  935. package/src/deploy/immutable-assets.ts +65 -0
  936. package/src/deploy/route-discovery.ts +458 -0
  937. package/src/deploy/workspace-core.ts +282 -0
  938. package/src/deploy/workspace-deploy.ts +1488 -0
  939. package/src/eject/provider-api-definitions.ts +193 -0
  940. package/src/eject/remote-mcp-presets.ts +137 -0
  941. package/src/eject/setup-readiness-ui.tsx +29 -0
  942. package/src/eject/workspace-connections.ts +92 -0
  943. package/src/embedding/agent.ts +159 -0
  944. package/src/embedding/bridge.ts +297 -0
  945. package/src/embedding/index.ts +43 -0
  946. package/src/embedding/protocol.ts +185 -0
  947. package/src/embedding/react.tsx +319 -0
  948. package/src/embeddings/index.ts +233 -0
  949. package/src/eval/agent-runner.ts +210 -0
  950. package/src/eval/define-eval.ts +55 -0
  951. package/src/eval/index.ts +49 -0
  952. package/src/eval/report.ts +75 -0
  953. package/src/eval/runner.ts +369 -0
  954. package/src/eval/scorer.ts +244 -0
  955. package/src/eval/types.ts +188 -0
  956. package/src/event-bus/bus.ts +140 -0
  957. package/src/event-bus/index.ts +3 -0
  958. package/src/event-bus/registry.ts +79 -0
  959. package/src/event-bus/types.ts +29 -0
  960. package/src/extensions/actions.ts +1636 -0
  961. package/src/extensions/change-marker.ts +54 -0
  962. package/src/extensions/content-patch.ts +468 -0
  963. package/src/extensions/fetch-tool.ts +461 -0
  964. package/src/extensions/html-shell.ts +803 -0
  965. package/src/extensions/local.ts +462 -0
  966. package/src/extensions/path.ts +40 -0
  967. package/src/extensions/proxy-security.ts +171 -0
  968. package/src/extensions/routes.ts +1080 -0
  969. package/src/extensions/schema.ts +269 -0
  970. package/src/extensions/session-replay-iframe.ts +131 -0
  971. package/src/extensions/slots/routes.ts +126 -0
  972. package/src/extensions/slots/schema.ts +87 -0
  973. package/src/extensions/slots/store.ts +450 -0
  974. package/src/extensions/store.ts +1347 -0
  975. package/src/extensions/theme.ts +114 -0
  976. package/src/extensions/url-safety.ts +316 -0
  977. package/src/extensions/web-content.ts +663 -0
  978. package/src/extensions/web-search-tool.ts +437 -0
  979. package/src/feature-flags/a2a-action-route.ts +56 -0
  980. package/src/feature-flags/actions/get-feature-flags.ts +24 -0
  981. package/src/feature-flags/actions/list-feature-flags.ts +69 -0
  982. package/src/feature-flags/actions/set-feature-flag.ts +89 -0
  983. package/src/feature-flags/index.ts +21 -0
  984. package/src/feature-flags/permissions.ts +53 -0
  985. package/src/feature-flags/plugin.ts +44 -0
  986. package/src/feature-flags/registry.ts +96 -0
  987. package/src/feature-flags/store.ts +176 -0
  988. package/src/file-upload/actions/upload-image.ts +213 -0
  989. package/src/file-upload/builder.ts +431 -0
  990. package/src/file-upload/index.ts +24 -0
  991. package/src/file-upload/pre-upload-attachments.ts +305 -0
  992. package/src/file-upload/registry.ts +125 -0
  993. package/src/file-upload/types.ts +89 -0
  994. package/src/guards/db-tool-scoping.ts +129 -0
  995. package/src/guards/index.ts +23 -0
  996. package/src/guards/no-drizzle-push.ts +116 -0
  997. package/src/guards/no-env-credentials.ts +229 -0
  998. package/src/guards/no-env-mutation.ts +114 -0
  999. package/src/guards/no-localhost-fallback.ts +124 -0
  1000. package/src/guards/no-unscoped-credentials.ts +227 -0
  1001. package/src/guards/no-unscoped-queries.ts +834 -0
  1002. package/src/guards/scan-utils.ts +105 -0
  1003. package/src/guards/types.ts +30 -0
  1004. package/src/history/actions/create-resource-version.ts +92 -0
  1005. package/src/history/actions/get-resource-version.ts +60 -0
  1006. package/src/history/actions/list-resource-history.ts +53 -0
  1007. package/src/history/actions/list-resource-versions.ts +43 -0
  1008. package/src/history/actions/restore-resource-version.ts +96 -0
  1009. package/src/history/index.ts +26 -0
  1010. package/src/history/registry.ts +111 -0
  1011. package/src/history/store.ts +379 -0
  1012. package/src/history/types.ts +69 -0
  1013. package/src/index.browser.ts +155 -0
  1014. package/src/index.ts +408 -0
  1015. package/src/ingestion/docx.ts +158 -0
  1016. package/src/ingestion/figma-node-to-html.ts +1860 -0
  1017. package/src/ingestion/figma.ts +548 -0
  1018. package/src/ingestion/index.ts +107 -0
  1019. package/src/ingestion/media.ts +264 -0
  1020. package/src/ingestion/notion.ts +121 -0
  1021. package/src/ingestion/office.ts +213 -0
  1022. package/src/ingestion/orchestration.ts +160 -0
  1023. package/src/ingestion/pptx.ts +331 -0
  1024. package/src/ingestion/selection.ts +81 -0
  1025. package/src/ingestion/website.ts +151 -0
  1026. package/src/integrations/a2a-continuation-marker.ts +2 -0
  1027. package/src/integrations/a2a-continuation-processor.ts +888 -0
  1028. package/src/integrations/a2a-continuations-store.ts +643 -0
  1029. package/src/integrations/adapter-overrides.ts +12 -0
  1030. package/src/integrations/adapters/discord.ts +364 -0
  1031. package/src/integrations/adapters/email.ts +1164 -0
  1032. package/src/integrations/adapters/google-docs.ts +371 -0
  1033. package/src/integrations/adapters/index.ts +29 -0
  1034. package/src/integrations/adapters/microsoft-teams.ts +413 -0
  1035. package/src/integrations/adapters/slack.ts +1914 -0
  1036. package/src/integrations/adapters/telegram.ts +386 -0
  1037. package/src/integrations/adapters/whatsapp.ts +358 -0
  1038. package/src/integrations/awaiting-input-store.ts +130 -0
  1039. package/src/integrations/catalog.ts +571 -0
  1040. package/src/integrations/computer-supervision-store.ts +423 -0
  1041. package/src/integrations/computer-supervision.ts +213 -0
  1042. package/src/integrations/config-store.ts +131 -0
  1043. package/src/integrations/controls-store.ts +187 -0
  1044. package/src/integrations/eject/messaging-adapters.ts +85 -0
  1045. package/src/integrations/google-docs-poller.ts +671 -0
  1046. package/src/integrations/identity-links-store.ts +210 -0
  1047. package/src/integrations/identity.ts +196 -0
  1048. package/src/integrations/index.ts +220 -0
  1049. package/src/integrations/installations-store.ts +677 -0
  1050. package/src/integrations/integration-memory.ts +187 -0
  1051. package/src/integrations/internal-token.ts +106 -0
  1052. package/src/integrations/pending-tasks-retry-job.ts +286 -0
  1053. package/src/integrations/pending-tasks-store.ts +468 -0
  1054. package/src/integrations/plugin.ts +3048 -0
  1055. package/src/integrations/remote-commands-store.ts +690 -0
  1056. package/src/integrations/remote-devices-store.ts +492 -0
  1057. package/src/integrations/remote-json-safety.ts +127 -0
  1058. package/src/integrations/remote-push-delivery-job.ts +48 -0
  1059. package/src/integrations/remote-push-delivery.ts +370 -0
  1060. package/src/integrations/remote-push-store.ts +664 -0
  1061. package/src/integrations/remote-retry-job.ts +55 -0
  1062. package/src/integrations/remote-run-events-store.ts +222 -0
  1063. package/src/integrations/remote-types.ts +186 -0
  1064. package/src/integrations/runtime.ts +1 -0
  1065. package/src/integrations/scope-store.ts +498 -0
  1066. package/src/integrations/slack-manifest.ts +78 -0
  1067. package/src/integrations/slack-oauth.ts +344 -0
  1068. package/src/integrations/task-queue-stats.ts +144 -0
  1069. package/src/integrations/thread-mapping-store.ts +134 -0
  1070. package/src/integrations/types.ts +485 -0
  1071. package/src/integrations/usage-budget-store.ts +906 -0
  1072. package/src/integrations/webhook-delivery.ts +55 -0
  1073. package/src/integrations/webhook-handler.ts +1939 -0
  1074. package/src/jobs/actions/list-recurring-jobs.ts +105 -0
  1075. package/src/jobs/actions/manage-recurring-job.ts +85 -0
  1076. package/src/jobs/cron.ts +126 -0
  1077. package/src/jobs/index.ts +9 -0
  1078. package/src/jobs/scheduler.ts +703 -0
  1079. package/src/jobs/tools.ts +367 -0
  1080. package/src/local-artifacts/index.ts +1372 -0
  1081. package/src/localization/actions/get-localization-preference.ts +24 -0
  1082. package/src/localization/actions/set-localization-preference.ts +32 -0
  1083. package/src/localization/default-messages.ts +1009 -0
  1084. package/src/localization/index.ts +2 -0
  1085. package/src/localization/server.ts +131 -0
  1086. package/src/localization/shared.ts +208 -0
  1087. package/src/mcp/actions/call-mcp-tool.ts +19 -0
  1088. package/src/mcp/actions/create-org-service-token.ts +87 -0
  1089. package/src/mcp/actions/list-mcp-tools.ts +18 -0
  1090. package/src/mcp/actions/list-org-service-tokens.ts +44 -0
  1091. package/src/mcp/actions/revoke-org-service-token.ts +30 -0
  1092. package/src/mcp/actions/service-token-access.ts +121 -0
  1093. package/src/mcp/ask-app-inline-tasks.ts +125 -0
  1094. package/src/mcp/build-server.ts +2356 -0
  1095. package/src/mcp/builtin-tools.ts +1506 -0
  1096. package/src/mcp/connect-route.ts +1460 -0
  1097. package/src/mcp/connect-store.ts +680 -0
  1098. package/src/mcp/embed-app.ts +2051 -0
  1099. package/src/mcp/embed-route.ts +84 -0
  1100. package/src/mcp/external-agent-policy.ts +18 -0
  1101. package/src/mcp/index.ts +47 -0
  1102. package/src/mcp/oauth-route.ts +1016 -0
  1103. package/src/mcp/oauth-store.ts +581 -0
  1104. package/src/mcp/oauth-token.ts +227 -0
  1105. package/src/mcp/org-directory.ts +343 -0
  1106. package/src/mcp/route-paths.ts +34 -0
  1107. package/src/mcp/screen-memory-stdio.ts +290 -0
  1108. package/src/mcp/server.ts +507 -0
  1109. package/src/mcp/stdio.ts +328 -0
  1110. package/src/mcp/workspace-resolve.ts +261 -0
  1111. package/src/mcp-client/app-api.ts +136 -0
  1112. package/src/mcp-client/app-result.ts +64 -0
  1113. package/src/mcp-client/builtin-capabilities.ts +146 -0
  1114. package/src/mcp-client/builtin-store.ts +93 -0
  1115. package/src/mcp-client/config.ts +281 -0
  1116. package/src/mcp-client/errors.ts +54 -0
  1117. package/src/mcp-client/hub-client.ts +172 -0
  1118. package/src/mcp-client/hub-routes.ts +198 -0
  1119. package/src/mcp-client/index.ts +504 -0
  1120. package/src/mcp-client/manager.ts +968 -0
  1121. package/src/mcp-client/oauth-client.ts +462 -0
  1122. package/src/mcp-client/oauth-routes.ts +307 -0
  1123. package/src/mcp-client/remote-store.ts +674 -0
  1124. package/src/mcp-client/remote-url.ts +97 -0
  1125. package/src/mcp-client/routes.ts +1093 -0
  1126. package/src/mcp-client/screen-memory-local.ts +461 -0
  1127. package/src/mcp-client/tool-policy.ts +182 -0
  1128. package/src/mcp-client/visibility.ts +56 -0
  1129. package/src/mcp-client/workspace-servers.ts +379 -0
  1130. package/src/navigation/index.ts +170 -0
  1131. package/src/notifications/actions.ts +151 -0
  1132. package/src/notifications/channels.ts +410 -0
  1133. package/src/notifications/index.ts +22 -0
  1134. package/src/notifications/registry.ts +216 -0
  1135. package/src/notifications/routes.ts +106 -0
  1136. package/src/notifications/store.ts +236 -0
  1137. package/src/notifications/types.ts +52 -0
  1138. package/src/oauth-tokens/google-refresh.ts +175 -0
  1139. package/src/oauth-tokens/index.ts +15 -0
  1140. package/src/oauth-tokens/store.ts +384 -0
  1141. package/src/observability/cleanup-job.ts +124 -0
  1142. package/src/observability/evals.ts +507 -0
  1143. package/src/observability/experiments.ts +359 -0
  1144. package/src/observability/feedback.ts +332 -0
  1145. package/src/observability/hosted-model-experiment.ts +118 -0
  1146. package/src/observability/index.ts +62 -0
  1147. package/src/observability/plugin.ts +31 -0
  1148. package/src/observability/routes.ts +431 -0
  1149. package/src/observability/sentiment.ts +261 -0
  1150. package/src/observability/store.ts +1347 -0
  1151. package/src/observability/traces.ts +789 -0
  1152. package/src/observability/tracing.ts +157 -0
  1153. package/src/observability/tracking-identity.ts +55 -0
  1154. package/src/observability/types.ts +211 -0
  1155. package/src/onboarding/default-steps.ts +428 -0
  1156. package/src/onboarding/index.ts +22 -0
  1157. package/src/onboarding/plugin.ts +262 -0
  1158. package/src/onboarding/registry.ts +47 -0
  1159. package/src/onboarding/types.ts +96 -0
  1160. package/src/org/accept-pending.ts +98 -0
  1161. package/src/org/auto-join-domain.ts +113 -0
  1162. package/src/org/context.ts +614 -0
  1163. package/src/org/free-email-providers.ts +124 -0
  1164. package/src/org/handlers.ts +1153 -0
  1165. package/src/org/index.ts +63 -0
  1166. package/src/org/migrations.ts +105 -0
  1167. package/src/org/permissions.ts +30 -0
  1168. package/src/org/plugin.ts +255 -0
  1169. package/src/org/schema.ts +28 -0
  1170. package/src/org/types.ts +57 -0
  1171. package/src/org-team/index.ts +1 -0
  1172. package/src/package-lifecycle/deprecated-imports.ts +179 -0
  1173. package/src/package-lifecycle/eject-manifest.ts +345 -0
  1174. package/src/package-lifecycle/index.ts +7 -0
  1175. package/src/package-lifecycle/manifest.ts +120 -0
  1176. package/src/package-lifecycle/migration-manifest.ts +159 -0
  1177. package/src/package-lifecycle/migration-message.ts +6 -0
  1178. package/src/package-lifecycle/tombstone.ts +58 -0
  1179. package/src/package-lifecycle/upgrade-error.ts +37 -0
  1180. package/src/private-blob/index.ts +18 -0
  1181. package/src/private-blob/registry.ts +242 -0
  1182. package/src/private-blob/types.ts +55 -0
  1183. package/src/progress/actions.ts +179 -0
  1184. package/src/progress/index.ts +16 -0
  1185. package/src/progress/registry.ts +127 -0
  1186. package/src/progress/routes.ts +89 -0
  1187. package/src/progress/store.ts +353 -0
  1188. package/src/progress/types.ts +59 -0
  1189. package/src/provider-api/actions/custom-provider-registration.ts +197 -0
  1190. package/src/provider-api/actions/delete-staged-dataset.ts +5 -0
  1191. package/src/provider-api/actions/github-repo-files.ts +266 -0
  1192. package/src/provider-api/actions/list-staged-datasets.ts +5 -0
  1193. package/src/provider-api/actions/provider-api-audit.ts +88 -0
  1194. package/src/provider-api/actions/provider-api.ts +460 -0
  1195. package/src/provider-api/actions/query-staged-dataset.ts +5 -0
  1196. package/src/provider-api/actions/staged-datasets.ts +359 -0
  1197. package/src/provider-api/corpus-jobs-store.ts +522 -0
  1198. package/src/provider-api/corpus-jobs.ts +1817 -0
  1199. package/src/provider-api/custom-registry.ts +456 -0
  1200. package/src/provider-api/github-repo.ts +675 -0
  1201. package/src/provider-api/gong.ts +108 -0
  1202. package/src/provider-api/index.ts +5444 -0
  1203. package/src/provider-api/quota-governor.ts +562 -0
  1204. package/src/provider-api/runtime.ts +1 -0
  1205. package/src/provider-api/staged-datasets-aggregate.ts +304 -0
  1206. package/src/provider-api/staged-datasets-store.ts +441 -0
  1207. package/src/provider-api/staging.ts +483 -0
  1208. package/src/resources/agents.ts +65 -0
  1209. package/src/resources/emitter.ts +54 -0
  1210. package/src/resources/handlers.ts +728 -0
  1211. package/src/resources/index.ts +4 -0
  1212. package/src/resources/metadata.ts +252 -0
  1213. package/src/resources/script-helpers.ts +160 -0
  1214. package/src/resources/store.ts +1618 -0
  1215. package/src/review/actions/consume-review-feedback.ts +48 -0
  1216. package/src/review/actions/create-review-comment.ts +108 -0
  1217. package/src/review/actions/delete-review-comment.ts +67 -0
  1218. package/src/review/actions/get-review-feedback.ts +49 -0
  1219. package/src/review/actions/list-review-comments.ts +87 -0
  1220. package/src/review/actions/reply-review-comment.ts +118 -0
  1221. package/src/review/actions/resolve-review-thread.ts +94 -0
  1222. package/src/review/actions/send-review-thread-to-agent.ts +62 -0
  1223. package/src/review/actions/set-review-status.ts +58 -0
  1224. package/src/review/identity.ts +101 -0
  1225. package/src/review/index.ts +45 -0
  1226. package/src/review/mentions.ts +44 -0
  1227. package/src/review/registry.ts +111 -0
  1228. package/src/review/store.ts +997 -0
  1229. package/src/review/types.ts +101 -0
  1230. package/src/router/index.ts +24 -0
  1231. package/src/scripts/agent-engines/list-agent-engines.ts +130 -0
  1232. package/src/scripts/agent-engines/manage-agent-engine.ts +197 -0
  1233. package/src/scripts/agent-engines/set-agent-engine.ts +84 -0
  1234. package/src/scripts/agent-engines/test-agent-engine.ts +174 -0
  1235. package/src/scripts/call-agent.ts +792 -0
  1236. package/src/scripts/chat/index.ts +8 -0
  1237. package/src/scripts/chat/open-chat.ts +56 -0
  1238. package/src/scripts/chat/search-chats.ts +121 -0
  1239. package/src/scripts/core-scripts.ts +22 -0
  1240. package/src/scripts/db/check-scoping.ts +212 -0
  1241. package/src/scripts/db/exec.ts +791 -0
  1242. package/src/scripts/db/index.ts +19 -0
  1243. package/src/scripts/db/migrate-encrypt-credentials.ts +223 -0
  1244. package/src/scripts/db/migrate-encrypt-oauth-tokens.ts +213 -0
  1245. package/src/scripts/db/migrate-user-api-keys.ts +257 -0
  1246. package/src/scripts/db/patch.ts +820 -0
  1247. package/src/scripts/db/query.ts +299 -0
  1248. package/src/scripts/db/reset-dev-owner.ts +285 -0
  1249. package/src/scripts/db/safety.ts +286 -0
  1250. package/src/scripts/db/schema.ts +364 -0
  1251. package/src/scripts/db/scoping.ts +341 -0
  1252. package/src/scripts/db/sqlite-client.ts +78 -0
  1253. package/src/scripts/db/tool-mode.ts +23 -0
  1254. package/src/scripts/db/tool-schemas.ts +31 -0
  1255. package/src/scripts/db/wipe-leaked-builder-keys.ts +201 -0
  1256. package/src/scripts/dev/index.ts +296 -0
  1257. package/src/scripts/dev/list-files.ts +119 -0
  1258. package/src/scripts/dev/read-file.ts +77 -0
  1259. package/src/scripts/dev/search-files.ts +151 -0
  1260. package/src/scripts/dev/shell.ts +111 -0
  1261. package/src/scripts/dev/write-file.ts +56 -0
  1262. package/src/scripts/dev-session.ts +96 -0
  1263. package/src/scripts/docs/index.ts +8 -0
  1264. package/src/scripts/docs/search.ts +274 -0
  1265. package/src/scripts/docs/source-search.ts +363 -0
  1266. package/src/scripts/index.ts +15 -0
  1267. package/src/scripts/manage-agent-loop-settings.ts +84 -0
  1268. package/src/scripts/parse-args.ts +46 -0
  1269. package/src/scripts/resources/delete-memory.ts +67 -0
  1270. package/src/scripts/resources/delete.ts +69 -0
  1271. package/src/scripts/resources/effective.ts +71 -0
  1272. package/src/scripts/resources/index.ts +18 -0
  1273. package/src/scripts/resources/list.ts +103 -0
  1274. package/src/scripts/resources/migrate-learnings.ts +40 -0
  1275. package/src/scripts/resources/read.ts +107 -0
  1276. package/src/scripts/resources/save-memory.ts +99 -0
  1277. package/src/scripts/resources/write.ts +158 -0
  1278. package/src/scripts/runner.ts +339 -0
  1279. package/src/scripts/utils.ts +130 -0
  1280. package/src/search/index.ts +413 -0
  1281. package/src/search-utils/index.ts +112 -0
  1282. package/src/secrets/crypto.ts +228 -0
  1283. package/src/secrets/index.ts +65 -0
  1284. package/src/secrets/onboarding.ts +101 -0
  1285. package/src/secrets/register-framework-secrets.ts +228 -0
  1286. package/src/secrets/register.ts +129 -0
  1287. package/src/secrets/routes.ts +697 -0
  1288. package/src/secrets/schema.ts +52 -0
  1289. package/src/secrets/storage.ts +561 -0
  1290. package/src/secrets/substitution.ts +305 -0
  1291. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +150 -0
  1292. package/src/server/action-change.ts +66 -0
  1293. package/src/server/action-discovery.ts +774 -0
  1294. package/src/server/action-routes.ts +608 -0
  1295. package/src/server/agent-access.ts +72 -0
  1296. package/src/server/agent-chat/action-filters-a2a.ts +339 -0
  1297. package/src/server/agent-chat/browser-team-tools.ts +510 -0
  1298. package/src/server/agent-chat/context-tools.ts +599 -0
  1299. package/src/server/agent-chat/framework-prompts.ts +467 -0
  1300. package/src/server/agent-chat/lazy-fs.ts +11 -0
  1301. package/src/server/agent-chat/mcp-glue.ts +91 -0
  1302. package/src/server/agent-chat/plugin-options.ts +379 -0
  1303. package/src/server/agent-chat/process-run-failure.ts +62 -0
  1304. package/src/server/agent-chat/prompt-resources.ts +1004 -0
  1305. package/src/server/agent-chat/recurring-jobs-runtime.ts +80 -0
  1306. package/src/server/agent-chat/request-surface.ts +71 -0
  1307. package/src/server/agent-chat/run-code-tools.ts +67 -0
  1308. package/src/server/agent-chat/script-entries.ts +796 -0
  1309. package/src/server/agent-chat/shared-thread.ts +301 -0
  1310. package/src/server/agent-chat/skill-frontmatter.ts +41 -0
  1311. package/src/server/agent-chat-plugin.ts +5930 -0
  1312. package/src/server/agent-discovery.ts +706 -0
  1313. package/src/server/agent-engine-api-key-route.ts +236 -0
  1314. package/src/server/agent-run-context.ts +204 -0
  1315. package/src/server/agent-teams-run-queue.ts +344 -0
  1316. package/src/server/agent-teams.ts +2257 -0
  1317. package/src/server/agents-bundle.ts +464 -0
  1318. package/src/server/analytics.ts +105 -0
  1319. package/src/server/app-base-path.ts +79 -0
  1320. package/src/server/app-name.ts +53 -0
  1321. package/src/server/app-url.ts +184 -0
  1322. package/src/server/attachment-actions.ts +276 -0
  1323. package/src/server/attribution.ts +214 -0
  1324. package/src/server/auth-marketing.ts +260 -0
  1325. package/src/server/auth-plugin.ts +27 -0
  1326. package/src/server/auth.ts +3803 -0
  1327. package/src/server/better-auth-instance.ts +1197 -0
  1328. package/src/server/builder-browser.ts +1701 -0
  1329. package/src/server/builder-design-systems.ts +668 -0
  1330. package/src/server/builder-space.ts +176 -0
  1331. package/src/server/captcha.ts +63 -0
  1332. package/src/server/capture-error.ts +64 -0
  1333. package/src/server/cli-capture.ts +141 -0
  1334. package/src/server/collab-plugin.ts +391 -0
  1335. package/src/server/complete-text.ts +231 -0
  1336. package/src/server/cookie-namespace.ts +159 -0
  1337. package/src/server/core-routes-plugin.ts +4122 -0
  1338. package/src/server/cors-origins.ts +60 -0
  1339. package/src/server/create-server.ts +268 -0
  1340. package/src/server/credential-provider.ts +1202 -0
  1341. package/src/server/csrf.ts +229 -0
  1342. package/src/server/date-utils.ts +42 -0
  1343. package/src/server/deep-link.ts +119 -0
  1344. package/src/server/derived-secret.ts +32 -0
  1345. package/src/server/design-token-utils.ts +1032 -0
  1346. package/src/server/desktop-sso.ts +83 -0
  1347. package/src/server/edge.ts +69 -0
  1348. package/src/server/email-actions.ts +218 -0
  1349. package/src/server/email-template.ts +192 -0
  1350. package/src/server/email-templates.ts +148 -0
  1351. package/src/server/email.ts +219 -0
  1352. package/src/server/embed-route.ts +283 -0
  1353. package/src/server/embed-session.ts +805 -0
  1354. package/src/server/embedded.ts +252 -0
  1355. package/src/server/entry-server.tsx +154 -0
  1356. package/src/server/framework-request-handler.ts +848 -0
  1357. package/src/server/fusion-app.ts +447 -0
  1358. package/src/server/google-auth-mode.ts +34 -0
  1359. package/src/server/google-auth-plugin.ts +496 -0
  1360. package/src/server/google-oauth-credentials.ts +128 -0
  1361. package/src/server/google-oauth.ts +972 -0
  1362. package/src/server/google-realtime-session.ts +182 -0
  1363. package/src/server/h3-helpers.ts +174 -0
  1364. package/src/server/http-response-telemetry.ts +396 -0
  1365. package/src/server/identity-sso-store.ts +304 -0
  1366. package/src/server/identity-sso.ts +514 -0
  1367. package/src/server/index.ts +593 -0
  1368. package/src/server/missing-key.ts +36 -0
  1369. package/src/server/oauth-helpers.ts +44 -0
  1370. package/src/server/oauth-public-origin.ts +44 -0
  1371. package/src/server/oauth-return-url.ts +120 -0
  1372. package/src/server/og-fonts-data.ts +15 -0
  1373. package/src/server/og-fonts.ts +75 -0
  1374. package/src/server/onboarding-html.ts +4040 -0
  1375. package/src/server/open-route.ts +311 -0
  1376. package/src/server/org-admin.ts +28 -0
  1377. package/src/server/poll-events.ts +88 -0
  1378. package/src/server/poll.ts +1224 -0
  1379. package/src/server/prompts/framework-core-compact.ts +107 -0
  1380. package/src/server/prompts/framework-core.ts +143 -0
  1381. package/src/server/prompts/index.ts +16 -0
  1382. package/src/server/prompts/model-overlays.ts +54 -0
  1383. package/src/server/prompts/shared-rules.ts +104 -0
  1384. package/src/server/realtime-voice.ts +967 -0
  1385. package/src/server/recap-image-route.ts +242 -0
  1386. package/src/server/recap-image-store.ts +185 -0
  1387. package/src/server/request-context.ts +416 -0
  1388. package/src/server/request-origin.ts +67 -0
  1389. package/src/server/resources-plugin.ts +119 -0
  1390. package/src/server/schema-prompt.ts +429 -0
  1391. package/src/server/scoped-key-storage.ts +223 -0
  1392. package/src/server/security-headers.ts +170 -0
  1393. package/src/server/self-dispatch.ts +224 -0
  1394. package/src/server/sentry-config.ts +73 -0
  1395. package/src/server/sentry-plugin.ts +138 -0
  1396. package/src/server/sentry.ts +444 -0
  1397. package/src/server/short-lived-token.ts +170 -0
  1398. package/src/server/social-og-image.ts +454 -0
  1399. package/src/server/sse.ts +102 -0
  1400. package/src/server/ssr-handler.ts +466 -0
  1401. package/src/server/transcribe-voice.ts +1076 -0
  1402. package/src/server/voice-providers-status.ts +118 -0
  1403. package/src/server/workspace-oauth.ts +31 -0
  1404. package/src/server/workspace-provider-oauth.ts +970 -0
  1405. package/src/session-replay-iframe-protocol.ts +58 -0
  1406. package/src/settings/handlers.ts +44 -0
  1407. package/src/settings/index.ts +34 -0
  1408. package/src/settings/org-settings.ts +83 -0
  1409. package/src/settings/script-helpers.ts +24 -0
  1410. package/src/settings/store.ts +247 -0
  1411. package/src/settings/user-settings.ts +47 -0
  1412. package/src/setup-connections/index.ts +90 -0
  1413. package/src/setup-connections/onboarding.ts +47 -0
  1414. package/src/shared/agent-access.ts +112 -0
  1415. package/src/shared/agent-chat.ts +124 -0
  1416. package/src/shared/agent-env.ts +46 -0
  1417. package/src/shared/agent-readable-resource.ts +111 -0
  1418. package/src/shared/agent-sidebar-url.ts +39 -0
  1419. package/src/shared/cache-control.ts +25 -0
  1420. package/src/shared/cloudflare-globals.d.ts +34 -0
  1421. package/src/shared/context-xray.ts +172 -0
  1422. package/src/shared/embed-auth.ts +6 -0
  1423. package/src/shared/index.ts +83 -0
  1424. package/src/shared/llm-connection.ts +42 -0
  1425. package/src/shared/markdown-block-split.ts +129 -0
  1426. package/src/shared/mcp-connect-content.ts +130 -0
  1427. package/src/shared/mcp-embed-headers.ts +175 -0
  1428. package/src/shared/mcp-integration-config.ts +101 -0
  1429. package/src/shared/merge-by-id.ts +14 -0
  1430. package/src/shared/oauth-state.ts +39 -0
  1431. package/src/shared/reasoning-effort.ts +228 -0
  1432. package/src/shared/route-warmup-config.ts +128 -0
  1433. package/src/shared/runtime.ts +31 -0
  1434. package/src/shared/social-meta.ts +82 -0
  1435. package/src/shared/streaming-text-smoothing.ts +184 -0
  1436. package/src/shared/truncate.ts +13 -0
  1437. package/src/shared/workspace-app-audience.ts +177 -0
  1438. package/src/shared/workspace-app-id.ts +54 -0
  1439. package/src/sharing/access.ts +585 -0
  1440. package/src/sharing/actions/create-agent-resource-link.ts +91 -0
  1441. package/src/sharing/actions/extension-change.ts +22 -0
  1442. package/src/sharing/actions/list-resource-shares.ts +93 -0
  1443. package/src/sharing/actions/set-resource-visibility.ts +91 -0
  1444. package/src/sharing/actions/share-resource.ts +322 -0
  1445. package/src/sharing/actions/unshare-resource.ts +72 -0
  1446. package/src/sharing/index.ts +35 -0
  1447. package/src/sharing/registry.ts +201 -0
  1448. package/src/sharing/schema.ts +99 -0
  1449. package/src/styles/agent-conversation.css +766 -0
  1450. package/src/styles/agent-native.css +938 -0
  1451. package/src/styles/blocks.css +1717 -0
  1452. package/src/styles/chat-history-list.css +1 -0
  1453. package/src/styles/rich-markdown-editor.css +1 -0
  1454. package/src/tailwind.preset.ts +140 -0
  1455. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1456. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1457. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
  1458. package/src/templates/chat/AGENTS.md +3 -2
  1459. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1460. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1461. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
  1462. package/src/templates/default/AGENTS.md +6 -5
  1463. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1464. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1465. package/src/templates/headless/AGENTS.md +5 -4
  1466. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1467. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
  1468. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1469. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
  1470. package/src/templates/workspace-core/AGENTS.md +4 -4
  1471. package/src/templates/workspace-root/AGENTS.md +4 -4
  1472. package/src/terminal/cli-registry.ts +57 -0
  1473. package/src/terminal/index.ts +22 -0
  1474. package/src/terminal/pty-server.ts +389 -0
  1475. package/src/terminal/terminal-plugin.ts +265 -0
  1476. package/src/testing.ts +23 -0
  1477. package/src/tracking/index.ts +10 -0
  1478. package/src/tracking/providers.ts +422 -0
  1479. package/src/tracking/registry.ts +102 -0
  1480. package/src/tracking/route.ts +108 -0
  1481. package/src/tracking/types.ts +16 -0
  1482. package/src/transcription/builder-transcription.ts +118 -0
  1483. package/src/triggers/actions/list-automations.ts +99 -0
  1484. package/src/triggers/actions/manage-automation.ts +78 -0
  1485. package/src/triggers/actions.ts +333 -0
  1486. package/src/triggers/condition-evaluator.ts +163 -0
  1487. package/src/triggers/dispatcher.ts +536 -0
  1488. package/src/triggers/index.ts +13 -0
  1489. package/src/triggers/routes.ts +322 -0
  1490. package/src/triggers/types.ts +42 -0
  1491. package/src/types/pglite.d.ts +26 -0
  1492. package/src/usage/store.ts +698 -0
  1493. package/src/vite/action-types-plugin.ts +481 -0
  1494. package/src/vite/agent-web-plugin.ts +78 -0
  1495. package/src/vite/agents-bundle-plugin.ts +185 -0
  1496. package/src/vite/client.ts +3039 -0
  1497. package/src/vite/index.ts +21 -0
  1498. package/src/voice/index.ts +18 -0
  1499. package/src/voice/voice-cleanup-prompt.ts +38 -0
  1500. package/src/voice/voice-context.ts +217 -0
  1501. package/src/voice/voice-replacements.ts +75 -0
  1502. package/src/workspace-connections/credentials.ts +603 -0
  1503. package/src/workspace-connections/index.ts +72 -0
  1504. package/src/workspace-connections/lifecycle.ts +43 -0
  1505. package/src/workspace-connections/store.ts +1943 -0
  1506. package/src/workspace-files/index.ts +18 -0
  1507. package/src/workspace-files/store.ts +339 -0
  1508. package/src/workspace-files/tool.ts +266 -0
@@ -0,0 +1,1943 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import {
4
+ listWorkspaceConnectionProviders,
5
+ type WorkspaceConnectionCapability,
6
+ type WorkspaceConnectionProvider,
7
+ type WorkspaceConnectionTemplateUse,
8
+ } from "../connections/catalog.js";
9
+ import {
10
+ getDbExec,
11
+ intType,
12
+ isPostgres,
13
+ isUniqueViolation,
14
+ retryOnDdlRace,
15
+ safeJsonParse,
16
+ type DbExec,
17
+ } from "../db/client.js";
18
+ import {
19
+ ensureColumnExists,
20
+ ensureIndexExists,
21
+ ensureTableExists,
22
+ } from "../db/ddl-guard.js";
23
+ import {
24
+ getRequestOrgId,
25
+ getRequestUserEmail,
26
+ } from "../server/request-context.js";
27
+ import { notifyWorkspaceConnectionLifecycle } from "./lifecycle.js";
28
+
29
+ export type WorkspaceConnectionStatus =
30
+ | "connected"
31
+ | "checking"
32
+ | "needs_reauth"
33
+ | "error"
34
+ | "disabled";
35
+
36
+ export interface WorkspaceConnectionCredentialRef {
37
+ key: string;
38
+ scope?: "user" | "org" | "workspace";
39
+ provider?: string;
40
+ label?: string;
41
+ [key: string]: unknown;
42
+ }
43
+
44
+ export interface WorkspaceConnection {
45
+ id: string;
46
+ provider: string;
47
+ label: string;
48
+ accountId: string | null;
49
+ accountLabel: string | null;
50
+ status: WorkspaceConnectionStatus;
51
+ scopes: string[];
52
+ config: Record<string, unknown>;
53
+ allowedApps: string[];
54
+ credentialRefs: WorkspaceConnectionCredentialRef[];
55
+ ownerEmail: string;
56
+ orgId: string | null;
57
+ createdAt: string;
58
+ updatedAt: string;
59
+ lastUsedAt?: string | null;
60
+ lastCheckedAt: string | null;
61
+ lastError: string | null;
62
+ }
63
+
64
+ export type SerializedWorkspaceConnection = WorkspaceConnection;
65
+
66
+ export interface WorkspaceConnectionGrant {
67
+ id: string;
68
+ connectionId: string;
69
+ provider: string;
70
+ appId: string;
71
+ scopes: string[];
72
+ config: Record<string, unknown>;
73
+ credentialRefs: WorkspaceConnectionCredentialRef[];
74
+ grantedByEmail: string;
75
+ ownerEmail: string;
76
+ orgId: string | null;
77
+ createdAt: string;
78
+ updatedAt: string;
79
+ lastUsedAt?: string | null;
80
+ }
81
+
82
+ export type SerializedWorkspaceConnectionGrant = WorkspaceConnectionGrant;
83
+
84
+ export interface ListWorkspaceConnectionsOptions {
85
+ provider?: string;
86
+ appId?: string;
87
+ includeDisabled?: boolean;
88
+ }
89
+
90
+ export interface ListWorkspaceConnectionGrantsOptions {
91
+ connectionId?: string;
92
+ appId?: string;
93
+ provider?: string;
94
+ }
95
+
96
+ export interface ListWorkspaceConnectionsForAppOptions {
97
+ appId: string;
98
+ provider?: string;
99
+ includeDisabled?: boolean;
100
+ }
101
+
102
+ export interface ResolveWorkspaceConnectionForAppOptions extends ListWorkspaceConnectionsForAppOptions {
103
+ connectionId?: string;
104
+ requireConnected?: boolean;
105
+ }
106
+
107
+ export interface UpsertWorkspaceConnectionInput {
108
+ id?: string;
109
+ provider: string;
110
+ label?: string;
111
+ accountId?: string | null;
112
+ accountLabel?: string | null;
113
+ status?: WorkspaceConnectionStatus;
114
+ scopes?: string[];
115
+ config?: Record<string, unknown>;
116
+ allowedApps?: string[];
117
+ credentialRefs?: WorkspaceConnectionCredentialRef[];
118
+ lastCheckedAt?: Date | number | string | null;
119
+ lastError?: string | null;
120
+ }
121
+
122
+ export interface UpsertWorkspaceConnectionGrantInput {
123
+ id?: string;
124
+ connectionId: string;
125
+ appId: string;
126
+ provider?: string;
127
+ scopes?: string[];
128
+ config?: Record<string, unknown>;
129
+ credentialRefs?: WorkspaceConnectionCredentialRef[];
130
+ }
131
+
132
+ export type WorkspaceConnectionAppAccessMode =
133
+ | "all-apps"
134
+ | "allowed-app"
135
+ | "explicit-grant"
136
+ | "unavailable";
137
+
138
+ export interface WorkspaceConnectionAppAccess {
139
+ appId: string;
140
+ available: boolean;
141
+ mode: WorkspaceConnectionAppAccessMode;
142
+ reason: string;
143
+ grantId: string | null;
144
+ }
145
+
146
+ export type WorkspaceConnectionGrantState =
147
+ | "connected"
148
+ | "granted"
149
+ | "needs_grant"
150
+ | "not_connected";
151
+
152
+ export type WorkspaceConnectionGrantAvailability =
153
+ | "available"
154
+ | "needs_grant"
155
+ | "not_connected";
156
+
157
+ export type WorkspaceConnectionProviderReadinessStatus =
158
+ | "ready"
159
+ | "checking"
160
+ | "needs_credentials"
161
+ | "needs_attention"
162
+ | "disabled"
163
+ | "not_configured";
164
+
165
+ export interface WorkspaceConnectionPublicCredentialRef {
166
+ key: string;
167
+ scope?: string;
168
+ provider?: string;
169
+ label?: string;
170
+ source: "connection" | "grant";
171
+ }
172
+
173
+ export interface WorkspaceConnectionExplicitGrantSummary {
174
+ id: string;
175
+ appId: string;
176
+ scopes: string[];
177
+ credentialRefs: WorkspaceConnectionPublicCredentialRef[];
178
+ updatedAt: string;
179
+ lastUsedAt: string | null;
180
+ }
181
+
182
+ export interface WorkspaceConnectionForAppSummary {
183
+ id: string;
184
+ label: string;
185
+ provider: string;
186
+ accountId: string | null;
187
+ accountLabel: string | null;
188
+ status: WorkspaceConnectionStatus;
189
+ grantedToApp: boolean;
190
+ grantScope: "all-apps" | "selected-apps";
191
+ appAccess: WorkspaceConnectionAppAccess;
192
+ allowedApps: string[];
193
+ credentialRefs: WorkspaceConnectionPublicCredentialRef[];
194
+ lastUsedAt: string | null;
195
+ lastCheckedAt: string | null;
196
+ lastError: string | null;
197
+ explicitGrant: WorkspaceConnectionExplicitGrantSummary | null;
198
+ }
199
+
200
+ export interface WorkspaceConnectionForApp extends SerializedWorkspaceConnection {
201
+ appAccess: WorkspaceConnectionAppAccess;
202
+ explicitGrant: SerializedWorkspaceConnectionGrant | null;
203
+ }
204
+
205
+ export interface ResolvedWorkspaceConnectionForApp {
206
+ available: boolean;
207
+ connection: WorkspaceConnectionForApp | null;
208
+ appAccess: WorkspaceConnectionAppAccess | null;
209
+ reason: string;
210
+ }
211
+
212
+ export interface WorkspaceConnectionProviderAppSummary {
213
+ appId: string;
214
+ provider: string;
215
+ grantState: WorkspaceConnectionGrantState;
216
+ grantAvailability: WorkspaceConnectionGrantAvailability;
217
+ grantAvailabilityMessage: string;
218
+ connectionCount: number;
219
+ grantedConnectionCount: number;
220
+ activeConnectionCount: number;
221
+ ungrantedConnectionCount: number;
222
+ unhealthyGrantedConnectionCount: number;
223
+ explicitGrantCount: number;
224
+ credentialRefCount: number;
225
+ hasWorkspaceConnection: boolean;
226
+ hasGrantedWorkspaceConnection: boolean;
227
+ hasActiveWorkspaceConnection: boolean;
228
+ lastUsedAt: string | null;
229
+ statuses: WorkspaceConnectionStatus[];
230
+ connections: WorkspaceConnectionForAppSummary[];
231
+ }
232
+
233
+ export interface WorkspaceConnectionProviderReadiness {
234
+ status: WorkspaceConnectionProviderReadinessStatus;
235
+ connectionCount: number;
236
+ activeConnectionCount: number;
237
+ readyConnectionCount: number;
238
+ requiredCredentialKeys: string[];
239
+ missingRequiredCredentialKeys: string[];
240
+ appGrant: WorkspaceConnectionProviderAppSummary | null;
241
+ }
242
+
243
+ export interface WorkspaceConnectionProviderLike {
244
+ id: string;
245
+ label?: string;
246
+ credentialKeys?: readonly {
247
+ key: string;
248
+ required?: boolean;
249
+ }[];
250
+ }
251
+
252
+ export interface SummarizeWorkspaceConnectionProviderForAppOptions {
253
+ providerId: string;
254
+ appId: string;
255
+ connections: SerializedWorkspaceConnection[];
256
+ grants?: SerializedWorkspaceConnectionGrant[];
257
+ includeConnections?: "all" | "granted";
258
+ }
259
+
260
+ export interface SummarizeWorkspaceConnectionProviderReadinessOptions {
261
+ provider: WorkspaceConnectionProviderLike;
262
+ connections: SerializedWorkspaceConnection[];
263
+ grants?: SerializedWorkspaceConnectionGrant[];
264
+ appId?: string;
265
+ includeConnections?: "all" | "granted";
266
+ }
267
+
268
+ export interface ListWorkspaceConnectionProviderCatalogForAppOptions {
269
+ appId: string;
270
+ provider?: string;
271
+ capability?: WorkspaceConnectionCapability;
272
+ templateUse?: WorkspaceConnectionTemplateUse;
273
+ includeDisabled?: boolean;
274
+ includeConnections?: "all" | "granted";
275
+ }
276
+
277
+ export interface MarkWorkspaceConnectionUsedOptions {
278
+ connectionId: string;
279
+ appId?: string | null;
280
+ usedAt?: Date | number | string | null;
281
+ }
282
+
283
+ export interface MarkWorkspaceConnectionUsedResult {
284
+ connectionUpdated: boolean;
285
+ grantUpdated: boolean;
286
+ lastUsedAt: string;
287
+ }
288
+
289
+ export interface WorkspaceConnectionProviderCatalogForAppItem extends WorkspaceConnectionProvider {
290
+ workspaceConnection: WorkspaceConnectionProviderAppSummary;
291
+ readiness: WorkspaceConnectionProviderReadiness;
292
+ }
293
+
294
+ export interface WorkspaceConnectionProviderCatalogForApp {
295
+ appId: string;
296
+ providers: WorkspaceConnectionProviderCatalogForAppItem[];
297
+ connections: SerializedWorkspaceConnection[];
298
+ grants: SerializedWorkspaceConnectionGrant[];
299
+ counts: {
300
+ providers: number;
301
+ connections: number;
302
+ grants: number;
303
+ readyProviders: number;
304
+ };
305
+ }
306
+
307
+ let _initPromise: Promise<void> | undefined;
308
+
309
+ function workspaceConnectionsTable(): string {
310
+ return isPostgres()
311
+ ? "public.workspace_connections"
312
+ : "workspace_connections";
313
+ }
314
+
315
+ function workspaceConnectionGrantsTable(): string {
316
+ return isPostgres()
317
+ ? "public.workspace_connection_grants"
318
+ : "workspace_connection_grants";
319
+ }
320
+
321
+ function isDuplicateColumnError(err: unknown): boolean {
322
+ const code = String((err as { code?: unknown })?.code ?? "");
323
+ const message = String((err as { message?: unknown })?.message ?? err)
324
+ .toLowerCase()
325
+ .trim();
326
+ return (
327
+ code === "42701" ||
328
+ message.includes("duplicate column") ||
329
+ message.includes("already exists")
330
+ );
331
+ }
332
+
333
+ async function ensureColumn(
334
+ client: DbExec,
335
+ table: string,
336
+ name: string,
337
+ definition: string,
338
+ ): Promise<void> {
339
+ try {
340
+ await retryOnDdlRace(() =>
341
+ client.execute(
342
+ isPostgres()
343
+ ? `ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS ${name} ${definition}`
344
+ : `ALTER TABLE ${table} ADD COLUMN ${name} ${definition}`,
345
+ ),
346
+ );
347
+ } catch (err) {
348
+ if (!isDuplicateColumnError(err)) throw err;
349
+ }
350
+ }
351
+
352
+ async function ensureWorkspaceConnectionColumns(
353
+ client: DbExec,
354
+ table: string,
355
+ ): Promise<void> {
356
+ await ensureColumn(client, table, "provider", "TEXT NOT NULL DEFAULT ''");
357
+ await ensureColumn(client, table, "label", "TEXT NOT NULL DEFAULT ''");
358
+ await ensureColumn(client, table, "account_id", "TEXT");
359
+ await ensureColumn(client, table, "account_label", "TEXT");
360
+ await ensureColumn(
361
+ client,
362
+ table,
363
+ "status",
364
+ "TEXT NOT NULL DEFAULT 'connected'",
365
+ );
366
+ await ensureColumn(
367
+ client,
368
+ table,
369
+ "scopes_json",
370
+ "TEXT NOT NULL DEFAULT '[]'",
371
+ );
372
+ await ensureColumn(
373
+ client,
374
+ table,
375
+ "config_json",
376
+ "TEXT NOT NULL DEFAULT '{}'",
377
+ );
378
+ await ensureColumn(
379
+ client,
380
+ table,
381
+ "allowed_apps_json",
382
+ "TEXT NOT NULL DEFAULT '[]'",
383
+ );
384
+ await ensureColumn(
385
+ client,
386
+ table,
387
+ "credential_refs_json",
388
+ "TEXT NOT NULL DEFAULT '[]'",
389
+ );
390
+ await ensureColumn(client, table, "owner_email", "TEXT NOT NULL DEFAULT ''");
391
+ await ensureColumn(client, table, "org_id", "TEXT");
392
+ await ensureColumn(
393
+ client,
394
+ table,
395
+ "created_at",
396
+ `${intType()} NOT NULL DEFAULT 0`,
397
+ );
398
+ await ensureColumn(
399
+ client,
400
+ table,
401
+ "updated_at",
402
+ `${intType()} NOT NULL DEFAULT 0`,
403
+ );
404
+ await ensureColumn(client, table, "last_checked_at", intType());
405
+ await ensureColumn(client, table, "last_used_at", intType());
406
+ await ensureColumn(client, table, "last_error", "TEXT");
407
+ }
408
+
409
+ async function ensureWorkspaceConnectionGrantColumns(
410
+ client: DbExec,
411
+ table: string,
412
+ ): Promise<void> {
413
+ await ensureColumn(
414
+ client,
415
+ table,
416
+ "connection_id",
417
+ "TEXT NOT NULL DEFAULT ''",
418
+ );
419
+ await ensureColumn(client, table, "provider", "TEXT NOT NULL DEFAULT ''");
420
+ await ensureColumn(client, table, "app_id", "TEXT NOT NULL DEFAULT ''");
421
+ await ensureColumn(
422
+ client,
423
+ table,
424
+ "scopes_json",
425
+ "TEXT NOT NULL DEFAULT '[]'",
426
+ );
427
+ await ensureColumn(
428
+ client,
429
+ table,
430
+ "config_json",
431
+ "TEXT NOT NULL DEFAULT '{}'",
432
+ );
433
+ await ensureColumn(
434
+ client,
435
+ table,
436
+ "credential_refs_json",
437
+ "TEXT NOT NULL DEFAULT '[]'",
438
+ );
439
+ await ensureColumn(
440
+ client,
441
+ table,
442
+ "granted_by_email",
443
+ "TEXT NOT NULL DEFAULT ''",
444
+ );
445
+ await ensureColumn(client, table, "owner_email", "TEXT NOT NULL DEFAULT ''");
446
+ await ensureColumn(client, table, "org_id", "TEXT");
447
+ await ensureColumn(
448
+ client,
449
+ table,
450
+ "created_at",
451
+ `${intType()} NOT NULL DEFAULT 0`,
452
+ );
453
+ await ensureColumn(
454
+ client,
455
+ table,
456
+ "updated_at",
457
+ `${intType()} NOT NULL DEFAULT 0`,
458
+ );
459
+ await ensureColumn(client, table, "last_used_at", intType());
460
+ }
461
+
462
+ export async function ensureWorkspaceConnectionsTable(): Promise<void> {
463
+ if (!_initPromise) {
464
+ _initPromise = (async () => {
465
+ const client = getDbExec();
466
+ const table = workspaceConnectionsTable();
467
+ const grantsTable = workspaceConnectionGrantsTable();
468
+
469
+ const createConnectionsSql = `
470
+ CREATE TABLE IF NOT EXISTS ${table} (
471
+ id TEXT PRIMARY KEY,
472
+ provider TEXT NOT NULL DEFAULT '',
473
+ label TEXT NOT NULL DEFAULT '',
474
+ account_id TEXT,
475
+ account_label TEXT,
476
+ status TEXT NOT NULL DEFAULT 'connected',
477
+ scopes_json TEXT NOT NULL DEFAULT '[]',
478
+ config_json TEXT NOT NULL DEFAULT '{}',
479
+ allowed_apps_json TEXT NOT NULL DEFAULT '[]',
480
+ credential_refs_json TEXT NOT NULL DEFAULT '[]',
481
+ owner_email TEXT NOT NULL DEFAULT '',
482
+ org_id TEXT,
483
+ created_at ${intType()} NOT NULL DEFAULT 0,
484
+ updated_at ${intType()} NOT NULL DEFAULT 0,
485
+ last_used_at ${intType()},
486
+ last_checked_at ${intType()},
487
+ last_error TEXT
488
+ )
489
+ `;
490
+ const createGrantsSql = `
491
+ CREATE TABLE IF NOT EXISTS ${grantsTable} (
492
+ id TEXT PRIMARY KEY,
493
+ connection_id TEXT NOT NULL DEFAULT '',
494
+ provider TEXT NOT NULL DEFAULT '',
495
+ app_id TEXT NOT NULL DEFAULT '',
496
+ scopes_json TEXT NOT NULL DEFAULT '[]',
497
+ config_json TEXT NOT NULL DEFAULT '{}',
498
+ credential_refs_json TEXT NOT NULL DEFAULT '[]',
499
+ granted_by_email TEXT NOT NULL DEFAULT '',
500
+ owner_email TEXT NOT NULL DEFAULT '',
501
+ org_id TEXT,
502
+ created_at ${intType()} NOT NULL DEFAULT 0,
503
+ updated_at ${intType()} NOT NULL DEFAULT 0,
504
+ last_used_at ${intType()}
505
+ )
506
+ `;
507
+
508
+ if (isPostgres()) {
509
+ // PG-guard: probe information_schema / pg_indexes first (no lock) and
510
+ // only issue DDL when the table/column/index is actually missing,
511
+ // wrapped in a transaction-scoped lock_timeout so a contended lock
512
+ // fails fast. Uses unqualified table names for the probe (the helpers
513
+ // always search the `public` schema).
514
+
515
+ // --- workspace_connections ---
516
+ await ensureTableExists("workspace_connections", createConnectionsSql);
517
+ await ensureColumnExists(
518
+ "workspace_connections",
519
+ "provider",
520
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS provider TEXT NOT NULL DEFAULT ''`,
521
+ );
522
+ await ensureColumnExists(
523
+ "workspace_connections",
524
+ "label",
525
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS label TEXT NOT NULL DEFAULT ''`,
526
+ );
527
+ await ensureColumnExists(
528
+ "workspace_connections",
529
+ "account_id",
530
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS account_id TEXT`,
531
+ );
532
+ await ensureColumnExists(
533
+ "workspace_connections",
534
+ "account_label",
535
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS account_label TEXT`,
536
+ );
537
+ await ensureColumnExists(
538
+ "workspace_connections",
539
+ "status",
540
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'connected'`,
541
+ );
542
+ await ensureColumnExists(
543
+ "workspace_connections",
544
+ "scopes_json",
545
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS scopes_json TEXT NOT NULL DEFAULT '[]'`,
546
+ );
547
+ await ensureColumnExists(
548
+ "workspace_connections",
549
+ "config_json",
550
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS config_json TEXT NOT NULL DEFAULT '{}'`,
551
+ );
552
+ await ensureColumnExists(
553
+ "workspace_connections",
554
+ "allowed_apps_json",
555
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS allowed_apps_json TEXT NOT NULL DEFAULT '[]'`,
556
+ );
557
+ await ensureColumnExists(
558
+ "workspace_connections",
559
+ "credential_refs_json",
560
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS credential_refs_json TEXT NOT NULL DEFAULT '[]'`,
561
+ );
562
+ await ensureColumnExists(
563
+ "workspace_connections",
564
+ "owner_email",
565
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS owner_email TEXT NOT NULL DEFAULT ''`,
566
+ );
567
+ await ensureColumnExists(
568
+ "workspace_connections",
569
+ "org_id",
570
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS org_id TEXT`,
571
+ );
572
+ await ensureColumnExists(
573
+ "workspace_connections",
574
+ "created_at",
575
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS created_at ${intType()} NOT NULL DEFAULT 0`,
576
+ );
577
+ await ensureColumnExists(
578
+ "workspace_connections",
579
+ "updated_at",
580
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS updated_at ${intType()} NOT NULL DEFAULT 0`,
581
+ );
582
+ await ensureColumnExists(
583
+ "workspace_connections",
584
+ "last_checked_at",
585
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS last_checked_at ${intType()}`,
586
+ );
587
+ await ensureColumnExists(
588
+ "workspace_connections",
589
+ "last_used_at",
590
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS last_used_at ${intType()}`,
591
+ );
592
+ await ensureColumnExists(
593
+ "workspace_connections",
594
+ "last_error",
595
+ `ALTER TABLE workspace_connections ADD COLUMN IF NOT EXISTS last_error TEXT`,
596
+ );
597
+ await ensureIndexExists(
598
+ "idx_workspace_connections_scope_provider",
599
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connections_scope_provider ON ${table} (org_id, owner_email, provider)`,
600
+ );
601
+ await ensureIndexExists(
602
+ "idx_workspace_connections_updated_at",
603
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connections_updated_at ON ${table} (updated_at)`,
604
+ );
605
+
606
+ // --- workspace_connection_grants ---
607
+ await ensureTableExists("workspace_connection_grants", createGrantsSql);
608
+ await ensureColumnExists(
609
+ "workspace_connection_grants",
610
+ "connection_id",
611
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS connection_id TEXT NOT NULL DEFAULT ''`,
612
+ );
613
+ await ensureColumnExists(
614
+ "workspace_connection_grants",
615
+ "provider",
616
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS provider TEXT NOT NULL DEFAULT ''`,
617
+ );
618
+ await ensureColumnExists(
619
+ "workspace_connection_grants",
620
+ "app_id",
621
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS app_id TEXT NOT NULL DEFAULT ''`,
622
+ );
623
+ await ensureColumnExists(
624
+ "workspace_connection_grants",
625
+ "scopes_json",
626
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS scopes_json TEXT NOT NULL DEFAULT '[]'`,
627
+ );
628
+ await ensureColumnExists(
629
+ "workspace_connection_grants",
630
+ "config_json",
631
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS config_json TEXT NOT NULL DEFAULT '{}'`,
632
+ );
633
+ await ensureColumnExists(
634
+ "workspace_connection_grants",
635
+ "credential_refs_json",
636
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS credential_refs_json TEXT NOT NULL DEFAULT '[]'`,
637
+ );
638
+ await ensureColumnExists(
639
+ "workspace_connection_grants",
640
+ "granted_by_email",
641
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS granted_by_email TEXT NOT NULL DEFAULT ''`,
642
+ );
643
+ await ensureColumnExists(
644
+ "workspace_connection_grants",
645
+ "owner_email",
646
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS owner_email TEXT NOT NULL DEFAULT ''`,
647
+ );
648
+ await ensureColumnExists(
649
+ "workspace_connection_grants",
650
+ "org_id",
651
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS org_id TEXT`,
652
+ );
653
+ await ensureColumnExists(
654
+ "workspace_connection_grants",
655
+ "created_at",
656
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS created_at ${intType()} NOT NULL DEFAULT 0`,
657
+ );
658
+ await ensureColumnExists(
659
+ "workspace_connection_grants",
660
+ "updated_at",
661
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS updated_at ${intType()} NOT NULL DEFAULT 0`,
662
+ );
663
+ await ensureColumnExists(
664
+ "workspace_connection_grants",
665
+ "last_used_at",
666
+ `ALTER TABLE workspace_connection_grants ADD COLUMN IF NOT EXISTS last_used_at ${intType()}`,
667
+ );
668
+ await ensureIndexExists(
669
+ "idx_workspace_connection_grants_connection_app",
670
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_connection_grants_connection_app ON ${grantsTable} (connection_id, app_id)`,
671
+ );
672
+ await ensureIndexExists(
673
+ "idx_workspace_connection_grants_scope_app",
674
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connection_grants_scope_app ON ${grantsTable} (org_id, owner_email, app_id)`,
675
+ );
676
+ await ensureIndexExists(
677
+ "idx_workspace_connection_grants_updated_at",
678
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connection_grants_updated_at ON ${grantsTable} (updated_at)`,
679
+ );
680
+ return;
681
+ }
682
+
683
+ // SQLite (local dev): no ACCESS EXCLUSIVE lock problem — keep existing
684
+ // retryOnDdlRace + ensureColumn behaviour.
685
+ await retryOnDdlRace(() => client.execute(createConnectionsSql));
686
+ await ensureWorkspaceConnectionColumns(client, table);
687
+ await retryOnDdlRace(() =>
688
+ client.execute(
689
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connections_scope_provider ON ${table} (org_id, owner_email, provider)`,
690
+ ),
691
+ );
692
+ await retryOnDdlRace(() =>
693
+ client.execute(
694
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connections_updated_at ON ${table} (updated_at)`,
695
+ ),
696
+ );
697
+ await retryOnDdlRace(() => client.execute(createGrantsSql));
698
+ await ensureWorkspaceConnectionGrantColumns(client, grantsTable);
699
+ await retryOnDdlRace(() =>
700
+ client.execute(
701
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_connection_grants_connection_app ON ${grantsTable} (connection_id, app_id)`,
702
+ ),
703
+ );
704
+ await retryOnDdlRace(() =>
705
+ client.execute(
706
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connection_grants_scope_app ON ${grantsTable} (org_id, owner_email, app_id)`,
707
+ ),
708
+ );
709
+ await retryOnDdlRace(() =>
710
+ client.execute(
711
+ `CREATE INDEX IF NOT EXISTS idx_workspace_connection_grants_updated_at ON ${grantsTable} (updated_at)`,
712
+ ),
713
+ );
714
+ })().catch((err) => {
715
+ _initPromise = undefined;
716
+ throw err;
717
+ });
718
+ }
719
+ return _initPromise;
720
+ }
721
+
722
+ function requireWorkspaceConnectionScope(): {
723
+ ownerEmail: string;
724
+ orgId: string | null;
725
+ } {
726
+ const ownerEmail = getRequestUserEmail()?.trim().toLowerCase();
727
+ if (!ownerEmail) {
728
+ throw new Error("Workspace connections require an authenticated user.");
729
+ }
730
+ return {
731
+ ownerEmail,
732
+ orgId: getRequestOrgId()?.trim() || null,
733
+ };
734
+ }
735
+
736
+ function scopedWhere(
737
+ scope: ReturnType<typeof requireWorkspaceConnectionScope>,
738
+ ): { sql: string; args: string[] } {
739
+ if (scope.orgId) {
740
+ return { sql: "org_id = ?", args: [scope.orgId] };
741
+ }
742
+ return {
743
+ sql: "owner_email = ? AND org_id IS NULL",
744
+ args: [scope.ownerEmail],
745
+ };
746
+ }
747
+
748
+ function normalizeStringArray(value: unknown): string[] {
749
+ if (!Array.isArray(value)) return [];
750
+ return value
751
+ .filter((entry): entry is string => typeof entry === "string")
752
+ .map((entry) => entry.trim())
753
+ .filter(Boolean);
754
+ }
755
+
756
+ function normalizeRequiredString(value: unknown, label: string): string {
757
+ const normalized = typeof value === "string" ? value.trim() : "";
758
+ if (!normalized) {
759
+ throw new Error(`${label} is required.`);
760
+ }
761
+ return normalized;
762
+ }
763
+
764
+ function normalizeObject(value: unknown): Record<string, unknown> {
765
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
766
+ return value as Record<string, unknown>;
767
+ }
768
+
769
+ function normalizeCredentialRefs(
770
+ value: unknown,
771
+ ): WorkspaceConnectionCredentialRef[] {
772
+ if (!Array.isArray(value)) return [];
773
+ return value
774
+ .filter(
775
+ (entry): entry is WorkspaceConnectionCredentialRef =>
776
+ !!entry &&
777
+ typeof entry === "object" &&
778
+ !Array.isArray(entry) &&
779
+ typeof (entry as WorkspaceConnectionCredentialRef).key === "string",
780
+ )
781
+ .map((entry) => sanitizeCredentialRef(entry))
782
+ .filter((entry) => entry.key.trim().length > 0);
783
+ }
784
+
785
+ function normalizeStatus(value: unknown): WorkspaceConnectionStatus {
786
+ if (
787
+ value === "checking" ||
788
+ value === "needs_reauth" ||
789
+ value === "error" ||
790
+ value === "disabled"
791
+ ) {
792
+ return value;
793
+ }
794
+ return "connected";
795
+ }
796
+
797
+ function millis(
798
+ value: Date | number | string | null | undefined,
799
+ ): number | null {
800
+ if (value == null) return null;
801
+ if (value instanceof Date) return value.getTime();
802
+ if (typeof value === "number" && Number.isFinite(value)) return value;
803
+ const parsed = Date.parse(String(value));
804
+ return Number.isFinite(parsed) ? parsed : null;
805
+ }
806
+
807
+ function iso(value: unknown): string | null {
808
+ if (value == null) return null;
809
+ const num = Number(value);
810
+ if (!Number.isFinite(num) || num <= 0) return null;
811
+ return new Date(num).toISOString();
812
+ }
813
+
814
+ const SECRET_KEYS = new Set([
815
+ "apikey",
816
+ "authorization",
817
+ "clientsecret",
818
+ "cookie",
819
+ "password",
820
+ "privatekey",
821
+ "refreshtoken",
822
+ "secret",
823
+ "token",
824
+ "accesstoken",
825
+ ]);
826
+
827
+ function normalizedKey(key: string): string {
828
+ return key.toLowerCase().replace(/[^a-z0-9]/g, "");
829
+ }
830
+
831
+ function sanitizeJson(value: unknown, allowCredentialRefKey = false): unknown {
832
+ if (Array.isArray(value)) {
833
+ return value.map((entry) => sanitizeJson(entry, allowCredentialRefKey));
834
+ }
835
+ if (!value || typeof value !== "object") return value;
836
+
837
+ const result: Record<string, unknown> = {};
838
+ for (const [key, entry] of Object.entries(value)) {
839
+ const normalized = normalizedKey(key);
840
+ if (
841
+ SECRET_KEYS.has(normalized) &&
842
+ !(allowCredentialRefKey && normalized === "key")
843
+ ) {
844
+ result[key] = "[redacted]";
845
+ continue;
846
+ }
847
+ result[key] = sanitizeJson(entry, allowCredentialRefKey);
848
+ }
849
+ return result;
850
+ }
851
+
852
+ function sanitizeConfig(
853
+ config: Record<string, unknown> | undefined,
854
+ ): Record<string, unknown> {
855
+ return sanitizeJson(normalizeObject(config), false) as Record<
856
+ string,
857
+ unknown
858
+ >;
859
+ }
860
+
861
+ function sanitizeCredentialRef(
862
+ ref: WorkspaceConnectionCredentialRef,
863
+ ): WorkspaceConnectionCredentialRef {
864
+ const sanitized = sanitizeJson(ref, true) as WorkspaceConnectionCredentialRef;
865
+ if (Object.prototype.hasOwnProperty.call(sanitized, "value")) {
866
+ sanitized.value = "[redacted]";
867
+ }
868
+ return sanitized;
869
+ }
870
+
871
+ function parseRow(row: Record<string, unknown>): WorkspaceConnection {
872
+ return serializeWorkspaceConnection({
873
+ id: String(row.id),
874
+ provider: String(row.provider ?? ""),
875
+ label: String(row.label ?? ""),
876
+ accountId: row.account_id == null ? null : String(row.account_id),
877
+ accountLabel: row.account_label == null ? null : String(row.account_label),
878
+ status: normalizeStatus(row.status),
879
+ scopes: normalizeStringArray(safeJsonParse<unknown>(row.scopes_json, [])),
880
+ config: normalizeObject(safeJsonParse<unknown>(row.config_json, {})),
881
+ allowedApps: normalizeStringArray(
882
+ safeJsonParse<unknown>(row.allowed_apps_json, []),
883
+ ),
884
+ credentialRefs: normalizeCredentialRefs(
885
+ safeJsonParse<unknown>(row.credential_refs_json, []),
886
+ ),
887
+ ownerEmail: String(row.owner_email ?? ""),
888
+ orgId: row.org_id == null ? null : String(row.org_id),
889
+ createdAt: iso(row.created_at) ?? new Date(0).toISOString(),
890
+ updatedAt: iso(row.updated_at) ?? new Date(0).toISOString(),
891
+ lastUsedAt: iso(row.last_used_at),
892
+ lastCheckedAt: iso(row.last_checked_at),
893
+ lastError: row.last_error == null ? null : String(row.last_error),
894
+ });
895
+ }
896
+
897
+ function parseGrantRow(row: Record<string, unknown>): WorkspaceConnectionGrant {
898
+ return serializeWorkspaceConnectionGrant({
899
+ id: String(row.id),
900
+ connectionId: String(row.connection_id ?? ""),
901
+ provider: String(row.provider ?? ""),
902
+ appId: String(row.app_id ?? ""),
903
+ scopes: normalizeStringArray(safeJsonParse<unknown>(row.scopes_json, [])),
904
+ config: normalizeObject(safeJsonParse<unknown>(row.config_json, {})),
905
+ credentialRefs: normalizeCredentialRefs(
906
+ safeJsonParse<unknown>(row.credential_refs_json, []),
907
+ ),
908
+ grantedByEmail: String(row.granted_by_email ?? ""),
909
+ ownerEmail: String(row.owner_email ?? ""),
910
+ orgId: row.org_id == null ? null : String(row.org_id),
911
+ createdAt: iso(row.created_at) ?? new Date(0).toISOString(),
912
+ updatedAt: iso(row.updated_at) ?? new Date(0).toISOString(),
913
+ lastUsedAt: iso(row.last_used_at),
914
+ });
915
+ }
916
+
917
+ export function serializeWorkspaceConnection(
918
+ connection: WorkspaceConnection,
919
+ ): SerializedWorkspaceConnection {
920
+ return {
921
+ ...connection,
922
+ scopes: normalizeStringArray(connection.scopes),
923
+ config: sanitizeConfig(connection.config),
924
+ allowedApps: normalizeStringArray(connection.allowedApps),
925
+ credentialRefs: normalizeCredentialRefs(connection.credentialRefs),
926
+ };
927
+ }
928
+
929
+ export function serializeWorkspaceConnectionGrant(
930
+ grant: WorkspaceConnectionGrant,
931
+ ): SerializedWorkspaceConnectionGrant {
932
+ return {
933
+ ...grant,
934
+ scopes: normalizeStringArray(grant.scopes),
935
+ config: sanitizeConfig(grant.config),
936
+ credentialRefs: normalizeCredentialRefs(grant.credentialRefs),
937
+ };
938
+ }
939
+
940
+ export function getWorkspaceConnectionAppAccess(
941
+ connection: Pick<
942
+ SerializedWorkspaceConnection,
943
+ "id" | "allowedApps" | "label"
944
+ >,
945
+ appId: string,
946
+ grants: Pick<
947
+ SerializedWorkspaceConnectionGrant,
948
+ "id" | "connectionId" | "appId"
949
+ >[] = [],
950
+ ): WorkspaceConnectionAppAccess {
951
+ const normalizedAppId = appId.trim();
952
+ if (!normalizedAppId) {
953
+ return {
954
+ appId: normalizedAppId,
955
+ available: false,
956
+ mode: "unavailable",
957
+ reason: "No app id was provided.",
958
+ grantId: null,
959
+ };
960
+ }
961
+
962
+ if (connection.allowedApps.length === 0) {
963
+ return {
964
+ appId: normalizedAppId,
965
+ available: true,
966
+ mode: "all-apps",
967
+ reason: "Connection is available to every app in the workspace.",
968
+ grantId: null,
969
+ };
970
+ }
971
+
972
+ if (connection.allowedApps.includes(normalizedAppId)) {
973
+ return {
974
+ appId: normalizedAppId,
975
+ available: true,
976
+ mode: "allowed-app",
977
+ reason: `Connection is directly allowed for ${normalizedAppId}.`,
978
+ grantId: null,
979
+ };
980
+ }
981
+
982
+ const explicitGrant = grants.find(
983
+ (grant) =>
984
+ grant.connectionId === connection.id && grant.appId === normalizedAppId,
985
+ );
986
+ if (explicitGrant) {
987
+ return {
988
+ appId: normalizedAppId,
989
+ available: true,
990
+ mode: "explicit-grant",
991
+ reason: `Connection has an explicit grant for ${normalizedAppId}.`,
992
+ grantId: explicitGrant.id,
993
+ };
994
+ }
995
+
996
+ return {
997
+ appId: normalizedAppId,
998
+ available: false,
999
+ mode: "unavailable",
1000
+ reason: `Grant ${normalizedAppId} access before this connection can be reused by the app.`,
1001
+ grantId: null,
1002
+ };
1003
+ }
1004
+
1005
+ export function workspaceConnectionIsAvailableToApp(
1006
+ connection: Pick<
1007
+ SerializedWorkspaceConnection,
1008
+ "id" | "allowedApps" | "label"
1009
+ >,
1010
+ appId: string,
1011
+ grants: Pick<
1012
+ SerializedWorkspaceConnectionGrant,
1013
+ "id" | "connectionId" | "appId"
1014
+ >[] = [],
1015
+ ): boolean {
1016
+ return getWorkspaceConnectionAppAccess(connection, appId, grants).available;
1017
+ }
1018
+
1019
+ function uniqueStrings(values: string[]): string[] {
1020
+ return Array.from(
1021
+ new Set(values.map((value) => value.trim()).filter(Boolean)),
1022
+ );
1023
+ }
1024
+
1025
+ function latestIso(values: Array<string | null | undefined>): string | null {
1026
+ const latest = values.reduce<number | null>((current, value) => {
1027
+ const parsed = value ? Date.parse(value) : NaN;
1028
+ if (!Number.isFinite(parsed)) return current;
1029
+ return current == null || parsed > current ? parsed : current;
1030
+ }, null);
1031
+ return latest == null ? null : new Date(latest).toISOString();
1032
+ }
1033
+
1034
+ function publicCredentialRefs(
1035
+ refs: WorkspaceConnectionCredentialRef[],
1036
+ source: WorkspaceConnectionPublicCredentialRef["source"],
1037
+ ): WorkspaceConnectionPublicCredentialRef[] {
1038
+ return refs.map((ref) => ({
1039
+ key: ref.key,
1040
+ scope: ref.scope,
1041
+ provider: ref.provider,
1042
+ label: ref.label,
1043
+ source,
1044
+ }));
1045
+ }
1046
+
1047
+ function grantsForConnection(
1048
+ connectionId: string,
1049
+ grants: SerializedWorkspaceConnectionGrant[],
1050
+ appId?: string,
1051
+ ): SerializedWorkspaceConnectionGrant[] {
1052
+ return grants.filter(
1053
+ (grant) =>
1054
+ grant.connectionId === connectionId && (!appId || grant.appId === appId),
1055
+ );
1056
+ }
1057
+
1058
+ function explicitGrantForConnection(
1059
+ connectionId: string,
1060
+ grants: SerializedWorkspaceConnectionGrant[],
1061
+ appId?: string,
1062
+ ): SerializedWorkspaceConnectionGrant | undefined {
1063
+ return grantsForConnection(connectionId, grants, appId)[0];
1064
+ }
1065
+
1066
+ function connectionForApp(
1067
+ connection: SerializedWorkspaceConnection,
1068
+ appId: string,
1069
+ grants: SerializedWorkspaceConnectionGrant[],
1070
+ ): WorkspaceConnectionForApp {
1071
+ const normalizedAppId = appId.trim();
1072
+ const appAccess = getWorkspaceConnectionAppAccess(
1073
+ connection,
1074
+ normalizedAppId,
1075
+ grants,
1076
+ );
1077
+ return {
1078
+ ...connection,
1079
+ appAccess,
1080
+ explicitGrant:
1081
+ explicitGrantForConnection(connection.id, grants, normalizedAppId) ??
1082
+ null,
1083
+ };
1084
+ }
1085
+
1086
+ function serializeConnectionForApp(
1087
+ connection: SerializedWorkspaceConnection,
1088
+ appId: string,
1089
+ grants: SerializedWorkspaceConnectionGrant[],
1090
+ ): WorkspaceConnectionForAppSummary {
1091
+ const explicitGrant = explicitGrantForConnection(
1092
+ connection.id,
1093
+ grants,
1094
+ appId,
1095
+ );
1096
+ const appAccess = getWorkspaceConnectionAppAccess(connection, appId, grants);
1097
+ return {
1098
+ id: connection.id,
1099
+ label: connection.label,
1100
+ provider: connection.provider,
1101
+ accountId: connection.accountId,
1102
+ accountLabel: connection.accountLabel,
1103
+ status: connection.status,
1104
+ grantedToApp: appAccess.available,
1105
+ grantScope:
1106
+ connection.allowedApps.length === 0 ? "all-apps" : "selected-apps",
1107
+ appAccess,
1108
+ allowedApps: connection.allowedApps,
1109
+ credentialRefs: publicCredentialRefs(
1110
+ connection.credentialRefs,
1111
+ "connection",
1112
+ ),
1113
+ lastUsedAt: latestIso([connection.lastUsedAt, explicitGrant?.lastUsedAt]),
1114
+ lastCheckedAt: connection.lastCheckedAt,
1115
+ lastError: connection.lastError,
1116
+ explicitGrant: explicitGrant
1117
+ ? {
1118
+ id: explicitGrant.id,
1119
+ appId: explicitGrant.appId,
1120
+ scopes: explicitGrant.scopes,
1121
+ credentialRefs: publicCredentialRefs(
1122
+ explicitGrant.credentialRefs,
1123
+ "grant",
1124
+ ),
1125
+ updatedAt: explicitGrant.updatedAt,
1126
+ lastUsedAt: explicitGrant.lastUsedAt ?? null,
1127
+ }
1128
+ : null,
1129
+ };
1130
+ }
1131
+
1132
+ function grantAvailabilityMessage(
1133
+ grantState: WorkspaceConnectionGrantState,
1134
+ providerId: string,
1135
+ appId: string,
1136
+ ): string {
1137
+ switch (grantState) {
1138
+ case "connected":
1139
+ return `${appId} has an active ${providerId} workspace connection.`;
1140
+ case "granted":
1141
+ return `${appId} has ${providerId} access, but the granted connection is not connected yet.`;
1142
+ case "needs_grant":
1143
+ return `A ${providerId} workspace connection exists; grant ${appId} access to reuse it.`;
1144
+ case "not_connected":
1145
+ default:
1146
+ return `No shared ${providerId} workspace connection is available yet.`;
1147
+ }
1148
+ }
1149
+
1150
+ export function summarizeWorkspaceConnectionProviderForApp({
1151
+ providerId,
1152
+ appId,
1153
+ connections,
1154
+ grants = [],
1155
+ includeConnections = "granted",
1156
+ }: SummarizeWorkspaceConnectionProviderForAppOptions): WorkspaceConnectionProviderAppSummary {
1157
+ const normalizedProviderId = providerId.trim();
1158
+ const normalizedAppId = appId.trim();
1159
+ const allConnections = connections.filter(
1160
+ (connection) => connection.provider === normalizedProviderId,
1161
+ );
1162
+ const grantedConnections = allConnections.filter(
1163
+ (connection) =>
1164
+ getWorkspaceConnectionAppAccess(connection, normalizedAppId, grants)
1165
+ .available,
1166
+ );
1167
+ const connectedConnections = grantedConnections.filter(
1168
+ (connection) => connection.status === "connected",
1169
+ );
1170
+ const ungrantedConnectionCount =
1171
+ allConnections.length - grantedConnections.length;
1172
+ const unhealthyGrantedConnectionCount =
1173
+ grantedConnections.length - connectedConnections.length;
1174
+ const grantState: WorkspaceConnectionGrantState = connectedConnections.length
1175
+ ? "connected"
1176
+ : grantedConnections.length
1177
+ ? "granted"
1178
+ : allConnections.length
1179
+ ? "needs_grant"
1180
+ : "not_connected";
1181
+ const explicitGrantCount = allConnections.reduce(
1182
+ (count, connection) =>
1183
+ explicitGrantForConnection(connection.id, grants, normalizedAppId)
1184
+ ? count + 1
1185
+ : count,
1186
+ 0,
1187
+ );
1188
+ const credentialRefCount = allConnections.reduce((count, connection) => {
1189
+ const explicitGrant = explicitGrantForConnection(
1190
+ connection.id,
1191
+ grants,
1192
+ normalizedAppId,
1193
+ );
1194
+ return (
1195
+ count +
1196
+ connection.credentialRefs.length +
1197
+ (explicitGrant?.credentialRefs.length ?? 0)
1198
+ );
1199
+ }, 0);
1200
+ const visibleConnections =
1201
+ includeConnections === "all" ? allConnections : grantedConnections;
1202
+ const lastUsedAt = latestIso(
1203
+ grantedConnections.flatMap((connection) => [
1204
+ connection.lastUsedAt,
1205
+ explicitGrantForConnection(connection.id, grants, normalizedAppId)
1206
+ ?.lastUsedAt,
1207
+ ]),
1208
+ );
1209
+
1210
+ return {
1211
+ appId: normalizedAppId,
1212
+ provider: normalizedProviderId,
1213
+ grantState,
1214
+ grantAvailability:
1215
+ grantState === "connected" || grantState === "granted"
1216
+ ? "available"
1217
+ : grantState,
1218
+ grantAvailabilityMessage: grantAvailabilityMessage(
1219
+ grantState,
1220
+ normalizedProviderId,
1221
+ normalizedAppId,
1222
+ ),
1223
+ connectionCount: allConnections.length,
1224
+ grantedConnectionCount: grantedConnections.length,
1225
+ activeConnectionCount: connectedConnections.length,
1226
+ ungrantedConnectionCount,
1227
+ unhealthyGrantedConnectionCount,
1228
+ explicitGrantCount,
1229
+ credentialRefCount,
1230
+ hasWorkspaceConnection: allConnections.length > 0,
1231
+ hasGrantedWorkspaceConnection: grantedConnections.length > 0,
1232
+ hasActiveWorkspaceConnection: connectedConnections.length > 0,
1233
+ lastUsedAt,
1234
+ statuses: uniqueStrings(
1235
+ allConnections.map((connection) => connection.status),
1236
+ ) as WorkspaceConnectionStatus[],
1237
+ connections: visibleConnections.map((connection) =>
1238
+ serializeConnectionForApp(connection, normalizedAppId, grants),
1239
+ ),
1240
+ };
1241
+ }
1242
+
1243
+ function requiredCredentialKeys(provider: WorkspaceConnectionProviderLike) {
1244
+ return uniqueStrings(
1245
+ (provider.credentialKeys ?? [])
1246
+ .filter((credential) => credential.required ?? false)
1247
+ .map((credential) => credential.key),
1248
+ );
1249
+ }
1250
+
1251
+ function missingRequiredCredentialKeys(
1252
+ provider: WorkspaceConnectionProviderLike,
1253
+ connection: SerializedWorkspaceConnection,
1254
+ grants: SerializedWorkspaceConnectionGrant[] = [],
1255
+ ): string[] {
1256
+ const available = new Set(
1257
+ [
1258
+ ...connection.credentialRefs,
1259
+ ...grants.flatMap((grant) => grant.credentialRefs),
1260
+ ]
1261
+ .map((ref) => ref.key.trim())
1262
+ .filter(Boolean),
1263
+ );
1264
+ return requiredCredentialKeys(provider).filter((key) => !available.has(key));
1265
+ }
1266
+
1267
+ export function summarizeWorkspaceConnectionProviderReadiness({
1268
+ provider,
1269
+ connections,
1270
+ grants = [],
1271
+ appId,
1272
+ includeConnections,
1273
+ }: SummarizeWorkspaceConnectionProviderReadinessOptions): WorkspaceConnectionProviderReadiness {
1274
+ const providerConnections = connections.filter(
1275
+ (connection) => connection.provider === provider.id,
1276
+ );
1277
+ const activeConnections = providerConnections.filter(
1278
+ (connection) => connection.status !== "disabled",
1279
+ );
1280
+ const attentionConnections = activeConnections.filter(
1281
+ (connection) =>
1282
+ connection.status === "error" ||
1283
+ connection.status === "needs_reauth" ||
1284
+ Boolean(connection.lastError),
1285
+ );
1286
+ const missingKeys = uniqueStrings(
1287
+ activeConnections.flatMap((connection) =>
1288
+ missingRequiredCredentialKeys(
1289
+ provider,
1290
+ connection,
1291
+ grantsForConnection(connection.id, grants, appId),
1292
+ ),
1293
+ ),
1294
+ );
1295
+ const readyConnections = activeConnections.filter(
1296
+ (connection) =>
1297
+ connection.status === "connected" &&
1298
+ missingRequiredCredentialKeys(
1299
+ provider,
1300
+ connection,
1301
+ grantsForConnection(connection.id, grants, appId),
1302
+ ).length === 0,
1303
+ );
1304
+ const checkingConnections = activeConnections.filter(
1305
+ (connection) => connection.status === "checking",
1306
+ );
1307
+
1308
+ let status: WorkspaceConnectionProviderReadinessStatus = "not_configured";
1309
+ if (readyConnections.length > 0) {
1310
+ status = "ready";
1311
+ } else if (attentionConnections.length > 0) {
1312
+ status = "needs_attention";
1313
+ } else if (missingKeys.length > 0) {
1314
+ status = "needs_credentials";
1315
+ } else if (checkingConnections.length > 0) {
1316
+ status = "checking";
1317
+ } else if (providerConnections.length > 0) {
1318
+ status = "disabled";
1319
+ }
1320
+
1321
+ return {
1322
+ status,
1323
+ connectionCount: providerConnections.length,
1324
+ activeConnectionCount: activeConnections.length,
1325
+ readyConnectionCount: readyConnections.length,
1326
+ requiredCredentialKeys: requiredCredentialKeys(provider),
1327
+ missingRequiredCredentialKeys: missingKeys,
1328
+ appGrant: appId
1329
+ ? summarizeWorkspaceConnectionProviderForApp({
1330
+ providerId: provider.id,
1331
+ appId,
1332
+ connections,
1333
+ grants,
1334
+ includeConnections,
1335
+ })
1336
+ : null,
1337
+ };
1338
+ }
1339
+
1340
+ export async function listWorkspaceConnectionProviderCatalogForApp({
1341
+ appId,
1342
+ provider,
1343
+ capability,
1344
+ templateUse,
1345
+ includeDisabled = true,
1346
+ includeConnections = "all",
1347
+ }: ListWorkspaceConnectionProviderCatalogForAppOptions): Promise<WorkspaceConnectionProviderCatalogForApp> {
1348
+ const [connections, grants] = await Promise.all([
1349
+ listWorkspaceConnections({ provider, includeDisabled }),
1350
+ listWorkspaceConnectionGrants({ provider, appId }),
1351
+ ]);
1352
+ const providers = listWorkspaceConnectionProviders({
1353
+ capability,
1354
+ templateUse,
1355
+ })
1356
+ .filter((item) => !provider || item.id === provider)
1357
+ .map((item) => {
1358
+ const workspaceConnection = summarizeWorkspaceConnectionProviderForApp({
1359
+ providerId: item.id,
1360
+ appId,
1361
+ connections,
1362
+ grants,
1363
+ includeConnections,
1364
+ });
1365
+ const readiness = summarizeWorkspaceConnectionProviderReadiness({
1366
+ provider: item,
1367
+ connections,
1368
+ grants,
1369
+ appId,
1370
+ includeConnections,
1371
+ });
1372
+ return {
1373
+ ...item,
1374
+ workspaceConnection,
1375
+ readiness,
1376
+ };
1377
+ });
1378
+
1379
+ return {
1380
+ appId,
1381
+ providers,
1382
+ connections,
1383
+ grants,
1384
+ counts: {
1385
+ providers: providers.length,
1386
+ connections: connections.length,
1387
+ grants: grants.length,
1388
+ readyProviders: providers.filter(
1389
+ (item) => item.readiness.status === "ready",
1390
+ ).length,
1391
+ },
1392
+ };
1393
+ }
1394
+
1395
+ export async function listWorkspaceConnectionsForApp({
1396
+ appId,
1397
+ provider,
1398
+ includeDisabled = false,
1399
+ }: ListWorkspaceConnectionsForAppOptions): Promise<
1400
+ WorkspaceConnectionForApp[]
1401
+ > {
1402
+ const normalizedAppId = normalizeRequiredString(
1403
+ appId,
1404
+ "listWorkspaceConnectionsForApp appId",
1405
+ );
1406
+ const [connections, grants] = await Promise.all([
1407
+ listWorkspaceConnections({ provider, includeDisabled }),
1408
+ listWorkspaceConnectionGrants({ provider, appId: normalizedAppId }),
1409
+ ]);
1410
+
1411
+ return connections
1412
+ .map((connection) => connectionForApp(connection, normalizedAppId, grants))
1413
+ .filter((connection) => connection.appAccess.available);
1414
+ }
1415
+
1416
+ export async function resolveWorkspaceConnectionForApp({
1417
+ appId,
1418
+ provider,
1419
+ includeDisabled = false,
1420
+ connectionId,
1421
+ requireConnected = false,
1422
+ }: ResolveWorkspaceConnectionForAppOptions): Promise<ResolvedWorkspaceConnectionForApp> {
1423
+ const normalizedAppId = normalizeRequiredString(
1424
+ appId,
1425
+ "resolveWorkspaceConnectionForApp appId",
1426
+ );
1427
+ const normalizedConnectionId = connectionId?.trim();
1428
+ const requestedConnections = await listWorkspaceConnections({
1429
+ provider,
1430
+ includeDisabled: includeDisabled || Boolean(normalizedConnectionId),
1431
+ });
1432
+ const candidateConnections = normalizedConnectionId
1433
+ ? requestedConnections.filter(
1434
+ (connection) => connection.id === normalizedConnectionId,
1435
+ )
1436
+ : requestedConnections;
1437
+ const grants = await listWorkspaceConnectionGrants({
1438
+ provider,
1439
+ appId: normalizedAppId,
1440
+ connectionId: normalizedConnectionId,
1441
+ });
1442
+
1443
+ if (normalizedConnectionId && candidateConnections.length === 0) {
1444
+ return {
1445
+ available: false,
1446
+ connection: null,
1447
+ appAccess: null,
1448
+ reason: `Workspace connection "${normalizedConnectionId}" was not found in the current request scope.`,
1449
+ };
1450
+ }
1451
+
1452
+ for (const connection of candidateConnections) {
1453
+ const connectionWithAccess = connectionForApp(
1454
+ connection,
1455
+ normalizedAppId,
1456
+ grants,
1457
+ );
1458
+
1459
+ if (!connectionWithAccess.appAccess.available) {
1460
+ if (normalizedConnectionId) {
1461
+ return {
1462
+ available: false,
1463
+ connection: connectionWithAccess,
1464
+ appAccess: connectionWithAccess.appAccess,
1465
+ reason: connectionWithAccess.appAccess.reason,
1466
+ };
1467
+ }
1468
+ continue;
1469
+ }
1470
+
1471
+ if (!includeDisabled && connection.status === "disabled") {
1472
+ if (normalizedConnectionId) {
1473
+ return {
1474
+ available: false,
1475
+ connection: connectionWithAccess,
1476
+ appAccess: connectionWithAccess.appAccess,
1477
+ reason: `Workspace connection "${connection.id}" is disabled.`,
1478
+ };
1479
+ }
1480
+ continue;
1481
+ }
1482
+
1483
+ if (requireConnected && connection.status !== "connected") {
1484
+ if (normalizedConnectionId) {
1485
+ return {
1486
+ available: false,
1487
+ connection: connectionWithAccess,
1488
+ appAccess: connectionWithAccess.appAccess,
1489
+ reason: `Workspace connection "${connection.id}" is ${connection.status}; a connected workspace connection is required.`,
1490
+ };
1491
+ }
1492
+ continue;
1493
+ }
1494
+
1495
+ return {
1496
+ available: true,
1497
+ connection: connectionWithAccess,
1498
+ appAccess: connectionWithAccess.appAccess,
1499
+ reason: connectionWithAccess.appAccess.reason,
1500
+ };
1501
+ }
1502
+
1503
+ return {
1504
+ available: false,
1505
+ connection: null,
1506
+ appAccess: null,
1507
+ reason: provider
1508
+ ? `No available ${provider} workspace connection was found for ${normalizedAppId}.`
1509
+ : `No available workspace connection was found for ${normalizedAppId}.`,
1510
+ };
1511
+ }
1512
+
1513
+ async function getGrantedConnectionIdsForApp(
1514
+ client: DbExec,
1515
+ scope: ReturnType<typeof requireWorkspaceConnectionScope>,
1516
+ appId: string,
1517
+ ): Promise<Set<string>> {
1518
+ const table = workspaceConnectionGrantsTable();
1519
+ const where = scopedWhere(scope);
1520
+ const { rows } = await client.execute({
1521
+ sql: `SELECT connection_id FROM ${table} WHERE app_id = ? AND ${where.sql}`,
1522
+ args: [appId, ...where.args],
1523
+ });
1524
+ return new Set(
1525
+ rows
1526
+ .map((row) =>
1527
+ String((row as Record<string, unknown>).connection_id ?? ""),
1528
+ )
1529
+ .filter(Boolean),
1530
+ );
1531
+ }
1532
+
1533
+ export async function listWorkspaceConnections(
1534
+ options: ListWorkspaceConnectionsOptions = {},
1535
+ ): Promise<SerializedWorkspaceConnection[]> {
1536
+ await ensureWorkspaceConnectionsTable();
1537
+ const client = getDbExec();
1538
+ const table = workspaceConnectionsTable();
1539
+ const scope = requireWorkspaceConnectionScope();
1540
+ const where = scopedWhere(scope);
1541
+ const clauses = [where.sql];
1542
+ const args: unknown[] = [...where.args];
1543
+ const appId = options.appId?.trim();
1544
+
1545
+ if (options.provider) {
1546
+ clauses.push("provider = ?");
1547
+ args.push(options.provider);
1548
+ }
1549
+ if (!options.includeDisabled) {
1550
+ clauses.push("status != ?");
1551
+ args.push("disabled");
1552
+ }
1553
+
1554
+ const { rows } = await client.execute({
1555
+ sql: `SELECT * FROM ${table} WHERE ${clauses.join(
1556
+ " AND ",
1557
+ )} ORDER BY updated_at DESC`,
1558
+ args,
1559
+ });
1560
+
1561
+ const connections = rows.map((row) =>
1562
+ parseRow(row as Record<string, unknown>),
1563
+ );
1564
+ if (!appId) return connections;
1565
+
1566
+ const grantedConnectionIds = await getGrantedConnectionIdsForApp(
1567
+ client,
1568
+ scope,
1569
+ appId,
1570
+ );
1571
+ return connections.filter(
1572
+ (connection) =>
1573
+ connection.allowedApps.length === 0 ||
1574
+ connection.allowedApps.includes(appId) ||
1575
+ grantedConnectionIds.has(connection.id),
1576
+ );
1577
+ }
1578
+
1579
+ export async function getWorkspaceConnection(
1580
+ id: string,
1581
+ ): Promise<SerializedWorkspaceConnection | null> {
1582
+ await ensureWorkspaceConnectionsTable();
1583
+ const client = getDbExec();
1584
+ const table = workspaceConnectionsTable();
1585
+ const scope = requireWorkspaceConnectionScope();
1586
+ const where = scopedWhere(scope);
1587
+ const { rows } = await client.execute({
1588
+ sql: `SELECT * FROM ${table} WHERE id = ? AND ${where.sql} LIMIT 1`,
1589
+ args: [id, ...where.args],
1590
+ });
1591
+ if (rows.length === 0) return null;
1592
+ return parseRow(rows[0] as Record<string, unknown>);
1593
+ }
1594
+
1595
+ export async function upsertWorkspaceConnection(
1596
+ input: UpsertWorkspaceConnectionInput,
1597
+ ): Promise<SerializedWorkspaceConnection> {
1598
+ await ensureWorkspaceConnectionsTable();
1599
+ const provider = input.provider.trim();
1600
+ if (!provider) {
1601
+ throw new Error("upsertWorkspaceConnection requires a provider.");
1602
+ }
1603
+
1604
+ const client = getDbExec();
1605
+ const table = workspaceConnectionsTable();
1606
+ const scope = requireWorkspaceConnectionScope();
1607
+ const where = scopedWhere(scope);
1608
+ const id = input.id?.trim() || randomUUID();
1609
+ const now = Date.now();
1610
+ const label = input.label?.trim() || input.accountLabel?.trim() || provider;
1611
+ const status = normalizeStatus(input.status);
1612
+ const scopes = normalizeStringArray(input.scopes);
1613
+ const config = sanitizeConfig(input.config);
1614
+ const allowedApps = normalizeStringArray(input.allowedApps);
1615
+ const credentialRefs = normalizeCredentialRefs(input.credentialRefs);
1616
+ const lastCheckedAt = millis(input.lastCheckedAt);
1617
+ const lastError = input.lastError ?? null;
1618
+
1619
+ const update = await client.execute({
1620
+ sql: `UPDATE ${table}
1621
+ SET provider = ?, label = ?, account_id = ?, account_label = ?,
1622
+ status = ?, scopes_json = ?, config_json = ?, allowed_apps_json = ?,
1623
+ credential_refs_json = ?, updated_at = ?, last_checked_at = ?,
1624
+ last_error = ?
1625
+ WHERE id = ? AND ${where.sql}`,
1626
+ args: [
1627
+ provider,
1628
+ label,
1629
+ input.accountId ?? null,
1630
+ input.accountLabel ?? null,
1631
+ status,
1632
+ JSON.stringify(scopes),
1633
+ JSON.stringify(config),
1634
+ JSON.stringify(allowedApps),
1635
+ JSON.stringify(credentialRefs),
1636
+ now,
1637
+ lastCheckedAt,
1638
+ lastError,
1639
+ id,
1640
+ ...where.args,
1641
+ ],
1642
+ });
1643
+
1644
+ if (update.rowsAffected === 0) {
1645
+ try {
1646
+ await client.execute({
1647
+ sql: `INSERT INTO ${table}
1648
+ (id, provider, label, account_id, account_label, status,
1649
+ scopes_json, config_json, allowed_apps_json, credential_refs_json,
1650
+ owner_email, org_id, created_at, updated_at, last_checked_at,
1651
+ last_error)
1652
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1653
+ args: [
1654
+ id,
1655
+ provider,
1656
+ label,
1657
+ input.accountId ?? null,
1658
+ input.accountLabel ?? null,
1659
+ status,
1660
+ JSON.stringify(scopes),
1661
+ JSON.stringify(config),
1662
+ JSON.stringify(allowedApps),
1663
+ JSON.stringify(credentialRefs),
1664
+ scope.ownerEmail,
1665
+ scope.orgId,
1666
+ now,
1667
+ now,
1668
+ lastCheckedAt,
1669
+ lastError,
1670
+ ],
1671
+ });
1672
+ } catch (err) {
1673
+ if (isUniqueViolation(err)) {
1674
+ throw new Error(
1675
+ `Workspace connection "${id}" already exists outside the current request scope.`,
1676
+ );
1677
+ }
1678
+ throw err;
1679
+ }
1680
+ }
1681
+
1682
+ const connection = await getWorkspaceConnection(id);
1683
+ if (!connection) {
1684
+ throw new Error(`Workspace connection "${id}" was not found after upsert.`);
1685
+ }
1686
+ return connection;
1687
+ }
1688
+
1689
+ export async function listWorkspaceConnectionGrants(
1690
+ options: ListWorkspaceConnectionGrantsOptions = {},
1691
+ ): Promise<SerializedWorkspaceConnectionGrant[]> {
1692
+ await ensureWorkspaceConnectionsTable();
1693
+ const client = getDbExec();
1694
+ const table = workspaceConnectionGrantsTable();
1695
+ const scope = requireWorkspaceConnectionScope();
1696
+ const where = scopedWhere(scope);
1697
+ const clauses = [where.sql];
1698
+ const args: unknown[] = [...where.args];
1699
+ const connectionId = options.connectionId?.trim();
1700
+ const appId = options.appId?.trim();
1701
+ const provider = options.provider?.trim();
1702
+
1703
+ if (connectionId) {
1704
+ clauses.push("connection_id = ?");
1705
+ args.push(connectionId);
1706
+ }
1707
+ if (appId) {
1708
+ clauses.push("app_id = ?");
1709
+ args.push(appId);
1710
+ }
1711
+ if (provider) {
1712
+ clauses.push("provider = ?");
1713
+ args.push(provider);
1714
+ }
1715
+
1716
+ const { rows } = await client.execute({
1717
+ sql: `SELECT * FROM ${table} WHERE ${clauses.join(
1718
+ " AND ",
1719
+ )} ORDER BY updated_at DESC`,
1720
+ args,
1721
+ });
1722
+
1723
+ return rows.map((row) => parseGrantRow(row as Record<string, unknown>));
1724
+ }
1725
+
1726
+ export async function getWorkspaceConnectionGrant(
1727
+ connectionId: string,
1728
+ appId: string,
1729
+ ): Promise<SerializedWorkspaceConnectionGrant | null> {
1730
+ await ensureWorkspaceConnectionsTable();
1731
+ const normalizedConnectionId = normalizeRequiredString(
1732
+ connectionId,
1733
+ "getWorkspaceConnectionGrant connectionId",
1734
+ );
1735
+ const normalizedAppId = normalizeRequiredString(
1736
+ appId,
1737
+ "getWorkspaceConnectionGrant appId",
1738
+ );
1739
+ const client = getDbExec();
1740
+ const table = workspaceConnectionGrantsTable();
1741
+ const scope = requireWorkspaceConnectionScope();
1742
+ const where = scopedWhere(scope);
1743
+ const { rows } = await client.execute({
1744
+ sql: `SELECT * FROM ${table} WHERE connection_id = ? AND app_id = ? AND ${where.sql} LIMIT 1`,
1745
+ args: [normalizedConnectionId, normalizedAppId, ...where.args],
1746
+ });
1747
+ if (rows.length === 0) return null;
1748
+ return parseGrantRow(rows[0] as Record<string, unknown>);
1749
+ }
1750
+
1751
+ export async function markWorkspaceConnectionUsed({
1752
+ connectionId,
1753
+ appId,
1754
+ usedAt,
1755
+ }: MarkWorkspaceConnectionUsedOptions): Promise<MarkWorkspaceConnectionUsedResult> {
1756
+ await ensureWorkspaceConnectionsTable();
1757
+ const normalizedConnectionId = normalizeRequiredString(
1758
+ connectionId,
1759
+ "markWorkspaceConnectionUsed connectionId",
1760
+ );
1761
+ const normalizedAppId = appId?.trim();
1762
+ const usedAtMillis = millis(usedAt) ?? Date.now();
1763
+ const client = getDbExec();
1764
+ const connectionsTable = workspaceConnectionsTable();
1765
+ const grantsTable = workspaceConnectionGrantsTable();
1766
+ const scope = requireWorkspaceConnectionScope();
1767
+ const where = scopedWhere(scope);
1768
+
1769
+ const connectionUpdate = await client.execute({
1770
+ sql: `UPDATE ${connectionsTable} SET last_used_at = ? WHERE id = ? AND ${where.sql}`,
1771
+ args: [usedAtMillis, normalizedConnectionId, ...where.args],
1772
+ });
1773
+
1774
+ let grantUpdated = false;
1775
+ if (normalizedAppId) {
1776
+ const grantUpdate = await client.execute({
1777
+ sql: `UPDATE ${grantsTable} SET last_used_at = ? WHERE connection_id = ? AND app_id = ? AND ${where.sql}`,
1778
+ args: [
1779
+ usedAtMillis,
1780
+ normalizedConnectionId,
1781
+ normalizedAppId,
1782
+ ...where.args,
1783
+ ],
1784
+ });
1785
+ grantUpdated = grantUpdate.rowsAffected > 0;
1786
+ }
1787
+
1788
+ return {
1789
+ connectionUpdated: connectionUpdate.rowsAffected > 0,
1790
+ grantUpdated,
1791
+ lastUsedAt: new Date(usedAtMillis).toISOString(),
1792
+ };
1793
+ }
1794
+
1795
+ export async function upsertWorkspaceConnectionGrant(
1796
+ input: UpsertWorkspaceConnectionGrantInput,
1797
+ ): Promise<SerializedWorkspaceConnectionGrant> {
1798
+ await ensureWorkspaceConnectionsTable();
1799
+ const connectionId = normalizeRequiredString(
1800
+ input.connectionId,
1801
+ "upsertWorkspaceConnectionGrant connectionId",
1802
+ );
1803
+ const appId = normalizeRequiredString(
1804
+ input.appId,
1805
+ "upsertWorkspaceConnectionGrant appId",
1806
+ );
1807
+
1808
+ const connection = await getWorkspaceConnection(connectionId);
1809
+ if (!connection) {
1810
+ throw new Error(
1811
+ `Workspace connection "${connectionId}" was not found in the current request scope.`,
1812
+ );
1813
+ }
1814
+
1815
+ const client = getDbExec();
1816
+ const table = workspaceConnectionGrantsTable();
1817
+ const scope = requireWorkspaceConnectionScope();
1818
+ const where = scopedWhere(scope);
1819
+ const id = input.id?.trim() || randomUUID();
1820
+ const now = Date.now();
1821
+ const provider = input.provider?.trim() || connection.provider;
1822
+ const scopes = normalizeStringArray(input.scopes);
1823
+ const config = sanitizeConfig(input.config);
1824
+ const credentialRefs = normalizeCredentialRefs(input.credentialRefs);
1825
+
1826
+ const update = await client.execute({
1827
+ sql: `UPDATE ${table}
1828
+ SET provider = ?, scopes_json = ?, config_json = ?,
1829
+ credential_refs_json = ?, granted_by_email = ?, updated_at = ?
1830
+ WHERE connection_id = ? AND app_id = ? AND ${where.sql}`,
1831
+ args: [
1832
+ provider,
1833
+ JSON.stringify(scopes),
1834
+ JSON.stringify(config),
1835
+ JSON.stringify(credentialRefs),
1836
+ scope.ownerEmail,
1837
+ now,
1838
+ connectionId,
1839
+ appId,
1840
+ ...where.args,
1841
+ ],
1842
+ });
1843
+
1844
+ if (update.rowsAffected === 0) {
1845
+ try {
1846
+ await client.execute({
1847
+ sql: `INSERT INTO ${table}
1848
+ (id, connection_id, provider, app_id, scopes_json, config_json,
1849
+ credential_refs_json, granted_by_email, owner_email, org_id,
1850
+ created_at, updated_at)
1851
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1852
+ args: [
1853
+ id,
1854
+ connectionId,
1855
+ provider,
1856
+ appId,
1857
+ JSON.stringify(scopes),
1858
+ JSON.stringify(config),
1859
+ JSON.stringify(credentialRefs),
1860
+ scope.ownerEmail,
1861
+ scope.ownerEmail,
1862
+ scope.orgId,
1863
+ now,
1864
+ now,
1865
+ ],
1866
+ });
1867
+ } catch (err) {
1868
+ if (isUniqueViolation(err)) {
1869
+ throw new Error(
1870
+ `Workspace connection grant for "${connectionId}" and "${appId}" already exists outside the current request scope.`,
1871
+ );
1872
+ }
1873
+ throw err;
1874
+ }
1875
+ }
1876
+
1877
+ const grant = await getWorkspaceConnectionGrant(connectionId, appId);
1878
+ if (!grant) {
1879
+ throw new Error(
1880
+ `Workspace connection grant for "${connectionId}" and "${appId}" was not found after upsert.`,
1881
+ );
1882
+ }
1883
+ return grant;
1884
+ }
1885
+
1886
+ export async function revokeWorkspaceConnectionGrant(
1887
+ connectionId: string,
1888
+ appId: string,
1889
+ ): Promise<boolean> {
1890
+ await ensureWorkspaceConnectionsTable();
1891
+ const normalizedConnectionId = normalizeRequiredString(
1892
+ connectionId,
1893
+ "revokeWorkspaceConnectionGrant connectionId",
1894
+ );
1895
+ const normalizedAppId = normalizeRequiredString(
1896
+ appId,
1897
+ "revokeWorkspaceConnectionGrant appId",
1898
+ );
1899
+ const client = getDbExec();
1900
+ const table = workspaceConnectionGrantsTable();
1901
+ const scope = requireWorkspaceConnectionScope();
1902
+ const where = scopedWhere(scope);
1903
+ const result = await client.execute({
1904
+ sql: `DELETE FROM ${table} WHERE connection_id = ? AND app_id = ? AND ${where.sql}`,
1905
+ args: [normalizedConnectionId, normalizedAppId, ...where.args],
1906
+ });
1907
+ if (result.rowsAffected > 0) {
1908
+ await notifyWorkspaceConnectionLifecycle({
1909
+ type: "grant-revoked",
1910
+ connectionId: normalizedConnectionId,
1911
+ appId: normalizedAppId,
1912
+ ownerEmail: scope.ownerEmail,
1913
+ orgId: scope.orgId,
1914
+ });
1915
+ }
1916
+ return result.rowsAffected > 0;
1917
+ }
1918
+
1919
+ export async function deleteWorkspaceConnection(id: string): Promise<boolean> {
1920
+ await ensureWorkspaceConnectionsTable();
1921
+ const client = getDbExec();
1922
+ const table = workspaceConnectionsTable();
1923
+ const grantsTable = workspaceConnectionGrantsTable();
1924
+ const scope = requireWorkspaceConnectionScope();
1925
+ const where = scopedWhere(scope);
1926
+ const result = await client.execute({
1927
+ sql: `DELETE FROM ${table} WHERE id = ? AND ${where.sql}`,
1928
+ args: [id, ...where.args],
1929
+ });
1930
+ if (result.rowsAffected > 0) {
1931
+ await client.execute({
1932
+ sql: `DELETE FROM ${grantsTable} WHERE connection_id = ? AND ${where.sql}`,
1933
+ args: [id, ...where.args],
1934
+ });
1935
+ await notifyWorkspaceConnectionLifecycle({
1936
+ type: "connection-deleted",
1937
+ connectionId: id,
1938
+ ownerEmail: scope.ownerEmail,
1939
+ orgId: scope.orgId,
1940
+ });
1941
+ }
1942
+ return result.rowsAffected > 0;
1943
+ }