@agent-native/core 0.149.2 → 0.149.3

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 (345) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +54 -488
  3. package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +136 -0
  4. package/corpus/templates/analytics/.agents/skills/actions/references/examples.md +94 -0
  5. package/corpus/templates/analytics/.agents/skills/actions/references/provider-apis.md +95 -0
  6. package/corpus/templates/analytics/.agents/skills/create-skill/SKILL.md +9 -35
  7. package/corpus/templates/analytics/.agents/skills/creative-context/SKILL.md +4 -2
  8. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
  9. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
  10. package/corpus/templates/analytics/AGENTS.md +25 -32
  11. package/corpus/templates/analytics/app/global.css +1 -1
  12. package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  13. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
  14. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
  15. package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
  16. package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
  17. package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
  18. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
  19. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
  20. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
  21. package/corpus/templates/assets/AGENTS.md +6 -9
  22. package/corpus/templates/assets/app/global.css +1 -1
  23. package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  24. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
  25. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
  26. package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
  27. package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
  28. package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
  29. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
  30. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
  31. package/corpus/templates/brain/AGENTS.md +5 -12
  32. package/corpus/templates/brain/app/global.css +1 -1
  33. package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  34. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
  35. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
  36. package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
  37. package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
  38. package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
  39. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
  40. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
  41. package/corpus/templates/calendar/AGENTS.md +8 -9
  42. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  43. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  44. package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  45. package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  46. package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  47. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  48. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  49. package/corpus/templates/chat/AGENTS.md +32 -80
  50. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
  51. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
  52. package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
  53. package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
  54. package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
  55. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
  56. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
  57. package/corpus/templates/clips/AGENTS.md +25 -31
  58. package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
  59. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
  60. package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
  61. package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
  62. package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
  63. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
  64. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
  65. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
  66. package/corpus/templates/content/AGENTS.md +5 -9
  67. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
  68. package/corpus/templates/crm/AGENTS.md +7 -11
  69. package/corpus/templates/crm/app/global.css +1 -1
  70. package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  71. package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
  72. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
  73. package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
  74. package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
  75. package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
  76. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
  77. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
  78. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
  79. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
  80. package/corpus/templates/design/AGENTS.md +13 -21
  81. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
  82. package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
  83. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
  84. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
  85. package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
  86. package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
  87. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
  88. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
  89. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
  90. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
  91. package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
  92. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
  93. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  94. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
  95. package/corpus/templates/design/app/i18n-data.ts +1 -0
  96. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
  97. package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
  98. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
  99. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
  100. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
  101. package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
  102. package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
  103. package/corpus/templates/design/e2e/global-setup.ts +27 -32
  104. package/corpus/templates/design/playwright.config.ts +3 -5
  105. package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
  106. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
  107. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
  108. package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
  109. package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
  110. package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
  111. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
  112. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
  113. package/corpus/templates/dispatch/AGENTS.md +9 -16
  114. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
  115. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
  116. package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
  117. package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
  118. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
  119. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
  120. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
  121. package/corpus/templates/factory/AGENTS.md +10 -24
  122. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
  123. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
  124. package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
  125. package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
  126. package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
  127. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
  128. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
  129. package/corpus/templates/forms/AGENTS.md +11 -17
  130. package/corpus/templates/forms/app/global.css +1 -0
  131. package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  132. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
  133. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
  134. package/corpus/templates/macros/AGENTS.md +8 -8
  135. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
  136. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
  137. package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
  138. package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
  139. package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
  140. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
  141. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
  142. package/corpus/templates/mail/AGENTS.md +5 -6
  143. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
  144. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
  145. package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
  146. package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
  147. package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
  148. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
  149. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
  150. package/corpus/templates/plan/AGENTS.md +5 -14
  151. package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
  152. package/corpus/templates/plan/vite.config.ts +5 -0
  153. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
  154. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
  155. package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
  156. package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
  157. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
  158. package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
  159. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
  160. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
  161. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
  162. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
  163. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
  164. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
  165. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
  166. package/corpus/templates/slides/AGENTS.md +22 -25
  167. package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
  168. package/corpus/templates/slides/actions/get-deck.ts +57 -9
  169. package/corpus/templates/slides/actions/import-file.ts +2 -1
  170. package/corpus/templates/slides/actions/patch-deck.ts +45 -2
  171. package/corpus/templates/slides/actions/update-slide.ts +1 -1
  172. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
  173. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
  174. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
  175. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
  176. package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
  177. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
  178. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  179. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +428 -180
  180. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +294 -266
  181. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +7 -5
  182. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
  183. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +40 -12
  184. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
  185. package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
  186. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
  187. package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
  188. package/corpus/templates/slides/app/global.css +76 -1
  189. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  190. package/corpus/templates/slides/app/lib/create-deck-generation.ts +51 -23
  191. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +68 -5
  192. package/corpus/templates/slides/app/pages/DeckEditor.tsx +13 -6
  193. package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
  194. package/corpus/templates/slides/app/pages/Index.tsx +87 -74
  195. package/corpus/templates/slides/app/root.tsx +43 -0
  196. package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
  197. package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
  198. package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
  199. package/corpus/templates/slides/package.json +1 -0
  200. package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
  201. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  202. package/corpus/templates/slides/shared/api.ts +46 -15
  203. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
  204. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
  205. package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
  206. package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
  207. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
  208. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
  209. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
  210. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
  211. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
  212. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
  213. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
  214. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
  215. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
  216. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
  217. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
  218. package/corpus/templates/tasks/AGENTS.md +5 -20
  219. package/dist/agent/production-agent.js +376 -345
  220. package/dist/agent/run-manager.js +156 -14
  221. package/dist/agent/run-store.d.ts +11 -10
  222. package/dist/agent/run-store.js +17 -13
  223. package/dist/client/AssistantChat.d.ts +6 -2
  224. package/dist/client/AssistantChat.js +216 -131
  225. package/dist/client/active-run-state.d.ts +9 -1
  226. package/dist/client/active-run-state.js +34 -3
  227. package/dist/client/agent-chat-adapter.d.ts +8 -0
  228. package/dist/client/agent-chat-adapter.js +114 -28
  229. package/dist/client/chat/message-components.d.ts +7 -1
  230. package/dist/client/chat/message-components.js +32 -5
  231. package/dist/client/chat/run-recovery.d.ts +1 -0
  232. package/dist/client/chat/run-recovery.js +8 -0
  233. package/dist/client/chat/tool-call-display.d.ts +2 -0
  234. package/dist/client/chat/tool-call-display.js +2 -0
  235. package/dist/client/chat-first/apps-rail.js +1 -1
  236. package/dist/client/chat-first/chat-history.d.ts +1 -1
  237. package/dist/client/chat-first/chat-history.js +5 -2
  238. package/dist/client/sse-event-processor.d.ts +4 -2
  239. package/dist/client/sse-event-processor.js +36 -6
  240. package/dist/client/use-run-stuck-detection.d.ts +2 -0
  241. package/dist/client/use-run-stuck-detection.js +85 -9
  242. package/dist/collab/awareness.d.ts +2 -2
  243. package/dist/collab/routes.d.ts +1 -1
  244. package/dist/integrations/adapters/slack.d.ts +0 -4
  245. package/dist/integrations/adapters/slack.js +6 -30
  246. package/dist/integrations/catalog.js +1 -1
  247. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  248. package/dist/integrations/pending-tasks-store.js +0 -21
  249. package/dist/integrations/slack-manifest.d.ts +2 -2
  250. package/dist/integrations/slack-manifest.js +0 -3
  251. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  252. package/dist/observability/routes.d.ts +3 -3
  253. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  254. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  255. package/dist/resources/handlers.d.ts +1 -1
  256. package/dist/scripts/docs/source-search.js +2 -2
  257. package/dist/secrets/routes.d.ts +9 -9
  258. package/dist/server/agent-chat/framework-prompts.js +7 -2
  259. package/dist/server/agent-chat/prompt-resources.js +2 -2
  260. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  261. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  262. package/dist/server/agent-chat-plugin.js +3 -3
  263. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  264. package/dist/server/agents-bundle.d.ts +16 -19
  265. package/dist/server/agents-bundle.js +19 -35
  266. package/dist/server/better-auth-instance.d.ts +1 -0
  267. package/dist/server/better-auth-instance.js +17 -2
  268. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  269. package/dist/server/prompts/framework-core-compact.js +12 -9
  270. package/dist/server/prompts/framework-core.d.ts +6 -1
  271. package/dist/server/prompts/framework-core.js +11 -9
  272. package/dist/server/prompts/index.d.ts +1 -1
  273. package/dist/server/prompts/index.js +1 -1
  274. package/dist/server/prompts/shared-rules.d.ts +15 -11
  275. package/dist/server/prompts/shared-rules.js +17 -13
  276. package/dist/server/realtime-token.d.ts +1 -1
  277. package/dist/server/transcribe-voice.d.ts +1 -1
  278. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  279. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  280. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  281. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  282. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  283. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  284. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  285. package/dist/templates/chat/AGENTS.md +32 -80
  286. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  287. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  288. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  289. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  290. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  291. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  292. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  293. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  294. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  295. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  296. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  297. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  298. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  299. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  300. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  301. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  302. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  303. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  304. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  305. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  306. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  307. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  308. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  309. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  310. package/dist/templates/workspace-core/AGENTS.md +7 -16
  311. package/docs/content/messaging.mdx +6 -7
  312. package/package.json +1 -1
  313. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  314. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  315. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  316. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  317. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  318. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  319. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  320. package/src/templates/chat/AGENTS.md +32 -80
  321. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  322. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  323. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  324. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  325. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  326. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  327. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  328. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  329. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  330. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  331. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  332. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  333. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  334. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  335. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  336. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  337. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  338. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  339. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  340. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  341. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  342. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  343. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  344. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  345. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -13,7 +13,7 @@ import {
13
13
  IconBrandGoogle,
14
14
  IconPlugConnected,
15
15
  } from "@tabler/icons-react";
16
- import { useRef, useState } from "react";
16
+ import { forwardRef, useImperativeHandle, useRef, useState } from "react";
17
17
  import { toast } from "sonner";
18
18
 
19
19
  import { Button } from "@/components/ui/button";
@@ -52,287 +52,315 @@ interface ExportMenuProps {
52
52
  inline?: boolean;
53
53
  }
54
54
 
55
- export function ExportMenu({
56
- deckId,
57
- deckTitle,
58
- onDuplicate,
59
- onExportPdf,
60
- onExportPptx,
61
- onExportGoogleSlides,
62
- onShareLink,
63
- onShareTeam,
64
- inline = false,
65
- }: ExportMenuProps) {
66
- const t = useT();
67
- const [googleSlidesImportOpen, setGoogleSlidesImportOpen] = useState(false);
68
- const googleSlidesImportTarget = useRef<Window | null>(null);
69
- const triggerBlobDownload = (blob: Blob, filename: string) => {
70
- const url = URL.createObjectURL(blob);
71
- const a = document.createElement("a");
72
- a.href = url;
73
- a.download = filename;
74
- a.rel = "noopener";
75
- document.body.appendChild(a);
76
- a.click();
77
- a.remove();
78
- window.setTimeout(() => URL.revokeObjectURL(url), 60_000);
79
- };
55
+ export interface ExportMenuHandle {
56
+ connectGoogle: () => Promise<void>;
57
+ exportGoogleSlides: () => Promise<void>;
58
+ exportHtml: () => Promise<void>;
59
+ exportPptx: () => Promise<void>;
60
+ }
80
61
 
81
- const filenameFromDisposition = (
82
- value: string | null,
83
- fallbackExt: string,
84
- ) => {
85
- const match = value?.match(/filename="?([^"]+)"?/i);
86
- const fallback = deckTitle.replace(/[^a-zA-Z0-9_-]/g, "-") || "deck";
87
- return match?.[1] ?? `${fallback}${fallbackExt}`;
88
- };
62
+ export const ExportMenu = forwardRef<ExportMenuHandle, ExportMenuProps>(
63
+ function ExportMenu(
64
+ {
65
+ deckId,
66
+ deckTitle,
67
+ onDuplicate,
68
+ onExportPdf,
69
+ onExportPptx,
70
+ onExportGoogleSlides,
71
+ onShareLink,
72
+ onShareTeam,
73
+ inline = false,
74
+ },
75
+ ref,
76
+ ) {
77
+ const t = useT();
78
+ const [googleSlidesImportOpen, setGoogleSlidesImportOpen] = useState(false);
79
+ const googleSlidesImportTarget = useRef<Window | null>(null);
80
+ const triggerBlobDownload = (blob: Blob, filename: string) => {
81
+ const url = URL.createObjectURL(blob);
82
+ const a = document.createElement("a");
83
+ a.href = url;
84
+ a.download = filename;
85
+ a.rel = "noopener";
86
+ document.body.appendChild(a);
87
+ a.click();
88
+ a.remove();
89
+ window.setTimeout(() => URL.revokeObjectURL(url), 60_000);
90
+ };
89
91
 
90
- const readErrorMessage = async (res: Response, fallback: string) => {
91
- try {
92
- const data = await res.json();
93
- return data.error || data.message || fallback;
94
- } catch {
95
- return fallback;
96
- }
97
- };
92
+ const filenameFromDisposition = (
93
+ value: string | null,
94
+ fallbackExt: string,
95
+ ) => {
96
+ const match = value?.match(/filename="?([^"]+)"?/i);
97
+ const fallback = deckTitle.replace(/[^a-zA-Z0-9_-]/g, "-") || "deck";
98
+ return match?.[1] ?? `${fallback}${fallbackExt}`;
99
+ };
98
100
 
99
- const handleExportPptx = async () => {
100
- try {
101
- await onExportPptx();
102
- } catch (err) {
103
- console.error("Export failed:", err);
104
- toast.error(t("editorExport.exportFailed"), {
105
- description:
106
- err instanceof Error
107
- ? err.message
108
- : t("editorExport.exportPptxError"),
109
- });
110
- }
111
- };
101
+ const readErrorMessage = async (res: Response, fallback: string) => {
102
+ try {
103
+ const data = await res.json();
104
+ return data.error || data.message || fallback;
105
+ } catch {
106
+ return fallback;
107
+ }
108
+ };
112
109
 
113
- const handleExportGoogleSlides = async () => {
114
- if (!onExportGoogleSlides) return;
115
- // Opened up-front: browsers only honour window.open() inside the click
116
- // gesture, and building the PPTX is async.
117
- const target = window.open("", "_blank");
118
- googleSlidesImportTarget.current = target;
119
- try {
120
- const result = await onExportGoogleSlides();
121
- if (result.url !== null) {
122
- googleSlidesImportTarget.current = null;
123
- if (target) target.location.href = result.url;
124
- toast.success(t("editorExport.googleSlidesCreated"), {
125
- description: t("editorExport.googleSlidesCreatedHint"),
110
+ const handleExportPptx = async () => {
111
+ try {
112
+ await onExportPptx();
113
+ } catch (err) {
114
+ console.error("Export failed:", err);
115
+ toast.error(t("editorExport.exportFailed"), {
116
+ description:
117
+ err instanceof Error
118
+ ? err.message
119
+ : t("editorExport.exportPptxError"),
126
120
  });
127
- return;
128
121
  }
129
- if (target) target.location.href = GOOGLE_SLIDES_IMPORT_URL;
130
- setGoogleSlidesImportOpen(true);
131
- // The deck did not reach Drive. Saying "success" here is why users read
132
- // the .pptx download as the intended result and never learn that their
133
- // Google account is unconnected or that Drive rejected the upload.
134
- toast.warning(t("editorExport.googleSlidesDownloaded"), {
135
- description: `${result.reason} ${t("editorExport.googleSlidesImportHint")}`,
136
- });
137
- } catch (err) {
138
- googleSlidesImportTarget.current = null;
139
- target?.close();
140
- console.error("Export failed:", err);
141
- toast.error(t("editorExport.exportFailed"), {
142
- description:
143
- err instanceof Error
144
- ? err.message
145
- : t("editorExport.exportGoogleSlidesError"),
146
- });
147
- }
148
- };
122
+ };
149
123
 
150
- const handleConnectGoogle = async () => {
151
- const authUrl = new URL(
152
- agentNativePath("/_agent-native/google-docs/auth-url"),
153
- window.location.origin,
154
- );
155
- authUrl.searchParams.set(
156
- "return",
157
- window.location.pathname + window.location.search,
158
- );
124
+ const handleExportGoogleSlides = async () => {
125
+ if (!onExportGoogleSlides) return;
126
+ // Opened up-front: browsers only honour window.open() inside the click
127
+ // gesture, and building the PPTX is async.
128
+ const target = window.open("", "_blank");
129
+ googleSlidesImportTarget.current = target;
130
+ try {
131
+ const result = await onExportGoogleSlides();
132
+ if (result.url !== null) {
133
+ googleSlidesImportTarget.current = null;
134
+ if (target) target.location.href = result.url;
135
+ toast.success(t("editorExport.googleSlidesCreated"), {
136
+ description: t("editorExport.googleSlidesCreatedHint"),
137
+ });
138
+ return;
139
+ }
140
+ if (target) target.location.href = GOOGLE_SLIDES_IMPORT_URL;
141
+ setGoogleSlidesImportOpen(true);
142
+ // The deck did not reach Drive. Saying "success" here is why users read
143
+ // the .pptx download as the intended result and never learn that their
144
+ // Google account is unconnected or that Drive rejected the upload.
145
+ toast.warning(t("editorExport.googleSlidesDownloaded"), {
146
+ description: `${result.reason} ${t("editorExport.googleSlidesImportHint")}`,
147
+ });
148
+ } catch (err) {
149
+ googleSlidesImportTarget.current = null;
150
+ target?.close();
151
+ console.error("Export failed:", err);
152
+ toast.error(t("editorExport.exportFailed"), {
153
+ description:
154
+ err instanceof Error
155
+ ? err.message
156
+ : t("editorExport.exportGoogleSlidesError"),
157
+ });
158
+ }
159
+ };
159
160
 
160
- const popup = window.open(
161
- "",
162
- "google-docs-oauth",
163
- "popup,width=520,height=720",
164
- );
165
- if (!popup) {
166
- toast.error(t("editorExport.exportFailed"), {
167
- description: t("editorExport.exportGoogleSlidesError"),
168
- });
169
- return;
170
- }
161
+ const handleConnectGoogle = async () => {
162
+ const authUrl = new URL(
163
+ agentNativePath("/_agent-native/google-docs/auth-url"),
164
+ window.location.origin,
165
+ );
166
+ authUrl.searchParams.set(
167
+ "return",
168
+ window.location.pathname + window.location.search,
169
+ );
171
170
 
172
- try {
173
- const response = await fetch(authUrl.toString(), {
174
- credentials: "same-origin",
175
- });
176
- if (!response.ok) {
177
- throw new Error(
178
- await readErrorMessage(
179
- response,
180
- t("editorExport.exportGoogleSlidesError"),
181
- ),
182
- );
171
+ const popup = window.open(
172
+ "",
173
+ "google-docs-oauth",
174
+ "popup,width=520,height=720",
175
+ );
176
+ if (!popup) {
177
+ toast.error(t("editorExport.exportFailed"), {
178
+ description: t("editorExport.exportGoogleSlidesError"),
179
+ });
180
+ return;
183
181
  }
184
- const data = (await response.json()) as { url?: unknown };
185
- if (typeof data.url !== "string") {
186
- throw new Error(t("editorExport.exportGoogleSlidesError"));
182
+
183
+ try {
184
+ const response = await fetch(authUrl.toString(), {
185
+ credentials: "same-origin",
186
+ });
187
+ if (!response.ok) {
188
+ throw new Error(
189
+ await readErrorMessage(
190
+ response,
191
+ t("editorExport.exportGoogleSlidesError"),
192
+ ),
193
+ );
194
+ }
195
+ const data = (await response.json()) as { url?: unknown };
196
+ if (typeof data.url !== "string") {
197
+ throw new Error(t("editorExport.exportGoogleSlidesError"));
198
+ }
199
+ popup.location.href = data.url;
200
+ } catch (err) {
201
+ popup?.close();
202
+ console.error("Google connection failed:", err);
203
+ toast.error(t("editorExport.exportFailed"), {
204
+ description:
205
+ err instanceof Error
206
+ ? err.message
207
+ : t("editorExport.exportGoogleSlidesError"),
208
+ });
187
209
  }
188
- popup.location.href = data.url;
189
- } catch (err) {
190
- popup?.close();
191
- console.error("Google connection failed:", err);
192
- toast.error(t("editorExport.exportFailed"), {
193
- description:
194
- err instanceof Error
195
- ? err.message
196
- : t("editorExport.exportGoogleSlidesError"),
197
- });
198
- }
199
- };
210
+ };
200
211
 
201
- const handleExportHtml = async () => {
202
- try {
203
- const res = await fetch(`${appBasePath()}/api/exports/html`, {
204
- method: "POST",
205
- headers: { "Content-Type": "application/json" },
206
- body: JSON.stringify({ deckId }),
207
- });
208
- if (!res.ok) {
209
- throw new Error(
210
- await readErrorMessage(res, t("editorExport.htmlFailed")),
212
+ const handleExportHtml = async () => {
213
+ try {
214
+ const res = await fetch(`${appBasePath()}/api/exports/html`, {
215
+ method: "POST",
216
+ headers: { "Content-Type": "application/json" },
217
+ body: JSON.stringify({ deckId }),
218
+ });
219
+ if (!res.ok) {
220
+ throw new Error(
221
+ await readErrorMessage(res, t("editorExport.htmlFailed")),
222
+ );
223
+ }
224
+ const blob = await res.blob();
225
+ const filename = filenameFromDisposition(
226
+ res.headers.get("content-disposition"),
227
+ ".html",
211
228
  );
229
+ triggerBlobDownload(blob, filename);
230
+ } catch (err) {
231
+ console.error("Export failed:", err);
232
+ toast.error(t("editorExport.exportFailed"), {
233
+ description:
234
+ err instanceof Error
235
+ ? err.message
236
+ : t("editorExport.exportHtmlError"),
237
+ });
212
238
  }
213
- const blob = await res.blob();
214
- const filename = filenameFromDisposition(
215
- res.headers.get("content-disposition"),
216
- ".html",
217
- );
218
- triggerBlobDownload(blob, filename);
219
- } catch (err) {
220
- console.error("Export failed:", err);
221
- toast.error(t("editorExport.exportFailed"), {
222
- description:
223
- err instanceof Error
224
- ? err.message
225
- : t("editorExport.exportHtmlError"),
226
- });
227
- }
228
- };
239
+ };
229
240
 
230
- const menuContent = (
231
- <>
232
- <DropdownMenuLabel className="text-[11px] text-muted-foreground">
233
- {t("editorExport.exportAndDuplicate")}
234
- </DropdownMenuLabel>
235
- {onShareTeam && (
236
- <DropdownMenuItem onClick={onShareTeam} className="cursor-pointer">
237
- <IconShare2 className="w-4 h-4 mr-2" />
238
- {t("editorExport.shareWithTeam")}
239
- </DropdownMenuItem>
240
- )}
241
- {onShareLink && (
242
- <DropdownMenuItem onClick={onShareLink} className="cursor-pointer">
243
- <IconShare2 className="w-4 h-4 mr-2" />
244
- {t("editorExport.publicShareLink")}
245
- </DropdownMenuItem>
246
- )}
247
- <DropdownMenuSeparator />
248
- <DropdownMenuItem onClick={handleExportHtml} className="cursor-pointer">
249
- <IconCode className="w-4 h-4 mr-2" />
250
- {t("editorExport.downloadHtml")}
251
- </DropdownMenuItem>
252
- <DropdownMenuItem onClick={onExportPdf} className="cursor-pointer">
253
- <IconFileTypePdf className="w-4 h-4 mr-2" />
254
- {t("editorExport.exportPdf")}
255
- </DropdownMenuItem>
256
- <DropdownMenuItem onClick={handleExportPptx} className="cursor-pointer">
257
- <IconDownload className="w-4 h-4 mr-2" />
258
- {t("editorExport.exportPptx")}
259
- </DropdownMenuItem>
260
- {onExportGoogleSlides && (
261
- <>
262
- <DropdownMenuItem
263
- onClick={handleConnectGoogle}
264
- className="cursor-pointer"
265
- >
266
- <IconPlugConnected className="w-4 h-4 mr-2" />
267
- {t("editorExport.connectGoogle")}
241
+ useImperativeHandle(
242
+ ref,
243
+ () => ({
244
+ connectGoogle: handleConnectGoogle,
245
+ exportGoogleSlides: handleExportGoogleSlides,
246
+ exportHtml: handleExportHtml,
247
+ exportPptx: handleExportPptx,
248
+ }),
249
+ [
250
+ handleConnectGoogle,
251
+ handleExportGoogleSlides,
252
+ handleExportHtml,
253
+ handleExportPptx,
254
+ ],
255
+ );
256
+
257
+ const menuContent = (
258
+ <>
259
+ <DropdownMenuLabel className="text-[11px] text-muted-foreground">
260
+ {t("editorExport.exportAndDuplicate")}
261
+ </DropdownMenuLabel>
262
+ {onShareTeam && (
263
+ <DropdownMenuItem onClick={onShareTeam} className="cursor-pointer">
264
+ <IconShare2 className="w-4 h-4 mr-2" />
265
+ {t("editorExport.shareWithTeam")}
268
266
  </DropdownMenuItem>
269
- <DropdownMenuItem
270
- onClick={handleExportGoogleSlides}
271
- className="cursor-pointer"
272
- >
273
- <IconBrandGoogle className="w-4 h-4 mr-2" />
274
- {t("editorExport.openInGoogleSlides")}
267
+ )}
268
+ {onShareLink && (
269
+ <DropdownMenuItem onClick={onShareLink} className="cursor-pointer">
270
+ <IconShare2 className="w-4 h-4 mr-2" />
271
+ {t("editorExport.publicShareLink")}
275
272
  </DropdownMenuItem>
276
- </>
277
- )}
278
- <DropdownMenuSeparator />
279
- <DropdownMenuItem onClick={onDuplicate} className="cursor-pointer">
280
- <IconCopy className="w-4 h-4 mr-2" />
281
- {t("editorExport.duplicateDeck")}
282
- </DropdownMenuItem>
283
- </>
284
- );
285
-
286
- return (
287
- <>
288
- {inline ? (
289
- menuContent
290
- ) : (
291
- <DropdownMenu>
292
- <DropdownMenuTrigger asChild>
293
- <button className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent text-xs cursor-pointer whitespace-nowrap">
294
- <IconUpload className="w-3.5 h-3.5" />
295
- <span className="hidden md:inline">
296
- {t("editorExport.export")}
297
- </span>
298
- </button>
299
- </DropdownMenuTrigger>
300
- <DropdownMenuContent align="end" className="w-52">
301
- {menuContent}
302
- </DropdownMenuContent>
303
- </DropdownMenu>
304
- )}
305
- <Dialog
306
- open={googleSlidesImportOpen}
307
- onOpenChange={setGoogleSlidesImportOpen}
308
- >
309
- <DialogContent>
310
- <DialogHeader>
311
- <DialogTitle>
312
- {t("editorExport.googleSlidesDownloaded")}
313
- </DialogTitle>
314
- <DialogDescription>
315
- {t("editorExport.googleSlidesImportHint")}
316
- </DialogDescription>
317
- </DialogHeader>
318
- <DialogFooter>
319
- <Button
320
- type="button"
321
- onClick={() => {
322
- const target = googleSlidesImportTarget.current;
323
- if (target && !target.closed) {
324
- target.focus?.();
325
- } else {
326
- window.open(GOOGLE_SLIDES_IMPORT_URL, "_blank");
327
- }
328
- setGoogleSlidesImportOpen(false);
329
- }}
273
+ )}
274
+ <DropdownMenuSeparator />
275
+ <DropdownMenuItem onClick={handleExportHtml} className="cursor-pointer">
276
+ <IconCode className="w-4 h-4 mr-2" />
277
+ {t("editorExport.downloadHtml")}
278
+ </DropdownMenuItem>
279
+ <DropdownMenuItem onClick={onExportPdf} className="cursor-pointer">
280
+ <IconFileTypePdf className="w-4 h-4 mr-2" />
281
+ {t("editorExport.exportPdf")}
282
+ </DropdownMenuItem>
283
+ <DropdownMenuItem onClick={handleExportPptx} className="cursor-pointer">
284
+ <IconDownload className="w-4 h-4 mr-2" />
285
+ {t("editorExport.exportPptx")}
286
+ </DropdownMenuItem>
287
+ {onExportGoogleSlides && (
288
+ <>
289
+ <DropdownMenuItem
290
+ onClick={handleConnectGoogle}
291
+ className="cursor-pointer"
330
292
  >
293
+ <IconPlugConnected className="w-4 h-4 mr-2" />
294
+ {t("editorExport.connectGoogle")}
295
+ </DropdownMenuItem>
296
+ <DropdownMenuItem
297
+ onClick={handleExportGoogleSlides}
298
+ className="cursor-pointer"
299
+ >
300
+ <IconBrandGoogle className="w-4 h-4 mr-2" />
331
301
  {t("editorExport.openInGoogleSlides")}
332
- </Button>
333
- </DialogFooter>
334
- </DialogContent>
335
- </Dialog>
336
- </>
337
- );
338
- }
302
+ </DropdownMenuItem>
303
+ </>
304
+ )}
305
+ <DropdownMenuSeparator />
306
+ <DropdownMenuItem onClick={onDuplicate} className="cursor-pointer">
307
+ <IconCopy className="w-4 h-4 mr-2" />
308
+ {t("editorExport.duplicateDeck")}
309
+ </DropdownMenuItem>
310
+ </>
311
+ );
312
+
313
+ return (
314
+ <>
315
+ {inline ? (
316
+ menuContent
317
+ ) : (
318
+ <DropdownMenu>
319
+ <DropdownMenuTrigger asChild>
320
+ <button className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent text-xs cursor-pointer whitespace-nowrap">
321
+ <IconUpload className="w-3.5 h-3.5" />
322
+ <span className="hidden md:inline">
323
+ {t("editorExport.export")}
324
+ </span>
325
+ </button>
326
+ </DropdownMenuTrigger>
327
+ <DropdownMenuContent align="end" className="w-52">
328
+ {menuContent}
329
+ </DropdownMenuContent>
330
+ </DropdownMenu>
331
+ )}
332
+ <Dialog
333
+ open={googleSlidesImportOpen}
334
+ onOpenChange={setGoogleSlidesImportOpen}
335
+ >
336
+ <DialogContent>
337
+ <DialogHeader>
338
+ <DialogTitle>
339
+ {t("editorExport.googleSlidesDownloaded")}
340
+ </DialogTitle>
341
+ <DialogDescription>
342
+ {t("editorExport.googleSlidesImportHint")}
343
+ </DialogDescription>
344
+ </DialogHeader>
345
+ <DialogFooter>
346
+ <Button
347
+ type="button"
348
+ onClick={() => {
349
+ const target = googleSlidesImportTarget.current;
350
+ if (target && !target.closed) {
351
+ target.focus?.();
352
+ } else {
353
+ window.open(GOOGLE_SLIDES_IMPORT_URL, "_blank");
354
+ }
355
+ setGoogleSlidesImportOpen(false);
356
+ }}
357
+ >
358
+ {t("editorExport.openInGoogleSlides")}
359
+ </Button>
360
+ </DialogFooter>
361
+ </DialogContent>
362
+ </Dialog>
363
+ </>
364
+ );
365
+ },
366
+ );
@@ -306,11 +306,13 @@ export default function PromptPopover({
306
306
  if (!open) return null;
307
307
 
308
308
  const importEnabled = Boolean(onImport && importFromLabel);
309
- const importFromCopy = importFromLabel?.trim().toLowerCase().startsWith("or ")
310
- ? importFromLabel.trim()
311
- : importFromLabel
312
- ? `or ${importFromLabel.trim().toLowerCase()}`
313
- : "";
309
+ const normalizedImportFromLabel = importFromLabel
310
+ ?.trim()
311
+ .replace(/^or\s+/i, "")
312
+ .toLowerCase();
313
+ const importFromCopy = normalizedImportFromLabel
314
+ ? `Or ${normalizedImportFromLabel}`
315
+ : "";
314
316
  const importModeLabel =
315
317
  importMode === "google-slides"
316
318
  ? t("home.googleSlidesReferenceTitle")
@@ -193,7 +193,7 @@ export function SlideContextToolbar({
193
193
  return (
194
194
  <div
195
195
  className={cn(
196
- "slide-context-toolbar flex h-10 shrink-0 items-center gap-1 overflow-x-auto whitespace-nowrap border-b border-border/70 bg-muted/60 px-2 sm:px-3",
196
+ "slide-context-toolbar flex h-10 shrink-0 items-center gap-1 overflow-x-auto whitespace-nowrap bg-transparent px-2 sm:px-3",
197
197
  className,
198
198
  )}
199
199
  data-slide-context-toolbar="true"