@agent-native/core 0.149.1 → 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 (422) 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/dashboard-management/SKILL.md +2 -0
  9. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
  10. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
  11. package/corpus/templates/analytics/AGENTS.md +25 -32
  12. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +150 -46
  13. package/corpus/templates/analytics/app/global.css +1 -1
  14. package/corpus/templates/analytics/app/i18n-data.ts +37 -0
  15. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
  16. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -0
  17. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +2 -0
  18. package/corpus/templates/analytics/changelog/2026-08-10-dashboard-tables-can-be-copied-and-sorted-by-multiple-column.md +6 -0
  19. package/corpus/templates/analytics/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  20. package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  21. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
  22. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
  23. package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
  24. package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
  25. package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
  26. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
  27. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
  28. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
  29. package/corpus/templates/assets/AGENTS.md +6 -9
  30. package/corpus/templates/assets/app/global.css +1 -1
  31. package/corpus/templates/assets/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  32. package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  33. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
  34. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
  35. package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
  36. package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
  37. package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
  38. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
  39. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
  40. package/corpus/templates/brain/AGENTS.md +5 -12
  41. package/corpus/templates/brain/app/global.css +1 -1
  42. package/corpus/templates/brain/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  43. package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  44. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
  45. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
  46. package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
  47. package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
  48. package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
  49. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
  50. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
  51. package/corpus/templates/calendar/AGENTS.md +8 -9
  52. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  53. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  54. package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  55. package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  56. package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  57. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  58. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  59. package/corpus/templates/chat/AGENTS.md +32 -80
  60. package/corpus/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  61. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
  62. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
  63. package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
  64. package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
  65. package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
  66. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
  67. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
  68. package/corpus/templates/clips/AGENTS.md +25 -31
  69. package/corpus/templates/clips/changelog/2026-08-10-clips-desktop-sign-in-now-starts-with-magic-links-and-google.md +6 -0
  70. package/corpus/templates/clips/chrome-extension/src/overlay.css +1 -0
  71. package/corpus/templates/clips/desktop/src/app.tsx +274 -137
  72. package/corpus/templates/clips/desktop/src/styles.css +35 -0
  73. package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
  74. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
  75. package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
  76. package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
  77. package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
  78. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
  79. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
  80. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
  81. package/corpus/templates/content/AGENTS.md +5 -9
  82. package/corpus/templates/content/app/global.css +1 -0
  83. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
  84. package/corpus/templates/crm/AGENTS.md +7 -11
  85. package/corpus/templates/crm/app/global.css +1 -1
  86. package/corpus/templates/crm/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  87. package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  88. package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
  89. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
  90. package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
  91. package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
  92. package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
  93. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
  94. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
  95. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
  96. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
  97. package/corpus/templates/design/AGENTS.md +13 -21
  98. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
  99. package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
  100. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
  101. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
  102. package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
  103. package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
  104. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
  105. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
  106. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
  107. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
  108. package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
  109. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
  110. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  111. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
  112. package/corpus/templates/design/app/i18n-data.ts +1 -0
  113. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
  114. package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
  115. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
  116. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
  117. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
  118. package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
  119. package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
  120. package/corpus/templates/design/e2e/global-setup.ts +27 -32
  121. package/corpus/templates/design/playwright.config.ts +3 -5
  122. package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
  123. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
  124. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
  125. package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
  126. package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
  127. package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
  128. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
  129. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
  130. package/corpus/templates/dispatch/AGENTS.md +9 -16
  131. package/corpus/templates/dispatch/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  132. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
  133. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
  134. package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
  135. package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
  136. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
  137. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
  138. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
  139. package/corpus/templates/factory/AGENTS.md +10 -24
  140. package/corpus/templates/factory/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  141. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
  142. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
  143. package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
  144. package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
  145. package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
  146. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
  147. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
  148. package/corpus/templates/forms/AGENTS.md +11 -17
  149. package/corpus/templates/forms/app/global.css +1 -0
  150. package/corpus/templates/forms/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  151. package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  152. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
  153. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
  154. package/corpus/templates/macros/AGENTS.md +8 -8
  155. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
  156. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
  157. package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
  158. package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
  159. package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
  160. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
  161. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
  162. package/corpus/templates/mail/AGENTS.md +5 -6
  163. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
  164. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
  165. package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
  166. package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
  167. package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
  168. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
  169. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
  170. package/corpus/templates/plan/AGENTS.md +5 -14
  171. package/corpus/templates/plan/app/global.css +1 -0
  172. package/corpus/templates/plan/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  173. package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
  174. package/corpus/templates/plan/server/ui-plan-html.ts +4 -1
  175. package/corpus/templates/plan/vite.config.ts +5 -0
  176. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
  177. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
  178. package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
  179. package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
  180. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
  181. package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
  182. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
  183. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
  184. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
  185. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
  186. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
  187. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
  188. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
  189. package/corpus/templates/slides/AGENTS.md +33 -35
  190. package/corpus/templates/slides/actions/add-deck.ts +2 -0
  191. package/corpus/templates/slides/actions/add-slide.ts +15 -1
  192. package/corpus/templates/slides/actions/create-deck.ts +18 -6
  193. package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
  194. package/corpus/templates/slides/actions/get-deck.ts +83 -7
  195. package/corpus/templates/slides/actions/import-file.ts +2 -1
  196. package/corpus/templates/slides/actions/patch-deck.ts +165 -9
  197. package/corpus/templates/slides/actions/save-deck.ts +24 -1
  198. package/corpus/templates/slides/actions/update-slide.ts +1 -1
  199. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
  200. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
  201. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
  202. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
  203. package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
  204. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
  205. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  206. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +432 -668
  207. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +296 -259
  208. package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -1
  209. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +13 -1
  210. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +56 -174
  211. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +241 -116
  212. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
  213. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +42 -14
  214. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
  215. package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
  216. package/corpus/templates/slides/app/components/layout/AgentWorkIndicator.tsx +1 -1
  217. package/corpus/templates/slides/app/components/layout/Layout.tsx +34 -35
  218. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
  219. package/corpus/templates/slides/app/components/layout/layout-route-policy.ts +2 -5
  220. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +45 -40
  221. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +63 -16
  222. package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
  223. package/corpus/templates/slides/app/global.css +76 -1
  224. package/corpus/templates/slides/app/hooks/use-generating-slide-preview.ts +25 -3
  225. package/corpus/templates/slides/app/i18n/en-US.ts +2 -0
  226. package/corpus/templates/slides/app/lib/create-deck-generation.ts +52 -23
  227. package/corpus/templates/slides/app/lib/recent-references.ts +23 -1
  228. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +104 -3
  229. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -33
  230. package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
  231. package/corpus/templates/slides/app/pages/Index.tsx +315 -151
  232. package/corpus/templates/slides/app/root.tsx +43 -0
  233. package/corpus/templates/slides/changelog/2026-08-10-ai-editing-avatar-badge.md +6 -0
  234. package/corpus/templates/slides/changelog/2026-08-10-generated-decks-keep-a-clear-human-readable-title.md +6 -0
  235. package/corpus/templates/slides/changelog/2026-08-10-new-deck-creation-now-shows-progress-opens-the-editor-direct.md +6 -0
  236. package/corpus/templates/slides/changelog/2026-08-10-presentation-reveals-now-follow-valid-targets.md +6 -0
  237. package/corpus/templates/slides/changelog/2026-08-10-slides-editing-controls-are-consolidated-into-one-focused-me.md +6 -0
  238. package/corpus/templates/slides/changelog/2026-08-10-slides-now-verify-and-restyle-every-imported-slide-in-one-pa.md +6 -0
  239. package/corpus/templates/slides/changelog/2026-08-10-slides-only-suggests-a-google-connection-for-relevant-reques.md +6 -0
  240. package/corpus/templates/slides/changelog/2026-08-10-the-google-slides-import-option-is-now-labeled-slides.md +6 -0
  241. package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
  242. package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
  243. package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
  244. package/corpus/templates/slides/package.json +1 -0
  245. package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
  246. package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
  247. package/corpus/templates/slides/server/plugins/agent-chat.ts +8 -5
  248. package/corpus/templates/slides/shared/api.ts +47 -15
  249. package/corpus/templates/slides/shared/deck-title.ts +135 -0
  250. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
  251. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
  252. package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
  253. package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
  254. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
  255. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
  256. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
  257. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
  258. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
  259. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
  260. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
  261. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
  262. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
  263. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
  264. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
  265. package/corpus/templates/tasks/AGENTS.md +5 -20
  266. package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +4 -1
  267. package/dist/agent/engine/ai-sdk-engine.js +1 -1
  268. package/dist/agent/production-agent.d.ts +21 -1
  269. package/dist/agent/production-agent.js +505 -355
  270. package/dist/agent/run-manager.js +156 -14
  271. package/dist/agent/run-store.d.ts +11 -10
  272. package/dist/agent/run-store.js +17 -13
  273. package/dist/agent/tool-approval-store.d.ts +18 -0
  274. package/dist/agent/tool-approval-store.js +122 -0
  275. package/dist/agent/types.d.ts +1 -1
  276. package/dist/cli/code-agent-executor.js +11 -2
  277. package/dist/client/AgentPanel.js +31 -6
  278. package/dist/client/AssistantChat.d.ts +9 -4
  279. package/dist/client/AssistantChat.js +221 -149
  280. package/dist/client/active-run-state.d.ts +9 -1
  281. package/dist/client/active-run-state.js +34 -3
  282. package/dist/client/agent-chat/index.d.ts +1 -1
  283. package/dist/client/agent-chat-adapter.d.ts +8 -0
  284. package/dist/client/agent-chat-adapter.js +125 -28
  285. package/dist/client/agent-chat.d.ts +1 -1
  286. package/dist/client/chat/markdown-renderer.js +14 -2
  287. package/dist/client/chat/message-components.d.ts +13 -3
  288. package/dist/client/chat/message-components.js +57 -52
  289. package/dist/client/chat/run-recovery.d.ts +1 -0
  290. package/dist/client/chat/run-recovery.js +8 -0
  291. package/dist/client/chat/tool-call-display.d.ts +5 -5
  292. package/dist/client/chat/tool-call-display.js +9 -212
  293. package/dist/client/chat-first/apps-rail.js +3 -3
  294. package/dist/client/chat-first/browser-pane.js +4 -1
  295. package/dist/client/chat-first/chat-history.d.ts +3 -1
  296. package/dist/client/chat-first/chat-history.js +7 -4
  297. package/dist/client/chat-first/surface-tabs.d.ts +1 -1
  298. package/dist/client/chat-first/surface-tabs.js +52 -41
  299. package/dist/client/chat-first/types.d.ts +3 -0
  300. package/dist/client/chat-first.d.ts +10 -0
  301. package/dist/client/chat-first.js +37 -2
  302. package/dist/client/components/ui/message-scroller.js +4 -1
  303. package/dist/client/i18n.js +3 -1
  304. package/dist/client/resources/McpConnectionSuggestion.js +9 -1
  305. package/dist/client/sse-event-processor.d.ts +4 -2
  306. package/dist/client/sse-event-processor.js +46 -6
  307. package/dist/client/use-chat-models.js +156 -80
  308. package/dist/client/use-run-stuck-detection.d.ts +2 -0
  309. package/dist/client/use-run-stuck-detection.js +85 -9
  310. package/dist/collab/awareness.d.ts +2 -2
  311. package/dist/collab/routes.d.ts +1 -1
  312. package/dist/collab/struct-routes.d.ts +1 -1
  313. package/dist/integrations/adapters/slack.d.ts +0 -4
  314. package/dist/integrations/adapters/slack.js +6 -30
  315. package/dist/integrations/catalog.js +1 -1
  316. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  317. package/dist/integrations/pending-tasks-store.js +0 -21
  318. package/dist/integrations/slack-manifest.d.ts +2 -2
  319. package/dist/integrations/slack-manifest.js +0 -3
  320. package/dist/integrations/webhook-handler.js +1 -1
  321. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  322. package/dist/observability/routes.d.ts +3 -3
  323. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  324. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  325. package/dist/scripts/docs/source-search.js +2 -2
  326. package/dist/server/agent-chat/framework-prompts.js +7 -2
  327. package/dist/server/agent-chat/prompt-resources.js +2 -2
  328. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  329. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  330. package/dist/server/agent-chat-plugin.js +3 -3
  331. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  332. package/dist/server/agents-bundle.d.ts +16 -19
  333. package/dist/server/agents-bundle.js +19 -35
  334. package/dist/server/auth.js +262 -31
  335. package/dist/server/better-auth-instance.d.ts +1 -0
  336. package/dist/server/better-auth-instance.js +17 -2
  337. package/dist/server/onboarding-html.js +56 -9
  338. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  339. package/dist/server/prompts/framework-core-compact.js +12 -9
  340. package/dist/server/prompts/framework-core.d.ts +6 -1
  341. package/dist/server/prompts/framework-core.js +11 -9
  342. package/dist/server/prompts/index.d.ts +1 -1
  343. package/dist/server/prompts/index.js +1 -1
  344. package/dist/server/prompts/shared-rules.d.ts +15 -11
  345. package/dist/server/prompts/shared-rules.js +17 -13
  346. package/dist/server/realtime-token.d.ts +1 -1
  347. package/dist/server/transcribe-voice.d.ts +1 -1
  348. package/dist/shared/reasoning-effort.d.ts +8 -8
  349. package/dist/shared/reasoning-effort.js +10 -10
  350. package/dist/shared/streaming-text-smoothing.js +41 -11
  351. package/dist/styles/agent-native.css +19 -32
  352. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  353. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  354. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  355. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  356. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  357. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  358. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  359. package/dist/templates/chat/AGENTS.md +32 -80
  360. package/dist/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  361. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  362. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  363. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  364. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  365. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  366. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  367. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  368. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  369. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  370. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  371. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  372. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  373. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  374. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  375. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  376. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  377. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  378. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  379. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  380. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  381. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  382. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  383. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  384. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  385. package/dist/templates/workspace-core/AGENTS.md +7 -16
  386. package/docs/content/messaging.mdx +6 -7
  387. package/docs/content/template-chat.mdx +1 -1
  388. package/package.json +2 -2
  389. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  390. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  391. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  392. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  393. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  394. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  395. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  396. package/src/templates/chat/AGENTS.md +32 -80
  397. package/src/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  398. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  399. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  400. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  401. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  402. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  403. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  404. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  405. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  406. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  407. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  408. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  409. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  410. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  411. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  412. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  413. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  414. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  415. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  416. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  417. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  418. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  419. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  420. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  421. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  422. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -33,6 +33,10 @@ import {
33
33
  } from "react-router";
34
34
  import type { LinksFunction } from "react-router";
35
35
 
36
+ import {
37
+ getEditorCommands,
38
+ type EditorCommandGroup,
39
+ } from "@/components/editor/editor-command-model";
36
40
  import { Layout as AppLayout } from "@/components/layout/Layout";
37
41
  import { FirstDeckOnboardingFlow } from "@/components/onboarding/FirstDeckOnboardingFlow";
38
42
  import { AppToolkitProvider } from "@/components/ui/toolkit-provider";
@@ -202,6 +206,17 @@ function AppContent() {
202
206
  const navigate = useNavigate();
203
207
  useCommandMenuShortcut(useCallback(() => setCmdkOpen(true), []));
204
208
  const location = useLocation();
209
+ const editorCommands = getEditorCommands();
210
+ const editorCommandGroups: Array<{
211
+ id: EditorCommandGroup;
212
+ heading: string;
213
+ }> = [
214
+ { id: "media", heading: t("editorToolbar.media") },
215
+ { id: "slideTools", heading: t("editorToolbar.slideTools") },
216
+ { id: "comments", heading: t("editorToolbar.comments") },
217
+ { id: "deck", heading: t("editorExport.exportAndDuplicate") },
218
+ { id: "other", heading: t("editorToolbar.more") },
219
+ ];
205
220
 
206
221
  const isBare =
207
222
  BARE_ROUTES.has(location.pathname) ||
@@ -236,6 +251,34 @@ function AppContent() {
236
251
  {t("settings.openAgentSettings")}
237
252
  </CommandMenu.Item>
238
253
  </CommandMenu.Group>
254
+ {editorCommandGroups.map((group) => {
255
+ const commands = editorCommands.filter(
256
+ (command) => command.group === group.id,
257
+ );
258
+ if (commands.length === 0) return null;
259
+ return (
260
+ <CommandMenu.Group key={group.id} heading={group.heading}>
261
+ {commands.map((command) => {
262
+ const Icon = command.icon;
263
+ return (
264
+ <CommandMenu.Item
265
+ key={command.id}
266
+ onSelect={command.run}
267
+ keywords={command.keywords}
268
+ className={
269
+ command.active
270
+ ? "bg-accent text-accent-foreground"
271
+ : undefined
272
+ }
273
+ >
274
+ {Icon ? <Icon size={16} /> : null}
275
+ {command.label}
276
+ </CommandMenu.Item>
277
+ );
278
+ })}
279
+ </CommandMenu.Group>
280
+ );
281
+ })}
239
282
  <CommandMenu.Group heading={t("root.commandAppearance")}>
240
283
  <CommandMenu.Item
241
284
  onSelect={() => setTheme(isDark ? "light" : "dark")}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ AI editing status now uses a cleaner combined avatar badge.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ Generated decks keep a clear, human-readable title
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ New deck creation now shows progress, opens the editor directly, and remembers your reference choices
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ Presentation reveals now follow validated ordered targets, queue rapid navigation, and settle cleanly after transitions.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ Slides editing controls are consolidated into one focused menu
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ Slides now verify and restyle every imported slide in one pass
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ Slides only suggests a Google connection for relevant requests, and the suggestion can be dismissed.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: changed
3
+ date: 2026-08-10
4
+ ---
5
+
6
+ The Google Slides import option is now labeled Slides.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-11
4
+ ---
5
+
6
+ Faster Slides chat deck reads
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-11
4
+ ---
5
+
6
+ Slides chat can read one slide without loading the full deck
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-11
4
+ ---
5
+
6
+ Slides clearly indicate when an AI agent is editing alongside you.
@@ -48,6 +48,7 @@
48
48
  "isbot": "^5",
49
49
  "jspdf": "4.2.1",
50
50
  "jszip": "3.10.1",
51
+ "linkedom": "0.18.13",
51
52
  "mammoth": "1.12.0",
52
53
  "mermaid": "^11.14.0",
53
54
  "modern-screenshot": "^4.7.0",
@@ -119,7 +119,7 @@ export async function prepareSlidesChatAttachments(args: {
119
119
  "",
120
120
  "File handling rules:",
121
121
  "- If the request refers to the current or visible deck, call `view-screen` first to confirm the active deckId, then pass that deckId to import or slide-edit actions.",
122
- '- PPTX files: when the user wants the visible deck improved, call `import-pptx --filePath "<path>" --deckId <deckId>` first, then edit those imported slide IDs in place with update-slide. Do not rebuild the source deck with add-slide.',
122
+ '- PPTX files: when the user wants the visible deck improved, call `import-pptx --filePath "<path>" --deckId <deckId>` first, then use one patch-deck call with requireAllSourceSlides=true and one content patch per imported slide for a deck-wide restyle. Use update-slide only for a targeted one-slide edit. Do not rebuild the source deck with add-slide.',
123
123
  '- PDF and DOCX files: call `import-file --filePath "<path>" --format auto --deckId <deckId>` and use the returned extracted text as source material before creating editable slides. For a visual PDF that the user wants preserved, beautified, or restyled from its original layout, pass `--importIntoDeck true` so each page is imported source-faithfully first; keep the full-page image and style around it, with source text persisted in slide notes for inspection.',
124
124
  '- Figma `.fig` files: call `import-file --filePath "<path>" --format fig` to start Builder design-system indexing. Do not create a local design system directly from the upload.',
125
125
  "- For deck-generation requests, start mutating promptly: create or update the first slide as soon as source material is extracted, then continue slide-by-slide with add-slide/update-slide.",
@@ -0,0 +1,163 @@
1
+ import { parseHTML } from "linkedom/worker";
2
+
3
+ import {
4
+ animationElementKey,
5
+ getElementPath,
6
+ getElementPreview,
7
+ resolveSlideAnimationElement,
8
+ resolveSlideAnimationTargetsWithDiagnostics,
9
+ type AnimationTarget,
10
+ } from "../../app/lib/slide-animation-elements.js";
11
+
12
+ interface SlideAnimation extends AnimationTarget {
13
+ id?: string;
14
+ }
15
+
16
+ export interface SlideAnimationTargetSummary {
17
+ targetPreview: string | null;
18
+ resolvedPath: string | null;
19
+ targetValid: boolean;
20
+ targetIssue:
21
+ | "missing-slide-root"
22
+ | "target-not-found"
23
+ | "duplicate-target"
24
+ | null;
25
+ }
26
+
27
+ function formatTarget(target: SlideAnimation): string {
28
+ const id = target.id ? ` (${target.id})` : "";
29
+ const path = Array.isArray(target.elementPath)
30
+ ? ` path [${target.elementPath.join(", ")}]`
31
+ : "";
32
+ return `step ${target.elementIndex + 1}${id}${path}`;
33
+ }
34
+
35
+ export function summarizeSlideAnimationTargets(
36
+ content: string,
37
+ animations: readonly SlideAnimation[],
38
+ ): SlideAnimationTargetSummary[] {
39
+ if (animations.length === 0) return [];
40
+
41
+ const { document } = parseHTML(
42
+ `<!doctype html><html><head></head><body>${content}</body></html>`,
43
+ );
44
+ const root = document.querySelector(".fmd-slide");
45
+ if (!root) {
46
+ return animations.map(() => ({
47
+ targetPreview: null,
48
+ resolvedPath: null,
49
+ targetValid: false,
50
+ targetIssue: "missing-slide-root",
51
+ }));
52
+ }
53
+
54
+ const seen = new Set<string>();
55
+ return animations.map((target) => {
56
+ const element = resolveSlideAnimationElement(root, target);
57
+ if (!element) {
58
+ return {
59
+ targetPreview: null,
60
+ resolvedPath: null,
61
+ targetValid: false,
62
+ targetIssue: "target-not-found",
63
+ };
64
+ }
65
+
66
+ const path = getElementPath(root, element);
67
+ if (!path) {
68
+ return {
69
+ targetPreview: getElementPreview(
70
+ element,
71
+ `Element ${target.elementIndex + 1}`,
72
+ ),
73
+ resolvedPath: null,
74
+ targetValid: false,
75
+ targetIssue: "target-not-found",
76
+ };
77
+ }
78
+
79
+ const key = animationElementKey(path);
80
+ if (seen.has(key)) {
81
+ return {
82
+ targetPreview: getElementPreview(
83
+ element,
84
+ `Element ${target.elementIndex + 1}`,
85
+ ),
86
+ resolvedPath: key,
87
+ targetValid: false,
88
+ targetIssue: "duplicate-target",
89
+ };
90
+ }
91
+
92
+ seen.add(key);
93
+ return {
94
+ targetPreview: getElementPreview(
95
+ element,
96
+ `Element ${target.elementIndex + 1}`,
97
+ ),
98
+ resolvedPath: key,
99
+ targetValid: true,
100
+ targetIssue: null,
101
+ };
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Validate animation identity against the exact HTML that is about to be
107
+ * persisted. Playback cannot repair a stale path without risking a different
108
+ * element being revealed, so reject the mutation before the deck is written.
109
+ */
110
+ export function assertSlideAnimationsResolve({
111
+ slideId,
112
+ content,
113
+ animations,
114
+ requireElementPaths = false,
115
+ }: {
116
+ slideId: string;
117
+ content: string;
118
+ animations: readonly SlideAnimation[];
119
+ requireElementPaths?: boolean;
120
+ }): void {
121
+ if (animations.length === 0) return;
122
+
123
+ if (requireElementPaths) {
124
+ const legacyIndex = animations.findIndex(
125
+ (animation) => !Array.isArray(animation.elementPath),
126
+ );
127
+ if (legacyIndex !== -1) {
128
+ const target = animations[legacyIndex];
129
+ throw new Error(
130
+ `Cannot save animations for slide ${slideId}: ${target ? formatTarget(target) : `step ${legacyIndex + 1}`} is missing elementPath. Agent-created or content-revised animations must use a path from the final HTML; elementIndex-only targets are legacy-only.`,
131
+ );
132
+ }
133
+ }
134
+
135
+ const { document } = parseHTML(
136
+ `<!doctype html><html><head></head><body>${content}</body></html>`,
137
+ );
138
+ const root = document.querySelector(".fmd-slide");
139
+ if (!root) {
140
+ throw new Error(
141
+ `Cannot save animations for slide ${slideId}: the final HTML has no .fmd-slide wrapper. Re-read the slide content, then send the content and complete animation list together.`,
142
+ );
143
+ }
144
+
145
+ const resolution = resolveSlideAnimationTargetsWithDiagnostics(
146
+ root,
147
+ animations,
148
+ );
149
+ const issue = resolution.issue;
150
+ if (!issue) return;
151
+
152
+ const target = animations[issue.animationIndex];
153
+ const targetDescription = target ? formatTarget(target) : "unknown step";
154
+ if (issue.code === "duplicate-target") {
155
+ throw new Error(
156
+ `Cannot save animations for slide ${slideId}: ${targetDescription} duplicates target path ${issue.key ?? "unknown"}${issue.preview ? ` (${issue.preview})` : ""}. Each reveal step must target a different element; re-read the final HTML and send the complete ordered list.`,
157
+ );
158
+ }
159
+
160
+ throw new Error(
161
+ `Cannot save animations for slide ${slideId}: ${targetDescription} does not resolve in the final HTML. Do not fall back to elementIndex; re-read the final HTML and send the content and complete ordered animation list together.`,
162
+ );
163
+ }
@@ -52,23 +52,26 @@ export default createAgentChatPlugin({
52
52
  prepareRequest: prepareSlidesChatAttachments,
53
53
  systemPrompt: `You are an AI deck assistant. You create, edit, import, export, style, share, and navigate decks through actions and shared application state. For a newly created presentation, use create-deck with slides: [] only when you are creating the deck yourself, then add-slide sequentially with full rendered HTML. The legacy generate-slides-ai action returns Markdown drafts and is not part of the persisted presentation workflow.
54
54
 
55
- When the user asks to improve, beautify, restyle, or make an uploaded/existing deck on-brand, treat it as an in-place source-preserving edit unless the user explicitly asks to rewrite the story or change slide count. First call view-screen when the active deck is unclear, then get-deck. If get-deck.sourceImport exists, preserve its slide count, order, IDs, factual copy, notes, images, charts, tables, diagrams, freeform objects, and source aspect ratio. Use update-slide on existing slide IDs. Do not use add-slide, delete, reorder, or replace source imagery with generic cards for this workflow. Verify the same slide IDs and count with get-deck after editing. If sourceImport.fidelity is partial or imagesSkipped is nonzero, stop and report the exact fidelity warning instead of claiming a reliable improvement.
55
+ When the user asks to improve, beautify, restyle, or make an uploaded/existing deck on-brand, treat it as an in-place source-preserving edit unless the user explicitly asks to rewrite the story or change slide count. First call view-screen when the active deck is unclear, then get-deck with compact=true for deck orientation. If you need slide markup, call get-deck with compact=false explicitly and only when the edit requires the full HTML. If get-deck.sourceImport exists, preserve its slide count, order, IDs, factual copy, notes, images, charts, tables, diagrams, freeform objects, and source aspect ratio. For a deck-wide restyle, use one patch-deck call with requireAllSourceSlides=true and one patch-slide operation with fields.content for every source slide ID; the action rejects partial coverage. Do not split a full-deck restyle into arbitrary batches or use one-by-one update-slide calls - reserve update-slide for targeted one-slide edits. After the patch succeeds, verify with get-deck using compact=true so the verification does not retransmit every slide's HTML. Do not claim a partial or initial pass. Do not use add-slide, delete, reorder, or replace source imagery with generic cards for this workflow. If sourceImport.fidelity is partial or imagesSkipped is nonzero, stop and report the exact fidelity warning instead of claiming a reliable improvement.
56
+ For a targeted one-slide edit, prefer get-deck with the stable slideId from view-screen or compact get-deck. It returns only that slide's full HTML by default, so do not load the full deck when one slide is enough. Pass compact=true when you only need a lightweight check of that slide.
56
57
 
57
- For source-faithful PDF slides, keep the original full-page image and style around it with restrained design-system chrome such as a frame, edge treatment, caption, or safe overlay that does not obscure source content; never OCR-reconstruct the page from extracted text. For PPTX slides, preserve the imported positioned HTML and every uploaded source image. The update-slide action enforces these preservation rules by default; pass preserveSource=false only when the user explicitly requests a rewrite of that slide.
58
+ When the active Slides editor is already showing the deck you just changed, do not include an "Open the updated deck" or similar link in the final response. The deck is already open and the action updated it in place; say that plainly instead. Only provide an open-deck link when the user is elsewhere, the active deck is different, or the user explicitly asks for a link.
59
+
60
+ For source-faithful PDF slides, keep the original full-page image and style around it with restrained design-system chrome such as a frame, edge treatment, caption, or safe overlay that does not obscure source content; never OCR-reconstruct the page from extracted text. For PPTX slides, preserve the imported positioned HTML and every uploaded source image. The patch-deck and update-slide actions enforce these preservation rules by default; pass preserveSource=false only when the user explicitly requests a rewrite of that slide.
58
61
 
59
62
  If the deck has designSystemId, call get-design-system before writing and follow its exact agentContext tokens, assets, and custom instructions. If the user asks for on-brand styling and no design system is linked, call get-workspace-defaults, link its usable design system with patch-deck, then call get-design-system. Do not improvise a generic Builder-like palette when configured Builder.io design-system context is available.
60
63
 
61
- Layout-fit workflow is strict. When the user asks to fix overflow, first call view-screen and inspect the deck-wide layout-fit section. If it says measurements are unknown, do not claim the deck fits. Call get-layout-overflows when you need the structured per-slide results. Read the affected slides with get-deck, then make one bounded structural repair pass with one patch-slide operation per affected slide in a single patch-deck call. Wait for the action result and verify the persisted HTML with get-deck before saying it is fixed. If a fresh measurement still reports overflow, make at most one focused follow-up repair based on that measurement; never loop, repeatedly re-measure, or claim success after a chat response alone.
64
+ Layout-fit workflow is strict. When the user asks to fix overflow, first call view-screen and inspect the deck-wide layout-fit section. If it says measurements are unknown, do not claim the deck fits. Call get-layout-overflows when you need the structured per-slide results. Read each affected slide with get-deck slideId=<id> (full HTML is returned for a targeted read), then make one bounded structural repair pass with one patch-slide operation per affected slide in a single patch-deck call. Wait for the action result and verify the persisted HTML with get-deck slideId=<id> compact=true before saying it is fixed. If a fresh measurement still reports overflow, make at most one focused follow-up repair based on that measurement; never loop, repeatedly re-measure, or claim success after a chat response alone.
62
65
 
63
66
  Fit means the main content fits the native content area. A small outer-wrapper spill is tolerated by the measurement, but cards, text, columns, and other visible content must fit. Never use zoom, transform: scale(), overflow: hidden/scroll, clipping, or a smaller-than-16px body font to hide overflow. Preserve manually positioned freeform objects and their data-slide-object-id values; repair normal-flow structure, copy, gaps, or slide padding instead. A successful action result must include the affected slide IDs; if it does not, report that no verified write occurred.
64
67
 
65
- Image workflow is strict. For direct insertion, call generate-image-api with insertIntoSlide: true plus deckId and slideId. Claim that an image was added only when that action returns inserted: true; a preview URL or completed generation alone is not a slide edit. For preview-only variations, call generate-image-api without insertIntoSlide, then use update-slide to place the chosen URL and re-read the target with get-deck to confirm its persisted HTML contains that image source before claiming success.
68
+ Image workflow is strict. For direct insertion, call generate-image-api with insertIntoSlide: true plus deckId and slideId. Claim that an image was added only when that action returns inserted: true; a preview URL or completed generation alone is not a slide edit. For preview-only variations, call generate-image-api without insertIntoSlide, then use update-slide to place the chosen URL and re-read the target with get-deck slideId=<id> compact=false to confirm its persisted HTML contains that image source before claiming success.
66
69
 
67
70
  Provider-specific Slides actions are shortcuts, not limits. If a first-class action cannot express the exact Google Drive endpoint, file metadata field, export format, query, request body, pagination mode, payload shape, or API version needed, call provider-api-catalog and provider-api-docs as needed, then call provider-api-request against the real provider API. Use the raw provider API escape hatch instead of weakening the answer or claiming Slides cannot do something the underlying Google Drive API can do.
68
71
 
69
72
  Slides' Google Drive provider API uses the user's connected Google Docs OAuth account. Picker imports keep the per-file drive.file path, while pasted Google Slides links use Drive export access and may ask the user to reconnect Google. For large Drive file lists or metadata sweeps, pass stageAs and pagination options to provider-api-request, then use query-staged-dataset to count, filter, group, or project the staged rows.
70
73
 
71
- When a Google Drive or Google Slides request needs authentication, tell the user to use the Connect Google button shown in Slides. Do not expose internal routes, API endpoints, OAuth setup instructions, client IDs, or keys in the response, and do not ask the user to configure an API manually.`,
74
+ When a Google Drive or Google Slides request needs authentication, tell the user to use the Connect Google button in the Google Slides import step. Do not expose internal routes, API endpoints, OAuth setup instructions, client IDs, or keys in the response, and do not ask the user to configure an API manually.`,
72
75
  mentionProviders: async () => {
73
76
  const { getDb } = await import("../db/index.js");
74
77
  const { decks, deckShares } = await import("../db/schema.js");
@@ -95,6 +95,18 @@ export type SharedSlideTransition =
95
95
 
96
96
  export type SharedAnimationType = "appear" | "fade" | "slide-up" | "zoom";
97
97
 
98
+ export type SharedAnimationIssueCode =
99
+ | "invalid-shape"
100
+ | "invalid-element-path"
101
+ | "missing-target"
102
+ | "unsupported-type";
103
+
104
+ export interface SharedSlideAnimationIssue {
105
+ index: number;
106
+ id: string | null;
107
+ code: SharedAnimationIssueCode;
108
+ }
109
+
98
110
  export interface SharedSlideAnimation {
99
111
  id: string;
100
112
  elementIndex: number;
@@ -110,6 +122,7 @@ export interface SharedDeckSlide {
110
122
  background?: string;
111
123
  transition?: SharedSlideTransition;
112
124
  animations?: SharedSlideAnimation[];
125
+ animationIssues?: SharedSlideAnimationIssue[];
113
126
  splitByParagraph?: boolean;
114
127
  }
115
128
 
@@ -137,7 +150,7 @@ function normalizeString(value: unknown, fallback: string): string {
137
150
  }
138
151
 
139
152
  function normalizeElementPath(value: unknown): number[] | undefined {
140
- if (!Array.isArray(value)) return undefined;
153
+ if (!Array.isArray(value) || value.length === 0) return undefined;
141
154
  const path = value.filter(
142
155
  (part): part is number =>
143
156
  typeof part === "number" &&
@@ -151,10 +164,18 @@ function normalizeElementPath(value: unknown): number[] | undefined {
151
164
  function normalizeSlideAnimation(
152
165
  value: unknown,
153
166
  index: number,
154
- ): SharedSlideAnimation | null {
155
- if (!isRecord(value)) return null;
167
+ ): { animation: SharedSlideAnimation } | { issue: SharedSlideAnimationIssue } {
168
+ const id = isRecord(value) && typeof value.id === "string" ? value.id : null;
169
+ const issue = (code: SharedAnimationIssueCode) => ({
170
+ issue: { index, id, code },
171
+ });
172
+
173
+ if (!isRecord(value)) return issue("invalid-shape");
156
174
 
157
175
  const elementPath = normalizeElementPath(value.elementPath);
176
+ if (value.elementPath !== undefined && !elementPath) {
177
+ return issue("invalid-element-path");
178
+ }
158
179
  const rawElementIndex = value.elementIndex;
159
180
  const hasElementIndex =
160
181
  typeof rawElementIndex === "number" &&
@@ -162,12 +183,13 @@ function normalizeSlideAnimation(
162
183
  Number.isFinite(rawElementIndex) &&
163
184
  rawElementIndex >= 0;
164
185
 
165
- if (!hasElementIndex && !elementPath) return null;
186
+ if (!hasElementIndex && !elementPath) return issue("missing-target");
166
187
 
167
188
  const rawType = value.type;
168
- const type = SHARED_ANIMATION_TYPES.has(rawType as SharedAnimationType)
169
- ? (rawType as SharedAnimationType)
170
- : "slide-up";
189
+ if (!SHARED_ANIMATION_TYPES.has(rawType as SharedAnimationType)) {
190
+ return issue("unsupported-type");
191
+ }
192
+ const type = rawType as SharedAnimationType;
171
193
 
172
194
  // When an explicit `elementIndex` is present, trust it. Otherwise derive
173
195
  // from the last segment of `elementPath` - keeps the index correlated
@@ -182,10 +204,12 @@ function normalizeSlideAnimation(
182
204
  : (elementPath![elementPath!.length - 1] ?? 0);
183
205
 
184
206
  return {
185
- id: normalizeString(value.id, `animation-${index + 1}`),
186
- elementIndex: resolvedElementIndex,
187
- ...(elementPath ? { elementPath } : {}),
188
- type,
207
+ animation: {
208
+ id: normalizeString(value.id, `animation-${index + 1}`),
209
+ elementIndex: resolvedElementIndex,
210
+ ...(elementPath ? { elementPath } : {}),
211
+ type,
212
+ },
189
213
  };
190
214
  }
191
215
 
@@ -214,14 +238,22 @@ export function toSharedDeckSlide(
214
238
  }
215
239
 
216
240
  if (Array.isArray(slide.animations)) {
217
- const animations = slide.animations
218
- .map((animation, animationIndex) =>
241
+ const normalizedAnimations = slide.animations.map(
242
+ (animation, animationIndex) =>
219
243
  normalizeSlideAnimation(animation, animationIndex),
220
- )
221
- .filter((animation): animation is SharedSlideAnimation => !!animation);
244
+ );
245
+ const animations = normalizedAnimations.flatMap((result) =>
246
+ "animation" in result ? [result.animation] : [],
247
+ );
248
+ const animationIssues = normalizedAnimations.flatMap((result) =>
249
+ "issue" in result ? [result.issue] : [],
250
+ );
222
251
  if (animations.length > 0) {
223
252
  shared.animations = animations;
224
253
  }
254
+ if (animationIssues.length > 0) {
255
+ shared.animationIssues = animationIssues;
256
+ }
225
257
  }
226
258
 
227
259
  return shared;
@@ -0,0 +1,135 @@
1
+ const GENERATED_TITLE_PLACEHOLDERS = new Set([
2
+ "deck",
3
+ "date",
4
+ "image slide title",
5
+ "presentation title",
6
+ "section",
7
+ "section title",
8
+ "slide title",
9
+ "untitled",
10
+ "untitled deck",
11
+ "your name",
12
+ ]);
13
+
14
+ /**
15
+ * Generated deck ids should never become user-facing titles. Keep this
16
+ * deliberately narrow so normal titles with spaces and punctuation remain
17
+ * valid, while catching opaque mixed-case tokens such as H3sVsnns-TEVUOpz9w.
18
+ */
19
+ const OPAQUE_DECK_TITLE_PATTERN =
20
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z0-9_-]{12,64}$/;
21
+
22
+ export const DEFAULT_DECK_TITLE = "Untitled Deck";
23
+
24
+ export function isOpaqueDeckTitle(value: unknown): value is string {
25
+ return (
26
+ typeof value === "string" && OPAQUE_DECK_TITLE_PATTERN.test(value.trim())
27
+ );
28
+ }
29
+
30
+ export function isGeneratedDeckTitle(value: unknown): value is string {
31
+ if (typeof value !== "string") return false;
32
+ const title = value.trim();
33
+ return (
34
+ GENERATED_TITLE_PLACEHOLDERS.has(title.toLowerCase()) ||
35
+ isOpaqueDeckTitle(title)
36
+ );
37
+ }
38
+
39
+ function decodeHtmlEntities(value: string): string {
40
+ const decodeCodePoint = (raw: string, radix: number): string => {
41
+ const codePoint = Number.parseInt(raw, radix);
42
+ return Number.isNaN(codePoint) || codePoint > 0x10ffff
43
+ ? ""
44
+ : String.fromCodePoint(codePoint);
45
+ };
46
+
47
+ return value
48
+ .replace(/&nbsp;/gi, " ")
49
+ .replace(/&amp;/gi, "&")
50
+ .replace(/&lt;/gi, "<")
51
+ .replace(/&gt;/gi, ">")
52
+ .replace(/&quot;/gi, '"')
53
+ .replace(/(?:&#39;|&apos;)/gi, "'")
54
+ .replace(/&#x([0-9a-f]+);?/gi, (_, hex: string) => decodeCodePoint(hex, 16))
55
+ .replace(/&#(\d+);?/g, (_, digits: string) => decodeCodePoint(digits, 10));
56
+ }
57
+
58
+ function plainText(value: string): string {
59
+ return decodeHtmlEntities(
60
+ value.replace(/<br\s*\/?>/gi, " ").replace(/<[^>]+>/g, " "),
61
+ )
62
+ .replace(/\s+/g, " ")
63
+ .trim();
64
+ }
65
+
66
+ function usableCandidate(value: string): string | null {
67
+ const candidate = plainText(value).replace(/^[•●▪‣\-\s]+/, "");
68
+ if (!candidate || candidate.length > 140) return null;
69
+ if (GENERATED_TITLE_PLACEHOLDERS.has(candidate.toLowerCase())) return null;
70
+ return candidate;
71
+ }
72
+
73
+ /**
74
+ * Recover a deck title from the largest title-like text in its first slide.
75
+ * This is intentionally HTML-string based because the action runs on the
76
+ * server without a browser DOM.
77
+ */
78
+ export function deriveDeckTitleFromSlideContent(
79
+ content: unknown,
80
+ ): string | null {
81
+ if (typeof content !== "string" || !content.trim()) return null;
82
+
83
+ const candidates: Array<{ score: number; text: string }> = [];
84
+ const headingPattern = /<(h[1-6])\b[^>]*>([\s\S]*?)<\/\1>/gi;
85
+ for (const match of content.matchAll(headingPattern)) {
86
+ const text = usableCandidate(match[2] ?? "");
87
+ if (text) {
88
+ const level = Number.parseInt(match[1].slice(1), 10);
89
+ candidates.push({ score: 1000 - level * 10, text });
90
+ }
91
+ }
92
+
93
+ const styledTextPattern =
94
+ /<([a-z][\w:-]*)\b[^>]*\bstyle\s*=\s*(["'])([\s\S]*?)\2[^>]*>([\s\S]*?)<\/\1>/gi;
95
+ for (const match of content.matchAll(styledTextPattern)) {
96
+ const fontSize = Number.parseFloat(
97
+ match[3]?.match(/(?:^|;)\s*font-size\s*:\s*([\d.]+)px/i)?.[1] ?? "0",
98
+ );
99
+ if (fontSize < 28) continue;
100
+ const text = usableCandidate(match[4] ?? "");
101
+ if (text) candidates.push({ score: fontSize, text });
102
+ }
103
+
104
+ return candidates.sort((a, b) => b.score - a.score)[0]?.text ?? null;
105
+ }
106
+
107
+ /**
108
+ * Return a human-readable replacement only when the requested title is a
109
+ * generated placeholder or opaque id. A meaningful existing title wins when
110
+ * a stale full-payload save tries to replace it with a generated value.
111
+ */
112
+ export function repairGeneratedDeckTitle(
113
+ requestedTitle: unknown,
114
+ firstSlideContent: unknown,
115
+ existingTitle?: unknown,
116
+ ): string | null {
117
+ if (!isGeneratedDeckTitle(requestedTitle)) return null;
118
+
119
+ return (
120
+ deriveDeckTitleFromSlideContent(firstSlideContent) ??
121
+ (typeof existingTitle === "string" &&
122
+ existingTitle.trim() &&
123
+ !isGeneratedDeckTitle(existingTitle)
124
+ ? existingTitle
125
+ : null)
126
+ );
127
+ }
128
+
129
+ export function assertHumanReadableDeckTitle(title: string): void {
130
+ if (isOpaqueDeckTitle(title)) {
131
+ throw new Error(
132
+ "Deck title must be a concise, human-readable title; generated ids are not valid titles.",
133
+ );
134
+ }
135
+ }