@agent-native/core 0.92.11 → 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 (777) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +45 -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 +48 -5
  55. package/corpus/core/src/agent/run-manager.ts +171 -20
  56. package/corpus/core/src/agent/run-store.ts +297 -42
  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 +110 -17
  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/components/player/transcript-panel.tsx +27 -5
  168. package/corpus/templates/clips/app/hooks/use-library.ts +1 -1
  169. package/corpus/templates/clips/app/hooks/use-navigation-state.ts +10 -2
  170. package/corpus/templates/clips/app/hooks/use-player-shortcuts.ts +1 -0
  171. package/corpus/templates/clips/app/i18n/ar-SA.ts +7 -1
  172. package/corpus/templates/clips/app/i18n/de-DE.ts +7 -1
  173. package/corpus/templates/clips/app/i18n/en-US.ts +7 -1
  174. package/corpus/templates/clips/app/i18n/es-ES.ts +7 -1
  175. package/corpus/templates/clips/app/i18n/fr-FR.ts +7 -1
  176. package/corpus/templates/clips/app/i18n/hi-IN.ts +7 -1
  177. package/corpus/templates/clips/app/i18n/ja-JP.ts +7 -1
  178. package/corpus/templates/clips/app/i18n/ko-KR.ts +7 -1
  179. package/corpus/templates/clips/app/i18n/pt-BR.ts +7 -1
  180. package/corpus/templates/clips/app/i18n/zh-CN.ts +8 -1
  181. package/corpus/templates/clips/app/i18n/zh-TW.ts +8 -1
  182. package/corpus/templates/clips/app/lib/recording-visibility.ts +70 -0
  183. package/corpus/templates/clips/app/routes/_app.shared.tsx +20 -0
  184. package/corpus/templates/clips/app/routes/download.tsx +24 -8
  185. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +115 -2
  186. package/corpus/templates/clips/app/routes/record.tsx +62 -0
  187. package/corpus/templates/clips/app/routes/share.$shareId.tsx +25 -16
  188. package/corpus/templates/clips/changelog/2026-07-10-clips-desktop-is-now-available-for-linux-with-appimage-debia.md +6 -0
  189. package/corpus/templates/clips/changelog/2026-07-10-clips-downloads-updates-sooner-in-the-background-and-offers-.md +6 -0
  190. package/corpus/templates/clips/changelog/2026-07-10-clips-shared-with-you-now-appear-in-a-searchable-shared-with.md +6 -0
  191. package/corpus/templates/clips/changelog/2026-07-10-clips-with-missing-mobile-video-frames-can-be-repaired-witho.md +6 -0
  192. package/corpus/templates/clips/changelog/2026-07-10-fixed-copying-agent-responses-and-transcript-text-from-recor.md +6 -0
  193. package/corpus/templates/clips/changelog/2026-07-10-mobile-camera-recordings-pause-while-backgrounded.md +6 -0
  194. package/corpus/templates/clips/changelog/2026-07-10-mp4-downloads-now-show-progress-immediately-after-the-option.md +6 -0
  195. package/corpus/templates/clips/changelog/2026-07-10-recording-pages-now-open-as-soon-as-you-stop-with-a-share-li.md +6 -0
  196. package/corpus/templates/clips/changelog/2026-07-10-recordings-now-seek-smoothly-downloads-use-the-correct-file-.md +6 -0
  197. package/corpus/templates/clips/changelog/2026-07-10-s3-compatible-storage-now-saves-hosted-recordings-without-re.md +6 -0
  198. package/corpus/templates/clips/desktop/README.md +22 -6
  199. package/corpus/templates/clips/desktop/package.json +1 -1
  200. package/corpus/templates/clips/desktop/src/app.tsx +32 -19
  201. package/corpus/templates/clips/desktop/src/components/ReadinessPanel.tsx +15 -9
  202. package/corpus/templates/clips/desktop/src/lib/finalization-guard.ts +22 -0
  203. package/corpus/templates/clips/desktop/src/lib/permissions.ts +3 -1
  204. package/corpus/templates/clips/desktop/src/lib/recorder.ts +97 -120
  205. package/corpus/templates/clips/desktop/src/lib/updater.ts +26 -4
  206. package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +4 -8
  207. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +1 -1
  208. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +2 -2
  209. package/corpus/templates/clips/desktop/src-tauri/src/permission_status.rs +11 -7
  210. package/corpus/templates/clips/desktop/src-tauri/tauri.linux.conf.json +11 -0
  211. package/corpus/templates/clips/netlify.toml +3 -0
  212. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +106 -0
  213. package/corpus/templates/clips/server/lib/public-agent-context.ts +9 -1
  214. package/corpus/templates/clips/server/lib/resumable-upload-provider.ts +52 -0
  215. package/corpus/templates/clips/server/lib/s3-upload-provider.ts +433 -85
  216. package/corpus/templates/clips/server/lib/video-remux.ts +114 -0
  217. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +109 -0
  218. package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +22 -11
  219. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +4 -2
  220. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +47 -5
  221. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +10 -2
  222. package/corpus/templates/clips/shared/share-loader-response.ts +12 -0
  223. package/corpus/templates/clips/shared/transcript-status.ts +40 -0
  224. package/corpus/templates/content/.agents/skills/capture-learnings/SKILL.md +22 -9
  225. package/corpus/templates/content/.agents/skills/content/SKILL.md +57 -5
  226. package/corpus/templates/content/AGENTS.md +65 -55
  227. package/corpus/templates/content/actions/_builder-cms-read-client.ts +92 -23
  228. package/corpus/templates/content/actions/_database-source-utils.ts +207 -41
  229. package/corpus/templates/content/actions/_property-utils.ts +30 -2
  230. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +316 -121
  231. package/corpus/templates/content/actions/attach-content-database-source.ts +41 -17
  232. package/corpus/templates/content/actions/change-content-database-source-role.ts +46 -8
  233. package/corpus/templates/content/actions/submit-content-database-form.ts +497 -0
  234. package/corpus/templates/content/actions/suggest-source-join-key.ts +8 -1
  235. package/corpus/templates/content/actions/update-content-database-view.ts +8 -1
  236. package/corpus/templates/content/actions/view-screen.ts +4 -1
  237. package/corpus/templates/content/agent-native.app-skill.json +1 -1
  238. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +250 -64
  239. package/corpus/templates/content/app/components/editor/database/FormView.tsx +460 -0
  240. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +3 -0
  241. package/corpus/templates/content/app/components/editor/database/settings.tsx +30 -37
  242. package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
  243. package/corpus/templates/content/app/components/editor/database/view-config.ts +29 -1
  244. package/corpus/templates/content/app/components/ui/textarea.tsx +1 -0
  245. package/corpus/templates/content/app/hooks/use-content-database.ts +22 -0
  246. package/corpus/templates/content/app/i18n/zh-TW.ts +21 -0
  247. package/corpus/templates/content/app/i18n-data.ts +225 -0
  248. package/corpus/templates/content/changelog/2026-07-09-builder-source-refreshes-now-keep-mapped-fields-such-as-topi.md +6 -0
  249. package/corpus/templates/content/changelog/2026-07-10-builder-backed-properties-now-load-current-source-values-as-.md +6 -0
  250. package/corpus/templates/content/changelog/2026-07-10-builder-database-refreshes-now-stay-explicit-and-accurate.md +6 -0
  251. package/corpus/templates/content/changelog/2026-07-10-database-form-views-now-collect-ordered-required-answers-and.md +6 -0
  252. package/corpus/templates/content/changelog/2026-07-10-database-tables-now-use-a-quieter-more-compact-layout-with-c.md +6 -0
  253. package/corpus/templates/content/changelog/2026-07-10-slack-intake-routes-to-content-database-forms.md +6 -0
  254. package/corpus/templates/content/parity/matrix.md +1 -0
  255. package/corpus/templates/content/parity/matrix.ts +18 -0
  256. package/corpus/templates/content/shared/api.ts +28 -1
  257. package/corpus/templates/content/shared/database-form.ts +53 -0
  258. package/corpus/templates/design/.agents/skills/capture-learnings/SKILL.md +22 -9
  259. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +26 -0
  260. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +85 -12
  261. package/corpus/templates/design/AGENTS.md +72 -18
  262. package/corpus/templates/design/DESIGN.md +1 -1
  263. package/corpus/templates/design/DEVELOPING.md +1 -1
  264. package/corpus/templates/design/FIGMA_INTEROPERABILITY.md +116 -0
  265. package/corpus/templates/design/actions/create-design-from-template.ts +220 -0
  266. package/corpus/templates/design/actions/create-design-system.ts +92 -16
  267. package/corpus/templates/design/actions/delete-design-template.ts +28 -0
  268. package/corpus/templates/design/actions/delete-file.ts +7 -0
  269. package/corpus/templates/design/actions/edit-design.ts +3 -0
  270. package/corpus/templates/design/actions/export-design-as-figma-svg.ts +137 -5
  271. package/corpus/templates/design/actions/export-pdf.ts +1 -1
  272. package/corpus/templates/design/actions/generate-design.ts +3 -0
  273. package/corpus/templates/design/actions/get-design-snapshot.ts +9 -0
  274. package/corpus/templates/design/actions/get-figma-connection-status.ts +26 -0
  275. package/corpus/templates/design/actions/get-figma-design-context.ts +138 -0
  276. package/corpus/templates/design/actions/get-figma-styles.ts +2 -2
  277. package/corpus/templates/design/actions/import-figma-clipboard.ts +112 -16
  278. package/corpus/templates/design/actions/import-figma-frame.ts +15 -4
  279. package/corpus/templates/design/actions/index-design-system-with-builder.ts +4 -0
  280. package/corpus/templates/design/actions/list-design-templates.ts +118 -0
  281. package/corpus/templates/design/actions/navigate.ts +16 -2
  282. package/corpus/templates/design/actions/provider-api-request.ts +11 -1
  283. package/corpus/templates/design/actions/save-design-as-template.ts +156 -0
  284. package/corpus/templates/design/actions/set-active-breakpoint.ts +13 -4
  285. package/corpus/templates/design/actions/take-design-screenshot.ts +73 -3
  286. package/corpus/templates/design/actions/update-file.ts +39 -22
  287. package/corpus/templates/design/actions/view-screen.ts +36 -1
  288. package/corpus/templates/design/actions/write-local-file.ts +50 -38
  289. package/corpus/templates/design/app/components/design/AutoLayoutSuggestionDialog.tsx +151 -0
  290. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +20 -0
  291. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +251 -22
  292. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +3 -3
  293. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +384 -9
  294. package/corpus/templates/design/app/components/design/EditPanel.tsx +105 -32
  295. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +58 -28
  296. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +6 -0
  297. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +539 -53
  298. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +40 -0
  299. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +1 -0
  300. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +1 -0
  301. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +5 -1
  302. package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
  303. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +3 -1
  304. package/corpus/templates/design/app/components/design/code-workbench/workspace/types.ts +2 -0
  305. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +19 -0
  306. package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +1 -0
  307. package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +27 -0
  308. package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +137 -81
  309. package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +25 -5
  310. package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +1 -1
  311. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +220 -3
  312. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +13 -0
  313. package/corpus/templates/design/app/components/design/multi-screen/types.ts +22 -1
  314. package/corpus/templates/design/app/components/design/types.ts +4 -0
  315. package/corpus/templates/design/app/components/design-system/ProductionDesignSystemShowcase.tsx +208 -0
  316. package/corpus/templates/design/app/components/editor/FigmaLinkComposerBubble.tsx +321 -0
  317. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +24 -4
  318. package/corpus/templates/design/app/components/layout/Layout.tsx +16 -2
  319. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -0
  320. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +72 -0
  321. package/corpus/templates/design/app/global.css +2 -35
  322. package/corpus/templates/design/app/hooks/use-navigation-state.ts +10 -0
  323. package/corpus/templates/design/app/i18n/zh-TW.ts +127 -5
  324. package/corpus/templates/design/app/i18n-breakpoints.ts +209 -0
  325. package/corpus/templates/design/app/i18n-data.ts +1317 -59
  326. package/corpus/templates/design/app/i18n-template-feature.ts +458 -0
  327. package/corpus/templates/design/app/lib/design-clipboard.ts +202 -0
  328. package/corpus/templates/design/app/lib/design-file-upload.ts +87 -0
  329. package/corpus/templates/design/app/lib/design-import.ts +168 -11
  330. package/corpus/templates/design/app/lib/desktop-design-preview.ts +423 -0
  331. package/corpus/templates/design/app/lib/figma-clipboard.ts +74 -8
  332. package/corpus/templates/design/app/lib/figma-connection.ts +161 -0
  333. package/corpus/templates/design/app/lib/figma-svg-copy.ts +814 -22
  334. package/corpus/templates/design/app/lib/figma-url.ts +77 -0
  335. package/corpus/templates/design/app/lib/pending-generation.ts +35 -0
  336. package/corpus/templates/design/app/pages/DesignSystems.tsx +236 -177
  337. package/corpus/templates/design/app/pages/Index.tsx +38 -0
  338. package/corpus/templates/design/app/pages/Templates.tsx +498 -0
  339. package/corpus/templates/design/app/pages/design-editor/auto-layout-suggestion.ts +328 -0
  340. package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +113 -0
  341. package/corpus/templates/design/app/pages/design-editor/created-screen-navigation.ts +55 -0
  342. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +32 -0
  343. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +49 -2
  344. package/corpus/templates/design/app/pages/design-editor/export-capture.ts +296 -0
  345. package/corpus/templates/design/app/pages/design-editor/history.ts +101 -2
  346. package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +28 -1
  347. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +34 -0
  348. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +202 -6
  349. package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +92 -0
  350. package/corpus/templates/design/app/pages/design-editor/save-failure.ts +58 -0
  351. package/corpus/templates/design/app/routes/templates.tsx +4 -6
  352. package/corpus/templates/design/changelog/2026-07-10-app-workspaces-now-use-clean-borderless-main-surfaces-throug.md +6 -0
  353. package/corpus/templates/design/changelog/2026-07-10-ask-chat-what-s-in-a-figma-file-or-frame-structure-screensho.md +6 -0
  354. package/corpus/templates/design/changelog/2026-07-10-canvas-edits-now-reject-malformed-html-before-it-can-corrupt.md +6 -0
  355. package/corpus/templates/design/changelog/2026-07-10-complex-designs-now-export-as-valid-secure-svgs-and-crisp-ra.md +6 -0
  356. package/corpus/templates/design/changelog/2026-07-10-complex-figma-masks-arcs-rich-text-transformed-images-and-ad.md +6 -0
  357. package/corpus/templates/design/changelog/2026-07-10-copied-layers-paste-across-designs-and-browser-tabs.md +6 -0
  358. package/corpus/templates/design/changelog/2026-07-10-copy-and-download-editable-figma-svg.md +6 -0
  359. package/corpus/templates/design/changelog/2026-07-10-copying-design-text-now-pastes-readable-text-into-other-apps.md +6 -0
  360. package/corpus/templates/design/changelog/2026-07-10-deleted-screens-can-be-restored-with-undo-and-removed-again-.md +6 -0
  361. package/corpus/templates/design/changelog/2026-07-10-design-changes-now-save-before-switching-apps-and-retry-when.md +6 -0
  362. package/corpus/templates/design/changelog/2026-07-10-design-stays-usable-on-phones-by-keeping-editor-panels-and-f.md +6 -0
  363. package/corpus/templates/design/changelog/2026-07-10-download-all-screens-as-one-multi-page-pdf-from-the-overview.md +6 -0
  364. package/corpus/templates/design/changelog/2026-07-10-duplicated-layers-now-keep-labels-aria-relationships-fragmen.md +6 -0
  365. package/corpus/templates/design/changelog/2026-07-10-fig-import-results-stay-compact.md +6 -0
  366. package/corpus/templates/design/changelog/2026-07-10-figma-imports-now-load-real-fonts-fix-rotated-gradient-dashe.md +6 -0
  367. package/corpus/templates/design/changelog/2026-07-10-figma-links-in-chat-and-the-import-tab-now-offer-secure-one-.md +6 -0
  368. package/corpus/templates/design/changelog/2026-07-10-fixed-cmd-z-not-restoring-content-after-an-agent-driven-desi.md +6 -0
  369. package/corpus/templates/design/changelog/2026-07-10-fixed-download-pdf-being-unreachable-from-the-export-panel-e.md +6 -0
  370. package/corpus/templates/design/changelog/2026-07-10-fixed-dragging-a-layer-out-of-an-auto-layout-row-column-no-l.md +6 -0
  371. package/corpus/templates/design/changelog/2026-07-10-fixed-figma-svg-export-text-wrapping-sizing-and-inner-layer.md +6 -0
  372. package/corpus/templates/design/changelog/2026-07-10-fixed-hiding-or-locking-one-layer-no-longer-hides-or-blocks-.md +6 -0
  373. package/corpus/templates/design/changelog/2026-07-10-fixed-png-screenshots-of-tall-screens-being-cropped-to-one-v.md +6 -0
  374. package/corpus/templates/design/changelog/2026-07-10-fixed-png-svg-exports-capturing-broken-layout-when-webfonts-.md +6 -0
  375. package/corpus/templates/design/changelog/2026-07-10-frame-tool-now-offers-standard-ad-unit-size-presets-medium-r.md +6 -0
  376. package/corpus/templates/design/changelog/2026-07-10-full-view-controls-stay-within-their-frame-instead-of-coveri.md +6 -0
  377. package/corpus/templates/design/changelog/2026-07-10-hover-focus-focus-visible-pressed-and-disabled-states-now-pr.md +6 -0
  378. package/corpus/templates/design/changelog/2026-07-10-layer-drops-now-land-in-the-intended-grid-row-stay-visually-.md +6 -0
  379. package/corpus/templates/design/changelog/2026-07-10-local-code-workspaces-now-keep-unsaved-edits-across-panel-sw.md +6 -0
  380. package/corpus/templates/design/changelog/2026-07-10-local-visual-editing-now-keeps-authenticated-sessions-shared.md +6 -0
  381. package/corpus/templates/design/changelog/2026-07-10-long-running-agent-work-no-longer-shows-a-premature-stuck-wa.md +6 -0
  382. package/corpus/templates/design/changelog/2026-07-10-managed-figma-connections-are-recognized-automatically.md +6 -0
  383. package/corpus/templates/design/changelog/2026-07-10-new-designs-can-open-directly-in-the-editor-without-a-pr.md +6 -0
  384. package/corpus/templates/design/changelog/2026-07-10-new-screens-are-selected-and-revealed-immediately.md +6 -0
  385. package/corpus/templates/design/changelog/2026-07-10-new-text-layers-undo-as-one-safe-creation.md +6 -0
  386. package/corpus/templates/design/changelog/2026-07-10-preview-and-apply-inferred-auto-layout-without-changing-yo.md +5 -0
  387. package/corpus/templates/design/changelog/2026-07-10-print-pdf-exports-and-paper-size-presets-letter-a4-now-match.md +6 -0
  388. package/corpus/templates/design/changelog/2026-07-10-responsive-frame-editing.md +6 -0
  389. package/corpus/templates/design/changelog/2026-07-10-reusable-design-templates.md +6 -0
  390. package/corpus/templates/design/changelog/2026-07-10-screen-overview-frames-now-use-a-clearer-interact-action-wit.md +6 -0
  391. package/corpus/templates/design/changelog/2026-07-10-start-designs-from-source-linked-material-3-carbon-or-primer.md +6 -0
  392. package/corpus/templates/design/changelog/2026-07-10-tweaks-guidance.md +6 -0
  393. package/corpus/templates/design/changelog/2026-07-10-uploaded-fig-files-can-now-become-editable-design-screens-wi.md +6 -0
  394. package/corpus/templates/design/e2e/helpers.ts +3 -3
  395. package/corpus/templates/design/package.json +2 -0
  396. package/corpus/templates/design/scripts/qa-figma-stress-import.ts +96 -0
  397. package/corpus/templates/design/server/db/index.ts +10 -0
  398. package/corpus/templates/design/server/db/schema.ts +44 -0
  399. package/corpus/templates/design/server/handlers/import-design-file.ts +114 -80
  400. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +19 -6
  401. package/corpus/templates/design/server/lib/design-export.ts +240 -3
  402. package/corpus/templates/design/server/lib/design-template-data.ts +89 -0
  403. package/corpus/templates/design/server/lib/design-to-figma-svg.ts +250 -26
  404. package/corpus/templates/design/server/lib/fig-file-decoder.ts +839 -0
  405. package/corpus/templates/design/server/lib/fig-file-import.ts +287 -0
  406. package/corpus/templates/design/server/lib/fig-file-limits.ts +3 -0
  407. package/corpus/templates/design/server/lib/fig-file-to-html.ts +2568 -0
  408. package/corpus/templates/design/server/lib/figma-design-context.ts +359 -0
  409. package/corpus/templates/design/server/lib/figma-node-import.ts +478 -22
  410. package/corpus/templates/design/server/lib/figma-node-to-html.ts +554 -29
  411. package/corpus/templates/design/server/lib/local-figma-qa-upload.ts +112 -0
  412. package/corpus/templates/design/server/lib/verify-write-grant.ts +16 -2
  413. package/corpus/templates/design/server/lib/visible-clipboard-html.ts +13 -3
  414. package/corpus/templates/design/server/plugins/agent-chat.ts +7 -0
  415. package/corpus/templates/design/server/plugins/db.ts +42 -0
  416. package/corpus/templates/design/server/plugins/local-figma-qa-upload.ts +7 -0
  417. package/corpus/templates/design/server/register-secrets.ts +8 -8
  418. package/corpus/templates/design/server/routes/api/qa-figma-import-assets/[assetId].get.ts +46 -0
  419. package/corpus/templates/design/server/source-workspace.ts +104 -12
  420. package/corpus/templates/design/shared/code-layer.ts +105 -28
  421. package/corpus/templates/design/shared/design-system-templates.ts +301 -0
  422. package/corpus/templates/design/shared/design-template-presets.ts +195 -0
  423. package/corpus/templates/design/shared/figma-url.ts +8 -0
  424. package/corpus/templates/design/shared/html-integrity.ts +306 -0
  425. package/corpus/templates/design/shared/interaction-states.ts +318 -23
  426. package/corpus/templates/design/shared/locked-layers.ts +151 -0
  427. package/corpus/templates/dispatch/.agents/skills/capture-learnings/SKILL.md +22 -9
  428. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +48 -0
  429. package/corpus/templates/dispatch/app/i18n-data.ts +536 -1
  430. package/corpus/templates/dispatch/changelog/2026-07-10-connect-slack-workspaces-with-oauth-and-manage-channel-ident.md +6 -0
  431. package/corpus/templates/dispatch/changelog/2026-07-10-microsoft-teams-bots-and-discord-slash-commands-can-now-conn.md +6 -0
  432. package/corpus/templates/dispatch/changelog/2026-07-10-slack-and-telegram-now-route-uptime-monitor-requests-to-anal.md +6 -0
  433. package/corpus/templates/forms/.agents/skills/capture-learnings/SKILL.md +22 -9
  434. package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +7 -0
  435. package/corpus/templates/forms/AGENTS.md +4 -0
  436. package/corpus/templates/forms/actions/create-form.ts +44 -7
  437. package/corpus/templates/forms/actions/lib/assert-publishable-form.ts +38 -0
  438. package/corpus/templates/forms/actions/patch-form-fields.ts +4 -0
  439. package/corpus/templates/forms/actions/update-form.ts +2 -36
  440. package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
  441. package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
  442. package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
  443. package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
  444. package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
  445. package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
  446. package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
  447. package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
  448. package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
  449. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  450. package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
  451. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +17 -0
  452. package/corpus/templates/forms/changelog/2026-07-10-agent-created-published-forms-now-return-the-anonymous-publi.md +6 -0
  453. package/corpus/templates/forms/changelog/2026-07-10-published-forms-can-no-longer-be-edited-into-an-unusable-emp.md +6 -0
  454. package/corpus/templates/forms/server/handlers/submissions.ts +4 -3
  455. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
  456. package/corpus/templates/forms/shared/types.ts +5 -0
  457. package/corpus/templates/mail/.agents/skills/capture-learnings/SKILL.md +22 -9
  458. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  459. package/corpus/templates/mail/changelog/2026-07-10-mail-navigation-now-uses-a-clean-borderless-drawer.md +6 -0
  460. package/corpus/templates/plan/.agents/skills/capture-learnings/SKILL.md +22 -9
  461. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +4 -1
  462. package/corpus/templates/plan/changelog/2026-07-10-local-plans-now-keep-valid-content-visible-when-one-generate.md +6 -0
  463. package/corpus/templates/plan/server/lib/local-plan-files.ts +4 -1
  464. package/corpus/templates/slides/.agents/skills/capture-learnings/SKILL.md +22 -9
  465. package/dist/a2a/artifact-response.d.ts.map +1 -1
  466. package/dist/a2a/artifact-response.js +88 -2
  467. package/dist/a2a/artifact-response.js.map +1 -1
  468. package/dist/a2a/client.d.ts +9 -0
  469. package/dist/a2a/client.d.ts.map +1 -1
  470. package/dist/a2a/client.js +1 -0
  471. package/dist/a2a/client.js.map +1 -1
  472. package/dist/a2a/handlers.d.ts.map +1 -1
  473. package/dist/a2a/handlers.js +24 -69
  474. package/dist/a2a/handlers.js.map +1 -1
  475. package/dist/a2a/types.d.ts +2 -0
  476. package/dist/a2a/types.d.ts.map +1 -1
  477. package/dist/a2a/types.js.map +1 -1
  478. package/dist/agent/durable-background.d.ts +11 -0
  479. package/dist/agent/durable-background.d.ts.map +1 -1
  480. package/dist/agent/durable-background.js +17 -0
  481. package/dist/agent/durable-background.js.map +1 -1
  482. package/dist/agent/production-agent.d.ts +5 -3
  483. package/dist/agent/production-agent.d.ts.map +1 -1
  484. package/dist/agent/production-agent.js +34 -8
  485. package/dist/agent/production-agent.js.map +1 -1
  486. package/dist/agent/run-manager.d.ts +44 -2
  487. package/dist/agent/run-manager.d.ts.map +1 -1
  488. package/dist/agent/run-manager.js +124 -18
  489. package/dist/agent/run-manager.js.map +1 -1
  490. package/dist/agent/run-store.d.ts +109 -0
  491. package/dist/agent/run-store.d.ts.map +1 -1
  492. package/dist/agent/run-store.js +274 -37
  493. package/dist/agent/run-store.js.map +1 -1
  494. package/dist/agent/types.d.ts +22 -0
  495. package/dist/agent/types.d.ts.map +1 -1
  496. package/dist/agent/types.js.map +1 -1
  497. package/dist/audit/record.d.ts.map +1 -1
  498. package/dist/audit/record.js +29 -0
  499. package/dist/audit/record.js.map +1 -1
  500. package/dist/audit/store.d.ts.map +1 -1
  501. package/dist/audit/store.js +62 -3
  502. package/dist/audit/store.js.map +1 -1
  503. package/dist/audit/types.d.ts +13 -0
  504. package/dist/audit/types.d.ts.map +1 -1
  505. package/dist/audit/types.js.map +1 -1
  506. package/dist/automation/index.d.ts +193 -0
  507. package/dist/automation/index.d.ts.map +1 -0
  508. package/dist/automation/index.js +464 -0
  509. package/dist/automation/index.js.map +1 -0
  510. package/dist/cli/create.d.ts.map +1 -1
  511. package/dist/cli/create.js +10 -3
  512. package/dist/cli/create.js.map +1 -1
  513. package/dist/cli/design-connect.d.ts.map +1 -1
  514. package/dist/cli/design-connect.js +492 -35
  515. package/dist/cli/design-connect.js.map +1 -1
  516. package/dist/client/AgentPanel.d.ts +7 -1
  517. package/dist/client/AgentPanel.d.ts.map +1 -1
  518. package/dist/client/AgentPanel.js +32 -8
  519. package/dist/client/AgentPanel.js.map +1 -1
  520. package/dist/client/AssistantChat.d.ts +15 -0
  521. package/dist/client/AssistantChat.d.ts.map +1 -1
  522. package/dist/client/AssistantChat.js +115 -47
  523. package/dist/client/AssistantChat.js.map +1 -1
  524. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  525. package/dist/client/MultiTabAssistantChat.js +1 -1
  526. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  527. package/dist/client/RunStuckBanner.d.ts +14 -1
  528. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  529. package/dist/client/RunStuckBanner.js +35 -7
  530. package/dist/client/RunStuckBanner.js.map +1 -1
  531. package/dist/client/agent-chat-adapter.d.ts +4 -1
  532. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  533. package/dist/client/agent-chat-adapter.js +97 -16
  534. package/dist/client/agent-chat-adapter.js.map +1 -1
  535. package/dist/client/automation.d.ts +14 -0
  536. package/dist/client/automation.d.ts.map +1 -0
  537. package/dist/client/automation.js +9 -0
  538. package/dist/client/automation.js.map +1 -0
  539. package/dist/client/chat/run-recovery.d.ts +4 -0
  540. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  541. package/dist/client/chat/run-recovery.js +12 -10
  542. package/dist/client/chat/run-recovery.js.map +1 -1
  543. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  544. package/dist/client/composer/TiptapComposer.js +8 -0
  545. package/dist/client/composer/TiptapComposer.js.map +1 -1
  546. package/dist/client/index.d.ts +2 -0
  547. package/dist/client/index.d.ts.map +1 -1
  548. package/dist/client/index.js +2 -0
  549. package/dist/client/index.js.map +1 -1
  550. package/dist/client/integrations/api.d.ts +115 -0
  551. package/dist/client/integrations/api.d.ts.map +1 -0
  552. package/dist/client/integrations/api.js +123 -0
  553. package/dist/client/integrations/api.js.map +1 -0
  554. package/dist/client/integrations/index.d.ts +1 -0
  555. package/dist/client/integrations/index.d.ts.map +1 -1
  556. package/dist/client/integrations/index.js +1 -0
  557. package/dist/client/integrations/index.js.map +1 -1
  558. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  559. package/dist/client/transcription/use-live-transcription.js +59 -5
  560. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  561. package/dist/client/use-run-stuck-detection.d.ts +16 -1
  562. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  563. package/dist/client/use-run-stuck-detection.js +23 -4
  564. package/dist/client/use-run-stuck-detection.js.map +1 -1
  565. package/dist/collab/awareness.d.ts +2 -2
  566. package/dist/collab/awareness.d.ts.map +1 -1
  567. package/dist/deploy/build.d.ts.map +1 -1
  568. package/dist/deploy/build.js +49 -4
  569. package/dist/deploy/build.js.map +1 -1
  570. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  571. package/dist/deploy/workspace-deploy.js +31 -2
  572. package/dist/deploy/workspace-deploy.js.map +1 -1
  573. package/dist/file-upload/types.d.ts +2 -0
  574. package/dist/file-upload/types.d.ts.map +1 -1
  575. package/dist/file-upload/types.js.map +1 -1
  576. package/dist/index.d.ts +2 -0
  577. package/dist/index.d.ts.map +1 -1
  578. package/dist/index.js +2 -0
  579. package/dist/index.js.map +1 -1
  580. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  581. package/dist/integrations/a2a-continuations-store.js +6 -4
  582. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  583. package/dist/integrations/adapters/discord.d.ts +3 -0
  584. package/dist/integrations/adapters/discord.d.ts.map +1 -0
  585. package/dist/integrations/adapters/discord.js +261 -0
  586. package/dist/integrations/adapters/discord.js.map +1 -0
  587. package/dist/integrations/adapters/index.d.ts +4 -0
  588. package/dist/integrations/adapters/index.d.ts.map +1 -0
  589. package/dist/integrations/adapters/index.js +26 -0
  590. package/dist/integrations/adapters/index.js.map +1 -0
  591. package/dist/integrations/adapters/microsoft-teams.d.ts +5 -0
  592. package/dist/integrations/adapters/microsoft-teams.d.ts.map +1 -0
  593. package/dist/integrations/adapters/microsoft-teams.js +295 -0
  594. package/dist/integrations/adapters/microsoft-teams.js.map +1 -0
  595. package/dist/integrations/adapters/slack.d.ts +8 -2
  596. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  597. package/dist/integrations/adapters/slack.js +736 -27
  598. package/dist/integrations/adapters/slack.js.map +1 -1
  599. package/dist/integrations/adapters/telegram.d.ts +0 -2
  600. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  601. package/dist/integrations/adapters/telegram.js +49 -15
  602. package/dist/integrations/adapters/telegram.js.map +1 -1
  603. package/dist/integrations/adapters/whatsapp.d.ts +0 -2
  604. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  605. package/dist/integrations/adapters/whatsapp.js +40 -17
  606. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  607. package/dist/integrations/catalog.d.ts +75 -0
  608. package/dist/integrations/catalog.d.ts.map +1 -0
  609. package/dist/integrations/catalog.js +451 -0
  610. package/dist/integrations/catalog.js.map +1 -0
  611. package/dist/integrations/controls-store.d.ts +44 -0
  612. package/dist/integrations/controls-store.d.ts.map +1 -0
  613. package/dist/integrations/controls-store.js +129 -0
  614. package/dist/integrations/controls-store.js.map +1 -0
  615. package/dist/integrations/index.d.ts +13 -1
  616. package/dist/integrations/index.d.ts.map +1 -1
  617. package/dist/integrations/index.js +9 -0
  618. package/dist/integrations/index.js.map +1 -1
  619. package/dist/integrations/installations-store.d.ts +112 -0
  620. package/dist/integrations/installations-store.d.ts.map +1 -0
  621. package/dist/integrations/installations-store.js +493 -0
  622. package/dist/integrations/installations-store.js.map +1 -0
  623. package/dist/integrations/integration-memory.d.ts +24 -0
  624. package/dist/integrations/integration-memory.d.ts.map +1 -0
  625. package/dist/integrations/integration-memory.js +136 -0
  626. package/dist/integrations/integration-memory.js.map +1 -0
  627. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  628. package/dist/integrations/pending-tasks-retry-job.js +6 -5
  629. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  630. package/dist/integrations/pending-tasks-store.d.ts +17 -0
  631. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  632. package/dist/integrations/pending-tasks-store.js +71 -5
  633. package/dist/integrations/pending-tasks-store.js.map +1 -1
  634. package/dist/integrations/plugin.d.ts.map +1 -1
  635. package/dist/integrations/plugin.js +520 -35
  636. package/dist/integrations/plugin.js.map +1 -1
  637. package/dist/integrations/scope-store.d.ts +65 -0
  638. package/dist/integrations/scope-store.d.ts.map +1 -0
  639. package/dist/integrations/scope-store.js +361 -0
  640. package/dist/integrations/scope-store.js.map +1 -0
  641. package/dist/integrations/slack-manifest.d.ts +66 -0
  642. package/dist/integrations/slack-manifest.d.ts.map +1 -0
  643. package/dist/integrations/slack-manifest.js +70 -0
  644. package/dist/integrations/slack-manifest.js.map +1 -0
  645. package/dist/integrations/slack-oauth.d.ts +99 -0
  646. package/dist/integrations/slack-oauth.d.ts.map +1 -0
  647. package/dist/integrations/slack-oauth.js +226 -0
  648. package/dist/integrations/slack-oauth.js.map +1 -0
  649. package/dist/integrations/types.d.ts +144 -0
  650. package/dist/integrations/types.d.ts.map +1 -1
  651. package/dist/integrations/types.js +16 -1
  652. package/dist/integrations/types.js.map +1 -1
  653. package/dist/integrations/usage-budget-store.d.ts +84 -0
  654. package/dist/integrations/usage-budget-store.d.ts.map +1 -0
  655. package/dist/integrations/usage-budget-store.js +650 -0
  656. package/dist/integrations/usage-budget-store.js.map +1 -0
  657. package/dist/integrations/webhook-handler.d.ts +4 -0
  658. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  659. package/dist/integrations/webhook-handler.js +415 -47
  660. package/dist/integrations/webhook-handler.js.map +1 -1
  661. package/dist/jobs/scheduler.d.ts +6 -0
  662. package/dist/jobs/scheduler.d.ts.map +1 -1
  663. package/dist/jobs/scheduler.js +83 -4
  664. package/dist/jobs/scheduler.js.map +1 -1
  665. package/dist/jobs/tools.d.ts.map +1 -1
  666. package/dist/jobs/tools.js +43 -11
  667. package/dist/jobs/tools.js.map +1 -1
  668. package/dist/provider-api/index.d.ts +4 -4
  669. package/dist/provider-api/index.d.ts.map +1 -1
  670. package/dist/provider-api/index.js +72 -1
  671. package/dist/provider-api/index.js.map +1 -1
  672. package/dist/resources/handlers.d.ts.map +1 -1
  673. package/dist/resources/handlers.js +57 -15
  674. package/dist/resources/handlers.js.map +1 -1
  675. package/dist/resources/script-helpers.d.ts.map +1 -1
  676. package/dist/resources/script-helpers.js +34 -8
  677. package/dist/resources/script-helpers.js.map +1 -1
  678. package/dist/resources/store.d.ts +10 -0
  679. package/dist/resources/store.d.ts.map +1 -1
  680. package/dist/resources/store.js +54 -47
  681. package/dist/resources/store.js.map +1 -1
  682. package/dist/scripts/call-agent.d.ts.map +1 -1
  683. package/dist/scripts/call-agent.js +106 -1
  684. package/dist/scripts/call-agent.js.map +1 -1
  685. package/dist/server/agent-chat-plugin.d.ts +15 -4
  686. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  687. package/dist/server/agent-chat-plugin.js +248 -113
  688. package/dist/server/agent-chat-plugin.js.map +1 -1
  689. package/dist/server/auth.d.ts.map +1 -1
  690. package/dist/server/auth.js +10 -14
  691. package/dist/server/auth.js.map +1 -1
  692. package/dist/server/builder-design-systems.d.ts +3 -1
  693. package/dist/server/builder-design-systems.d.ts.map +1 -1
  694. package/dist/server/builder-design-systems.js +9 -2
  695. package/dist/server/builder-design-systems.js.map +1 -1
  696. package/dist/server/edge.d.ts +1 -1
  697. package/dist/server/edge.d.ts.map +1 -1
  698. package/dist/server/edge.js +1 -1
  699. package/dist/server/edge.js.map +1 -1
  700. package/dist/server/index.d.ts +2 -1
  701. package/dist/server/index.d.ts.map +1 -1
  702. package/dist/server/index.js +2 -1
  703. package/dist/server/index.js.map +1 -1
  704. package/dist/server/request-context.d.ts +18 -0
  705. package/dist/server/request-context.d.ts.map +1 -1
  706. package/dist/server/request-context.js.map +1 -1
  707. package/dist/server/social-og-image.d.ts.map +1 -1
  708. package/dist/server/social-og-image.js +3 -2
  709. package/dist/server/social-og-image.js.map +1 -1
  710. package/dist/server/transcribe-voice.d.ts +1 -1
  711. package/dist/styles/agent-native.css +62 -44
  712. package/dist/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
  713. package/dist/templates/default/AGENTS.md +7 -3
  714. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
  715. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
  716. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
  717. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
  718. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
  719. package/dist/templates/workspace-core/AGENTS.md +3 -2
  720. package/dist/usage/store.d.ts +7 -0
  721. package/dist/usage/store.d.ts.map +1 -1
  722. package/dist/usage/store.js +24 -3
  723. package/dist/usage/store.js.map +1 -1
  724. package/docs/content/automation-connectors.mdx +80 -0
  725. package/docs/content/extensions.mdx +8 -0
  726. package/docs/content/locales/ar-SA/extensions.mdx +8 -0
  727. package/docs/content/locales/ar-SA/messaging.mdx +84 -15
  728. package/docs/content/locales/ar-SA/template-clips.mdx +1 -0
  729. package/docs/content/locales/ar-SA/template-design.mdx +1 -0
  730. package/docs/content/locales/de-DE/extensions.mdx +10 -0
  731. package/docs/content/locales/de-DE/messaging.mdx +92 -15
  732. package/docs/content/locales/de-DE/template-clips.mdx +1 -0
  733. package/docs/content/locales/de-DE/template-design.mdx +1 -0
  734. package/docs/content/locales/es-ES/extensions.mdx +10 -0
  735. package/docs/content/locales/es-ES/messaging.mdx +91 -15
  736. package/docs/content/locales/es-ES/template-clips.mdx +1 -0
  737. package/docs/content/locales/es-ES/template-design.mdx +1 -0
  738. package/docs/content/locales/fr-FR/extensions.mdx +10 -0
  739. package/docs/content/locales/fr-FR/messaging.mdx +91 -15
  740. package/docs/content/locales/fr-FR/template-clips.mdx +1 -0
  741. package/docs/content/locales/fr-FR/template-design.mdx +1 -0
  742. package/docs/content/locales/hi-IN/extensions.mdx +8 -0
  743. package/docs/content/locales/hi-IN/messaging.mdx +81 -15
  744. package/docs/content/locales/hi-IN/template-clips.mdx +1 -0
  745. package/docs/content/locales/hi-IN/template-design.mdx +1 -0
  746. package/docs/content/locales/ja-JP/extensions.mdx +9 -0
  747. package/docs/content/locales/ja-JP/messaging.mdx +81 -15
  748. package/docs/content/locales/ja-JP/template-clips.mdx +1 -0
  749. package/docs/content/locales/ja-JP/template-design.mdx +1 -0
  750. package/docs/content/locales/ko-KR/extensions.mdx +8 -0
  751. package/docs/content/locales/ko-KR/messaging.mdx +80 -15
  752. package/docs/content/locales/ko-KR/template-clips.mdx +1 -0
  753. package/docs/content/locales/ko-KR/template-design.mdx +1 -0
  754. package/docs/content/locales/pt-BR/extensions.mdx +9 -0
  755. package/docs/content/locales/pt-BR/messaging.mdx +88 -15
  756. package/docs/content/locales/pt-BR/template-clips.mdx +1 -0
  757. package/docs/content/locales/pt-BR/template-design.mdx +1 -0
  758. package/docs/content/locales/zh-CN/extensions.mdx +6 -0
  759. package/docs/content/locales/zh-CN/messaging.mdx +78 -15
  760. package/docs/content/locales/zh-CN/template-clips.mdx +1 -0
  761. package/docs/content/locales/zh-CN/template-design.mdx +1 -0
  762. package/docs/content/locales/zh-TW/extensions.mdx +6 -0
  763. package/docs/content/locales/zh-TW/messaging.mdx +78 -15
  764. package/docs/content/locales/zh-TW/template-clips.mdx +1 -0
  765. package/docs/content/locales/zh-TW/template-design.mdx +1 -0
  766. package/docs/content/messaging.mdx +227 -45
  767. package/docs/content/template-clips.mdx +3 -0
  768. package/docs/content/template-design.mdx +4 -0
  769. package/package.json +5 -1
  770. package/src/templates/default/.agents/skills/capture-learnings/SKILL.md +22 -9
  771. package/src/templates/default/AGENTS.md +7 -3
  772. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
  773. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +22 -9
  774. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +6 -3
  775. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +25 -0
  776. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +15 -0
  777. package/src/templates/workspace-core/AGENTS.md +3 -2
@@ -1,9 +1,21 @@
1
1
  import { createError, getHeader, readRawBody } from "h3";
2
2
  import { resolveSecret } from "../../server/credential-provider.js";
3
+ import { getRequestContext } from "../../server/request-context.js";
4
+ import { getIntegrationRequestContext } from "../../server/request-context.js";
5
+ import { createIntegrationControl } from "../controls-store.js";
6
+ import { getActiveIntegrationInstallationByKey, getActiveIntegrationInstallationForTenant, listIntegrationInstallations, resolveIntegrationTokenBundle, } from "../installations-store.js";
7
+ import { hasActivePendingTask } from "../pending-tasks-store.js";
8
+ import { slackInstallationKey } from "../slack-oauth.js";
3
9
  /** Slack's max message length */
4
10
  const SLACK_MAX_LENGTH = 4000;
5
11
  const SLACK_SECTION_TEXT_MAX_LENGTH = 3000;
6
12
  const SLACK_API_TIMEOUT_MS = 10_000;
13
+ // Permalink lookup happens on Slack's acknowledgement path, so keep it well
14
+ // inside Slack's three-second Events API deadline. Failure is non-fatal: the
15
+ // normalized message still carries channel/thread ids for replies.
16
+ const SLACK_PERMALINK_TIMEOUT_MS = 1_000;
17
+ const SLACK_CONTEXT_MESSAGE_LIMIT = 15;
18
+ const SLACK_CONTEXT_TEXT_LIMIT = 2_000;
7
19
  /**
8
20
  * Create a Slack platform adapter.
9
21
  *
@@ -24,18 +36,44 @@ const SLACK_API_TIMEOUT_MS = 10_000;
24
36
  * (`api_app_id`) to additionally pin events to. Useful when the same
25
37
  * signing secret rotation surfaces multiple app installs.
26
38
  */
27
- export function slackAdapter() {
39
+ export function slackAdapter(options = {}) {
40
+ const resolveBotToken = async (incoming) => (await options.resolveBotToken?.(incoming)) ??
41
+ (await resolveManagedSlackBotToken(incoming)) ??
42
+ (await resolveSecret("SLACK_BOT_TOKEN")) ??
43
+ undefined;
28
44
  return {
29
45
  platform: "slack",
30
46
  label: "Slack",
47
+ capabilities: {
48
+ replyText: true,
49
+ proactiveMessages: true,
50
+ nativeThreads: true,
51
+ contextualReplies: true,
52
+ deferredWebhookResponse: false,
53
+ interactionOnly: false,
54
+ nativeContextHydration: true,
55
+ liveRunProgress: true,
56
+ },
31
57
  getRequiredEnvKeys() {
32
58
  return [
33
59
  {
34
60
  key: "SLACK_BOT_TOKEN",
35
61
  label: "Slack Bot Token",
36
- required: true,
62
+ required: false,
37
63
  helpText: "In your Slack app's left nav: OAuth & Permissions → Bot User OAuth Token (starts with `xoxb-`).",
38
64
  },
65
+ {
66
+ key: "SLACK_CLIENT_ID",
67
+ label: "Slack OAuth Client ID",
68
+ required: false,
69
+ helpText: "Slack app Basic Information → App Credentials → Client ID.",
70
+ },
71
+ {
72
+ key: "SLACK_CLIENT_SECRET",
73
+ label: "Slack OAuth Client Secret",
74
+ required: false,
75
+ helpText: "Slack app Basic Information → App Credentials → Client Secret.",
76
+ },
39
77
  {
40
78
  key: "SLACK_SIGNING_SECRET",
41
79
  label: "Slack Signing Secret",
@@ -107,7 +145,7 @@ export function slackAdapter() {
107
145
  // handler, so this is purely a tenant-isolation gate (not a forgery
108
146
  // defense). When unset in production we surface a one-time warning
109
147
  // recommending it be configured.
110
- enforceWorkspaceAllowlist(payload);
148
+ await enforceWorkspaceAllowlist(payload);
111
149
  // Handle Events API wrapper
112
150
  if (payload.type === "event_callback") {
113
151
  const e = payload.event;
@@ -119,35 +157,91 @@ export function slackAdapter() {
119
157
  // Ignore message edits and deletes
120
158
  if (e.subtype === "message_changed" || e.subtype === "message_deleted")
121
159
  return null;
122
- // Handle both direct messages and app_mentions
160
+ // Handle DMs and explicit mentions. Ordinary channel replies are only
161
+ // accepted while this exact workspace-qualified thread has queued or
162
+ // executing work; broad message subscriptions must never invoke the
163
+ // agent for general channel chatter.
123
164
  const text = e.text?.trim();
124
165
  if (!text)
125
166
  return null;
167
+ const teamId = typeof payload.team_id === "string" ? payload.team_id : "unknown";
168
+ const apiAppId = typeof payload.api_app_id === "string"
169
+ ? payload.api_app_id
170
+ : "unknown";
171
+ const agentContext = normalizeSlackAgentContext(e.app_context, teamId);
172
+ const isDm = typeof e.channel_type === "string"
173
+ ? e.channel_type === "im"
174
+ : typeof e.channel === "string" && e.channel.startsWith("D");
175
+ const isMention = e.type === "app_mention";
176
+ const isThreadReply = !isDm && !isMention && !!e.thread_ts;
177
+ if (!isDm && !isMention && !isThreadReply)
178
+ return null;
126
179
  // Remove bot mention from text (e.g., "<@U123> do something" → "do something")
127
180
  const cleanText = text.replace(/<@[A-Z0-9]+>/g, "").trim();
128
181
  if (!cleanText)
129
182
  return null;
130
183
  // Thread ID: use thread_ts if in a thread, otherwise message ts
131
184
  const threadTs = e.thread_ts || e.ts;
132
- const externalThreadId = `${e.channel}:${threadTs}`;
133
- return {
185
+ const externalThreadId = `${apiAppId}:${teamId}:${e.channel}:${threadTs}`;
186
+ const partialIncoming = {
134
187
  platform: "slack",
135
188
  externalThreadId,
136
189
  text: cleanText,
137
190
  senderName: e.user,
138
191
  senderId: e.user,
192
+ triggerKind: isDm ? "dm" : isMention ? "mention" : "thread_reply",
193
+ conversationType: isDm ? "dm" : "unknown",
194
+ tenantId: teamId,
195
+ actorTrust: { memberType: "unknown", verified: true },
139
196
  platformContext: {
140
197
  channelId: e.channel,
141
- threadTs: threadTs,
198
+ channelType: e.channel_type,
199
+ threadTs,
142
200
  messageTs: e.ts,
143
- teamId: payload.team_id,
201
+ teamId,
202
+ apiAppId,
203
+ enterpriseId: typeof payload.enterprise_id === "string"
204
+ ? payload.enterprise_id
205
+ : undefined,
144
206
  eventId: payload.event_id,
207
+ ...(agentContext
208
+ ? {
209
+ agentContext: agentContext.entities,
210
+ activeContextChannelId: agentContext.channelId,
211
+ }
212
+ : {}),
145
213
  },
214
+ threadRef: threadTs,
215
+ replyRef: e.ts,
146
216
  timestamp: Math.floor(parseFloat(e.ts) * 1000),
147
217
  };
218
+ if (isThreadReply) {
219
+ const active = options.isThreadActive
220
+ ? await options.isThreadActive(partialIncoming)
221
+ : await hasActivePendingTask("slack", externalThreadId);
222
+ if (!active)
223
+ return null;
224
+ }
225
+ const token = await resolveBotToken(partialIncoming);
226
+ const threadPermalink = await resolveSlackThreadPermalink(e.channel, threadTs, token);
227
+ return {
228
+ ...partialIncoming,
229
+ platformContext: {
230
+ ...partialIncoming.platformContext,
231
+ ...(threadPermalink ? { threadPermalink } : {}),
232
+ },
233
+ ...(threadPermalink ? { sourceUrl: threadPermalink } : {}),
234
+ };
148
235
  }
149
236
  return null;
150
237
  },
238
+ getLegacyExternalThreadIds(incoming) {
239
+ const channelId = incoming.platformContext.channelId;
240
+ const threadTs = incoming.platformContext.threadTs;
241
+ return typeof channelId === "string" && typeof threadTs === "string"
242
+ ? [`${channelId}:${threadTs}`]
243
+ : [];
244
+ },
151
245
  async postProcessingPlaceholder(incoming) {
152
246
  // No placeholder reply in the thread — Slack's native assistant
153
247
  // status bar ("agent-native is thinking…", below the composer) is the
@@ -155,21 +249,34 @@ export function slackAdapter() {
155
249
  // redundant and added an extra chunk that we then had to overwrite.
156
250
  // We just set the native status and return null so sendResponse posts
157
251
  // the final reply as a fresh message.
158
- const token = await resolveSecret("SLACK_BOT_TOKEN");
252
+ const token = await resolveBotToken(incoming);
159
253
  if (!token)
160
254
  return null;
161
255
  const channelId = incoming.platformContext.channelId;
162
256
  const threadTs = incoming.platformContext.threadTs;
163
257
  if (!channelId || !threadTs)
164
258
  return null;
165
- // Best-effort: flip the native AI-assistant "is thinking…" status bar
166
- // in the channel input area. Requires `assistant:write` scope on the
167
- // app otherwise silently no-ops.
259
+ // Best-effort: flip the native Agent "is thinking…" status bar in the
260
+ // channel input area. Slack accepts chat:write for this method. The
261
+ // canonical manifest separately requests assistant:write for Agent View
262
+ // and app_context_changed events.
168
263
  setSlackAssistantStatus(token, channelId, threadTs, "is thinking…");
169
264
  return null;
170
265
  },
266
+ async hydrateIncomingMessage(incoming) {
267
+ const token = await resolveBotToken(incoming);
268
+ if (!token)
269
+ return incoming;
270
+ return hydrateSlackContext(token, incoming);
271
+ },
272
+ async startRunProgress(incoming) {
273
+ const token = await resolveBotToken(incoming);
274
+ if (!token)
275
+ return null;
276
+ return startSlackRunProgress(token, incoming);
277
+ },
171
278
  async sendResponse(message, context, opts) {
172
- const token = await resolveSecret("SLACK_BOT_TOKEN");
279
+ const token = await resolveBotToken(context);
173
280
  if (!token) {
174
281
  console.error("[slack] SLACK_BOT_TOKEN not configured");
175
282
  return;
@@ -247,7 +354,19 @@ export function slackAdapter() {
247
354
  }
248
355
  },
249
356
  async sendMessageToTarget(message, target) {
250
- const token = await resolveSecret("SLACK_BOT_TOKEN");
357
+ const targetContext = {
358
+ platform: "slack",
359
+ externalThreadId: `${target.tenantId ?? "unknown"}:${target.destination}:${target.threadRef ?? "root"}`,
360
+ text: "",
361
+ platformContext: {
362
+ channelId: target.destination,
363
+ threadTs: target.threadRef,
364
+ teamId: target.tenantId,
365
+ },
366
+ tenantId: target.tenantId,
367
+ timestamp: Date.now(),
368
+ };
369
+ const token = await resolveBotToken(targetContext);
251
370
  if (!token) {
252
371
  console.error("[slack] SLACK_BOT_TOKEN not configured");
253
372
  return;
@@ -293,7 +412,15 @@ export function slackAdapter() {
293
412
  async getStatus(_baseUrl) {
294
413
  const hasToken = !!(await resolveSecret("SLACK_BOT_TOKEN"));
295
414
  const hasSecret = !!(await resolveSecret("SLACK_SIGNING_SECRET"));
296
- const configured = hasToken && hasSecret;
415
+ const ctx = getRequestContext();
416
+ const managedInstallations = ctx?.userEmail
417
+ ? await listIntegrationInstallations({
418
+ userEmail: ctx.userEmail,
419
+ orgId: ctx.orgId ?? null,
420
+ }, "slack").catch(() => [])
421
+ : [];
422
+ const connectedInstallations = managedInstallations.filter((installation) => installation.status === "connected");
423
+ const configured = hasSecret && (hasToken || connectedInstallations.length > 0);
297
424
  return {
298
425
  platform: "slack",
299
426
  label: "Slack",
@@ -302,9 +429,18 @@ export function slackAdapter() {
302
429
  details: {
303
430
  hasToken,
304
431
  hasSecret,
432
+ managedInstallationCount: connectedInstallations.length,
433
+ managedInstallations: connectedInstallations.map((installation) => ({
434
+ id: installation.id,
435
+ teamId: installation.teamId,
436
+ teamName: installation.teamName,
437
+ enterpriseId: installation.enterpriseId,
438
+ health: installation.health,
439
+ scopes: installation.scopes,
440
+ })),
305
441
  },
306
442
  error: !configured
307
- ? "Save SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in settings"
443
+ ? "Connect a Slack workspace with OAuth or save a bot token and signing secret"
308
444
  : undefined,
309
445
  };
310
446
  },
@@ -327,6 +463,36 @@ function parseAllowlistEnv(name) {
327
463
  return null;
328
464
  return new Set(values);
329
465
  }
466
+ async function resolveManagedSlackBotToken(incoming) {
467
+ const teamId = typeof incoming.platformContext.teamId === "string"
468
+ ? incoming.platformContext.teamId
469
+ : incoming.tenantId;
470
+ const apiAppId = typeof incoming.platformContext.apiAppId === "string"
471
+ ? incoming.platformContext.apiAppId
472
+ : undefined;
473
+ const enterpriseId = typeof incoming.platformContext.enterpriseId === "string"
474
+ ? incoming.platformContext.enterpriseId
475
+ : undefined;
476
+ if (!teamId && !enterpriseId)
477
+ return undefined;
478
+ try {
479
+ let installation = apiAppId
480
+ ? await getActiveIntegrationInstallationByKey("slack", slackInstallationKey({ teamId, enterpriseId, apiAppId }))
481
+ : null;
482
+ if (!installation && teamId) {
483
+ installation = await getActiveIntegrationInstallationForTenant("slack", teamId);
484
+ }
485
+ if (!installation && enterpriseId) {
486
+ installation = await getActiveIntegrationInstallationForTenant("slack", enterpriseId);
487
+ }
488
+ const key = installation?.installationKey ??
489
+ slackInstallationKey({ teamId, enterpriseId, apiAppId });
490
+ return (await resolveIntegrationTokenBundle("slack", key))?.accessToken;
491
+ }
492
+ catch {
493
+ return undefined;
494
+ }
495
+ }
330
496
  let _missingAllowlistWarned = false;
331
497
  /**
332
498
  * Enforce that an incoming Slack event comes from an allowlisted workspace.
@@ -354,17 +520,25 @@ let _missingAllowlistWarned = false;
354
520
  * received, which the integrations plugin surfaces to the caller as
355
521
  * "Unrecognized Slack workspace" without enqueuing the event.
356
522
  */
357
- function enforceWorkspaceAllowlist(payload) {
523
+ async function enforceWorkspaceAllowlist(payload) {
358
524
  const teamId = typeof payload?.team_id === "string" ? payload.team_id : undefined;
359
525
  const apiAppId = typeof payload?.api_app_id === "string" ? payload.api_app_id : undefined;
360
526
  const allowedTeamIds = parseAllowlistEnv("SLACK_ALLOWED_TEAM_IDS");
361
527
  const allowedAppIds = parseAllowlistEnv("SLACK_ALLOWED_API_APP_IDS");
362
528
  if (!allowedTeamIds) {
363
529
  if (process.env.NODE_ENV === "production") {
364
- throw createError({
365
- statusCode: 401,
366
- statusMessage: "Slack workspace allowlist is not configured",
367
- });
530
+ let managed = false;
531
+ try {
532
+ const key = slackInstallationKey({ teamId, apiAppId });
533
+ managed = !!(await getActiveIntegrationInstallationByKey("slack", key));
534
+ }
535
+ catch { }
536
+ if (!managed) {
537
+ throw createError({
538
+ statusCode: 401,
539
+ statusMessage: "Slack workspace is not connected",
540
+ });
541
+ }
368
542
  }
369
543
  if (!_missingAllowlistWarned) {
370
544
  _missingAllowlistWarned = true;
@@ -489,10 +663,10 @@ function markdownToSlackMrkdwn(text) {
489
663
  .replace(/\*\*([^*]{1,5000})\*\*/g, "*$1*"));
490
664
  }
491
665
  /**
492
- * Optionally set Slack's native AI-assistant status indicator (the small
493
- * "is thinking…" line under the message composer) for an app configured
494
- * with the `assistant:write` scope. Pure best-effort fails silently for
495
- * apps that aren't set up as AI assistants.
666
+ * Optionally set Slack's native Agent status indicator (the small "is
667
+ * thinking…" line under the message composer). The method uses chat:write;
668
+ * Agent View itself is configured separately by the Slack app manifest.
669
+ * Pure best-effort failures never block the response.
496
670
  */
497
671
  function setSlackAssistantStatus(token, channelId, threadTs, status) {
498
672
  slackApiFetch("https://slack.com/api/assistant.threads.setStatus", {
@@ -566,10 +740,10 @@ async function postFresh(token, channelId, threadTs, body) {
566
740
  throw new Error(data.error || "chat.postMessage failed");
567
741
  }
568
742
  }
569
- async function slackApiFetch(url, init) {
743
+ async function slackApiFetch(url, init, timeoutMs = SLACK_API_TIMEOUT_MS) {
570
744
  const controller = typeof AbortController !== "undefined" ? new AbortController() : undefined;
571
745
  const timer = controller
572
- ? setTimeout(() => controller.abort(), SLACK_API_TIMEOUT_MS)
746
+ ? setTimeout(() => controller.abort(), timeoutMs)
573
747
  : undefined;
574
748
  try {
575
749
  return await fetch(url, {
@@ -582,4 +756,539 @@ async function slackApiFetch(url, init) {
582
756
  clearTimeout(timer);
583
757
  }
584
758
  }
759
+ async function resolveSlackThreadPermalink(channelId, threadTs, resolvedToken) {
760
+ if (typeof channelId !== "string" || typeof threadTs !== "string") {
761
+ return undefined;
762
+ }
763
+ const token = resolvedToken ?? (await resolveSecret("SLACK_BOT_TOKEN"));
764
+ if (!token)
765
+ return undefined;
766
+ try {
767
+ const url = new URL("https://slack.com/api/chat.getPermalink");
768
+ url.searchParams.set("channel", channelId);
769
+ url.searchParams.set("message_ts", threadTs);
770
+ const res = await slackApiFetch(url.toString(), { headers: { Authorization: `Bearer ${token}` } }, SLACK_PERMALINK_TIMEOUT_MS);
771
+ const data = (await res.json());
772
+ if (!data.ok || typeof data.permalink !== "string")
773
+ return undefined;
774
+ const permalink = new URL(data.permalink);
775
+ const isSlackHost = permalink.hostname === "slack.com" ||
776
+ permalink.hostname.endsWith(".slack.com");
777
+ if (permalink.protocol !== "https:" || !isSlackHost)
778
+ return undefined;
779
+ return permalink.toString();
780
+ }
781
+ catch {
782
+ return undefined;
783
+ }
784
+ }
785
+ function boundedSlackText(value) {
786
+ return typeof value === "string"
787
+ ? value.slice(0, SLACK_CONTEXT_TEXT_LIMIT)
788
+ : "";
789
+ }
790
+ function normalizeSlackAgentContext(value, eventTeamId) {
791
+ if (!value || typeof value !== "object")
792
+ return null;
793
+ const rawEntities = value.entities;
794
+ if (!Array.isArray(rawEntities))
795
+ return null;
796
+ const entities = rawEntities.slice(0, 10).flatMap((entity) => {
797
+ if (!entity || typeof entity !== "object")
798
+ return [];
799
+ const record = entity;
800
+ if (typeof record.type !== "string" || typeof record.value !== "string") {
801
+ return [];
802
+ }
803
+ const teamId = typeof record.team_id === "string" ? record.team_id : undefined;
804
+ if (teamId && eventTeamId !== "unknown" && teamId !== eventTeamId) {
805
+ return [];
806
+ }
807
+ return [
808
+ {
809
+ type: record.type.slice(0, 100),
810
+ value: record.value.slice(0, 200),
811
+ ...(teamId ? { teamId } : {}),
812
+ },
813
+ ];
814
+ });
815
+ if (!entities.length)
816
+ return null;
817
+ const channelId = entities.find((entity) => entity.type === "slack#/types/channel_id" &&
818
+ /^[CDG][A-Z0-9]+$/.test(entity.value))?.value;
819
+ return { entities, ...(channelId ? { channelId } : {}) };
820
+ }
821
+ function slackFileReference(value) {
822
+ if (!value || typeof value !== "object")
823
+ return null;
824
+ const file = value;
825
+ if (typeof file.id !== "string")
826
+ return null;
827
+ return {
828
+ id: file.id,
829
+ ...(typeof file.name === "string" ? { name: file.name } : {}),
830
+ ...(typeof file.mimetype === "string" ? { mimetype: file.mimetype } : {}),
831
+ ...(typeof file.size === "number" ? { size: file.size } : {}),
832
+ ...(typeof file.permalink === "string"
833
+ ? { permalink: file.permalink }
834
+ : {}),
835
+ ...(typeof file.url_private_download === "string"
836
+ ? { downloadUrl: file.url_private_download }
837
+ : {}),
838
+ };
839
+ }
840
+ async function slackJson(token, method, params, timeoutMs = 2_000) {
841
+ try {
842
+ const url = new URL(`https://slack.com/api/${method}`);
843
+ for (const [key, value] of Object.entries(params)) {
844
+ url.searchParams.set(key, value);
845
+ }
846
+ const response = await slackApiFetch(url.toString(), { headers: { Authorization: `Bearer ${token}` } }, timeoutMs);
847
+ const body = (await response.json());
848
+ return body.ok ? body : null;
849
+ }
850
+ catch {
851
+ return null;
852
+ }
853
+ }
854
+ async function hydrateSlackContext(token, incoming) {
855
+ const channelId = incoming.platformContext.channelId;
856
+ const threadTs = incoming.platformContext.threadTs;
857
+ const senderId = incoming.senderId;
858
+ if (typeof channelId !== "string" || typeof threadTs !== "string") {
859
+ return incoming;
860
+ }
861
+ const [thread, history, pins, conversation, user] = await Promise.all([
862
+ slackJson(token, "conversations.replies", {
863
+ channel: channelId,
864
+ ts: threadTs,
865
+ limit: String(SLACK_CONTEXT_MESSAGE_LIMIT),
866
+ }),
867
+ slackJson(token, "conversations.history", {
868
+ channel: channelId,
869
+ latest: String(incoming.platformContext.messageTs ?? threadTs),
870
+ inclusive: "true",
871
+ limit: String(SLACK_CONTEXT_MESSAGE_LIMIT),
872
+ }),
873
+ slackJson(token, "pins.list", { channel: channelId }),
874
+ slackJson(token, "conversations.info", { channel: channelId }),
875
+ senderId ? slackJson(token, "users.info", { user: senderId }) : null,
876
+ ]);
877
+ // Agent View can attach the Slack surface the user is currently viewing to
878
+ // a DM. Treat it only as a context hint: Slack requires us to prove the bot
879
+ // can access the referenced channel with conversations.info before reading
880
+ // any history from it.
881
+ const activeContextChannelId = typeof incoming.platformContext.activeContextChannelId === "string"
882
+ ? incoming.platformContext.activeContextChannelId
883
+ : null;
884
+ const activeContextConversation = activeContextChannelId && activeContextChannelId !== channelId
885
+ ? await slackJson(token, "conversations.info", {
886
+ channel: activeContextChannelId,
887
+ })
888
+ : null;
889
+ const activeContextHistory = activeContextConversation
890
+ ? await slackJson(token, "conversations.history", {
891
+ channel: activeContextChannelId,
892
+ limit: "5",
893
+ })
894
+ : null;
895
+ const activeContextName = typeof activeContextConversation?.channel?.name === "string"
896
+ ? activeContextConversation.channel.name
897
+ : null;
898
+ const activeContextMessages = Array.isArray(activeContextHistory?.messages)
899
+ ? activeContextHistory.messages.map((message) => ({
900
+ ...message,
901
+ text: `[Active Slack context${activeContextName ? ` #${activeContextName}` : ""}] ${boundedSlackText(message.text)}`,
902
+ }))
903
+ : [];
904
+ const rawMessages = [
905
+ ...(Array.isArray(history?.messages) ? history.messages : []),
906
+ ...(Array.isArray(pins?.items)
907
+ ? pins.items
908
+ .map((item) => item.message)
909
+ .filter(Boolean)
910
+ : []),
911
+ ...(Array.isArray(thread?.messages) ? thread.messages : []),
912
+ ...activeContextMessages,
913
+ ];
914
+ const uniqueMessages = [
915
+ ...new Map(rawMessages.map((message, index) => [
916
+ typeof message.ts === "string" ? message.ts : `unknown:${index}`,
917
+ message,
918
+ ])).values(),
919
+ ].slice(-SLACK_CONTEXT_MESSAGE_LIMIT);
920
+ const messages = uniqueMessages.length
921
+ ? uniqueMessages.map((message) => {
922
+ const files = Array.isArray(message.files)
923
+ ? message.files
924
+ .map(slackFileReference)
925
+ .filter((file) => file !== null)
926
+ : undefined;
927
+ const reactions = Array.isArray(message.reactions)
928
+ ? message.reactions
929
+ .filter((reaction) => typeof reaction?.name === "string" &&
930
+ typeof reaction?.count === "number")
931
+ .map((reaction) => ({
932
+ name: reaction.name,
933
+ count: reaction.count,
934
+ }))
935
+ : undefined;
936
+ return {
937
+ ...(typeof message.user === "string"
938
+ ? { senderId: message.user }
939
+ : {}),
940
+ text: boundedSlackText(message.text),
941
+ timestamp: typeof message.ts === "string"
942
+ ? Math.floor(parseFloat(message.ts) * 1000)
943
+ : incoming.timestamp,
944
+ ...(reactions?.length ? { reactions } : {}),
945
+ ...(files?.length ? { files } : {}),
946
+ };
947
+ })
948
+ : [];
949
+ const profile = user?.user?.profile;
950
+ const isGuest = user?.user?.is_restricted === true;
951
+ const isExternal = user?.user?.is_ultra_restricted === true;
952
+ const isPrivate = conversation?.channel?.is_private === true;
953
+ const isExternalShared = conversation?.channel?.is_ext_shared === true;
954
+ const isMpim = conversation?.channel?.is_mpim === true;
955
+ const isIm = conversation?.channel?.is_im === true;
956
+ const conversationType = isIm
957
+ ? "dm"
958
+ : isMpim
959
+ ? "group_dm"
960
+ : isPrivate
961
+ ? "private_channel"
962
+ : "channel";
963
+ const attachedFiles = messages.flatMap((message) => message.files ?? []);
964
+ const detailedFiles = await Promise.all([...new Set(attachedFiles.map((file) => file.id))]
965
+ .slice(0, 5)
966
+ .map(async (fileId) => {
967
+ const result = await slackJson(token, "files.info", { file: fileId });
968
+ return slackFileReference(result?.file);
969
+ }));
970
+ const fileById = new Map(detailedFiles
971
+ .filter((file) => file !== null)
972
+ .map((file) => [file.id, file]));
973
+ const hydratedMessages = messages.map((message) => ({
974
+ ...message,
975
+ ...(message.files?.length
976
+ ? {
977
+ files: message.files.map((file) => ({
978
+ ...file,
979
+ ...(fileById.get(file.id) ?? {}),
980
+ })),
981
+ }
982
+ : {}),
983
+ }));
984
+ const hydratedFiles = hydratedMessages.flatMap((message) => message.files ?? []);
985
+ return {
986
+ ...incoming,
987
+ ...(typeof profile?.display_name === "string" && profile.display_name
988
+ ? { senderName: profile.display_name }
989
+ : typeof profile?.real_name === "string" && profile.real_name
990
+ ? { senderName: profile.real_name }
991
+ : {}),
992
+ ...(typeof profile?.email === "string"
993
+ ? { senderEmail: profile.email, senderVerified: true }
994
+ : {}),
995
+ conversationType,
996
+ actorTrust: {
997
+ memberType: isExternal ? "external" : isGuest ? "guest" : "member",
998
+ verified: true,
999
+ },
1000
+ contextMessages: hydratedMessages,
1001
+ ...(hydratedFiles.length ? { files: hydratedFiles.slice(0, 20) } : {}),
1002
+ platformContext: {
1003
+ ...incoming.platformContext,
1004
+ channelName: typeof conversation?.channel?.name === "string"
1005
+ ? conversation.channel.name
1006
+ : undefined,
1007
+ isExternalShared,
1008
+ ...(activeContextChannelId
1009
+ ? {
1010
+ activeContextChannelId,
1011
+ ...(activeContextName
1012
+ ? { activeContextChannelName: activeContextName }
1013
+ : {}),
1014
+ }
1015
+ : {}),
1016
+ },
1017
+ };
1018
+ }
1019
+ function shortTaskTitle(value) {
1020
+ const text = typeof value === "string" ? value : "Working";
1021
+ return text.replace(/[-_]/g, " ").slice(0, 200);
1022
+ }
1023
+ async function postSlackJson(token, method, body) {
1024
+ const response = await slackApiFetch(`https://slack.com/api/${method}`, {
1025
+ method: "POST",
1026
+ headers: {
1027
+ Authorization: `Bearer ${token}`,
1028
+ "Content-Type": "application/json",
1029
+ },
1030
+ body: JSON.stringify(body),
1031
+ });
1032
+ const data = (await response.json());
1033
+ if (!data.ok)
1034
+ throw new Error(data.error || `${method} failed`);
1035
+ return data;
1036
+ }
1037
+ async function startSlackRunProgress(token, incoming) {
1038
+ const channel = incoming.platformContext.channelId;
1039
+ const threadTs = incoming.platformContext.threadTs;
1040
+ if (typeof channel !== "string" || typeof threadTs !== "string")
1041
+ return null;
1042
+ let started;
1043
+ try {
1044
+ started = await postSlackJson(token, "chat.startStream", {
1045
+ channel,
1046
+ thread_ts: threadTs,
1047
+ ...(incoming.tenantId ? { recipient_team_id: incoming.tenantId } : {}),
1048
+ ...(incoming.senderId ? { recipient_user_id: incoming.senderId } : {}),
1049
+ task_display_mode: "plan",
1050
+ markdown_text: "Working on your request…",
1051
+ chunks: [
1052
+ {
1053
+ type: "plan_update",
1054
+ title: "Working on your request",
1055
+ },
1056
+ {
1057
+ type: "task_update",
1058
+ id: "agent-native:context",
1059
+ title: "Understand the request",
1060
+ status: "in_progress",
1061
+ details: "Loading relevant context",
1062
+ },
1063
+ ],
1064
+ });
1065
+ }
1066
+ catch {
1067
+ return null;
1068
+ }
1069
+ const streamTs = started.ts;
1070
+ if (typeof streamTs !== "string")
1071
+ return null;
1072
+ const tasks = new Map();
1073
+ const toolTaskIds = new Map();
1074
+ tasks.set("agent-native:context", {
1075
+ title: "Understand the request",
1076
+ status: "in_progress",
1077
+ });
1078
+ let sequence = 0;
1079
+ let lastWriteAt = 0;
1080
+ let pending = null;
1081
+ let pendingTimer = null;
1082
+ let approvalControls = null;
1083
+ let cancelControl = null;
1084
+ const append = async (chunk) => {
1085
+ const now = Date.now();
1086
+ const write = async (value) => {
1087
+ lastWriteAt = Date.now();
1088
+ await postSlackJson(token, "chat.appendStream", {
1089
+ channel,
1090
+ ts: streamTs,
1091
+ markdown_text: "Progress updated.",
1092
+ chunks: [value],
1093
+ }).catch(() => { });
1094
+ };
1095
+ if (now - lastWriteAt >= 900) {
1096
+ await write(chunk);
1097
+ return;
1098
+ }
1099
+ pending = chunk;
1100
+ if (!pendingTimer) {
1101
+ pendingTimer = setTimeout(() => {
1102
+ const value = pending;
1103
+ pending = null;
1104
+ pendingTimer = null;
1105
+ if (value)
1106
+ void write(value);
1107
+ }, 900 - (now - lastWriteAt));
1108
+ }
1109
+ };
1110
+ const taskId = (prefix, explicit) => `${prefix}:${explicit || ++sequence}`.slice(0, 240);
1111
+ return {
1112
+ async onEvent(event) {
1113
+ if (!cancelControl) {
1114
+ const context = getIntegrationRequestContext();
1115
+ const ownerEmail = getRequestContext()?.userEmail;
1116
+ if (context?.lineage?.runId &&
1117
+ ownerEmail &&
1118
+ incoming.senderId &&
1119
+ incoming.tenantId) {
1120
+ cancelControl = await createIntegrationControl({
1121
+ action: "cancel",
1122
+ ownerEmail,
1123
+ orgId: getRequestContext()?.orgId ?? null,
1124
+ requesterId: incoming.senderId,
1125
+ teamId: incoming.tenantId,
1126
+ apiAppId: typeof incoming.platformContext.apiAppId === "string"
1127
+ ? incoming.platformContext.apiAppId
1128
+ : null,
1129
+ channelId: channel,
1130
+ messageTs: streamTs,
1131
+ runId: context.lineage.runId,
1132
+ incoming,
1133
+ });
1134
+ await append({
1135
+ type: "blocks",
1136
+ blocks: [
1137
+ {
1138
+ type: "actions",
1139
+ block_id: `agent-native-running-${Date.now()}`,
1140
+ elements: [
1141
+ {
1142
+ type: "button",
1143
+ text: { type: "plain_text", text: "Cancel" },
1144
+ style: "danger",
1145
+ action_id: "agent_native_cancel",
1146
+ value: cancelControl,
1147
+ },
1148
+ ],
1149
+ },
1150
+ ],
1151
+ });
1152
+ }
1153
+ }
1154
+ if (event.type === "approval_required") {
1155
+ const context = getIntegrationRequestContext();
1156
+ const ownerEmail = getRequestContext()?.userEmail;
1157
+ if (context && ownerEmail && incoming.senderId && incoming.tenantId) {
1158
+ const common = {
1159
+ ownerEmail,
1160
+ orgId: getRequestContext()?.orgId ?? null,
1161
+ requesterId: incoming.senderId,
1162
+ teamId: incoming.tenantId,
1163
+ apiAppId: typeof incoming.platformContext.apiAppId === "string"
1164
+ ? incoming.platformContext.apiAppId
1165
+ : null,
1166
+ channelId: channel,
1167
+ messageTs: streamTs,
1168
+ runId: context.lineage?.runId ?? null,
1169
+ approvalKey: event.approvalKey,
1170
+ incoming,
1171
+ };
1172
+ const [approve, deny] = await Promise.all([
1173
+ createIntegrationControl({ ...common, action: "approve" }),
1174
+ createIntegrationControl({ ...common, action: "deny" }),
1175
+ ]);
1176
+ approvalControls = { approve, deny };
1177
+ }
1178
+ await append({
1179
+ type: "task_update",
1180
+ id: "agent-native:approval",
1181
+ title: `Approve ${shortTaskTitle(event.tool)}`,
1182
+ status: "pending",
1183
+ details: "Waiting for the requester",
1184
+ });
1185
+ }
1186
+ else if (event.type === "tool_start") {
1187
+ const key = event.id || event.tool;
1188
+ const id = taskId("tool", event.id);
1189
+ toolTaskIds.set(key, id);
1190
+ const title = shortTaskTitle(event.tool);
1191
+ tasks.set(id, { title, status: "in_progress" });
1192
+ await append({
1193
+ type: "task_update",
1194
+ id,
1195
+ title,
1196
+ status: "in_progress",
1197
+ });
1198
+ }
1199
+ else if (event.type === "tool_done") {
1200
+ const key = event.id || event.tool;
1201
+ const id = toolTaskIds.get(key) ?? taskId("tool", event.id);
1202
+ const title = tasks.get(id)?.title ?? shortTaskTitle(event.tool);
1203
+ tasks.set(id, {
1204
+ title,
1205
+ status: event.isError ? "error" : "complete",
1206
+ });
1207
+ await append({
1208
+ type: "task_update",
1209
+ id,
1210
+ title,
1211
+ status: event.isError ? "error" : "complete",
1212
+ });
1213
+ }
1214
+ else if (event.type === "agent_call") {
1215
+ const id = taskId("agent", event.agent);
1216
+ const status = event.status === "start"
1217
+ ? "in_progress"
1218
+ : event.status === "done"
1219
+ ? "complete"
1220
+ : "error";
1221
+ const title = `Ask ${shortTaskTitle(event.agent)}`;
1222
+ tasks.set(id, { title, status });
1223
+ await append({ type: "task_update", id, title, status });
1224
+ }
1225
+ else if (event.type === "activity") {
1226
+ await append({
1227
+ type: "task_update",
1228
+ id: "agent-native:context",
1229
+ title: "Understand the request",
1230
+ status: "in_progress",
1231
+ details: shortTaskTitle(event.label),
1232
+ });
1233
+ }
1234
+ },
1235
+ async complete(message) {
1236
+ if (pendingTimer)
1237
+ clearTimeout(pendingTimer);
1238
+ const finalChunks = [...tasks.entries()].map(([id, task]) => ({
1239
+ type: "task_update",
1240
+ id,
1241
+ title: task.title,
1242
+ status: task.status === "in_progress" ? "complete" : task.status,
1243
+ }));
1244
+ const messageBlocks = Array.isArray(message.platformContext.blocks)
1245
+ ? message.platformContext.blocks
1246
+ : [];
1247
+ const controlBlocks = approvalControls
1248
+ ? [
1249
+ {
1250
+ type: "actions",
1251
+ block_id: `agent-native-approval-${Date.now()}`,
1252
+ elements: [
1253
+ {
1254
+ type: "button",
1255
+ text: { type: "plain_text", text: "Approve" },
1256
+ style: "primary",
1257
+ action_id: "agent_native_approve",
1258
+ value: approvalControls.approve,
1259
+ },
1260
+ {
1261
+ type: "button",
1262
+ text: { type: "plain_text", text: "Deny" },
1263
+ style: "danger",
1264
+ action_id: "agent_native_deny",
1265
+ value: approvalControls.deny,
1266
+ },
1267
+ ],
1268
+ },
1269
+ ]
1270
+ : [];
1271
+ await postSlackJson(token, "chat.stopStream", {
1272
+ channel,
1273
+ ts: streamTs,
1274
+ markdown_text: message.text || "Done.",
1275
+ ...(finalChunks.length ? { chunks: finalChunks } : {}),
1276
+ ...(messageBlocks.length || controlBlocks.length
1277
+ ? { blocks: [...messageBlocks, ...controlBlocks].slice(0, 50) }
1278
+ : {}),
1279
+ });
1280
+ setSlackAssistantStatus(token, channel, threadTs, "");
1281
+ },
1282
+ async fail(message) {
1283
+ if (pendingTimer)
1284
+ clearTimeout(pendingTimer);
1285
+ await postSlackJson(token, "chat.stopStream", {
1286
+ channel,
1287
+ ts: streamTs,
1288
+ markdown_text: message.slice(0, SLACK_MAX_LENGTH),
1289
+ }).catch(() => { });
1290
+ setSlackAssistantStatus(token, channel, threadTs, "");
1291
+ },
1292
+ };
1293
+ }
585
1294
  //# sourceMappingURL=slack.js.map