@agent-native/core 0.92.12 → 0.93.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 (772) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +39 -0
  3. package/corpus/core/docs/content/automation-connectors.mdx +80 -0
  4. package/corpus/core/docs/content/extensions.mdx +8 -0
  5. package/corpus/core/docs/content/locales/ar-SA/extensions.mdx +8 -0
  6. package/corpus/core/docs/content/locales/ar-SA/messaging.mdx +84 -15
  7. package/corpus/core/docs/content/locales/ar-SA/template-clips.mdx +1 -0
  8. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -0
  9. package/corpus/core/docs/content/locales/de-DE/extensions.mdx +10 -0
  10. package/corpus/core/docs/content/locales/de-DE/messaging.mdx +92 -15
  11. package/corpus/core/docs/content/locales/de-DE/template-clips.mdx +1 -0
  12. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -0
  13. package/corpus/core/docs/content/locales/es-ES/extensions.mdx +10 -0
  14. package/corpus/core/docs/content/locales/es-ES/messaging.mdx +91 -15
  15. package/corpus/core/docs/content/locales/es-ES/template-clips.mdx +1 -0
  16. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -0
  17. package/corpus/core/docs/content/locales/fr-FR/extensions.mdx +10 -0
  18. package/corpus/core/docs/content/locales/fr-FR/messaging.mdx +91 -15
  19. package/corpus/core/docs/content/locales/fr-FR/template-clips.mdx +1 -0
  20. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -0
  21. package/corpus/core/docs/content/locales/hi-IN/extensions.mdx +8 -0
  22. package/corpus/core/docs/content/locales/hi-IN/messaging.mdx +81 -15
  23. package/corpus/core/docs/content/locales/hi-IN/template-clips.mdx +1 -0
  24. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -0
  25. package/corpus/core/docs/content/locales/ja-JP/extensions.mdx +9 -0
  26. package/corpus/core/docs/content/locales/ja-JP/messaging.mdx +81 -15
  27. package/corpus/core/docs/content/locales/ja-JP/template-clips.mdx +1 -0
  28. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -0
  29. package/corpus/core/docs/content/locales/ko-KR/extensions.mdx +8 -0
  30. package/corpus/core/docs/content/locales/ko-KR/messaging.mdx +80 -15
  31. package/corpus/core/docs/content/locales/ko-KR/template-clips.mdx +1 -0
  32. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -0
  33. package/corpus/core/docs/content/locales/pt-BR/extensions.mdx +9 -0
  34. package/corpus/core/docs/content/locales/pt-BR/messaging.mdx +88 -15
  35. package/corpus/core/docs/content/locales/pt-BR/template-clips.mdx +1 -0
  36. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -0
  37. package/corpus/core/docs/content/locales/zh-CN/extensions.mdx +6 -0
  38. package/corpus/core/docs/content/locales/zh-CN/messaging.mdx +78 -15
  39. package/corpus/core/docs/content/locales/zh-CN/template-clips.mdx +1 -0
  40. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -0
  41. package/corpus/core/docs/content/locales/zh-TW/extensions.mdx +6 -0
  42. package/corpus/core/docs/content/locales/zh-TW/messaging.mdx +78 -15
  43. package/corpus/core/docs/content/locales/zh-TW/template-clips.mdx +1 -0
  44. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -0
  45. package/corpus/core/docs/content/messaging.mdx +227 -45
  46. package/corpus/core/docs/content/template-clips.mdx +3 -0
  47. package/corpus/core/docs/content/template-design.mdx +4 -0
  48. package/corpus/core/package.json +5 -1
  49. package/corpus/core/src/a2a/artifact-response.ts +131 -2
  50. package/corpus/core/src/a2a/client.ts +10 -0
  51. package/corpus/core/src/a2a/handlers.ts +40 -76
  52. package/corpus/core/src/a2a/types.ts +2 -0
  53. package/corpus/core/src/agent/durable-background.ts +24 -0
  54. package/corpus/core/src/agent/production-agent.ts +15 -3
  55. package/corpus/core/src/agent/run-manager.ts +130 -10
  56. package/corpus/core/src/agent/run-store.ts +225 -15
  57. package/corpus/core/src/agent/types.ts +23 -0
  58. package/corpus/core/src/audit/record.ts +31 -0
  59. package/corpus/core/src/audit/store.ts +69 -3
  60. package/corpus/core/src/audit/types.ts +13 -0
  61. package/corpus/core/src/automation/index.ts +802 -0
  62. package/corpus/core/src/cli/create.ts +12 -5
  63. package/corpus/core/src/cli/design-connect.ts +596 -36
  64. package/corpus/core/src/client/AgentPanel.tsx +51 -6
  65. package/corpus/core/src/client/AssistantChat.tsx +274 -147
  66. package/corpus/core/src/client/MultiTabAssistantChat.tsx +3 -0
  67. package/corpus/core/src/client/RunStuckBanner.tsx +69 -20
  68. package/corpus/core/src/client/agent-chat-adapter.ts +54 -5
  69. package/corpus/core/src/client/automation.ts +22 -0
  70. package/corpus/core/src/client/chat/run-recovery.tsx +67 -50
  71. package/corpus/core/src/client/composer/TiptapComposer.tsx +8 -0
  72. package/corpus/core/src/client/index.ts +30 -0
  73. package/corpus/core/src/client/integrations/api.ts +295 -0
  74. package/corpus/core/src/client/integrations/index.ts +26 -0
  75. package/corpus/core/src/client/transcription/use-live-transcription.ts +68 -5
  76. package/corpus/core/src/client/use-run-stuck-detection.ts +41 -3
  77. package/corpus/core/src/deploy/build.ts +59 -3
  78. package/corpus/core/src/deploy/workspace-deploy.ts +37 -2
  79. package/corpus/core/src/file-upload/types.ts +2 -0
  80. package/corpus/core/src/index.ts +37 -0
  81. package/corpus/core/src/integrations/a2a-continuations-store.ts +6 -4
  82. package/corpus/core/src/integrations/adapters/discord.ts +362 -0
  83. package/corpus/core/src/integrations/adapters/index.ts +29 -0
  84. package/corpus/core/src/integrations/adapters/microsoft-teams.ts +411 -0
  85. package/corpus/core/src/integrations/adapters/slack.ts +861 -27
  86. package/corpus/core/src/integrations/adapters/telegram.ts +54 -15
  87. package/corpus/core/src/integrations/adapters/whatsapp.ts +41 -17
  88. package/corpus/core/src/integrations/catalog.ts +571 -0
  89. package/corpus/core/src/integrations/controls-store.ts +187 -0
  90. package/corpus/core/src/integrations/index.ts +100 -0
  91. package/corpus/core/src/integrations/installations-store.ts +677 -0
  92. package/corpus/core/src/integrations/integration-memory.ts +187 -0
  93. package/corpus/core/src/integrations/pending-tasks-retry-job.ts +6 -6
  94. package/corpus/core/src/integrations/pending-tasks-store.ts +83 -5
  95. package/corpus/core/src/integrations/plugin.ts +685 -47
  96. package/corpus/core/src/integrations/scope-store.ts +498 -0
  97. package/corpus/core/src/integrations/slack-manifest.ts +78 -0
  98. package/corpus/core/src/integrations/slack-oauth.ts +343 -0
  99. package/corpus/core/src/integrations/types.ts +179 -0
  100. package/corpus/core/src/integrations/usage-budget-store.ts +906 -0
  101. package/corpus/core/src/integrations/webhook-handler.ts +562 -51
  102. package/corpus/core/src/jobs/scheduler.ts +100 -2
  103. package/corpus/core/src/jobs/tools.ts +45 -9
  104. package/corpus/core/src/provider-api/index.ts +72 -1
  105. package/corpus/core/src/resources/handlers.ts +88 -14
  106. package/corpus/core/src/resources/script-helpers.ts +36 -7
  107. package/corpus/core/src/resources/store.ts +59 -52
  108. package/corpus/core/src/scripts/call-agent.ts +107 -1
  109. package/corpus/core/src/server/agent-chat-plugin.ts +294 -119
  110. package/corpus/core/src/server/auth.ts +10 -14
  111. package/corpus/core/src/server/builder-design-systems.ts +16 -1
  112. package/corpus/core/src/server/edge.ts +18 -0
  113. package/corpus/core/src/server/index.ts +26 -0
  114. package/corpus/core/src/server/request-context.ts +18 -0
  115. package/corpus/core/src/server/social-og-image.ts +3 -2
  116. package/corpus/core/src/styles/agent-native.css +62 -44
  117. package/corpus/core/src/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
  118. package/corpus/core/src/templates/default/AGENTS.md +7 -3
  119. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
  120. package/corpus/core/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
  121. package/corpus/core/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
  122. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
  123. package/corpus/core/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
  124. package/corpus/core/src/templates/workspace-core/AGENTS.md +3 -2
  125. package/corpus/core/src/usage/store.ts +37 -2
  126. package/corpus/templates/analytics/.agents/skills/capture-learnings/SKILL.md +22 -9
  127. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +23 -0
  128. package/corpus/templates/analytics/.builder/skills/provider-api/SKILL.md +15 -0
  129. package/corpus/templates/analytics/actions/save-monitor.ts +25 -2
  130. package/corpus/templates/analytics/app/lib/data-sources.ts +28 -0
  131. package/corpus/templates/analytics/changelog/2026-07-10-agent-created-uptime-monitors-now-return-a-direct-link-to-th.md +6 -0
  132. package/corpus/templates/analytics/changelog/2026-07-10-dashboard-email-reports-still-arrive-when-screenshot-capture-temporarily-fails.md +6 -0
  133. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +3 -7
  134. package/corpus/templates/analytics/server/lib/credential-keys.ts +12 -0
  135. package/corpus/templates/analytics/server/lib/dashboard-report.ts +5 -1
  136. package/corpus/templates/analytics/server/lib/provider-credentials.ts +2 -0
  137. package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +16 -0
  138. package/corpus/templates/assets/.agents/skills/capture-learnings/SKILL.md +22 -9
  139. package/corpus/templates/brain/.agents/skills/capture-learnings/SKILL.md +22 -9
  140. package/corpus/templates/calendar/.agents/skills/capture-learnings/SKILL.md +22 -9
  141. package/corpus/templates/calendar/app/components/calendar/CommandPalette.tsx +98 -108
  142. package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +97 -90
  143. package/corpus/templates/calendar/changelog/2026-07-10-event-guest-details-and-option-menus-now-use-valid-accessibl.md +6 -0
  144. package/corpus/templates/calendar/changelog/2026-07-10-natural-language-event-phrases-stay-available-as-quick-creat.md +6 -0
  145. package/corpus/templates/chat/.agents/skills/capture-learnings/SKILL.md +22 -9
  146. package/corpus/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
  147. package/corpus/templates/clips/.agents/skills/capture-learnings/SKILL.md +22 -9
  148. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +17 -1
  149. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +8 -0
  150. package/corpus/templates/clips/AGENTS.md +8 -3
  151. package/corpus/templates/clips/actions/finalize-recording.ts +63 -23
  152. package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -2
  153. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +72 -9
  154. package/corpus/templates/clips/actions/list-recordings.ts +19 -3
  155. package/corpus/templates/clips/actions/navigate.ts +2 -0
  156. package/corpus/templates/clips/actions/reprocess-recording.ts +20 -6
  157. package/corpus/templates/clips/actions/request-transcript.ts +16 -31
  158. package/corpus/templates/clips/actions/view-screen.ts +57 -5
  159. package/corpus/templates/clips/app/components/layout/Header.tsx +1 -0
  160. package/corpus/templates/clips/app/components/library/empty-state.tsx +2 -0
  161. package/corpus/templates/clips/app/components/library/library-grid.tsx +69 -42
  162. package/corpus/templates/clips/app/components/library/library-layout.tsx +15 -1
  163. package/corpus/templates/clips/app/components/library/recording-card.tsx +81 -68
  164. package/corpus/templates/clips/app/components/library/search-bar.tsx +4 -3
  165. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +9 -3
  166. package/corpus/templates/clips/app/components/player/share-dialog.tsx +1 -1
  167. package/corpus/templates/clips/app/hooks/use-library.ts +1 -1
  168. package/corpus/templates/clips/app/hooks/use-navigation-state.ts +10 -2
  169. package/corpus/templates/clips/app/i18n/ar-SA.ts +7 -1
  170. package/corpus/templates/clips/app/i18n/de-DE.ts +7 -1
  171. package/corpus/templates/clips/app/i18n/en-US.ts +7 -1
  172. package/corpus/templates/clips/app/i18n/es-ES.ts +7 -1
  173. package/corpus/templates/clips/app/i18n/fr-FR.ts +7 -1
  174. package/corpus/templates/clips/app/i18n/hi-IN.ts +7 -1
  175. package/corpus/templates/clips/app/i18n/ja-JP.ts +7 -1
  176. package/corpus/templates/clips/app/i18n/ko-KR.ts +7 -1
  177. package/corpus/templates/clips/app/i18n/pt-BR.ts +7 -1
  178. package/corpus/templates/clips/app/i18n/zh-CN.ts +8 -1
  179. package/corpus/templates/clips/app/i18n/zh-TW.ts +8 -1
  180. package/corpus/templates/clips/app/lib/recording-visibility.ts +70 -0
  181. package/corpus/templates/clips/app/routes/_app.shared.tsx +20 -0
  182. package/corpus/templates/clips/app/routes/download.tsx +24 -8
  183. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +115 -2
  184. package/corpus/templates/clips/app/routes/record.tsx +62 -0
  185. package/corpus/templates/clips/app/routes/share.$shareId.tsx +25 -16
  186. package/corpus/templates/clips/changelog/2026-07-10-clips-desktop-is-now-available-for-linux-with-appimage-debia.md +6 -0
  187. package/corpus/templates/clips/changelog/2026-07-10-clips-downloads-updates-sooner-in-the-background-and-offers-.md +6 -0
  188. package/corpus/templates/clips/changelog/2026-07-10-clips-shared-with-you-now-appear-in-a-searchable-shared-with.md +6 -0
  189. package/corpus/templates/clips/changelog/2026-07-10-clips-with-missing-mobile-video-frames-can-be-repaired-witho.md +6 -0
  190. package/corpus/templates/clips/changelog/2026-07-10-mobile-camera-recordings-pause-while-backgrounded.md +6 -0
  191. package/corpus/templates/clips/changelog/2026-07-10-mp4-downloads-now-show-progress-immediately-after-the-option.md +6 -0
  192. package/corpus/templates/clips/changelog/2026-07-10-recording-pages-now-open-as-soon-as-you-stop-with-a-share-li.md +6 -0
  193. package/corpus/templates/clips/changelog/2026-07-10-recordings-now-seek-smoothly-downloads-use-the-correct-file-.md +6 -0
  194. package/corpus/templates/clips/changelog/2026-07-10-s3-compatible-storage-now-saves-hosted-recordings-without-re.md +6 -0
  195. package/corpus/templates/clips/desktop/README.md +22 -6
  196. package/corpus/templates/clips/desktop/package.json +1 -1
  197. package/corpus/templates/clips/desktop/src/app.tsx +32 -19
  198. package/corpus/templates/clips/desktop/src/components/ReadinessPanel.tsx +15 -9
  199. package/corpus/templates/clips/desktop/src/lib/finalization-guard.ts +22 -0
  200. package/corpus/templates/clips/desktop/src/lib/permissions.ts +3 -1
  201. package/corpus/templates/clips/desktop/src/lib/recorder.ts +97 -120
  202. package/corpus/templates/clips/desktop/src/lib/updater.ts +26 -4
  203. package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +4 -8
  204. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +1 -1
  205. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +2 -2
  206. package/corpus/templates/clips/desktop/src-tauri/src/permission_status.rs +11 -7
  207. package/corpus/templates/clips/desktop/src-tauri/tauri.linux.conf.json +11 -0
  208. package/corpus/templates/clips/netlify.toml +3 -0
  209. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +106 -0
  210. package/corpus/templates/clips/server/lib/public-agent-context.ts +9 -1
  211. package/corpus/templates/clips/server/lib/resumable-upload-provider.ts +52 -0
  212. package/corpus/templates/clips/server/lib/s3-upload-provider.ts +433 -85
  213. package/corpus/templates/clips/server/lib/video-remux.ts +114 -0
  214. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +109 -0
  215. package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +22 -11
  216. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +4 -2
  217. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +47 -5
  218. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +10 -2
  219. package/corpus/templates/clips/shared/share-loader-response.ts +12 -0
  220. package/corpus/templates/clips/shared/transcript-status.ts +40 -0
  221. package/corpus/templates/content/.agents/skills/capture-learnings/SKILL.md +22 -9
  222. package/corpus/templates/content/.agents/skills/content/SKILL.md +57 -5
  223. package/corpus/templates/content/AGENTS.md +65 -55
  224. package/corpus/templates/content/actions/_builder-cms-read-client.ts +10 -16
  225. package/corpus/templates/content/actions/_database-source-utils.ts +58 -11
  226. package/corpus/templates/content/actions/_property-utils.ts +30 -2
  227. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +312 -114
  228. package/corpus/templates/content/actions/submit-content-database-form.ts +497 -0
  229. package/corpus/templates/content/actions/update-content-database-view.ts +8 -1
  230. package/corpus/templates/content/actions/view-screen.ts +4 -1
  231. package/corpus/templates/content/agent-native.app-skill.json +1 -1
  232. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +250 -64
  233. package/corpus/templates/content/app/components/editor/database/FormView.tsx +460 -0
  234. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +3 -0
  235. package/corpus/templates/content/app/components/editor/database/settings.tsx +30 -37
  236. package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
  237. package/corpus/templates/content/app/components/editor/database/view-config.ts +29 -1
  238. package/corpus/templates/content/app/components/ui/textarea.tsx +1 -0
  239. package/corpus/templates/content/app/hooks/use-content-database.ts +22 -0
  240. package/corpus/templates/content/app/i18n/zh-TW.ts +21 -0
  241. package/corpus/templates/content/app/i18n-data.ts +225 -0
  242. package/corpus/templates/content/changelog/2026-07-10-builder-backed-properties-now-load-current-source-values-as-.md +6 -0
  243. package/corpus/templates/content/changelog/2026-07-10-builder-database-refreshes-now-stay-explicit-and-accurate.md +6 -0
  244. package/corpus/templates/content/changelog/2026-07-10-database-form-views-now-collect-ordered-required-answers-and.md +6 -0
  245. package/corpus/templates/content/changelog/2026-07-10-database-tables-now-use-a-quieter-more-compact-layout-with-c.md +6 -0
  246. package/corpus/templates/content/changelog/2026-07-10-slack-intake-routes-to-content-database-forms.md +6 -0
  247. package/corpus/templates/content/parity/matrix.md +1 -0
  248. package/corpus/templates/content/parity/matrix.ts +18 -0
  249. package/corpus/templates/content/shared/api.ts +27 -1
  250. package/corpus/templates/content/shared/database-form.ts +53 -0
  251. package/corpus/templates/design/.agents/skills/capture-learnings/SKILL.md +22 -9
  252. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +26 -0
  253. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +85 -12
  254. package/corpus/templates/design/AGENTS.md +72 -18
  255. package/corpus/templates/design/DESIGN.md +1 -1
  256. package/corpus/templates/design/DEVELOPING.md +1 -1
  257. package/corpus/templates/design/FIGMA_INTEROPERABILITY.md +116 -0
  258. package/corpus/templates/design/actions/create-design-from-template.ts +220 -0
  259. package/corpus/templates/design/actions/create-design-system.ts +92 -16
  260. package/corpus/templates/design/actions/delete-design-template.ts +28 -0
  261. package/corpus/templates/design/actions/delete-file.ts +7 -0
  262. package/corpus/templates/design/actions/edit-design.ts +3 -0
  263. package/corpus/templates/design/actions/export-design-as-figma-svg.ts +137 -5
  264. package/corpus/templates/design/actions/export-pdf.ts +1 -1
  265. package/corpus/templates/design/actions/generate-design.ts +3 -0
  266. package/corpus/templates/design/actions/get-design-snapshot.ts +9 -0
  267. package/corpus/templates/design/actions/get-figma-connection-status.ts +26 -0
  268. package/corpus/templates/design/actions/get-figma-design-context.ts +138 -0
  269. package/corpus/templates/design/actions/get-figma-styles.ts +2 -2
  270. package/corpus/templates/design/actions/import-figma-clipboard.ts +112 -16
  271. package/corpus/templates/design/actions/import-figma-frame.ts +15 -4
  272. package/corpus/templates/design/actions/index-design-system-with-builder.ts +4 -0
  273. package/corpus/templates/design/actions/list-design-templates.ts +118 -0
  274. package/corpus/templates/design/actions/navigate.ts +16 -2
  275. package/corpus/templates/design/actions/provider-api-request.ts +11 -1
  276. package/corpus/templates/design/actions/save-design-as-template.ts +156 -0
  277. package/corpus/templates/design/actions/set-active-breakpoint.ts +13 -4
  278. package/corpus/templates/design/actions/take-design-screenshot.ts +73 -3
  279. package/corpus/templates/design/actions/update-file.ts +39 -22
  280. package/corpus/templates/design/actions/view-screen.ts +36 -1
  281. package/corpus/templates/design/actions/write-local-file.ts +50 -38
  282. package/corpus/templates/design/app/components/design/AutoLayoutSuggestionDialog.tsx +151 -0
  283. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +20 -0
  284. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +251 -22
  285. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +3 -3
  286. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +384 -9
  287. package/corpus/templates/design/app/components/design/EditPanel.tsx +105 -32
  288. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +58 -28
  289. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +6 -0
  290. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +539 -53
  291. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +40 -0
  292. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +1 -0
  293. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +1 -0
  294. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +5 -1
  295. package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
  296. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +3 -1
  297. package/corpus/templates/design/app/components/design/code-workbench/workspace/types.ts +2 -0
  298. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +19 -0
  299. package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +1 -0
  300. package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +27 -0
  301. package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +137 -81
  302. package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +25 -5
  303. package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +1 -1
  304. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +220 -3
  305. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +13 -0
  306. package/corpus/templates/design/app/components/design/multi-screen/types.ts +22 -1
  307. package/corpus/templates/design/app/components/design/types.ts +4 -0
  308. package/corpus/templates/design/app/components/design-system/ProductionDesignSystemShowcase.tsx +208 -0
  309. package/corpus/templates/design/app/components/editor/FigmaLinkComposerBubble.tsx +321 -0
  310. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +24 -4
  311. package/corpus/templates/design/app/components/layout/Layout.tsx +16 -2
  312. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -0
  313. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +72 -0
  314. package/corpus/templates/design/app/global.css +2 -35
  315. package/corpus/templates/design/app/hooks/use-navigation-state.ts +10 -0
  316. package/corpus/templates/design/app/i18n/zh-TW.ts +127 -5
  317. package/corpus/templates/design/app/i18n-breakpoints.ts +209 -0
  318. package/corpus/templates/design/app/i18n-data.ts +1317 -59
  319. package/corpus/templates/design/app/i18n-template-feature.ts +458 -0
  320. package/corpus/templates/design/app/lib/design-clipboard.ts +202 -0
  321. package/corpus/templates/design/app/lib/design-file-upload.ts +87 -0
  322. package/corpus/templates/design/app/lib/design-import.ts +168 -11
  323. package/corpus/templates/design/app/lib/desktop-design-preview.ts +423 -0
  324. package/corpus/templates/design/app/lib/figma-clipboard.ts +74 -8
  325. package/corpus/templates/design/app/lib/figma-connection.ts +161 -0
  326. package/corpus/templates/design/app/lib/figma-svg-copy.ts +814 -22
  327. package/corpus/templates/design/app/lib/figma-url.ts +77 -0
  328. package/corpus/templates/design/app/lib/pending-generation.ts +35 -0
  329. package/corpus/templates/design/app/pages/DesignSystems.tsx +236 -177
  330. package/corpus/templates/design/app/pages/Index.tsx +38 -0
  331. package/corpus/templates/design/app/pages/Templates.tsx +498 -0
  332. package/corpus/templates/design/app/pages/design-editor/auto-layout-suggestion.ts +328 -0
  333. package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +113 -0
  334. package/corpus/templates/design/app/pages/design-editor/created-screen-navigation.ts +55 -0
  335. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +32 -0
  336. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +49 -2
  337. package/corpus/templates/design/app/pages/design-editor/export-capture.ts +296 -0
  338. package/corpus/templates/design/app/pages/design-editor/history.ts +101 -2
  339. package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +28 -1
  340. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +34 -0
  341. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +202 -6
  342. package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +92 -0
  343. package/corpus/templates/design/app/pages/design-editor/save-failure.ts +58 -0
  344. package/corpus/templates/design/app/routes/templates.tsx +4 -6
  345. package/corpus/templates/design/changelog/2026-07-10-app-workspaces-now-use-clean-borderless-main-surfaces-throug.md +6 -0
  346. package/corpus/templates/design/changelog/2026-07-10-ask-chat-what-s-in-a-figma-file-or-frame-structure-screensho.md +6 -0
  347. package/corpus/templates/design/changelog/2026-07-10-canvas-edits-now-reject-malformed-html-before-it-can-corrupt.md +6 -0
  348. package/corpus/templates/design/changelog/2026-07-10-complex-designs-now-export-as-valid-secure-svgs-and-crisp-ra.md +6 -0
  349. package/corpus/templates/design/changelog/2026-07-10-complex-figma-masks-arcs-rich-text-transformed-images-and-ad.md +6 -0
  350. package/corpus/templates/design/changelog/2026-07-10-copied-layers-paste-across-designs-and-browser-tabs.md +6 -0
  351. package/corpus/templates/design/changelog/2026-07-10-copy-and-download-editable-figma-svg.md +6 -0
  352. package/corpus/templates/design/changelog/2026-07-10-copying-design-text-now-pastes-readable-text-into-other-apps.md +6 -0
  353. package/corpus/templates/design/changelog/2026-07-10-deleted-screens-can-be-restored-with-undo-and-removed-again-.md +6 -0
  354. package/corpus/templates/design/changelog/2026-07-10-design-changes-now-save-before-switching-apps-and-retry-when.md +6 -0
  355. package/corpus/templates/design/changelog/2026-07-10-design-stays-usable-on-phones-by-keeping-editor-panels-and-f.md +6 -0
  356. package/corpus/templates/design/changelog/2026-07-10-download-all-screens-as-one-multi-page-pdf-from-the-overview.md +6 -0
  357. package/corpus/templates/design/changelog/2026-07-10-duplicated-layers-now-keep-labels-aria-relationships-fragmen.md +6 -0
  358. package/corpus/templates/design/changelog/2026-07-10-fig-import-results-stay-compact.md +6 -0
  359. package/corpus/templates/design/changelog/2026-07-10-figma-imports-now-load-real-fonts-fix-rotated-gradient-dashe.md +6 -0
  360. package/corpus/templates/design/changelog/2026-07-10-figma-links-in-chat-and-the-import-tab-now-offer-secure-one-.md +6 -0
  361. package/corpus/templates/design/changelog/2026-07-10-fixed-cmd-z-not-restoring-content-after-an-agent-driven-desi.md +6 -0
  362. package/corpus/templates/design/changelog/2026-07-10-fixed-download-pdf-being-unreachable-from-the-export-panel-e.md +6 -0
  363. package/corpus/templates/design/changelog/2026-07-10-fixed-dragging-a-layer-out-of-an-auto-layout-row-column-no-l.md +6 -0
  364. package/corpus/templates/design/changelog/2026-07-10-fixed-figma-svg-export-text-wrapping-sizing-and-inner-layer.md +6 -0
  365. package/corpus/templates/design/changelog/2026-07-10-fixed-hiding-or-locking-one-layer-no-longer-hides-or-blocks-.md +6 -0
  366. package/corpus/templates/design/changelog/2026-07-10-fixed-png-screenshots-of-tall-screens-being-cropped-to-one-v.md +6 -0
  367. package/corpus/templates/design/changelog/2026-07-10-fixed-png-svg-exports-capturing-broken-layout-when-webfonts-.md +6 -0
  368. package/corpus/templates/design/changelog/2026-07-10-frame-tool-now-offers-standard-ad-unit-size-presets-medium-r.md +6 -0
  369. package/corpus/templates/design/changelog/2026-07-10-full-view-controls-stay-within-their-frame-instead-of-coveri.md +6 -0
  370. package/corpus/templates/design/changelog/2026-07-10-hover-focus-focus-visible-pressed-and-disabled-states-now-pr.md +6 -0
  371. package/corpus/templates/design/changelog/2026-07-10-layer-drops-now-land-in-the-intended-grid-row-stay-visually-.md +6 -0
  372. package/corpus/templates/design/changelog/2026-07-10-local-code-workspaces-now-keep-unsaved-edits-across-panel-sw.md +6 -0
  373. package/corpus/templates/design/changelog/2026-07-10-local-visual-editing-now-keeps-authenticated-sessions-shared.md +6 -0
  374. package/corpus/templates/design/changelog/2026-07-10-long-running-agent-work-no-longer-shows-a-premature-stuck-wa.md +6 -0
  375. package/corpus/templates/design/changelog/2026-07-10-managed-figma-connections-are-recognized-automatically.md +6 -0
  376. package/corpus/templates/design/changelog/2026-07-10-new-designs-can-open-directly-in-the-editor-without-a-pr.md +6 -0
  377. package/corpus/templates/design/changelog/2026-07-10-new-screens-are-selected-and-revealed-immediately.md +6 -0
  378. package/corpus/templates/design/changelog/2026-07-10-new-text-layers-undo-as-one-safe-creation.md +6 -0
  379. package/corpus/templates/design/changelog/2026-07-10-preview-and-apply-inferred-auto-layout-without-changing-yo.md +5 -0
  380. package/corpus/templates/design/changelog/2026-07-10-print-pdf-exports-and-paper-size-presets-letter-a4-now-match.md +6 -0
  381. package/corpus/templates/design/changelog/2026-07-10-responsive-frame-editing.md +6 -0
  382. package/corpus/templates/design/changelog/2026-07-10-reusable-design-templates.md +6 -0
  383. package/corpus/templates/design/changelog/2026-07-10-screen-overview-frames-now-use-a-clearer-interact-action-wit.md +6 -0
  384. package/corpus/templates/design/changelog/2026-07-10-start-designs-from-source-linked-material-3-carbon-or-primer.md +6 -0
  385. package/corpus/templates/design/changelog/2026-07-10-tweaks-guidance.md +6 -0
  386. package/corpus/templates/design/changelog/2026-07-10-uploaded-fig-files-can-now-become-editable-design-screens-wi.md +6 -0
  387. package/corpus/templates/design/e2e/helpers.ts +3 -3
  388. package/corpus/templates/design/package.json +2 -0
  389. package/corpus/templates/design/scripts/qa-figma-stress-import.ts +96 -0
  390. package/corpus/templates/design/server/db/index.ts +10 -0
  391. package/corpus/templates/design/server/db/schema.ts +44 -0
  392. package/corpus/templates/design/server/handlers/import-design-file.ts +114 -80
  393. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +19 -6
  394. package/corpus/templates/design/server/lib/design-export.ts +240 -3
  395. package/corpus/templates/design/server/lib/design-template-data.ts +89 -0
  396. package/corpus/templates/design/server/lib/design-to-figma-svg.ts +250 -26
  397. package/corpus/templates/design/server/lib/fig-file-decoder.ts +839 -0
  398. package/corpus/templates/design/server/lib/fig-file-import.ts +287 -0
  399. package/corpus/templates/design/server/lib/fig-file-limits.ts +3 -0
  400. package/corpus/templates/design/server/lib/fig-file-to-html.ts +2568 -0
  401. package/corpus/templates/design/server/lib/figma-design-context.ts +359 -0
  402. package/corpus/templates/design/server/lib/figma-node-import.ts +478 -22
  403. package/corpus/templates/design/server/lib/figma-node-to-html.ts +554 -29
  404. package/corpus/templates/design/server/lib/local-figma-qa-upload.ts +112 -0
  405. package/corpus/templates/design/server/lib/verify-write-grant.ts +16 -2
  406. package/corpus/templates/design/server/lib/visible-clipboard-html.ts +13 -3
  407. package/corpus/templates/design/server/plugins/agent-chat.ts +7 -0
  408. package/corpus/templates/design/server/plugins/db.ts +42 -0
  409. package/corpus/templates/design/server/plugins/local-figma-qa-upload.ts +7 -0
  410. package/corpus/templates/design/server/register-secrets.ts +8 -8
  411. package/corpus/templates/design/server/routes/api/qa-figma-import-assets/[assetId].get.ts +46 -0
  412. package/corpus/templates/design/server/source-workspace.ts +104 -12
  413. package/corpus/templates/design/shared/code-layer.ts +105 -28
  414. package/corpus/templates/design/shared/design-system-templates.ts +301 -0
  415. package/corpus/templates/design/shared/design-template-presets.ts +195 -0
  416. package/corpus/templates/design/shared/figma-url.ts +8 -0
  417. package/corpus/templates/design/shared/html-integrity.ts +306 -0
  418. package/corpus/templates/design/shared/interaction-states.ts +318 -23
  419. package/corpus/templates/design/shared/locked-layers.ts +151 -0
  420. package/corpus/templates/dispatch/.agents/skills/capture-learnings/SKILL.md +22 -9
  421. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +48 -0
  422. package/corpus/templates/dispatch/app/i18n-data.ts +536 -1
  423. package/corpus/templates/dispatch/changelog/2026-07-10-connect-slack-workspaces-with-oauth-and-manage-channel-ident.md +6 -0
  424. package/corpus/templates/dispatch/changelog/2026-07-10-microsoft-teams-bots-and-discord-slash-commands-can-now-conn.md +6 -0
  425. package/corpus/templates/dispatch/changelog/2026-07-10-slack-and-telegram-now-route-uptime-monitor-requests-to-anal.md +6 -0
  426. package/corpus/templates/forms/.agents/skills/capture-learnings/SKILL.md +22 -9
  427. package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +7 -0
  428. package/corpus/templates/forms/AGENTS.md +4 -0
  429. package/corpus/templates/forms/actions/create-form.ts +44 -7
  430. package/corpus/templates/forms/actions/lib/assert-publishable-form.ts +38 -0
  431. package/corpus/templates/forms/actions/patch-form-fields.ts +4 -0
  432. package/corpus/templates/forms/actions/update-form.ts +2 -36
  433. package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
  434. package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
  435. package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
  436. package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
  437. package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
  438. package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
  439. package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
  440. package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
  441. package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
  442. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  443. package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
  444. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +17 -0
  445. package/corpus/templates/forms/changelog/2026-07-10-agent-created-published-forms-now-return-the-anonymous-publi.md +6 -0
  446. package/corpus/templates/forms/changelog/2026-07-10-published-forms-can-no-longer-be-edited-into-an-unusable-emp.md +6 -0
  447. package/corpus/templates/forms/server/handlers/submissions.ts +4 -3
  448. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
  449. package/corpus/templates/forms/shared/types.ts +5 -0
  450. package/corpus/templates/mail/.agents/skills/capture-learnings/SKILL.md +22 -9
  451. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  452. package/corpus/templates/mail/changelog/2026-07-10-mail-navigation-now-uses-a-clean-borderless-drawer.md +6 -0
  453. package/corpus/templates/plan/.agents/skills/capture-learnings/SKILL.md +22 -9
  454. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +4 -1
  455. package/corpus/templates/plan/changelog/2026-07-10-local-plans-now-keep-valid-content-visible-when-one-generate.md +6 -0
  456. package/corpus/templates/plan/server/lib/local-plan-files.ts +4 -1
  457. package/corpus/templates/slides/.agents/skills/capture-learnings/SKILL.md +22 -9
  458. package/dist/a2a/artifact-response.d.ts.map +1 -1
  459. package/dist/a2a/artifact-response.js +88 -2
  460. package/dist/a2a/artifact-response.js.map +1 -1
  461. package/dist/a2a/client.d.ts +9 -0
  462. package/dist/a2a/client.d.ts.map +1 -1
  463. package/dist/a2a/client.js +1 -0
  464. package/dist/a2a/client.js.map +1 -1
  465. package/dist/a2a/handlers.d.ts.map +1 -1
  466. package/dist/a2a/handlers.js +24 -69
  467. package/dist/a2a/handlers.js.map +1 -1
  468. package/dist/a2a/types.d.ts +2 -0
  469. package/dist/a2a/types.d.ts.map +1 -1
  470. package/dist/a2a/types.js.map +1 -1
  471. package/dist/agent/durable-background.d.ts +11 -0
  472. package/dist/agent/durable-background.d.ts.map +1 -1
  473. package/dist/agent/durable-background.js +17 -0
  474. package/dist/agent/durable-background.js.map +1 -1
  475. package/dist/agent/production-agent.d.ts +2 -2
  476. package/dist/agent/production-agent.d.ts.map +1 -1
  477. package/dist/agent/production-agent.js +15 -5
  478. package/dist/agent/production-agent.js.map +1 -1
  479. package/dist/agent/run-manager.d.ts +44 -2
  480. package/dist/agent/run-manager.d.ts.map +1 -1
  481. package/dist/agent/run-manager.js +90 -9
  482. package/dist/agent/run-manager.js.map +1 -1
  483. package/dist/agent/run-store.d.ts +109 -0
  484. package/dist/agent/run-store.d.ts.map +1 -1
  485. package/dist/agent/run-store.js +206 -15
  486. package/dist/agent/run-store.js.map +1 -1
  487. package/dist/agent/types.d.ts +22 -0
  488. package/dist/agent/types.d.ts.map +1 -1
  489. package/dist/agent/types.js.map +1 -1
  490. package/dist/audit/record.d.ts.map +1 -1
  491. package/dist/audit/record.js +29 -0
  492. package/dist/audit/record.js.map +1 -1
  493. package/dist/audit/store.d.ts.map +1 -1
  494. package/dist/audit/store.js +62 -3
  495. package/dist/audit/store.js.map +1 -1
  496. package/dist/audit/types.d.ts +13 -0
  497. package/dist/audit/types.d.ts.map +1 -1
  498. package/dist/audit/types.js.map +1 -1
  499. package/dist/automation/index.d.ts +193 -0
  500. package/dist/automation/index.d.ts.map +1 -0
  501. package/dist/automation/index.js +464 -0
  502. package/dist/automation/index.js.map +1 -0
  503. package/dist/cli/create.d.ts.map +1 -1
  504. package/dist/cli/create.js +10 -3
  505. package/dist/cli/create.js.map +1 -1
  506. package/dist/cli/design-connect.d.ts.map +1 -1
  507. package/dist/cli/design-connect.js +492 -35
  508. package/dist/cli/design-connect.js.map +1 -1
  509. package/dist/client/AgentPanel.d.ts +7 -1
  510. package/dist/client/AgentPanel.d.ts.map +1 -1
  511. package/dist/client/AgentPanel.js +32 -8
  512. package/dist/client/AgentPanel.js.map +1 -1
  513. package/dist/client/AssistantChat.d.ts +15 -0
  514. package/dist/client/AssistantChat.d.ts.map +1 -1
  515. package/dist/client/AssistantChat.js +115 -47
  516. package/dist/client/AssistantChat.js.map +1 -1
  517. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  518. package/dist/client/MultiTabAssistantChat.js +1 -1
  519. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  520. package/dist/client/RunStuckBanner.d.ts +14 -1
  521. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  522. package/dist/client/RunStuckBanner.js +35 -7
  523. package/dist/client/RunStuckBanner.js.map +1 -1
  524. package/dist/client/agent-chat-adapter.d.ts +4 -1
  525. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  526. package/dist/client/agent-chat-adapter.js +49 -4
  527. package/dist/client/agent-chat-adapter.js.map +1 -1
  528. package/dist/client/automation.d.ts +14 -0
  529. package/dist/client/automation.d.ts.map +1 -0
  530. package/dist/client/automation.js +9 -0
  531. package/dist/client/automation.js.map +1 -0
  532. package/dist/client/chat/run-recovery.d.ts +4 -0
  533. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  534. package/dist/client/chat/run-recovery.js +12 -10
  535. package/dist/client/chat/run-recovery.js.map +1 -1
  536. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  537. package/dist/client/composer/TiptapComposer.js +8 -0
  538. package/dist/client/composer/TiptapComposer.js.map +1 -1
  539. package/dist/client/index.d.ts +2 -0
  540. package/dist/client/index.d.ts.map +1 -1
  541. package/dist/client/index.js +2 -0
  542. package/dist/client/index.js.map +1 -1
  543. package/dist/client/integrations/api.d.ts +115 -0
  544. package/dist/client/integrations/api.d.ts.map +1 -0
  545. package/dist/client/integrations/api.js +123 -0
  546. package/dist/client/integrations/api.js.map +1 -0
  547. package/dist/client/integrations/index.d.ts +1 -0
  548. package/dist/client/integrations/index.d.ts.map +1 -1
  549. package/dist/client/integrations/index.js +1 -0
  550. package/dist/client/integrations/index.js.map +1 -1
  551. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  552. package/dist/client/transcription/use-live-transcription.js +59 -5
  553. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  554. package/dist/client/use-run-stuck-detection.d.ts +16 -1
  555. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  556. package/dist/client/use-run-stuck-detection.js +23 -4
  557. package/dist/client/use-run-stuck-detection.js.map +1 -1
  558. package/dist/collab/struct-routes.d.ts +1 -1
  559. package/dist/deploy/build.d.ts.map +1 -1
  560. package/dist/deploy/build.js +49 -4
  561. package/dist/deploy/build.js.map +1 -1
  562. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  563. package/dist/deploy/workspace-deploy.js +31 -2
  564. package/dist/deploy/workspace-deploy.js.map +1 -1
  565. package/dist/file-upload/types.d.ts +2 -0
  566. package/dist/file-upload/types.d.ts.map +1 -1
  567. package/dist/file-upload/types.js.map +1 -1
  568. package/dist/index.d.ts +2 -0
  569. package/dist/index.d.ts.map +1 -1
  570. package/dist/index.js +2 -0
  571. package/dist/index.js.map +1 -1
  572. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  573. package/dist/integrations/a2a-continuations-store.js +6 -4
  574. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  575. package/dist/integrations/adapters/discord.d.ts +3 -0
  576. package/dist/integrations/adapters/discord.d.ts.map +1 -0
  577. package/dist/integrations/adapters/discord.js +261 -0
  578. package/dist/integrations/adapters/discord.js.map +1 -0
  579. package/dist/integrations/adapters/index.d.ts +4 -0
  580. package/dist/integrations/adapters/index.d.ts.map +1 -0
  581. package/dist/integrations/adapters/index.js +26 -0
  582. package/dist/integrations/adapters/index.js.map +1 -0
  583. package/dist/integrations/adapters/microsoft-teams.d.ts +5 -0
  584. package/dist/integrations/adapters/microsoft-teams.d.ts.map +1 -0
  585. package/dist/integrations/adapters/microsoft-teams.js +295 -0
  586. package/dist/integrations/adapters/microsoft-teams.js.map +1 -0
  587. package/dist/integrations/adapters/slack.d.ts +8 -2
  588. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  589. package/dist/integrations/adapters/slack.js +736 -27
  590. package/dist/integrations/adapters/slack.js.map +1 -1
  591. package/dist/integrations/adapters/telegram.d.ts +0 -2
  592. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  593. package/dist/integrations/adapters/telegram.js +49 -15
  594. package/dist/integrations/adapters/telegram.js.map +1 -1
  595. package/dist/integrations/adapters/whatsapp.d.ts +0 -2
  596. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  597. package/dist/integrations/adapters/whatsapp.js +40 -17
  598. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  599. package/dist/integrations/catalog.d.ts +75 -0
  600. package/dist/integrations/catalog.d.ts.map +1 -0
  601. package/dist/integrations/catalog.js +451 -0
  602. package/dist/integrations/catalog.js.map +1 -0
  603. package/dist/integrations/controls-store.d.ts +44 -0
  604. package/dist/integrations/controls-store.d.ts.map +1 -0
  605. package/dist/integrations/controls-store.js +129 -0
  606. package/dist/integrations/controls-store.js.map +1 -0
  607. package/dist/integrations/index.d.ts +13 -1
  608. package/dist/integrations/index.d.ts.map +1 -1
  609. package/dist/integrations/index.js +9 -0
  610. package/dist/integrations/index.js.map +1 -1
  611. package/dist/integrations/installations-store.d.ts +112 -0
  612. package/dist/integrations/installations-store.d.ts.map +1 -0
  613. package/dist/integrations/installations-store.js +493 -0
  614. package/dist/integrations/installations-store.js.map +1 -0
  615. package/dist/integrations/integration-memory.d.ts +24 -0
  616. package/dist/integrations/integration-memory.d.ts.map +1 -0
  617. package/dist/integrations/integration-memory.js +136 -0
  618. package/dist/integrations/integration-memory.js.map +1 -0
  619. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  620. package/dist/integrations/pending-tasks-retry-job.js +6 -5
  621. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  622. package/dist/integrations/pending-tasks-store.d.ts +17 -0
  623. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  624. package/dist/integrations/pending-tasks-store.js +71 -5
  625. package/dist/integrations/pending-tasks-store.js.map +1 -1
  626. package/dist/integrations/plugin.d.ts.map +1 -1
  627. package/dist/integrations/plugin.js +520 -35
  628. package/dist/integrations/plugin.js.map +1 -1
  629. package/dist/integrations/scope-store.d.ts +65 -0
  630. package/dist/integrations/scope-store.d.ts.map +1 -0
  631. package/dist/integrations/scope-store.js +361 -0
  632. package/dist/integrations/scope-store.js.map +1 -0
  633. package/dist/integrations/slack-manifest.d.ts +66 -0
  634. package/dist/integrations/slack-manifest.d.ts.map +1 -0
  635. package/dist/integrations/slack-manifest.js +70 -0
  636. package/dist/integrations/slack-manifest.js.map +1 -0
  637. package/dist/integrations/slack-oauth.d.ts +99 -0
  638. package/dist/integrations/slack-oauth.d.ts.map +1 -0
  639. package/dist/integrations/slack-oauth.js +226 -0
  640. package/dist/integrations/slack-oauth.js.map +1 -0
  641. package/dist/integrations/types.d.ts +144 -0
  642. package/dist/integrations/types.d.ts.map +1 -1
  643. package/dist/integrations/types.js +16 -1
  644. package/dist/integrations/types.js.map +1 -1
  645. package/dist/integrations/usage-budget-store.d.ts +84 -0
  646. package/dist/integrations/usage-budget-store.d.ts.map +1 -0
  647. package/dist/integrations/usage-budget-store.js +650 -0
  648. package/dist/integrations/usage-budget-store.js.map +1 -0
  649. package/dist/integrations/webhook-handler.d.ts +4 -0
  650. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  651. package/dist/integrations/webhook-handler.js +415 -47
  652. package/dist/integrations/webhook-handler.js.map +1 -1
  653. package/dist/jobs/scheduler.d.ts +6 -0
  654. package/dist/jobs/scheduler.d.ts.map +1 -1
  655. package/dist/jobs/scheduler.js +83 -4
  656. package/dist/jobs/scheduler.js.map +1 -1
  657. package/dist/jobs/tools.d.ts.map +1 -1
  658. package/dist/jobs/tools.js +43 -11
  659. package/dist/jobs/tools.js.map +1 -1
  660. package/dist/observability/routes.d.ts +5 -5
  661. package/dist/progress/routes.d.ts +1 -1
  662. package/dist/provider-api/index.d.ts +4 -4
  663. package/dist/provider-api/index.d.ts.map +1 -1
  664. package/dist/provider-api/index.js +72 -1
  665. package/dist/provider-api/index.js.map +1 -1
  666. package/dist/resources/handlers.d.ts +3 -3
  667. package/dist/resources/handlers.d.ts.map +1 -1
  668. package/dist/resources/handlers.js +57 -15
  669. package/dist/resources/handlers.js.map +1 -1
  670. package/dist/resources/script-helpers.d.ts.map +1 -1
  671. package/dist/resources/script-helpers.js +34 -8
  672. package/dist/resources/script-helpers.js.map +1 -1
  673. package/dist/resources/store.d.ts +10 -0
  674. package/dist/resources/store.d.ts.map +1 -1
  675. package/dist/resources/store.js +54 -47
  676. package/dist/resources/store.js.map +1 -1
  677. package/dist/scripts/call-agent.d.ts.map +1 -1
  678. package/dist/scripts/call-agent.js +106 -1
  679. package/dist/scripts/call-agent.js.map +1 -1
  680. package/dist/server/agent-chat-plugin.d.ts +15 -4
  681. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  682. package/dist/server/agent-chat-plugin.js +248 -113
  683. package/dist/server/agent-chat-plugin.js.map +1 -1
  684. package/dist/server/auth.d.ts.map +1 -1
  685. package/dist/server/auth.js +10 -14
  686. package/dist/server/auth.js.map +1 -1
  687. package/dist/server/builder-design-systems.d.ts +3 -1
  688. package/dist/server/builder-design-systems.d.ts.map +1 -1
  689. package/dist/server/builder-design-systems.js +9 -2
  690. package/dist/server/builder-design-systems.js.map +1 -1
  691. package/dist/server/edge.d.ts +1 -1
  692. package/dist/server/edge.d.ts.map +1 -1
  693. package/dist/server/edge.js +1 -1
  694. package/dist/server/edge.js.map +1 -1
  695. package/dist/server/index.d.ts +2 -1
  696. package/dist/server/index.d.ts.map +1 -1
  697. package/dist/server/index.js +2 -1
  698. package/dist/server/index.js.map +1 -1
  699. package/dist/server/request-context.d.ts +18 -0
  700. package/dist/server/request-context.d.ts.map +1 -1
  701. package/dist/server/request-context.js.map +1 -1
  702. package/dist/server/social-og-image.d.ts.map +1 -1
  703. package/dist/server/social-og-image.js +3 -2
  704. package/dist/server/social-og-image.js.map +1 -1
  705. package/dist/server/transcribe-voice.d.ts +1 -1
  706. package/dist/styles/agent-native.css +62 -44
  707. package/dist/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
  708. package/dist/templates/default/AGENTS.md +7 -3
  709. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
  710. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
  711. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
  712. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
  713. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
  714. package/dist/templates/workspace-core/AGENTS.md +3 -2
  715. package/dist/usage/store.d.ts +7 -0
  716. package/dist/usage/store.d.ts.map +1 -1
  717. package/dist/usage/store.js +24 -3
  718. package/dist/usage/store.js.map +1 -1
  719. package/docs/content/automation-connectors.mdx +80 -0
  720. package/docs/content/extensions.mdx +8 -0
  721. package/docs/content/locales/ar-SA/extensions.mdx +8 -0
  722. package/docs/content/locales/ar-SA/messaging.mdx +84 -15
  723. package/docs/content/locales/ar-SA/template-clips.mdx +1 -0
  724. package/docs/content/locales/ar-SA/template-design.mdx +1 -0
  725. package/docs/content/locales/de-DE/extensions.mdx +10 -0
  726. package/docs/content/locales/de-DE/messaging.mdx +92 -15
  727. package/docs/content/locales/de-DE/template-clips.mdx +1 -0
  728. package/docs/content/locales/de-DE/template-design.mdx +1 -0
  729. package/docs/content/locales/es-ES/extensions.mdx +10 -0
  730. package/docs/content/locales/es-ES/messaging.mdx +91 -15
  731. package/docs/content/locales/es-ES/template-clips.mdx +1 -0
  732. package/docs/content/locales/es-ES/template-design.mdx +1 -0
  733. package/docs/content/locales/fr-FR/extensions.mdx +10 -0
  734. package/docs/content/locales/fr-FR/messaging.mdx +91 -15
  735. package/docs/content/locales/fr-FR/template-clips.mdx +1 -0
  736. package/docs/content/locales/fr-FR/template-design.mdx +1 -0
  737. package/docs/content/locales/hi-IN/extensions.mdx +8 -0
  738. package/docs/content/locales/hi-IN/messaging.mdx +81 -15
  739. package/docs/content/locales/hi-IN/template-clips.mdx +1 -0
  740. package/docs/content/locales/hi-IN/template-design.mdx +1 -0
  741. package/docs/content/locales/ja-JP/extensions.mdx +9 -0
  742. package/docs/content/locales/ja-JP/messaging.mdx +81 -15
  743. package/docs/content/locales/ja-JP/template-clips.mdx +1 -0
  744. package/docs/content/locales/ja-JP/template-design.mdx +1 -0
  745. package/docs/content/locales/ko-KR/extensions.mdx +8 -0
  746. package/docs/content/locales/ko-KR/messaging.mdx +80 -15
  747. package/docs/content/locales/ko-KR/template-clips.mdx +1 -0
  748. package/docs/content/locales/ko-KR/template-design.mdx +1 -0
  749. package/docs/content/locales/pt-BR/extensions.mdx +9 -0
  750. package/docs/content/locales/pt-BR/messaging.mdx +88 -15
  751. package/docs/content/locales/pt-BR/template-clips.mdx +1 -0
  752. package/docs/content/locales/pt-BR/template-design.mdx +1 -0
  753. package/docs/content/locales/zh-CN/extensions.mdx +6 -0
  754. package/docs/content/locales/zh-CN/messaging.mdx +78 -15
  755. package/docs/content/locales/zh-CN/template-clips.mdx +1 -0
  756. package/docs/content/locales/zh-CN/template-design.mdx +1 -0
  757. package/docs/content/locales/zh-TW/extensions.mdx +6 -0
  758. package/docs/content/locales/zh-TW/messaging.mdx +78 -15
  759. package/docs/content/locales/zh-TW/template-clips.mdx +1 -0
  760. package/docs/content/locales/zh-TW/template-design.mdx +1 -0
  761. package/docs/content/messaging.mdx +227 -45
  762. package/docs/content/template-clips.mdx +3 -0
  763. package/docs/content/template-design.mdx +4 -0
  764. package/package.json +5 -1
  765. package/src/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
  766. package/src/templates/default/AGENTS.md +7 -3
  767. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
  768. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
  769. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
  770. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
  771. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
  772. package/src/templates/workspace-core/AGENTS.md +3 -2
@@ -0,0 +1,65 @@
1
+ export type IntegrationConversationType = "channel" | "direct_message" | "group_direct_message";
2
+ export type IntegrationConversationTrust = "trusted" | "guest" | "external_shared" | "unknown";
3
+ export interface IntegrationScopeAccess {
4
+ ownerEmail: string;
5
+ orgId?: string | null;
6
+ }
7
+ export interface IntegrationScopeKey {
8
+ platform: string;
9
+ tenantId: string;
10
+ conversationId: string;
11
+ }
12
+ export interface IntegrationScopePolicy {
13
+ requireMention: boolean;
14
+ allowDirectMessages: boolean;
15
+ allowGuests: boolean;
16
+ allowExternalShared: boolean;
17
+ allowUnknownTrust: boolean;
18
+ }
19
+ export declare const DEFAULT_INTEGRATION_SCOPE_POLICY: Readonly<IntegrationScopePolicy>;
20
+ export interface IntegrationScope extends IntegrationScopeKey {
21
+ id: string;
22
+ conversationType: IntegrationConversationType;
23
+ trust: IntegrationConversationTrust;
24
+ ownerEmail: string;
25
+ orgId: string | null;
26
+ installationId: string | null;
27
+ serviceOwnerEmail: string;
28
+ defaultModel: string | null;
29
+ policy: IntegrationScopePolicy;
30
+ createdAt: number;
31
+ updatedAt: number;
32
+ }
33
+ export interface SaveIntegrationScopeInput extends IntegrationScopeKey {
34
+ conversationType: IntegrationConversationType;
35
+ trust?: IntegrationConversationTrust;
36
+ /**
37
+ * Omit to use the caller's active org, or pass null for a personal scope.
38
+ * Passing an org other than the caller's active org is always rejected.
39
+ */
40
+ orgId?: string | null;
41
+ installationId?: string | null;
42
+ defaultModel?: string | null;
43
+ policy?: Partial<IntegrationScopePolicy>;
44
+ }
45
+ /** A stable, non-secret subject key suitable for a scope budget. */
46
+ export declare function integrationScopeSubjectKey(key: IntegrationScopeKey): string;
47
+ export declare function getIntegrationScope(keyInput: IntegrationScopeKey, accessInput: IntegrationScopeAccess): Promise<IntegrationScope | null>;
48
+ export declare function listIntegrationScopes(accessInput: IntegrationScopeAccess, filter?: {
49
+ platform?: string;
50
+ tenantId?: string;
51
+ }): Promise<IntegrationScope[]>;
52
+ export declare function saveIntegrationScope(input: SaveIntegrationScopeInput, accessInput: IntegrationScopeAccess): Promise<IntegrationScope>;
53
+ export declare function deleteIntegrationScope(keyInput: IntegrationScopeKey, accessInput: IntegrationScopeAccess): Promise<boolean>;
54
+ export type IntegrationScopePolicyDenial = "mention_required" | "direct_messages_disabled" | "guests_disabled" | "external_shared_disabled" | "unverified_conversation_disabled";
55
+ export declare function evaluateIntegrationScopePolicy(scope: Pick<IntegrationScope, "conversationType" | "trust" | "policy">, context: {
56
+ mentioned: boolean;
57
+ }): {
58
+ allowed: true;
59
+ } | {
60
+ allowed: false;
61
+ reason: IntegrationScopePolicyDenial;
62
+ };
63
+ /** Test-only reset for suites that swap the injected database. */
64
+ export declare function _resetIntegrationScopeStoreForTests(): void;
65
+ //# sourceMappingURL=scope-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-store.d.ts","sourceRoot":"","sources":["../../src/integrations/scope-store.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,2BAA2B,GACnC,SAAS,GACT,gBAAgB,GAChB,sBAAsB,CAAC;AAE3B,MAAM,MAAM,4BAA4B,GACpC,SAAS,GACT,OAAO,GACP,iBAAiB,GACjB,SAAS,CAAC;AAEd,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,sBAAsB,CAO1E,CAAC;AAEL,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,2BAA2B,CAAC;IAC9C,KAAK,EAAE,4BAA4B,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,gBAAgB,EAAE,2BAA2B,CAAC;IAC9C,KAAK,CAAC,EAAE,4BAA4B,CAAC;IACrC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC1C;AAkHD,oEAAoE;AACpE,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAO3E;AA+FD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,mBAAmB,EAC7B,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAoBlC;AAED,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,sBAAsB,EACnC,MAAM,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqB7B;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,EAChC,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CA0F3B;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,mBAAmB,EAC7B,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED,MAAM,MAAM,4BAA4B,GACpC,kBAAkB,GAClB,0BAA0B,GAC1B,iBAAiB,GACjB,0BAA0B,GAC1B,kCAAkC,CAAC;AAEvC,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,OAAO,GAAG,QAAQ,CAAC,EACtE,OAAO,EAAE;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GAE7B;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,4BAA4B,CAAA;CAAE,CAqB3D;AAED,kEAAkE;AAClE,wBAAgB,mCAAmC,IAAI,IAAI,CAE1D"}
@@ -0,0 +1,361 @@
1
+ import { createHash } from "node:crypto";
2
+ import { getDbExec, intType, isPostgres } from "../db/client.js";
3
+ import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
4
+ let initPromise;
5
+ export const DEFAULT_INTEGRATION_SCOPE_POLICY = Object.freeze({
6
+ requireMention: true,
7
+ allowDirectMessages: false,
8
+ allowGuests: false,
9
+ allowExternalShared: false,
10
+ allowUnknownTrust: false,
11
+ });
12
+ const CONVERSATION_TYPES = new Set([
13
+ "channel",
14
+ "direct_message",
15
+ "group_direct_message",
16
+ ]);
17
+ const TRUST_VALUES = new Set([
18
+ "trusted",
19
+ "guest",
20
+ "external_shared",
21
+ "unknown",
22
+ ]);
23
+ async function ensureTable() {
24
+ if (!initPromise) {
25
+ initPromise = (async () => {
26
+ const db = getDbExec();
27
+ const createSql = `CREATE TABLE IF NOT EXISTS integration_conversation_scopes (
28
+ id TEXT PRIMARY KEY,
29
+ platform TEXT NOT NULL,
30
+ tenant_id TEXT NOT NULL,
31
+ conversation_id TEXT NOT NULL,
32
+ conversation_type TEXT NOT NULL,
33
+ trust_level TEXT NOT NULL DEFAULT 'unknown',
34
+ owner_email TEXT NOT NULL,
35
+ org_id TEXT,
36
+ installation_id TEXT,
37
+ service_owner_email TEXT NOT NULL,
38
+ default_model TEXT,
39
+ require_mention ${intType()} NOT NULL DEFAULT 1,
40
+ allow_direct_messages ${intType()} NOT NULL DEFAULT 0,
41
+ allow_guests ${intType()} NOT NULL DEFAULT 0,
42
+ allow_external_shared ${intType()} NOT NULL DEFAULT 0,
43
+ allow_unknown_trust ${intType()} NOT NULL DEFAULT 0,
44
+ created_at ${intType()} NOT NULL,
45
+ updated_at ${intType()} NOT NULL
46
+ )`;
47
+ const uniqueIndexSql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_scope_external_key ON integration_conversation_scopes(platform, tenant_id, conversation_id)";
48
+ const ownerIndexSql = "CREATE INDEX IF NOT EXISTS idx_integration_scope_owner ON integration_conversation_scopes(owner_email, platform, tenant_id)";
49
+ const orgIndexSql = "CREATE INDEX IF NOT EXISTS idx_integration_scope_org ON integration_conversation_scopes(org_id, platform, tenant_id)";
50
+ if (isPostgres()) {
51
+ await ensureTableExists("integration_conversation_scopes", createSql);
52
+ await ensureColumnExists("integration_conversation_scopes", "default_model", "ALTER TABLE integration_conversation_scopes ADD COLUMN IF NOT EXISTS default_model TEXT");
53
+ await ensureIndexExists("idx_integration_scope_external_key", uniqueIndexSql);
54
+ await ensureIndexExists("idx_integration_scope_owner", ownerIndexSql);
55
+ await ensureIndexExists("idx_integration_scope_org", orgIndexSql);
56
+ return;
57
+ }
58
+ await db.execute(createSql);
59
+ try {
60
+ await db.execute("ALTER TABLE integration_conversation_scopes ADD COLUMN default_model TEXT");
61
+ }
62
+ catch (error) {
63
+ if (!/duplicate/i.test(String(error?.message ?? error))) {
64
+ throw error;
65
+ }
66
+ }
67
+ await db.execute(uniqueIndexSql);
68
+ await db.execute(ownerIndexSql);
69
+ await db.execute(orgIndexSql);
70
+ })().catch((error) => {
71
+ initPromise = undefined;
72
+ throw error;
73
+ });
74
+ }
75
+ return initPromise;
76
+ }
77
+ function requiredString(value, name, maxLength = 255) {
78
+ const normalized = String(value ?? "").trim();
79
+ if (!normalized)
80
+ throw new Error(`${name} is required`);
81
+ if (normalized.length > maxLength) {
82
+ throw new Error(`${name} must be at most ${maxLength} characters`);
83
+ }
84
+ return normalized;
85
+ }
86
+ function normalizeEmail(value, name) {
87
+ const email = requiredString(value, name, 320).toLowerCase();
88
+ if (!email.includes("@"))
89
+ throw new Error(`${name} must be an email address`);
90
+ return email;
91
+ }
92
+ function normalizeAccess(access) {
93
+ return {
94
+ ownerEmail: normalizeEmail(access.ownerEmail, "ownerEmail"),
95
+ orgId: access.orgId ? requiredString(access.orgId, "orgId") : null,
96
+ };
97
+ }
98
+ function normalizeKey(key) {
99
+ return {
100
+ platform: requiredString(key.platform, "platform", 80).toLowerCase(),
101
+ tenantId: requiredString(key.tenantId, "tenantId"),
102
+ conversationId: requiredString(key.conversationId, "conversationId"),
103
+ };
104
+ }
105
+ /** A stable, non-secret subject key suitable for a scope budget. */
106
+ export function integrationScopeSubjectKey(key) {
107
+ const normalized = normalizeKey(key);
108
+ return JSON.stringify([
109
+ normalized.platform,
110
+ normalized.tenantId,
111
+ normalized.conversationId,
112
+ ]);
113
+ }
114
+ function scopeId(key) {
115
+ return `scope:${integrationScopeSubjectKey(key)}`;
116
+ }
117
+ function serviceOwnerForScope(key, access, orgId) {
118
+ if (!orgId)
119
+ return access.ownerEmail;
120
+ const subject = createHash("sha256")
121
+ .update(`${orgId}:${integrationScopeSubjectKey(key)}`)
122
+ .digest("hex")
123
+ .slice(0, 24);
124
+ return `integration+${subject}@service.agent-native.local`;
125
+ }
126
+ function authorizationSql(alias = "") {
127
+ const prefix = alias ? `${alias}.` : "";
128
+ return `((${prefix}org_id = ? AND ? IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))`;
129
+ }
130
+ function authorizationArgs(access) {
131
+ return [access.orgId, access.orgId, access.ownerEmail];
132
+ }
133
+ function policyFromRow(row) {
134
+ return {
135
+ requireMention: Number(row.require_mention) === 1,
136
+ allowDirectMessages: Number(row.allow_direct_messages) === 1,
137
+ allowGuests: Number(row.allow_guests) === 1,
138
+ allowExternalShared: Number(row.allow_external_shared) === 1,
139
+ allowUnknownTrust: Number(row.allow_unknown_trust) === 1,
140
+ };
141
+ }
142
+ function rowToScope(row) {
143
+ return {
144
+ id: String(row.id),
145
+ platform: String(row.platform),
146
+ tenantId: String(row.tenant_id),
147
+ conversationId: String(row.conversation_id),
148
+ conversationType: row.conversation_type,
149
+ trust: row.trust_level,
150
+ ownerEmail: String(row.owner_email),
151
+ orgId: row.org_id == null ? null : String(row.org_id),
152
+ installationId: row.installation_id == null ? null : String(row.installation_id),
153
+ serviceOwnerEmail: String(row.service_owner_email),
154
+ defaultModel: row.default_model == null ? null : String(row.default_model),
155
+ policy: policyFromRow(row),
156
+ createdAt: Number(row.created_at),
157
+ updatedAt: Number(row.updated_at),
158
+ };
159
+ }
160
+ const SELECT_COLUMNS = `id, platform, tenant_id, conversation_id,
161
+ conversation_type, trust_level, owner_email, org_id, installation_id,
162
+ service_owner_email, require_mention, allow_direct_messages, allow_guests,
163
+ allow_external_shared, allow_unknown_trust, default_model, created_at, updated_at`;
164
+ function isUniqueViolation(error) {
165
+ const value = error;
166
+ if (value?.code === "23505")
167
+ return true;
168
+ return /unique|duplicate/i.test(String(value?.message ?? error ?? ""));
169
+ }
170
+ function normalizePolicy(policy) {
171
+ return {
172
+ ...DEFAULT_INTEGRATION_SCOPE_POLICY,
173
+ ...policy,
174
+ };
175
+ }
176
+ function resolveOrgId(requested, access) {
177
+ if (requested === null)
178
+ return null;
179
+ if (requested === undefined)
180
+ return access.orgId;
181
+ const normalized = requiredString(requested, "orgId");
182
+ if (!access.orgId || normalized !== access.orgId) {
183
+ throw new Error("Not authorized to manage an integration scope for that org");
184
+ }
185
+ return normalized;
186
+ }
187
+ export async function getIntegrationScope(keyInput, accessInput) {
188
+ await ensureTable();
189
+ const key = normalizeKey(keyInput);
190
+ const access = normalizeAccess(accessInput);
191
+ const { rows } = await getDbExec().execute({
192
+ sql: `SELECT ${SELECT_COLUMNS}
193
+ FROM integration_conversation_scopes
194
+ WHERE platform = ? AND tenant_id = ? AND conversation_id = ?
195
+ AND ${authorizationSql()}
196
+ LIMIT 1`,
197
+ args: [
198
+ key.platform,
199
+ key.tenantId,
200
+ key.conversationId,
201
+ ...authorizationArgs(access),
202
+ ],
203
+ });
204
+ return rows.length > 0
205
+ ? rowToScope(rows[0])
206
+ : null;
207
+ }
208
+ export async function listIntegrationScopes(accessInput, filter = {}) {
209
+ await ensureTable();
210
+ const access = normalizeAccess(accessInput);
211
+ const clauses = [authorizationSql()];
212
+ const args = [...authorizationArgs(access)];
213
+ if (filter.platform) {
214
+ clauses.push("platform = ?");
215
+ args.push(requiredString(filter.platform, "platform", 80).toLowerCase());
216
+ }
217
+ if (filter.tenantId) {
218
+ clauses.push("tenant_id = ?");
219
+ args.push(requiredString(filter.tenantId, "tenantId"));
220
+ }
221
+ const { rows } = await getDbExec().execute({
222
+ sql: `SELECT ${SELECT_COLUMNS}
223
+ FROM integration_conversation_scopes
224
+ WHERE ${clauses.join(" AND ")}
225
+ ORDER BY platform, tenant_id, conversation_id`,
226
+ args,
227
+ });
228
+ return rows.map((row) => rowToScope(row));
229
+ }
230
+ export async function saveIntegrationScope(input, accessInput) {
231
+ await ensureTable();
232
+ const key = normalizeKey(input);
233
+ const access = normalizeAccess(accessInput);
234
+ const orgId = resolveOrgId(input.orgId, access);
235
+ if (!CONVERSATION_TYPES.has(input.conversationType)) {
236
+ throw new Error("Unsupported integration conversation type");
237
+ }
238
+ const trust = input.trust ?? "unknown";
239
+ if (!TRUST_VALUES.has(trust)) {
240
+ throw new Error("Unsupported integration conversation trust level");
241
+ }
242
+ const serviceOwnerEmail = serviceOwnerForScope(key, access, orgId);
243
+ const installationId = input.installationId
244
+ ? requiredString(input.installationId, "installationId")
245
+ : null;
246
+ const defaultModel = input.defaultModel?.trim().slice(0, 200) || null;
247
+ const policy = normalizePolicy(input.policy);
248
+ const now = Date.now();
249
+ const db = getDbExec();
250
+ const updated = await db.execute({
251
+ sql: `UPDATE integration_conversation_scopes SET
252
+ conversation_type = ?, trust_level = ?, installation_id = ?,
253
+ service_owner_email = ?, require_mention = ?, allow_direct_messages = ?,
254
+ allow_guests = ?, allow_external_shared = ?, allow_unknown_trust = ?,
255
+ default_model = ?, updated_at = ?
256
+ WHERE platform = ? AND tenant_id = ? AND conversation_id = ?
257
+ AND ${authorizationSql()}`,
258
+ args: [
259
+ input.conversationType,
260
+ trust,
261
+ installationId,
262
+ serviceOwnerEmail,
263
+ policy.requireMention ? 1 : 0,
264
+ policy.allowDirectMessages ? 1 : 0,
265
+ policy.allowGuests ? 1 : 0,
266
+ policy.allowExternalShared ? 1 : 0,
267
+ policy.allowUnknownTrust ? 1 : 0,
268
+ defaultModel,
269
+ now,
270
+ key.platform,
271
+ key.tenantId,
272
+ key.conversationId,
273
+ ...authorizationArgs(access),
274
+ ],
275
+ });
276
+ if (updated.rowsAffected === 0) {
277
+ try {
278
+ await db.execute({
279
+ sql: `INSERT INTO integration_conversation_scopes (
280
+ id, platform, tenant_id, conversation_id, conversation_type,
281
+ trust_level, owner_email, org_id, installation_id,
282
+ service_owner_email, require_mention, allow_direct_messages,
283
+ allow_guests, allow_external_shared, allow_unknown_trust,
284
+ default_model, created_at, updated_at
285
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
286
+ args: [
287
+ scopeId(key),
288
+ key.platform,
289
+ key.tenantId,
290
+ key.conversationId,
291
+ input.conversationType,
292
+ trust,
293
+ access.ownerEmail,
294
+ orgId,
295
+ installationId,
296
+ serviceOwnerEmail,
297
+ policy.requireMention ? 1 : 0,
298
+ policy.allowDirectMessages ? 1 : 0,
299
+ policy.allowGuests ? 1 : 0,
300
+ policy.allowExternalShared ? 1 : 0,
301
+ policy.allowUnknownTrust ? 1 : 0,
302
+ defaultModel,
303
+ now,
304
+ now,
305
+ ],
306
+ });
307
+ }
308
+ catch (error) {
309
+ if (isUniqueViolation(error)) {
310
+ throw new Error("Integration scope is not available to this caller");
311
+ }
312
+ throw error;
313
+ }
314
+ }
315
+ const saved = await getIntegrationScope(key, access);
316
+ if (!saved)
317
+ throw new Error("Integration scope write could not be verified");
318
+ return saved;
319
+ }
320
+ export async function deleteIntegrationScope(keyInput, accessInput) {
321
+ await ensureTable();
322
+ const key = normalizeKey(keyInput);
323
+ const access = normalizeAccess(accessInput);
324
+ const result = await getDbExec().execute({
325
+ sql: `DELETE FROM integration_conversation_scopes
326
+ WHERE platform = ? AND tenant_id = ? AND conversation_id = ?
327
+ AND ${authorizationSql()}`,
328
+ args: [
329
+ key.platform,
330
+ key.tenantId,
331
+ key.conversationId,
332
+ ...authorizationArgs(access),
333
+ ],
334
+ });
335
+ return result.rowsAffected > 0;
336
+ }
337
+ export function evaluateIntegrationScopePolicy(scope, context) {
338
+ if (scope.policy.requireMention && !context.mentioned) {
339
+ return { allowed: false, reason: "mention_required" };
340
+ }
341
+ if ((scope.conversationType === "direct_message" ||
342
+ scope.conversationType === "group_direct_message") &&
343
+ !scope.policy.allowDirectMessages) {
344
+ return { allowed: false, reason: "direct_messages_disabled" };
345
+ }
346
+ if (scope.trust === "guest" && !scope.policy.allowGuests) {
347
+ return { allowed: false, reason: "guests_disabled" };
348
+ }
349
+ if (scope.trust === "external_shared" && !scope.policy.allowExternalShared) {
350
+ return { allowed: false, reason: "external_shared_disabled" };
351
+ }
352
+ if (scope.trust === "unknown" && !scope.policy.allowUnknownTrust) {
353
+ return { allowed: false, reason: "unverified_conversation_disabled" };
354
+ }
355
+ return { allowed: true };
356
+ }
357
+ /** Test-only reset for suites that swap the injected database. */
358
+ export function _resetIntegrationScopeStoreForTests() {
359
+ initPromise = undefined;
360
+ }
361
+ //# sourceMappingURL=scope-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-store.js","sourceRoot":"","sources":["../../src/integrations/scope-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { getDbExec, intType, isPostgres } from \"../db/client.js\";\nimport {\n ensureColumnExists,\n ensureIndexExists,\n ensureTableExists,\n} from \"../db/ddl-guard.js\";\n\nlet initPromise: Promise<void> | undefined;\n\nexport type IntegrationConversationType =\n | \"channel\"\n | \"direct_message\"\n | \"group_direct_message\";\n\nexport type IntegrationConversationTrust =\n | \"trusted\"\n | \"guest\"\n | \"external_shared\"\n | \"unknown\";\n\nexport interface IntegrationScopeAccess {\n ownerEmail: string;\n orgId?: string | null;\n}\n\nexport interface IntegrationScopeKey {\n platform: string;\n tenantId: string;\n conversationId: string;\n}\n\nexport interface IntegrationScopePolicy {\n requireMention: boolean;\n allowDirectMessages: boolean;\n allowGuests: boolean;\n allowExternalShared: boolean;\n allowUnknownTrust: boolean;\n}\n\nexport const DEFAULT_INTEGRATION_SCOPE_POLICY: Readonly<IntegrationScopePolicy> =\n Object.freeze({\n requireMention: true,\n allowDirectMessages: false,\n allowGuests: false,\n allowExternalShared: false,\n allowUnknownTrust: false,\n });\n\nexport interface IntegrationScope extends IntegrationScopeKey {\n id: string;\n conversationType: IntegrationConversationType;\n trust: IntegrationConversationTrust;\n ownerEmail: string;\n orgId: string | null;\n installationId: string | null;\n serviceOwnerEmail: string;\n defaultModel: string | null;\n policy: IntegrationScopePolicy;\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface SaveIntegrationScopeInput extends IntegrationScopeKey {\n conversationType: IntegrationConversationType;\n trust?: IntegrationConversationTrust;\n /**\n * Omit to use the caller's active org, or pass null for a personal scope.\n * Passing an org other than the caller's active org is always rejected.\n */\n orgId?: string | null;\n installationId?: string | null;\n defaultModel?: string | null;\n policy?: Partial<IntegrationScopePolicy>;\n}\n\nconst CONVERSATION_TYPES = new Set<IntegrationConversationType>([\n \"channel\",\n \"direct_message\",\n \"group_direct_message\",\n]);\nconst TRUST_VALUES = new Set<IntegrationConversationTrust>([\n \"trusted\",\n \"guest\",\n \"external_shared\",\n \"unknown\",\n]);\n\nasync function ensureTable(): Promise<void> {\n if (!initPromise) {\n initPromise = (async () => {\n const db = getDbExec();\n const createSql = `CREATE TABLE IF NOT EXISTS integration_conversation_scopes (\n id TEXT PRIMARY KEY,\n platform TEXT NOT NULL,\n tenant_id TEXT NOT NULL,\n conversation_id TEXT NOT NULL,\n conversation_type TEXT NOT NULL,\n trust_level TEXT NOT NULL DEFAULT 'unknown',\n owner_email TEXT NOT NULL,\n org_id TEXT,\n installation_id TEXT,\n service_owner_email TEXT NOT NULL,\n default_model TEXT,\n require_mention ${intType()} NOT NULL DEFAULT 1,\n allow_direct_messages ${intType()} NOT NULL DEFAULT 0,\n allow_guests ${intType()} NOT NULL DEFAULT 0,\n allow_external_shared ${intType()} NOT NULL DEFAULT 0,\n allow_unknown_trust ${intType()} NOT NULL DEFAULT 0,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )`;\n const uniqueIndexSql =\n \"CREATE UNIQUE INDEX IF NOT EXISTS idx_integration_scope_external_key ON integration_conversation_scopes(platform, tenant_id, conversation_id)\";\n const ownerIndexSql =\n \"CREATE INDEX IF NOT EXISTS idx_integration_scope_owner ON integration_conversation_scopes(owner_email, platform, tenant_id)\";\n const orgIndexSql =\n \"CREATE INDEX IF NOT EXISTS idx_integration_scope_org ON integration_conversation_scopes(org_id, platform, tenant_id)\";\n\n if (isPostgres()) {\n await ensureTableExists(\"integration_conversation_scopes\", createSql);\n await ensureColumnExists(\n \"integration_conversation_scopes\",\n \"default_model\",\n \"ALTER TABLE integration_conversation_scopes ADD COLUMN IF NOT EXISTS default_model TEXT\",\n );\n await ensureIndexExists(\n \"idx_integration_scope_external_key\",\n uniqueIndexSql,\n );\n await ensureIndexExists(\"idx_integration_scope_owner\", ownerIndexSql);\n await ensureIndexExists(\"idx_integration_scope_org\", orgIndexSql);\n return;\n }\n\n await db.execute(createSql);\n try {\n await db.execute(\n \"ALTER TABLE integration_conversation_scopes ADD COLUMN default_model TEXT\",\n );\n } catch (error) {\n if (!/duplicate/i.test(String((error as Error)?.message ?? error))) {\n throw error;\n }\n }\n await db.execute(uniqueIndexSql);\n await db.execute(ownerIndexSql);\n await db.execute(orgIndexSql);\n })().catch((error) => {\n initPromise = undefined;\n throw error;\n });\n }\n return initPromise;\n}\n\nfunction requiredString(value: unknown, name: string, maxLength = 255): string {\n const normalized = String(value ?? \"\").trim();\n if (!normalized) throw new Error(`${name} is required`);\n if (normalized.length > maxLength) {\n throw new Error(`${name} must be at most ${maxLength} characters`);\n }\n return normalized;\n}\n\nfunction normalizeEmail(value: unknown, name: string): string {\n const email = requiredString(value, name, 320).toLowerCase();\n if (!email.includes(\"@\")) throw new Error(`${name} must be an email address`);\n return email;\n}\n\nfunction normalizeAccess(\n access: IntegrationScopeAccess,\n): Required<IntegrationScopeAccess> {\n return {\n ownerEmail: normalizeEmail(access.ownerEmail, \"ownerEmail\"),\n orgId: access.orgId ? requiredString(access.orgId, \"orgId\") : null,\n };\n}\n\nfunction normalizeKey(key: IntegrationScopeKey): IntegrationScopeKey {\n return {\n platform: requiredString(key.platform, \"platform\", 80).toLowerCase(),\n tenantId: requiredString(key.tenantId, \"tenantId\"),\n conversationId: requiredString(key.conversationId, \"conversationId\"),\n };\n}\n\n/** A stable, non-secret subject key suitable for a scope budget. */\nexport function integrationScopeSubjectKey(key: IntegrationScopeKey): string {\n const normalized = normalizeKey(key);\n return JSON.stringify([\n normalized.platform,\n normalized.tenantId,\n normalized.conversationId,\n ]);\n}\n\nfunction scopeId(key: IntegrationScopeKey): string {\n return `scope:${integrationScopeSubjectKey(key)}`;\n}\n\nfunction serviceOwnerForScope(\n key: IntegrationScopeKey,\n access: Required<IntegrationScopeAccess>,\n orgId: string | null,\n): string {\n if (!orgId) return access.ownerEmail;\n const subject = createHash(\"sha256\")\n .update(`${orgId}:${integrationScopeSubjectKey(key)}`)\n .digest(\"hex\")\n .slice(0, 24);\n return `integration+${subject}@service.agent-native.local`;\n}\n\nfunction authorizationSql(alias = \"\"): string {\n const prefix = alias ? `${alias}.` : \"\";\n return `((${prefix}org_id = ? AND ? IS NOT NULL) OR (${prefix}org_id IS NULL AND ${prefix}owner_email = ?))`;\n}\n\nfunction authorizationArgs(\n access: Required<IntegrationScopeAccess>,\n): unknown[] {\n return [access.orgId, access.orgId, access.ownerEmail];\n}\n\nfunction policyFromRow(row: Record<string, unknown>): IntegrationScopePolicy {\n return {\n requireMention: Number(row.require_mention) === 1,\n allowDirectMessages: Number(row.allow_direct_messages) === 1,\n allowGuests: Number(row.allow_guests) === 1,\n allowExternalShared: Number(row.allow_external_shared) === 1,\n allowUnknownTrust: Number(row.allow_unknown_trust) === 1,\n };\n}\n\nfunction rowToScope(row: Record<string, unknown>): IntegrationScope {\n return {\n id: String(row.id),\n platform: String(row.platform),\n tenantId: String(row.tenant_id),\n conversationId: String(row.conversation_id),\n conversationType: row.conversation_type as IntegrationConversationType,\n trust: row.trust_level as IntegrationConversationTrust,\n ownerEmail: String(row.owner_email),\n orgId: row.org_id == null ? null : String(row.org_id),\n installationId:\n row.installation_id == null ? null : String(row.installation_id),\n serviceOwnerEmail: String(row.service_owner_email),\n defaultModel: row.default_model == null ? null : String(row.default_model),\n policy: policyFromRow(row),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n };\n}\n\nconst SELECT_COLUMNS = `id, platform, tenant_id, conversation_id,\n conversation_type, trust_level, owner_email, org_id, installation_id,\n service_owner_email, require_mention, allow_direct_messages, allow_guests,\n allow_external_shared, allow_unknown_trust, default_model, created_at, updated_at`;\n\nfunction isUniqueViolation(error: unknown): boolean {\n const value = error as { code?: string; message?: string } | null;\n if (value?.code === \"23505\") return true;\n return /unique|duplicate/i.test(String(value?.message ?? error ?? \"\"));\n}\n\nfunction normalizePolicy(\n policy: Partial<IntegrationScopePolicy> | undefined,\n): IntegrationScopePolicy {\n return {\n ...DEFAULT_INTEGRATION_SCOPE_POLICY,\n ...policy,\n };\n}\n\nfunction resolveOrgId(\n requested: string | null | undefined,\n access: Required<IntegrationScopeAccess>,\n): string | null {\n if (requested === null) return null;\n if (requested === undefined) return access.orgId;\n const normalized = requiredString(requested, \"orgId\");\n if (!access.orgId || normalized !== access.orgId) {\n throw new Error(\n \"Not authorized to manage an integration scope for that org\",\n );\n }\n return normalized;\n}\n\nexport async function getIntegrationScope(\n keyInput: IntegrationScopeKey,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationScope | null> {\n await ensureTable();\n const key = normalizeKey(keyInput);\n const access = normalizeAccess(accessInput);\n const { rows } = await getDbExec().execute({\n sql: `SELECT ${SELECT_COLUMNS}\n FROM integration_conversation_scopes\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}\n LIMIT 1`,\n args: [\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n return rows.length > 0\n ? rowToScope(rows[0] as Record<string, unknown>)\n : null;\n}\n\nexport async function listIntegrationScopes(\n accessInput: IntegrationScopeAccess,\n filter: { platform?: string; tenantId?: string } = {},\n): Promise<IntegrationScope[]> {\n await ensureTable();\n const access = normalizeAccess(accessInput);\n const clauses = [authorizationSql()];\n const args: unknown[] = [...authorizationArgs(access)];\n if (filter.platform) {\n clauses.push(\"platform = ?\");\n args.push(requiredString(filter.platform, \"platform\", 80).toLowerCase());\n }\n if (filter.tenantId) {\n clauses.push(\"tenant_id = ?\");\n args.push(requiredString(filter.tenantId, \"tenantId\"));\n }\n const { rows } = await getDbExec().execute({\n sql: `SELECT ${SELECT_COLUMNS}\n FROM integration_conversation_scopes\n WHERE ${clauses.join(\" AND \")}\n ORDER BY platform, tenant_id, conversation_id`,\n args,\n });\n return rows.map((row) => rowToScope(row as Record<string, unknown>));\n}\n\nexport async function saveIntegrationScope(\n input: SaveIntegrationScopeInput,\n accessInput: IntegrationScopeAccess,\n): Promise<IntegrationScope> {\n await ensureTable();\n const key = normalizeKey(input);\n const access = normalizeAccess(accessInput);\n const orgId = resolveOrgId(input.orgId, access);\n if (!CONVERSATION_TYPES.has(input.conversationType)) {\n throw new Error(\"Unsupported integration conversation type\");\n }\n const trust = input.trust ?? \"unknown\";\n if (!TRUST_VALUES.has(trust)) {\n throw new Error(\"Unsupported integration conversation trust level\");\n }\n const serviceOwnerEmail = serviceOwnerForScope(key, access, orgId);\n const installationId = input.installationId\n ? requiredString(input.installationId, \"installationId\")\n : null;\n const defaultModel = input.defaultModel?.trim().slice(0, 200) || null;\n const policy = normalizePolicy(input.policy);\n const now = Date.now();\n const db = getDbExec();\n\n const updated = await db.execute({\n sql: `UPDATE integration_conversation_scopes SET\n conversation_type = ?, trust_level = ?, installation_id = ?,\n service_owner_email = ?, require_mention = ?, allow_direct_messages = ?,\n allow_guests = ?, allow_external_shared = ?, allow_unknown_trust = ?,\n default_model = ?, updated_at = ?\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}`,\n args: [\n input.conversationType,\n trust,\n installationId,\n serviceOwnerEmail,\n policy.requireMention ? 1 : 0,\n policy.allowDirectMessages ? 1 : 0,\n policy.allowGuests ? 1 : 0,\n policy.allowExternalShared ? 1 : 0,\n policy.allowUnknownTrust ? 1 : 0,\n defaultModel,\n now,\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n\n if (updated.rowsAffected === 0) {\n try {\n await db.execute({\n sql: `INSERT INTO integration_conversation_scopes (\n id, platform, tenant_id, conversation_id, conversation_type,\n trust_level, owner_email, org_id, installation_id,\n service_owner_email, require_mention, allow_direct_messages,\n allow_guests, allow_external_shared, allow_unknown_trust,\n default_model, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n scopeId(key),\n key.platform,\n key.tenantId,\n key.conversationId,\n input.conversationType,\n trust,\n access.ownerEmail,\n orgId,\n installationId,\n serviceOwnerEmail,\n policy.requireMention ? 1 : 0,\n policy.allowDirectMessages ? 1 : 0,\n policy.allowGuests ? 1 : 0,\n policy.allowExternalShared ? 1 : 0,\n policy.allowUnknownTrust ? 1 : 0,\n defaultModel,\n now,\n now,\n ],\n });\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new Error(\"Integration scope is not available to this caller\");\n }\n throw error;\n }\n }\n\n const saved = await getIntegrationScope(key, access);\n if (!saved) throw new Error(\"Integration scope write could not be verified\");\n return saved;\n}\n\nexport async function deleteIntegrationScope(\n keyInput: IntegrationScopeKey,\n accessInput: IntegrationScopeAccess,\n): Promise<boolean> {\n await ensureTable();\n const key = normalizeKey(keyInput);\n const access = normalizeAccess(accessInput);\n const result = await getDbExec().execute({\n sql: `DELETE FROM integration_conversation_scopes\n WHERE platform = ? AND tenant_id = ? AND conversation_id = ?\n AND ${authorizationSql()}`,\n args: [\n key.platform,\n key.tenantId,\n key.conversationId,\n ...authorizationArgs(access),\n ],\n });\n return result.rowsAffected > 0;\n}\n\nexport type IntegrationScopePolicyDenial =\n | \"mention_required\"\n | \"direct_messages_disabled\"\n | \"guests_disabled\"\n | \"external_shared_disabled\"\n | \"unverified_conversation_disabled\";\n\nexport function evaluateIntegrationScopePolicy(\n scope: Pick<IntegrationScope, \"conversationType\" | \"trust\" | \"policy\">,\n context: { mentioned: boolean },\n):\n | { allowed: true }\n | { allowed: false; reason: IntegrationScopePolicyDenial } {\n if (scope.policy.requireMention && !context.mentioned) {\n return { allowed: false, reason: \"mention_required\" };\n }\n if (\n (scope.conversationType === \"direct_message\" ||\n scope.conversationType === \"group_direct_message\") &&\n !scope.policy.allowDirectMessages\n ) {\n return { allowed: false, reason: \"direct_messages_disabled\" };\n }\n if (scope.trust === \"guest\" && !scope.policy.allowGuests) {\n return { allowed: false, reason: \"guests_disabled\" };\n }\n if (scope.trust === \"external_shared\" && !scope.policy.allowExternalShared) {\n return { allowed: false, reason: \"external_shared_disabled\" };\n }\n if (scope.trust === \"unknown\" && !scope.policy.allowUnknownTrust) {\n return { allowed: false, reason: \"unverified_conversation_disabled\" };\n }\n return { allowed: true };\n}\n\n/** Test-only reset for suites that swap the injected database. */\nexport function _resetIntegrationScopeStoreForTests(): void {\n initPromise = undefined;\n}\n"]}
@@ -0,0 +1,66 @@
1
+ export declare const SLACK_AGENT_BOT_EVENTS: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.channels", "message.groups", "message.im", "message.mpim"];
2
+ export interface SlackAgentManifestUrls {
3
+ oauthRedirectUrl: string;
4
+ eventsRequestUrl: string;
5
+ interactivityRequestUrl: string;
6
+ }
7
+ /**
8
+ * Build the canonical Slack app manifest for Agent Native.
9
+ *
10
+ * Slack app capabilities are controlled by the app configuration, not by an
11
+ * individual workspace's OAuth install. Keeping this manifest in core gives
12
+ * self-hosted apps one exact, versioned configuration for Agent View, writable
13
+ * DMs, channel mentions, contextual messages, and interactive run controls.
14
+ */
15
+ export declare function buildSlackAgentManifest(urls: SlackAgentManifestUrls): {
16
+ readonly _metadata: {
17
+ readonly major_version: 2;
18
+ readonly minor_version: 1;
19
+ };
20
+ readonly display_information: {
21
+ readonly name: "Agent Native";
22
+ readonly description: "Delegate work to your Agent Native apps from Slack.";
23
+ readonly background_color: "#0f172a";
24
+ };
25
+ readonly features: {
26
+ readonly bot_user: {
27
+ readonly display_name: "agent-native";
28
+ readonly always_online: false;
29
+ };
30
+ readonly app_home: {
31
+ readonly home_tab_enabled: false;
32
+ readonly messages_tab_enabled: true;
33
+ readonly messages_tab_read_only_enabled: false;
34
+ };
35
+ readonly agent_view: {
36
+ readonly agent_description: "Delegate work to your Agent Native apps from Slack.";
37
+ readonly suggested_prompts: readonly [{
38
+ readonly title: "Start a task";
39
+ readonly message: "What can you help me accomplish?";
40
+ }, {
41
+ readonly title: "Check work";
42
+ readonly message: "What work is currently in progress?";
43
+ }];
44
+ };
45
+ };
46
+ readonly oauth_config: {
47
+ readonly redirect_urls: readonly [string];
48
+ readonly scopes: {
49
+ readonly bot: readonly ["assistant:write", "app_mentions:read", "channels:read", "channels:history", "chat:write", "files:read", "groups:history", "groups:read", "im:history", "im:read", "mpim:history", "mpim:read", "pins:read", "reactions:read", "users:read", "users:read.email"];
50
+ };
51
+ };
52
+ readonly settings: {
53
+ readonly event_subscriptions: {
54
+ readonly request_url: string;
55
+ readonly bot_events: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.channels", "message.groups", "message.im", "message.mpim"];
56
+ };
57
+ readonly interactivity: {
58
+ readonly is_enabled: true;
59
+ readonly request_url: string;
60
+ };
61
+ readonly org_deploy_enabled: false;
62
+ readonly socket_mode_enabled: false;
63
+ readonly token_rotation_enabled: false;
64
+ };
65
+ };
66
+ //# sourceMappingURL=slack-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-manifest.d.ts","sourceRoot":"","sources":["../../src/integrations/slack-manifest.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,YACjC,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,cAAc,CACN,CAAC;AAEX,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,sBAAsB;aAEhE,SAAS;iBAAI,aAAa,EAAE,CAAC;iBAAE,aAAa,EAAE,CAAC;;aAC/C,mBAAmB;iBACjB,IAAI,EAAE,cAAc;iBACpB,WAAW,EAAE,qDAAqD;iBAClE,gBAAgB,EAAE,SAAS;;aAE7B,QAAQ;iBACN,QAAQ;qBACN,YAAY,EAAE,cAAc;qBAC5B,aAAa;;iBAEf,QAAQ;qBACN,gBAAgB;qBAChB,oBAAoB;qBACpB,8BAA8B;;iBAEhC,UAAU;qBACR,iBAAiB,EACf,qDAAqD;qBACvD,iBAAiB;yBAEb,KAAK,EAAE,cAAc;yBACrB,OAAO,EAAE,kCAAkC;;yBAG3C,KAAK,EAAE,YAAY;yBACnB,OAAO,EAAE,qCAAqC;;;;aAKtD,YAAY;iBACV,aAAa;iBACb,MAAM;qBAAI,GAAG;;;aAEf,QAAQ;iBACN,mBAAmB;qBACjB,WAAW;qBACX,UAAU;;iBAEZ,aAAa;qBACX,UAAU;qBACV,WAAW;;iBAEb,kBAAkB;iBAClB,mBAAmB;iBACnB,sBAAsB;;EAG3B"}
@@ -0,0 +1,70 @@
1
+ import { SLACK_AGENT_BOT_SCOPES } from "./slack-oauth.js";
2
+ export const SLACK_AGENT_BOT_EVENTS = [
3
+ "app_home_opened",
4
+ "app_context_changed",
5
+ "app_mention",
6
+ "message.channels",
7
+ "message.groups",
8
+ "message.im",
9
+ "message.mpim",
10
+ ];
11
+ /**
12
+ * Build the canonical Slack app manifest for Agent Native.
13
+ *
14
+ * Slack app capabilities are controlled by the app configuration, not by an
15
+ * individual workspace's OAuth install. Keeping this manifest in core gives
16
+ * self-hosted apps one exact, versioned configuration for Agent View, writable
17
+ * DMs, channel mentions, contextual messages, and interactive run controls.
18
+ */
19
+ export function buildSlackAgentManifest(urls) {
20
+ return {
21
+ _metadata: { major_version: 2, minor_version: 1 },
22
+ display_information: {
23
+ name: "Agent Native",
24
+ description: "Delegate work to your Agent Native apps from Slack.",
25
+ background_color: "#0f172a",
26
+ },
27
+ features: {
28
+ bot_user: {
29
+ display_name: "agent-native",
30
+ always_online: false,
31
+ },
32
+ app_home: {
33
+ home_tab_enabled: false,
34
+ messages_tab_enabled: true,
35
+ messages_tab_read_only_enabled: false,
36
+ },
37
+ agent_view: {
38
+ agent_description: "Delegate work to your Agent Native apps from Slack.",
39
+ suggested_prompts: [
40
+ {
41
+ title: "Start a task",
42
+ message: "What can you help me accomplish?",
43
+ },
44
+ {
45
+ title: "Check work",
46
+ message: "What work is currently in progress?",
47
+ },
48
+ ],
49
+ },
50
+ },
51
+ oauth_config: {
52
+ redirect_urls: [urls.oauthRedirectUrl],
53
+ scopes: { bot: [...SLACK_AGENT_BOT_SCOPES] },
54
+ },
55
+ settings: {
56
+ event_subscriptions: {
57
+ request_url: urls.eventsRequestUrl,
58
+ bot_events: [...SLACK_AGENT_BOT_EVENTS],
59
+ },
60
+ interactivity: {
61
+ is_enabled: true,
62
+ request_url: urls.interactivityRequestUrl,
63
+ },
64
+ org_deploy_enabled: false,
65
+ socket_mode_enabled: false,
66
+ token_rotation_enabled: false,
67
+ },
68
+ };
69
+ }
70
+ //# sourceMappingURL=slack-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-manifest.js","sourceRoot":"","sources":["../../src/integrations/slack-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,iBAAiB;IACjB,qBAAqB;IACrB,aAAa;IACb,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,cAAc;CACN,CAAC;AAQX;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAA4B;IAClE,OAAO;QACL,SAAS,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;QACjD,mBAAmB,EAAE;YACnB,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,qDAAqD;YAClE,gBAAgB,EAAE,SAAS;SAC5B;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE;gBACR,YAAY,EAAE,cAAc;gBAC5B,aAAa,EAAE,KAAK;aACrB;YACD,QAAQ,EAAE;gBACR,gBAAgB,EAAE,KAAK;gBACvB,oBAAoB,EAAE,IAAI;gBAC1B,8BAA8B,EAAE,KAAK;aACtC;YACD,UAAU,EAAE;gBACV,iBAAiB,EACf,qDAAqD;gBACvD,iBAAiB,EAAE;oBACjB;wBACE,KAAK,EAAE,cAAc;wBACrB,OAAO,EAAE,kCAAkC;qBAC5C;oBACD;wBACE,KAAK,EAAE,YAAY;wBACnB,OAAO,EAAE,qCAAqC;qBAC/C;iBACF;aACF;SACF;QACD,YAAY,EAAE;YACZ,aAAa,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC;YACtC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,sBAAsB,CAAC,EAAE;SAC7C;QACD,QAAQ,EAAE;YACR,mBAAmB,EAAE;gBACnB,WAAW,EAAE,IAAI,CAAC,gBAAgB;gBAClC,UAAU,EAAE,CAAC,GAAG,sBAAsB,CAAC;aACxC;YACD,aAAa,EAAE;gBACb,UAAU,EAAE,IAAI;gBAChB,WAAW,EAAE,IAAI,CAAC,uBAAuB;aAC1C;YACD,kBAAkB,EAAE,KAAK;YACzB,mBAAmB,EAAE,KAAK;YAC1B,sBAAsB,EAAE,KAAK;SAC9B;KACO,CAAC;AACb,CAAC","sourcesContent":["import { SLACK_AGENT_BOT_SCOPES } from \"./slack-oauth.js\";\n\nexport const SLACK_AGENT_BOT_EVENTS = [\n \"app_home_opened\",\n \"app_context_changed\",\n \"app_mention\",\n \"message.channels\",\n \"message.groups\",\n \"message.im\",\n \"message.mpim\",\n] as const;\n\nexport interface SlackAgentManifestUrls {\n oauthRedirectUrl: string;\n eventsRequestUrl: string;\n interactivityRequestUrl: string;\n}\n\n/**\n * Build the canonical Slack app manifest for Agent Native.\n *\n * Slack app capabilities are controlled by the app configuration, not by an\n * individual workspace's OAuth install. Keeping this manifest in core gives\n * self-hosted apps one exact, versioned configuration for Agent View, writable\n * DMs, channel mentions, contextual messages, and interactive run controls.\n */\nexport function buildSlackAgentManifest(urls: SlackAgentManifestUrls) {\n return {\n _metadata: { major_version: 2, minor_version: 1 },\n display_information: {\n name: \"Agent Native\",\n description: \"Delegate work to your Agent Native apps from Slack.\",\n background_color: \"#0f172a\",\n },\n features: {\n bot_user: {\n display_name: \"agent-native\",\n always_online: false,\n },\n app_home: {\n home_tab_enabled: false,\n messages_tab_enabled: true,\n messages_tab_read_only_enabled: false,\n },\n agent_view: {\n agent_description:\n \"Delegate work to your Agent Native apps from Slack.\",\n suggested_prompts: [\n {\n title: \"Start a task\",\n message: \"What can you help me accomplish?\",\n },\n {\n title: \"Check work\",\n message: \"What work is currently in progress?\",\n },\n ],\n },\n },\n oauth_config: {\n redirect_urls: [urls.oauthRedirectUrl],\n scopes: { bot: [...SLACK_AGENT_BOT_SCOPES] },\n },\n settings: {\n event_subscriptions: {\n request_url: urls.eventsRequestUrl,\n bot_events: [...SLACK_AGENT_BOT_EVENTS],\n },\n interactivity: {\n is_enabled: true,\n request_url: urls.interactivityRequestUrl,\n },\n org_deploy_enabled: false,\n socket_mode_enabled: false,\n token_rotation_enabled: false,\n },\n } as const;\n}\n"]}