@agent-native/core 0.149.2 → 0.149.4

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 (347) 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/routes.d.ts +1 -1
  243. package/dist/deploy/build.d.ts +4 -0
  244. package/dist/deploy/build.js +5 -0
  245. package/dist/deploy/workspace-deploy.js +5 -0
  246. package/dist/integrations/adapters/slack.d.ts +0 -4
  247. package/dist/integrations/adapters/slack.js +6 -30
  248. package/dist/integrations/catalog.js +1 -1
  249. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  250. package/dist/integrations/pending-tasks-store.js +0 -21
  251. package/dist/integrations/slack-manifest.d.ts +2 -2
  252. package/dist/integrations/slack-manifest.js +0 -3
  253. package/dist/notifications/routes.d.ts +3 -3
  254. package/dist/observability/routes.d.ts +3 -3
  255. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  256. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  257. package/dist/resources/handlers.d.ts +1 -1
  258. package/dist/scripts/docs/source-search.js +2 -2
  259. package/dist/secrets/routes.d.ts +9 -9
  260. package/dist/server/agent-chat/framework-prompts.js +7 -2
  261. package/dist/server/agent-chat/prompt-resources.js +2 -2
  262. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  263. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  264. package/dist/server/agent-chat-plugin.js +3 -3
  265. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  266. package/dist/server/agents-bundle.d.ts +16 -19
  267. package/dist/server/agents-bundle.js +19 -35
  268. package/dist/server/better-auth-instance.d.ts +1 -0
  269. package/dist/server/better-auth-instance.js +17 -2
  270. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  271. package/dist/server/prompts/framework-core-compact.js +12 -9
  272. package/dist/server/prompts/framework-core.d.ts +6 -1
  273. package/dist/server/prompts/framework-core.js +11 -9
  274. package/dist/server/prompts/index.d.ts +1 -1
  275. package/dist/server/prompts/index.js +1 -1
  276. package/dist/server/prompts/shared-rules.d.ts +15 -11
  277. package/dist/server/prompts/shared-rules.js +17 -13
  278. package/dist/server/realtime-token.d.ts +1 -1
  279. package/dist/server/transcribe-voice.d.ts +1 -1
  280. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  281. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  282. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  283. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  284. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  285. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  286. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  287. package/dist/templates/chat/AGENTS.md +32 -80
  288. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  289. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  290. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  291. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  292. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  293. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  294. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  295. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  296. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  297. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  298. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  299. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  300. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  301. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  302. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  303. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  304. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  305. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  306. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  307. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  308. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  309. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  310. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  311. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  312. package/dist/templates/workspace-core/AGENTS.md +7 -16
  313. package/docs/content/messaging.mdx +6 -7
  314. package/package.json +1 -1
  315. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  316. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  317. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  318. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  319. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  320. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  321. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  322. package/src/templates/chat/AGENTS.md +32 -80
  323. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  324. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  325. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  326. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  327. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  328. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  329. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  330. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  331. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  332. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  333. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  334. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  335. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  336. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  337. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  338. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  339. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  340. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  341. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  342. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  343. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  344. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  345. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  346. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  347. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -187,6 +187,8 @@ export default function DeckEditor() {
187
187
  );
188
188
  const [contextToolbarSlot, setContextToolbarSlot] =
189
189
  useState<HTMLDivElement | null>(null);
190
+ const [wideContextToolbarSlot, setWideContextToolbarSlot] =
191
+ useState<HTMLDivElement | null>(null);
190
192
  const [retryingMissingDeck, setRetryingMissingDeck] = useState(false);
191
193
  const [checkedDeckAccessKey, setCheckedDeckAccessKey] = useState<
192
194
  string | null
@@ -1013,7 +1015,7 @@ export default function DeckEditor() {
1013
1015
 
1014
1016
  return (
1015
1017
  <div
1016
- className="flex h-full min-h-0 flex-1 flex-col overflow-hidden bg-background"
1018
+ className="deck-editor-shell flex h-full min-h-0 flex-1 flex-col overflow-hidden rounded-l-lg bg-background"
1017
1019
  onDragOver={editorDragOver}
1018
1020
  onDrop={editorDrop}
1019
1021
  >
@@ -1035,6 +1037,7 @@ export default function DeckEditor() {
1035
1037
  onShowHistory={() => setHistoryOpen(!historyOpen)}
1036
1038
  historyButtonRef={historyButtonRef}
1037
1039
  currentSlide={currentSlide}
1040
+ onWideContextToolbarSlotChange={setWideContextToolbarSlot}
1038
1041
  activeUsers={slideActiveUsers.filter((u) => u.email !== session?.email)}
1039
1042
  agentPresent={agentPresent}
1040
1043
  agentActive={agentActive}
@@ -1119,9 +1122,13 @@ export default function DeckEditor() {
1119
1122
 
1120
1123
  {/* Full-width host for the slide's contextual style toolbar: it spans the
1121
1124
  * slide rail as well as the canvas, matching the deck toolbar above it. */}
1122
- <div ref={setContextToolbarSlot} className="shrink-0" />
1125
+ <div
1126
+ ref={setContextToolbarSlot}
1127
+ data-context-toolbar-host="narrow"
1128
+ className="deck-editor-context-toolbar-host deck-editor-context-toolbar-host--narrow shrink-0"
1129
+ />
1123
1130
 
1124
- <div className="relative flex min-h-0 flex-1 overflow-hidden">
1131
+ <div className="deck-editor-workspace relative flex min-h-0 flex-1 overflow-hidden rounded-l-lg bg-background">
1125
1132
  {sidebarOpen && (
1126
1133
  <>
1127
1134
  <div
@@ -1181,7 +1188,7 @@ export default function DeckEditor() {
1181
1188
  )}
1182
1189
 
1183
1190
  {generatingSlideSelected && generatingSlideVisible && (
1184
- <div className="flex min-h-0 flex-1 overflow-auto bg-background p-4 md:p-8">
1191
+ <div className="flex min-h-0 flex-1 overflow-auto bg-[var(--slides-editor-surface)] p-4 md:p-8">
1185
1192
  <div className="m-auto w-full max-w-6xl">
1186
1193
  <GeneratingSlidePreview
1187
1194
  content={streamedGeneratingSlideContent}
@@ -1197,7 +1204,7 @@ export default function DeckEditor() {
1197
1204
  generatingSlideVisible &&
1198
1205
  deck.slides.length === 0 &&
1199
1206
  !showQuestionFlow && (
1200
- <div className="flex min-h-0 flex-1 overflow-auto bg-background p-4 md:p-8">
1207
+ <div className="flex min-h-0 flex-1 overflow-auto bg-[var(--slides-editor-surface)] p-4 md:p-8">
1201
1208
  <div className="m-auto w-full max-w-6xl">
1202
1209
  <GeneratingSlidePreview
1203
1210
  content={streamedGeneratingSlideContent}
@@ -1215,6 +1222,7 @@ export default function DeckEditor() {
1215
1222
  deckId={id}
1216
1223
  readOnly={!canEdit}
1217
1224
  contextToolbarSlot={contextToolbarSlot}
1225
+ wideContextToolbarSlot={wideContextToolbarSlot}
1218
1226
  contextToolbarLeading={
1219
1227
  canEdit ? (
1220
1228
  <EditorActionCluster
@@ -1264,7 +1272,6 @@ export default function DeckEditor() {
1264
1272
  onDropImageUrl={dropImageUrlOnSlide}
1265
1273
  onToggleObjectFit={toggleObjectFit}
1266
1274
  slideIndex={currentIndex >= 0 ? currentIndex : 0}
1267
- slideCount={deck.slides.length}
1268
1275
  designSystem={designSystem}
1269
1276
  aspectRatio={deck.aspectRatio}
1270
1277
  collabUser={
@@ -6,7 +6,7 @@ import {
6
6
  } from "@agent-native/toolkit/app-shell";
7
7
  import {
8
8
  IconAlertTriangle,
9
- IconPalette,
9
+ IconComponents,
10
10
  IconPlus,
11
11
  IconRefresh,
12
12
  } from "@tabler/icons-react";
@@ -349,7 +349,7 @@ function EmptyState({ onCreateNew }: { onCreateNew: () => void }) {
349
349
  return (
350
350
  <div className="flex flex-col items-center justify-center min-h-[60vh] text-center">
351
351
  <div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-[#609FF8]/20 to-[#4080E0]/20 border border-[#609FF8]/20 flex items-center justify-center mb-6">
352
- <IconPalette className="w-7 h-7 text-[#609FF8]" />
352
+ <IconComponents className="w-7 h-7 text-primary" />
353
353
  </div>
354
354
  <h2 className="text-xl font-semibold text-foreground mb-2">
355
355
  {t("designSystems.emptyTitle")}
@@ -15,6 +15,7 @@ import {
15
15
  IconAlertTriangle,
16
16
  IconPlus,
17
17
  IconRefresh,
18
+ IconSearch,
18
19
  IconStack2,
19
20
  IconUserCircle,
20
21
  } from "@tabler/icons-react";
@@ -47,6 +48,7 @@ import {
47
48
  AlertDialogTitle,
48
49
  } from "@/components/ui/alert-dialog";
49
50
  import { Button } from "@/components/ui/button";
51
+ import { Input } from "@/components/ui/input";
50
52
  import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
51
53
  import {
52
54
  describeDeckPersistenceFailure,
@@ -58,6 +60,7 @@ import { useDesignSystems } from "@/hooks/use-design-systems";
58
60
  import { useWorkspaceDefaults } from "@/hooks/use-workspace-defaults";
59
61
  import { createDeckAgentMessage } from "@/lib/agent-visible-message";
60
62
  import { savePromptToComposerDraft } from "@/lib/composer-draft";
63
+ import { isSourceImprovementRequest } from "@/lib/create-deck-generation";
61
64
  import { sortDecksByRecency } from "@/lib/deck-sorting";
62
65
  import {
63
66
  IMPORT_ACTION_TIMEOUT_MS,
@@ -208,20 +211,22 @@ function describeUploadedFilesForAgent(
208
211
  "",
209
212
  importedSourceDeck
210
213
  ? `The user uploaded ${files.length} file(s). The ${importedSourceDeck.file.originalName} source deck has already been imported into target deck ${deckId} with ${importedSourceDeck.slideCount} source slide(s); do not import it again.`
211
- : `The user uploaded ${files.length} file(s). These are mandatory source material, not optional references — process every one of them with the matching import action BEFORE adding the first slide:`,
214
+ : `The user attached ${files.length} file(s) as reference material for this new deck. Attachments are context for the agent by default; do not import or append their slides to target deck ${deckId} merely because they were attached.`,
212
215
  fileList,
213
216
  "",
214
217
  "File handling rules:",
215
218
  importedSourceDeck
216
- ? "- The imported source deck is the canonical source. Preserve its slide count, order, IDs, factual copy, notes, imagery, charts, tables, diagrams, and freeform objects while improving styling. Use update-slide on existing slide IDs; do not rebuild it with add-slide."
217
- : `- PPTX files: call \`import-pptx --filePath "<path>" --deckId ${deckId}\` before adding or editing slides.`,
219
+ ? "- The imported source deck is canonical. Preserve its slide count, order, IDs, factual copy, notes, imagery, charts, tables, diagrams, and freeform objects while improving styling. For a deck-wide restyle, use one patch-deck call with requireAllSourceSlides=true; use update-slide only for a targeted one-slide edit. Do not rebuild it with add-slide."
220
+ : `- PDF, PPTX, and DOCX files: call \`import-file --filePath "<path>" --format auto\` (without \`importIntoDeck\`) when you need their text or structure. Use the returned material as reference while creating new slides with \`add-slide\`.`,
218
221
  importedSourceDeck
219
222
  ? "- For a PDF source, keep the original full-page image in every slide and add restrained design-system chrome around it without obscuring source content. Never OCR-reconstruct a source-faithful page from extracted text."
220
- : `- PDF and DOCX files: call \`import-file --filePath "<path>" --format auto --deckId ${deckId}\` and use the returned extracted text as source material. The returned text is capped for reliability; re-run with maxChars only if more context is needed. For a visual PDF whose original layout should be preserved, pass \`--importIntoDeck true\` instead of rebuilding the pages from extracted text. Do not proceed to add-slide until this call has returned for every PDF/DOCX in the list above.`,
223
+ : "- Do not pass `importIntoDeck: true` for an attached file unless the user explicitly asks to import or preserve the source pages in the current deck. An attached reference is not an instruction to replace or seed the deck.",
221
224
  "- Text-like files: use the uploaded-text-file blocks already included in the prompt; do not call import-file for them.",
222
225
  '- Image files with an embeddable URL are mandatory assets: if the user specified where to use one (e.g. "on the first and last slide"), embed it there with `<img src="...">` exactly as requested. Do not omit a requested image and continue silently — if it truly cannot be placed, say why in your final chat response.',
223
226
  "- Image files without a URL are visual/reference assets only; do not claim to have processed a PPTX/PDF/DOCX unless the relevant import action succeeds.",
224
- "- Before your final response, verify every uploaded file above was either imported (PPTX/PDF/DOCX) or placed as requested (images). If any file's content or requested placement is missing from the deck, say so explicitly instead of reporting success.",
227
+ importedSourceDeck
228
+ ? "- Before your final response, verify the same source slide IDs and count with get-deck after the restyle. If source fidelity is partial or images were skipped, report the exact warning instead of claiming success."
229
+ : "- Before your final response, verify every uploaded file above was either used as reference or placed as explicitly requested. If any file's content or requested placement is missing from the deck, say so explicitly instead of reporting success.",
225
230
  ].join("\n");
226
231
  }
227
232
 
@@ -278,6 +283,7 @@ export default function Index() {
278
283
  const [selectedReferenceDeckId, setSelectedReferenceDeckId] = useState<
279
284
  string | null
280
285
  >(null);
286
+ const [deckSearch, setDeckSearch] = useState("");
281
287
  // True while the picker still reflects an auto-applied default rather than
282
288
  // an explicit user choice. `useWorkspaceDefaults()`/`useDesignSystems()`
283
289
  // resolve asynchronously, so the initial value set on dialog open can be a
@@ -292,10 +298,6 @@ export default function Index() {
292
298
  const anchorRef = useRef<HTMLElement | null>(null);
293
299
  // Keep anchorRef.current in sync so PromptPopover can read it
294
300
  anchorRef.current = anchorElRef.current;
295
- const designSystemTitleById = useMemo<Map<string, string>>(
296
- () => new Map(designSystems.map((ds) => [ds.id, ds.title])),
297
- [designSystems],
298
- );
299
301
  const workspaceDesignSystemId =
300
302
  workspaceDesignSystem && !workspaceDesignSystem.unavailable
301
303
  ? workspaceDesignSystem.id
@@ -316,14 +318,19 @@ export default function Index() {
316
318
  lastUsedDesignSystemId ?? workspaceDesignSystemId;
317
319
  const initialReferenceDeckId = lastUsedReferenceDeckId;
318
320
  const deckFilter = searchParams.get("createdBy") === "me" ? "mine" : "all";
321
+ const normalizedDeckSearch = deckSearch.trim().toLowerCase();
319
322
  const visibleDecks = useMemo(
320
323
  () =>
321
324
  sortDecksByRecency(
322
- deckFilter === "mine"
323
- ? decks.filter((deck) => deck.createdByMe)
324
- : decks,
325
+ decks.filter((deck) => {
326
+ if (deckFilter === "mine" && !deck.createdByMe) return false;
327
+ return (
328
+ normalizedDeckSearch.length === 0 ||
329
+ deck.title.toLowerCase().includes(normalizedDeckSearch)
330
+ );
331
+ }),
325
332
  ),
326
- [deckFilter, decks],
333
+ [deckFilter, decks, normalizedDeckSearch],
327
334
  );
328
335
  const rememberReference = useCallback(
329
336
  (reference: Parameters<typeof rememberRecentReference>[0]) => {
@@ -591,7 +598,7 @@ export default function Index() {
591
598
  setNewDeckPromptOpen(false);
592
599
 
593
600
  // Leave the grid as soon as the optimistic deck exists. Persistence and
594
- // source import can take several seconds for a large PDF, so the editor's
601
+ // agent context hydration can take several seconds, so the editor's
595
602
  // generation state is the only useful surface while that work finishes.
596
603
  navigate(`/deck/${deck.id}?generating=1`, {
597
604
  replace: true,
@@ -632,18 +639,20 @@ export default function Index() {
632
639
  }
633
640
 
634
641
  let importedSourceDeck: ImportedSourceDeck | null = null;
635
- try {
636
- importedSourceDeck = await importUploadedDeckIntoDeck(
637
- filesForGeneration,
638
- deckId,
639
- );
640
- } catch (error) {
641
- recoverFromGenerationSetupFailure(
642
- error instanceof Error
643
- ? error.message
644
- : t("home.generationStartFailedDescription"),
645
- );
646
- return;
642
+ if (isSourceImprovementRequest(prompt, filesForGeneration)) {
643
+ try {
644
+ importedSourceDeck = await importUploadedDeckIntoDeck(
645
+ filesForGeneration,
646
+ deckId,
647
+ );
648
+ } catch (error) {
649
+ recoverFromGenerationSetupFailure(
650
+ error instanceof Error
651
+ ? error.message
652
+ : t("home.generationStartFailedDescription"),
653
+ );
654
+ return;
655
+ }
647
656
  }
648
657
 
649
658
  clearPendingPromptForRetry();
@@ -710,10 +719,10 @@ export default function Index() {
710
719
  "Source-preserving improvement mode:",
711
720
  `- The target deck already contains ${importedSourceDeck.slideCount} imported source slides. Treat those slides as the user's complete source, not as inspiration for a new deck.`,
712
721
  "- Keep the exact source slide count, order, IDs, factual meaning, notes, images, charts, tables, diagrams, and freeform objects unless the user explicitly asks to change one of them.",
713
- "- Read `get-deck` once before editing to obtain every existing slide ID and source HTML, load the linked design system with `get-design-system`, then make a deck-wide restyle with one `patch-deck` call using `requireAllSourceSlides: true` and one `patch-slide` operation with `fields.content` for every source slide ID. Do not split a full-deck restyle into arbitrary batches or fall back to one-by-one `update-slide` calls; use `update-slide` only for a targeted one-slide edit. Keep every original `<img>` source and enough original factual copy for each slide; for PDF slides, use restrained design-system chrome around the page without obscuring it.",
714
- "- Do not call `add-slide`, delete slides, reorder slides, or replace source images with generic cards. Do not claim success until `get-deck` verifies the same slide IDs and count after the edits.",
715
- '- After the patch succeeds, verify with `get-deck` using `compact: "true"` so only slide IDs, count, and previews are returned. Do not report an initial or partial pass, and do not leave any source slides for a later run.',
716
- "- If `get-deck` reports partial source fidelity or skipped images, stop and report the exact warning instead of claiming a reliable restyle.",
722
+ "- Read get-deck once before editing to obtain every existing slide ID and source HTML, load the linked design system with get-design-system, then make a deck-wide restyle with one patch-deck call using requireAllSourceSlides=true and one patch-slide operation with fields.content for every source slide ID. Do not split a full-deck restyle into arbitrary batches or fall back to one-by-one update-slide calls; use update-slide only for a targeted one-slide edit. Keep every original image source and enough original factual copy for each slide; for PDF slides, use restrained design-system chrome around the page without obscuring it.",
723
+ "- Do not call add-slide, delete slides, reorder slides, or replace source images with generic cards. Do not claim success until get-deck verifies the same slide IDs and count after the edits.",
724
+ '- After the patch succeeds, verify with get-deck using compact: "true" so only slide IDs, count, and previews are returned. Do not report an initial or partial pass, and do not leave any source slides for a later run.',
725
+ "- If get-deck reports partial source fidelity or skipped images, stop and report the exact warning instead of claiming a reliable restyle.",
717
726
  ].join("\n")
718
727
  : "";
719
728
  const sourceModeInstructions = importedSourceDeck
@@ -722,8 +731,9 @@ export default function Index() {
722
731
  "Do not use the new-deck add-slide workflow for this source-preserving request. Finish every source slide in this run; if patch-deck rejects incomplete coverage, continue with the returned missing IDs instead of reporting success with a partial deck.",
723
732
  ].join("\n")
724
733
  : [
734
+ "This is a new deck. Keep it empty until generation begins; attached reference files must not seed it with imported slides.",
725
735
  "Start a `manage-progress` run so progress appears in the app header. Add the first slide as soon as it is ready, then continue one slide at a time so the editor visibly fills in.",
726
- "After reading any requested or imported source material, but before adding the first slide, choose a concise, specific deck title from the user's request and source material. Never use the deck id, run id, file id, or another opaque alphanumeric token as the title. Call `patch-deck` with `deckId: \"" +
736
+ "After reading any requested or attached reference material, but before adding the first slide, choose a concise, specific deck title from the user's request and source material. Never use the deck id, run id, file id, or another opaque alphanumeric token as the title. Call `patch-deck` with `deckId: \"" +
727
737
  deckId +
728
738
  '\"` and `operations: [{ "op": "patch-deck-fields", "fields": { "title": "<generated title>" } }]`. Include only `title` in `fields`; omit all other optional fields. Never leave a generated deck named "Untitled Deck" or another placeholder.',
729
739
  "If the user asks for a standalone visual, diagram, hero, one-pager, poster, or a couple of visuals, create only the requested one/few polished visual slides. Do not pad the result into a full presentation.",
@@ -1281,7 +1291,7 @@ export default function Index() {
1281
1291
  );
1282
1292
 
1283
1293
  return (
1284
- <main className="min-w-0 flex-1 overflow-y-auto px-4 py-6 sm:px-6 sm:py-10">
1294
+ <main className="min-w-0 flex-1 overflow-y-auto px-4 pb-6 pt-0 sm:px-6 sm:pb-10">
1285
1295
  {loading ? (
1286
1296
  <>
1287
1297
  <div className="mb-4 flex items-center justify-end">
@@ -1290,10 +1300,7 @@ export default function Index() {
1290
1300
  <div className="deck-grid-container">
1291
1301
  <div className="deck-grid grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
1292
1302
  {Array.from({ length: 8 }).map((_, i) => (
1293
- <div
1294
- key={i}
1295
- className="overflow-hidden rounded-xl border border-border bg-card"
1296
- >
1303
+ <div key={i} className="overflow-hidden rounded-xl bg-card">
1297
1304
  <div className="aspect-video animate-pulse bg-muted/50" />
1298
1305
  <div className="space-y-2 p-4">
1299
1306
  <div className="h-4 w-3/4 animate-pulse rounded bg-muted" />
@@ -1329,37 +1336,49 @@ export default function Index() {
1329
1336
  ) : (
1330
1337
  <>
1331
1338
  <div className="mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
1332
- <ToggleGroup
1333
- type="single"
1334
- value={deckFilter}
1335
- onValueChange={(value) => value && setDeckFilter(value)}
1336
- className="w-fit rounded-lg border border-border bg-card p-0.5"
1337
- size="sm"
1338
- >
1339
- <ToggleGroupItem
1340
- value="all"
1341
- aria-label={t("home.showAllDecks")}
1342
- className="h-7 rounded-md px-3 text-xs data-[state=on]:bg-accent"
1339
+ <div className="flex min-w-0 flex-col gap-3 sm:flex-row sm:items-center">
1340
+ <ToggleGroup
1341
+ type="single"
1342
+ value={deckFilter}
1343
+ onValueChange={(value) => value && setDeckFilter(value)}
1344
+ className="w-fit rounded-lg border border-border bg-card p-0.5"
1345
+ size="sm"
1343
1346
  >
1344
- <IconStack2 className="me-1.5 h-3.5 w-3.5" />
1345
- {t("home.all")}
1346
- </ToggleGroupItem>
1347
- <ToggleGroupItem
1348
- value="mine"
1349
- aria-label={t("home.showMineDecks")}
1350
- className="h-7 rounded-md px-3 text-xs data-[state=on]:bg-accent"
1351
- >
1352
- <IconUserCircle className="me-1.5 h-3.5 w-3.5" />
1353
- {t("home.mine")}
1354
- </ToggleGroupItem>
1355
- </ToggleGroup>
1347
+ <ToggleGroupItem
1348
+ value="all"
1349
+ aria-label={t("home.showAllDecks")}
1350
+ className="h-7 rounded-md px-3 text-xs data-[state=on]:bg-accent"
1351
+ >
1352
+ <IconStack2 className="me-1.5 h-3.5 w-3.5" />
1353
+ {t("home.all")}
1354
+ </ToggleGroupItem>
1355
+ <ToggleGroupItem
1356
+ value="mine"
1357
+ aria-label={t("home.showMineDecks")}
1358
+ className="h-7 rounded-md px-3 text-xs data-[state=on]:bg-accent"
1359
+ >
1360
+ <IconUserCircle className="me-1.5 h-3.5 w-3.5" />
1361
+ {t("home.mine")}
1362
+ </ToggleGroupItem>
1363
+ </ToggleGroup>
1364
+ <label className="flex h-8 w-full items-center gap-2 rounded-lg border border-border bg-card px-2.5 text-muted-foreground sm:w-60">
1365
+ <IconSearch className="size-3.5 shrink-0" aria-hidden="true" />
1366
+ <Input
1367
+ type="search"
1368
+ value={deckSearch}
1369
+ onChange={(event) => setDeckSearch(event.target.value)}
1370
+ placeholder={t("root.searchDecks")}
1371
+ aria-label={t("root.searchDecks")}
1372
+ className="h-7 min-w-0 flex-1 border-0 bg-transparent p-0 text-xs shadow-none focus-visible:ring-0 focus-visible:ring-offset-0"
1373
+ />
1374
+ </label>
1375
+ </div>
1356
1376
  <span className="text-xs text-muted-foreground/70">
1357
- {deckFilter === "mine"
1377
+ {deckFilter === "mine" || normalizedDeckSearch
1358
1378
  ? `${visibleDecks.length} of ${decks.length}`
1359
- : decks.length}{" "}
1379
+ : visibleDecks.length}{" "}
1360
1380
  {t("home.deckCount", {
1361
- count:
1362
- deckFilter === "mine" ? visibleDecks.length : decks.length,
1381
+ count: visibleDecks.length,
1363
1382
  })}
1364
1383
  </span>
1365
1384
  </div>
@@ -1368,7 +1387,7 @@ export default function Index() {
1368
1387
  {/* New deck card */}
1369
1388
  <button
1370
1389
  onClick={openNewDeck}
1371
- className="group relative cursor-pointer overflow-hidden rounded-xl border border-dashed border-border bg-card text-start hover:border-foreground/15"
1390
+ className="group relative cursor-pointer overflow-hidden rounded-xl border border-transparent bg-card text-start transition-[background-color,border-color] duration-200 hover:border-border hover:bg-accent/30"
1372
1391
  >
1373
1392
  <div className="flex aspect-video items-center justify-center bg-muted/30">
1374
1393
  <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-accent/50 group-hover:bg-accent">
@@ -1379,9 +1398,6 @@ export default function Index() {
1379
1398
  <h3 className="text-sm font-medium text-muted-foreground group-hover:text-foreground/70">
1380
1399
  {t("home.newDeck")}
1381
1400
  </h3>
1382
- <div className="mt-1 text-xs text-muted-foreground/70">
1383
- {t("home.createDeckOrVisual")}
1384
- </div>
1385
1401
  </div>
1386
1402
  </button>
1387
1403
 
@@ -1393,19 +1409,16 @@ export default function Index() {
1393
1409
  onRename={handleRename}
1394
1410
  onDuplicate={handleDuplicate}
1395
1411
  onToggleStar={handleToggleStar}
1396
- designSystemTitle={
1397
- deck.designSystemId
1398
- ? designSystemTitleById.get(deck.designSystemId)
1399
- : null
1400
- }
1401
1412
  isWorkspaceDefault={workspaceReferenceDeck?.id === deck.id}
1402
1413
  canSetWorkspaceDefault={canManageWorkspaceDefaults}
1403
1414
  onSetWorkspaceDefault={handleSetWorkspaceDefaultDeck}
1404
1415
  />
1405
1416
  ))}
1406
1417
  {visibleDecks.length === 0 && (
1407
- <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground">
1408
- {t("home.noMineDecks")}
1418
+ <div className="rounded-xl bg-card p-6 text-sm text-muted-foreground">
1419
+ {normalizedDeckSearch
1420
+ ? t("home.noDecksMatchSearch")
1421
+ : t("home.noMineDecks")}
1409
1422
  </div>
1410
1423
  )}
1411
1424
  </div>
@@ -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-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",
@@ -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
+ }