@agent-native/core 0.85.7 → 0.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1019) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +124 -1
  3. package/corpus/core/README.md +0 -11
  4. package/corpus/core/docs/content/cloneable-saas.mdx +0 -1
  5. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +0 -1
  6. package/corpus/core/docs/content/locales/ar-SA/plan-plugin.mdx +10 -9
  7. package/corpus/core/docs/content/locales/ar-SA/sharing.mdx +1 -2
  8. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +2 -3
  9. package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +23 -7
  10. package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +1 -1
  11. package/corpus/core/docs/content/locales/ar-SA/workspace-connections.mdx +11 -11
  12. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +0 -1
  13. package/corpus/core/docs/content/locales/de-DE/plan-plugin.mdx +10 -9
  14. package/corpus/core/docs/content/locales/de-DE/sharing.mdx +1 -2
  15. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +2 -3
  16. package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +23 -7
  17. package/corpus/core/docs/content/locales/de-DE/tracking.mdx +1 -1
  18. package/corpus/core/docs/content/locales/de-DE/workspace-connections.mdx +1 -1
  19. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +0 -1
  20. package/corpus/core/docs/content/locales/es-ES/plan-plugin.mdx +10 -9
  21. package/corpus/core/docs/content/locales/es-ES/sharing.mdx +1 -2
  22. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +2 -3
  23. package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +23 -7
  24. package/corpus/core/docs/content/locales/es-ES/tracking.mdx +1 -1
  25. package/corpus/core/docs/content/locales/es-ES/workspace-connections.mdx +1 -1
  26. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +0 -1
  27. package/corpus/core/docs/content/locales/fr-FR/plan-plugin.mdx +10 -9
  28. package/corpus/core/docs/content/locales/fr-FR/sharing.mdx +1 -2
  29. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +2 -3
  30. package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +23 -7
  31. package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +1 -1
  32. package/corpus/core/docs/content/locales/fr-FR/workspace-connections.mdx +1 -1
  33. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +0 -1
  34. package/corpus/core/docs/content/locales/hi-IN/plan-plugin.mdx +10 -9
  35. package/corpus/core/docs/content/locales/hi-IN/sharing.mdx +1 -2
  36. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +2 -3
  37. package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +23 -7
  38. package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +1 -1
  39. package/corpus/core/docs/content/locales/hi-IN/workspace-connections.mdx +1 -1
  40. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +0 -1
  41. package/corpus/core/docs/content/locales/ja-JP/plan-plugin.mdx +10 -9
  42. package/corpus/core/docs/content/locales/ja-JP/sharing.mdx +1 -2
  43. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +2 -3
  44. package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +23 -7
  45. package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +1 -1
  46. package/corpus/core/docs/content/locales/ja-JP/workspace-connections.mdx +1 -1
  47. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +0 -1
  48. package/corpus/core/docs/content/locales/ko-KR/plan-plugin.mdx +10 -9
  49. package/corpus/core/docs/content/locales/ko-KR/sharing.mdx +1 -2
  50. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +2 -3
  51. package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +23 -7
  52. package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +1 -1
  53. package/corpus/core/docs/content/locales/ko-KR/workspace-connections.mdx +1 -1
  54. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +0 -1
  55. package/corpus/core/docs/content/locales/pt-BR/plan-plugin.mdx +10 -9
  56. package/corpus/core/docs/content/locales/pt-BR/sharing.mdx +1 -2
  57. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +2 -3
  58. package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +23 -7
  59. package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +1 -1
  60. package/corpus/core/docs/content/locales/pt-BR/workspace-connections.mdx +1 -1
  61. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +0 -1
  62. package/corpus/core/docs/content/locales/zh-CN/plan-plugin.mdx +10 -9
  63. package/corpus/core/docs/content/locales/zh-CN/sharing.mdx +1 -2
  64. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +2 -3
  65. package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +23 -7
  66. package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +1 -1
  67. package/corpus/core/docs/content/locales/zh-CN/workspace-connections.mdx +1 -1
  68. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +0 -1
  69. package/corpus/core/docs/content/locales/zh-TW/plan-plugin.mdx +10 -9
  70. package/corpus/core/docs/content/locales/zh-TW/sharing.mdx +1 -2
  71. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +2 -3
  72. package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +23 -7
  73. package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +1 -1
  74. package/corpus/core/docs/content/locales/zh-TW/workspace-connections.mdx +1 -1
  75. package/corpus/core/docs/content/plan-plugin.mdx +12 -11
  76. package/corpus/core/docs/content/sharing.mdx +1 -2
  77. package/corpus/core/docs/content/skills-guide.mdx +4 -3
  78. package/corpus/core/docs/content/template-plan.mdx +37 -6
  79. package/corpus/core/docs/content/tracking.mdx +1 -1
  80. package/corpus/core/docs/content/workspace-connections.mdx +1 -1
  81. package/corpus/core/package.json +6 -6
  82. package/corpus/core/src/agent/run-store.ts +1 -1
  83. package/corpus/core/src/chat-threads/store.ts +73 -11
  84. package/corpus/core/src/checkpoints/store.ts +13 -2
  85. package/corpus/core/src/cli/create.ts +3 -4
  86. package/corpus/core/src/cli/design-connect.ts +469 -9
  87. package/corpus/core/src/cli/index.ts +13 -0
  88. package/corpus/core/src/cli/plan-local.ts +281 -24
  89. package/corpus/core/src/cli/skills.ts +177 -21
  90. package/corpus/core/src/cli/templates-meta.ts +0 -13
  91. package/corpus/core/src/cli/visualize-repo.ts +715 -0
  92. package/corpus/core/src/client/AssistantChat.tsx +126 -17
  93. package/corpus/core/src/client/agent-chat-adapter.ts +6 -5
  94. package/corpus/core/src/client/app-providers.tsx +2 -2
  95. package/corpus/core/src/client/collab/index.ts +31 -0
  96. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +16 -1
  97. package/corpus/core/src/client/components/PresenceBar.tsx +14 -1
  98. package/corpus/core/src/client/components/RecentEditHighlights.tsx +219 -0
  99. package/corpus/core/src/client/components/RemoteSelectionRings.tsx +40 -6
  100. package/corpus/core/src/client/index.ts +48 -0
  101. package/corpus/core/src/client/org/OrgSwitcher.tsx +0 -4
  102. package/corpus/core/src/client/rich-markdown-editor/SharedRichEditor.tsx +49 -32
  103. package/corpus/core/src/client/rich-markdown-editor/index.ts +6 -0
  104. package/corpus/core/src/client/rich-markdown-editor/surgical-apply.ts +192 -0
  105. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +59 -8
  106. package/corpus/core/src/client/session-replay.ts +181 -15
  107. package/corpus/core/src/client/sse-event-processor.ts +90 -1
  108. package/corpus/core/src/client/use-action.ts +123 -25
  109. package/corpus/core/src/client/use-agent-engine-configured.ts +7 -1
  110. package/corpus/core/src/client/use-chat-threads.ts +18 -7
  111. package/corpus/core/src/client/use-db-sync.ts +104 -19
  112. package/corpus/core/src/client/visual-style-controls.tsx +475 -0
  113. package/corpus/core/src/collab/agent-presence.ts +191 -62
  114. package/corpus/core/src/collab/awareness.ts +83 -6
  115. package/corpus/core/src/collab/client.ts +89 -146
  116. package/corpus/core/src/collab/index.ts +34 -0
  117. package/corpus/core/src/collab/recent-edits.ts +171 -0
  118. package/corpus/core/src/collab/undo.ts +432 -0
  119. package/corpus/core/src/collab/ydoc-manager.ts +68 -0
  120. package/corpus/core/src/connections/catalog.ts +2 -3
  121. package/corpus/core/src/db/create-get-db.ts +86 -1
  122. package/corpus/core/src/db/ensure-additive-columns.ts +430 -0
  123. package/corpus/core/src/db/index.ts +6 -0
  124. package/corpus/core/src/db/migrations.ts +236 -35
  125. package/corpus/core/src/jobs/scheduler.ts +17 -14
  126. package/corpus/core/src/observability/traces.ts +182 -1
  127. package/corpus/core/src/org/context.ts +79 -2
  128. package/corpus/core/src/server/agent-chat-plugin.ts +10 -6
  129. package/corpus/core/src/server/auth-marketing.ts +0 -11
  130. package/corpus/core/src/server/auth.ts +11 -4
  131. package/corpus/core/src/server/collab-plugin.ts +56 -13
  132. package/corpus/core/src/server/design-token-utils.ts +1 -1
  133. package/corpus/core/src/server/fusion-app.ts +447 -0
  134. package/corpus/core/src/server/index.ts +13 -0
  135. package/corpus/core/src/server/onboarding-html.ts +3 -4
  136. package/corpus/core/src/server/poll-events.ts +14 -2
  137. package/corpus/core/src/server/poll.ts +219 -12
  138. package/corpus/core/src/server/schema-prompt.ts +28 -9
  139. package/corpus/core/src/settings/store.ts +33 -2
  140. package/corpus/core/src/sharing/actions/set-resource-visibility.ts +2 -0
  141. package/corpus/core/src/sharing/actions/share-resource.ts +3 -0
  142. package/corpus/core/src/sharing/actions/unshare-resource.ts +2 -0
  143. package/corpus/core/src/styles/agent-native.css +0 -5
  144. package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
  145. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
  146. package/corpus/core/src/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
  147. package/corpus/core/src/templates/default/package.json +3 -3
  148. package/corpus/core/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
  149. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
  150. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
  151. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
  152. package/corpus/core/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
  153. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
  154. package/corpus/core/src/tracking/providers.ts +22 -1
  155. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +15 -0
  156. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +20 -5
  157. package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +8 -0
  158. package/corpus/templates/analytics/AGENTS.md +33 -6
  159. package/corpus/templates/analytics/actions/navigate.ts +14 -4
  160. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  161. package/corpus/templates/analytics/actions/view-screen.ts +57 -0
  162. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +23 -1
  163. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  164. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +21 -0
  165. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +7 -0
  166. package/corpus/templates/analytics/app/i18n/zh-TW.ts +15 -1
  167. package/corpus/templates/analytics/app/i18n-data.ts +151 -10
  168. package/corpus/templates/analytics/app/pages/Agents.tsx +118 -0
  169. package/corpus/templates/analytics/app/pages/DataSources.tsx +11 -1
  170. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +76 -40
  171. package/corpus/templates/analytics/app/pages/sessions/session-replay-devtools.ts +5 -0
  172. package/corpus/templates/analytics/app/routes/agents.tsx +10 -0
  173. package/corpus/templates/analytics/changelog/2026-07-03-agent-admin-tools-page.md +6 -0
  174. package/corpus/templates/analytics/changelog/2026-07-03-agent-llm-observability-dashboard.md +6 -0
  175. package/corpus/templates/analytics/changelog/2026-07-03-session-recordings-now-include-response-bodies-for-5xx-error.md +6 -0
  176. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +34 -0
  177. package/corpus/templates/analytics/docs/schemas/tracked-events.md +6 -0
  178. package/corpus/templates/analytics/package.json +3 -3
  179. package/corpus/templates/analytics/seeds/dashboards/agent-observability-llm.json +173 -0
  180. package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +23 -5
  181. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +58 -13
  182. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +23 -0
  183. package/corpus/templates/analytics/server/lib/dashboard-seeds.ts +5 -0
  184. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +120 -8
  185. package/corpus/templates/analytics/server/lib/session-replay.ts +3 -2
  186. package/corpus/templates/analytics/server/plugins/db.ts +93 -2
  187. package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +45 -1
  188. package/corpus/templates/analytics/shared/session-replay-diagnostics.ts +10 -0
  189. package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +82 -19
  190. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +15 -0
  191. package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +8 -0
  192. package/corpus/templates/assets/package.json +3 -3
  193. package/corpus/templates/assets/server/plugins/db.ts +63 -2
  194. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +15 -0
  195. package/corpus/templates/brain/package.json +3 -3
  196. package/corpus/templates/brain/server/plugins/db.ts +75 -2
  197. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +15 -0
  198. package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +8 -0
  199. package/corpus/templates/calendar/package.json +3 -3
  200. package/corpus/templates/calendar/server/plugins/db.ts +64 -2
  201. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +15 -0
  202. package/corpus/templates/chat/package.json +3 -3
  203. package/corpus/templates/clips/actions/finalize-recording.ts +50 -40
  204. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +8 -6
  205. package/corpus/templates/clips/app/routes/share.$shareId.tsx +3 -3
  206. package/corpus/templates/clips/changelog/2026-07-03-mobile-recording-pages-keep-videos-in-a-16-9-player-with-act.md +6 -0
  207. package/corpus/templates/clips/package.json +3 -3
  208. package/corpus/templates/clips/server/lib/recording-upload-state.ts +56 -0
  209. package/corpus/templates/clips/server/plugins/db.ts +68 -1
  210. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +27 -3
  211. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +15 -0
  212. package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +8 -0
  213. package/corpus/templates/content/actions/edit-document.ts +48 -1
  214. package/corpus/templates/content/actions/list-documents.ts +101 -94
  215. package/corpus/templates/content/actions/search-documents.ts +19 -3
  216. package/corpus/templates/content/actions/update-document.ts +54 -1
  217. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +127 -7
  218. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +97 -2
  219. package/corpus/templates/content/changelog/2026-07-03-agent-document-edits-now-appear-as-a-live-collaborator-prese.md +6 -0
  220. package/corpus/templates/content/changelog/2026-07-03-document-search-and-list-views-load-faster-on-large-workspac.md +6 -0
  221. package/corpus/templates/content/package.json +3 -3
  222. package/corpus/templates/content/server/plugins/db.ts +57 -1
  223. package/corpus/templates/design/.agents/skills/full-app-build/SKILL.md +140 -0
  224. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +20 -0
  225. package/corpus/templates/design/AGENTS.md +50 -12
  226. package/corpus/templates/design/actions/add-fusion-screens.ts +91 -0
  227. package/corpus/templates/design/actions/apply-a11y-fix.ts +5 -1
  228. package/corpus/templates/design/actions/apply-component-prop-edit.ts +10 -2
  229. package/corpus/templates/design/actions/apply-fusion-edits.ts +161 -0
  230. package/corpus/templates/design/actions/apply-visual-edit.ts +34 -1
  231. package/corpus/templates/design/actions/create-component.ts +5 -1
  232. package/corpus/templates/design/actions/create-fusion-app.ts +202 -0
  233. package/corpus/templates/design/actions/deploy-fusion-app.ts +123 -0
  234. package/corpus/templates/design/actions/edit-design.ts +13 -16
  235. package/corpus/templates/design/actions/get-fusion-deploy-status.ts +86 -0
  236. package/corpus/templates/design/actions/list-fusion-edits.ts +96 -0
  237. package/corpus/templates/design/actions/list-local-files.ts +133 -0
  238. package/corpus/templates/design/actions/push-fusion-app.ts +62 -0
  239. package/corpus/templates/design/actions/queue-fusion-edit.ts +112 -0
  240. package/corpus/templates/design/actions/read-local-file.ts +139 -0
  241. package/corpus/templates/design/actions/send-fusion-message.ts +69 -0
  242. package/corpus/templates/design/actions/sync-fusion-app.ts +196 -0
  243. package/corpus/templates/design/actions/write-local-file.ts +115 -14
  244. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +12 -0
  245. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +379 -0
  246. package/corpus/templates/design/app/components/design/EditPanel.tsx +149 -73
  247. package/corpus/templates/design/app/components/design/FusionAppBanner.tsx +328 -0
  248. package/corpus/templates/design/app/components/design/LayersPanel.tsx +148 -30
  249. package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +1 -1
  250. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +567 -6
  251. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +7 -98
  252. package/corpus/templates/design/app/components/design/code-workbench/ActivityBar.tsx +85 -0
  253. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +466 -0
  254. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +53 -0
  255. package/corpus/templates/design/app/components/design/code-workbench/commands.ts +339 -0
  256. package/corpus/templates/design/app/components/design/code-workbench/editor/Breadcrumbs.tsx +42 -0
  257. package/corpus/templates/design/app/components/design/code-workbench/editor/BufferSync.tsx +128 -0
  258. package/corpus/templates/design/app/components/design/code-workbench/editor/EditorTabs.tsx +363 -0
  259. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +268 -0
  260. package/corpus/templates/design/app/components/design/code-workbench/editor/StatusBar.tsx +208 -0
  261. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +61 -0
  262. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-theme-palette.ts +191 -0
  263. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-theme.ts +29 -0
  264. package/corpus/templates/design/app/components/design/code-workbench/editor/status-bar-lang.ts +21 -0
  265. package/corpus/templates/design/app/components/design/code-workbench/editor/tab-drag.ts +27 -0
  266. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +155 -0
  267. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +551 -0
  268. package/corpus/templates/design/app/components/design/code-workbench/explorer/file-icons.tsx +115 -0
  269. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +65 -0
  270. package/corpus/templates/design/app/components/design/code-workbench/format/prettier-format.ts +182 -0
  271. package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +133 -0
  272. package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +563 -0
  273. package/corpus/templates/design/app/components/design/code-workbench/quickinput/fuzzy.ts +170 -0
  274. package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +508 -0
  275. package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +280 -0
  276. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +734 -0
  277. package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +39 -0
  278. package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +196 -0
  279. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +177 -0
  280. package/corpus/templates/design/app/components/design/code-workbench/workspace/tree.ts +110 -0
  281. package/corpus/templates/design/app/components/design/code-workbench/workspace/types.ts +103 -0
  282. package/corpus/templates/design/app/components/design/code-workbench-theme.ts +68 -0
  283. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +127 -10
  284. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +52 -29
  285. package/corpus/templates/design/app/components/design/inspector/index.ts +9 -0
  286. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +56 -0
  287. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +80 -1
  288. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +6 -16
  289. package/corpus/templates/design/app/i18n/zh-TW.ts +2 -1
  290. package/corpus/templates/design/app/i18n-data.ts +31 -18
  291. package/corpus/templates/design/app/pages/DesignEditor.tsx +1474 -175
  292. package/corpus/templates/design/app/pages/Index.tsx +90 -17
  293. package/corpus/templates/design/changelog/2026-07-03-the-ai-now-edits-like-a-collaborator-on-canvas-its-cursor-gl.md +6 -0
  294. package/corpus/templates/design/changelog/2026-07-03-the-code-panel-is-now-a-full-vs-code-style-editor-with-a-fil.md +6 -0
  295. package/corpus/templates/design/package.json +4 -3
  296. package/corpus/templates/design/server/db/schema.ts +31 -0
  297. package/corpus/templates/design/server/lib/fusion-screens.ts +246 -0
  298. package/corpus/templates/design/server/plugins/db.ts +89 -2
  299. package/corpus/templates/design/shared/collab-selection.ts +52 -0
  300. package/corpus/templates/design/shared/full-app.ts +126 -0
  301. package/corpus/templates/design/shared/pen-path.ts +296 -0
  302. package/corpus/templates/dispatch/package.json +3 -3
  303. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +15 -0
  304. package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +8 -0
  305. package/corpus/templates/forms/package.json +3 -3
  306. package/corpus/templates/forms/server/plugins/db.ts +62 -2
  307. package/corpus/templates/macros/package.json +3 -3
  308. package/corpus/templates/macros/server/plugins/db.ts +63 -2
  309. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +15 -0
  310. package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +8 -0
  311. package/corpus/templates/mail/package.json +3 -3
  312. package/corpus/templates/mail/server/lib/contact-frequency.ts +42 -15
  313. package/corpus/templates/mail/server/plugins/db.ts +63 -2
  314. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +15 -0
  315. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +9 -3
  316. package/corpus/templates/plan/.agents/skills/visualize-repo/SKILL.md +92 -0
  317. package/corpus/templates/plan/actions/export-visual-plan.ts +5 -0
  318. package/corpus/templates/plan/actions/get-local-plan-folder.ts +4 -22
  319. package/corpus/templates/plan/actions/get-plan-version.ts +6 -16
  320. package/corpus/templates/plan/actions/list-plan-versions.ts +48 -20
  321. package/corpus/templates/plan/actions/patch-visual-plan-source.ts +41 -1
  322. package/corpus/templates/plan/actions/promote-local-plan-folder.ts +4 -22
  323. package/corpus/templates/plan/actions/update-local-plan-comments.ts +4 -2
  324. package/corpus/templates/plan/actions/update-local-plan-folder.ts +4 -22
  325. package/corpus/templates/plan/actions/update-visual-plan.ts +60 -1
  326. package/corpus/templates/plan/agent-native.app-skill.json +10 -0
  327. package/corpus/templates/plan/app/components/editor/PlanDocumentEditor.tsx +138 -39
  328. package/corpus/templates/plan/app/components/editor/usePlanUndoStack.ts +165 -23
  329. package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +80 -4
  330. package/corpus/templates/plan/app/global.css +11 -9
  331. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +10 -1
  332. package/corpus/templates/plan/app/hooks/use-plan-presence.ts +66 -0
  333. package/corpus/templates/plan/app/pages/PlansPage.tsx +215 -63
  334. package/corpus/templates/plan/changelog/2026-07-03-local-visual-plans-and-recaps-can-save-comments-without-sign.md +6 -0
  335. package/corpus/templates/plan/changelog/2026-07-03-plan-tabs-render-nested-text-instead-of-raw-json.md +6 -0
  336. package/corpus/templates/plan/changelog/2026-07-03-plans-are-now-fully-real-time-collaborative-multiple-people-.md +6 -0
  337. package/corpus/templates/plan/changelog/2026-07-03-plans-open-and-refresh-faster-especially-long-lived-plans-wi.md +6 -0
  338. package/corpus/templates/plan/changelog/2026-07-03-undo-now-survives-agent-edits-cmd-z-keeps-working-on-your-ow.md +6 -0
  339. package/corpus/templates/plan/package.json +5 -3
  340. package/corpus/templates/plan/server/db/schema.ts +12 -0
  341. package/corpus/templates/plan/server/lib/local-plan-kind.ts +25 -0
  342. package/corpus/templates/plan/server/lib/plan-versions.ts +83 -1
  343. package/corpus/templates/plan/server/lib/public-action-paths.ts +0 -2
  344. package/corpus/templates/plan/server/plans.ts +26 -3
  345. package/corpus/templates/plan/server/plugins/db.ts +105 -2
  346. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +8 -4
  347. package/corpus/templates/slides/AGENTS.md +4 -0
  348. package/corpus/templates/slides/actions/_agent-presence.ts +48 -0
  349. package/corpus/templates/slides/actions/add-slide.ts +16 -18
  350. package/corpus/templates/slides/actions/patch-deck.ts +4 -2
  351. package/corpus/templates/slides/actions/update-slide.ts +114 -77
  352. package/corpus/templates/slides/actions/view-screen.ts +39 -0
  353. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +47 -3
  354. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +32 -35
  355. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +625 -199
  356. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +342 -0
  357. package/corpus/templates/slides/app/components/editor/TweaksPanel.tsx +46 -96
  358. package/corpus/templates/slides/app/components/visual-editor/SaveStatusIndicator.tsx +8 -1
  359. package/corpus/templates/slides/app/context/DeckContext.tsx +589 -176
  360. package/corpus/templates/slides/app/hooks/use-deck-presence.ts +84 -42
  361. package/corpus/templates/slides/app/i18n/ar-SA.ts +46 -0
  362. package/corpus/templates/slides/app/i18n/de-DE.ts +46 -0
  363. package/corpus/templates/slides/app/i18n/en-US.ts +46 -0
  364. package/corpus/templates/slides/app/i18n/es-ES.ts +46 -0
  365. package/corpus/templates/slides/app/i18n/fr-FR.ts +46 -0
  366. package/corpus/templates/slides/app/i18n/hi-IN.ts +46 -0
  367. package/corpus/templates/slides/app/i18n/ja-JP.ts +46 -0
  368. package/corpus/templates/slides/app/i18n/ko-KR.ts +46 -0
  369. package/corpus/templates/slides/app/i18n/pt-BR.ts +46 -0
  370. package/corpus/templates/slides/app/i18n/zh-CN.ts +46 -0
  371. package/corpus/templates/slides/app/i18n/zh-TW.ts +46 -0
  372. package/corpus/templates/slides/app/pages/DeckEditor.tsx +25 -13
  373. package/corpus/templates/slides/changelog/2026-07-03-figma-style-slide-editing.md +6 -0
  374. package/corpus/templates/slides/changelog/2026-07-03-see-the-ai-working-with-you-when-the-agent-edits-a-slide-it-.md +6 -0
  375. package/corpus/templates/slides/changelog/2026-07-03-undo-redo-is-now-precise-and-safe-with-collaborators-it-only.md +6 -0
  376. package/corpus/templates/slides/package.json +3 -3
  377. package/corpus/templates/slides/server/handlers/decks.ts +31 -3
  378. package/corpus/templates/slides/server/plugins/db.ts +65 -2
  379. package/corpus/templates/videos/netlify.toml +1 -12
  380. package/dist/agent/run-store.js +1 -1
  381. package/dist/agent/run-store.js.map +1 -1
  382. package/dist/chat-threads/store.d.ts +9 -1
  383. package/dist/chat-threads/store.d.ts.map +1 -1
  384. package/dist/chat-threads/store.js +63 -11
  385. package/dist/chat-threads/store.js.map +1 -1
  386. package/dist/checkpoints/store.d.ts.map +1 -1
  387. package/dist/checkpoints/store.js +10 -2
  388. package/dist/checkpoints/store.js.map +1 -1
  389. package/dist/cli/create.d.ts.map +1 -1
  390. package/dist/cli/create.js +3 -5
  391. package/dist/cli/create.js.map +1 -1
  392. package/dist/cli/design-connect.d.ts +49 -1
  393. package/dist/cli/design-connect.d.ts.map +1 -1
  394. package/dist/cli/design-connect.js +414 -9
  395. package/dist/cli/design-connect.js.map +1 -1
  396. package/dist/cli/index.js +12 -0
  397. package/dist/cli/index.js.map +1 -1
  398. package/dist/cli/plan-local.d.ts +24 -0
  399. package/dist/cli/plan-local.d.ts.map +1 -1
  400. package/dist/cli/plan-local.js +188 -20
  401. package/dist/cli/plan-local.js.map +1 -1
  402. package/dist/cli/skills.d.ts +3 -1
  403. package/dist/cli/skills.d.ts.map +1 -1
  404. package/dist/cli/skills.js +173 -21
  405. package/dist/cli/skills.js.map +1 -1
  406. package/dist/cli/templates-meta.d.ts.map +1 -1
  407. package/dist/cli/templates-meta.js +0 -14
  408. package/dist/cli/templates-meta.js.map +1 -1
  409. package/dist/cli/visualize-repo.d.ts +49 -0
  410. package/dist/cli/visualize-repo.d.ts.map +1 -0
  411. package/dist/cli/visualize-repo.js +561 -0
  412. package/dist/cli/visualize-repo.js.map +1 -0
  413. package/dist/client/AssistantChat.d.ts.map +1 -1
  414. package/dist/client/AssistantChat.js +120 -15
  415. package/dist/client/AssistantChat.js.map +1 -1
  416. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  417. package/dist/client/agent-chat-adapter.js +6 -5
  418. package/dist/client/agent-chat-adapter.js.map +1 -1
  419. package/dist/client/app-providers.d.ts +2 -2
  420. package/dist/client/app-providers.js.map +1 -1
  421. package/dist/client/collab/index.d.ts +4 -1
  422. package/dist/client/collab/index.d.ts.map +1 -1
  423. package/dist/client/collab/index.js +3 -0
  424. package/dist/client/collab/index.js.map +1 -1
  425. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  426. package/dist/client/components/LiveCursorOverlay.js +11 -3
  427. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  428. package/dist/client/components/PresenceBar.d.ts.map +1 -1
  429. package/dist/client/components/PresenceBar.js +6 -1
  430. package/dist/client/components/PresenceBar.js.map +1 -1
  431. package/dist/client/components/RecentEditHighlights.d.ts +43 -0
  432. package/dist/client/components/RecentEditHighlights.d.ts.map +1 -0
  433. package/dist/client/components/RecentEditHighlights.js +146 -0
  434. package/dist/client/components/RecentEditHighlights.js.map +1 -0
  435. package/dist/client/components/RemoteSelectionRings.d.ts +9 -0
  436. package/dist/client/components/RemoteSelectionRings.d.ts.map +1 -1
  437. package/dist/client/components/RemoteSelectionRings.js +22 -8
  438. package/dist/client/components/RemoteSelectionRings.js.map +1 -1
  439. package/dist/client/index.d.ts +6 -1
  440. package/dist/client/index.d.ts.map +1 -1
  441. package/dist/client/index.js +7 -0
  442. package/dist/client/index.js.map +1 -1
  443. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  444. package/dist/client/org/OrgSwitcher.js +1 -3
  445. package/dist/client/org/OrgSwitcher.js.map +1 -1
  446. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +8 -1
  447. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -1
  448. package/dist/client/rich-markdown-editor/SharedRichEditor.js +8 -2
  449. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -1
  450. package/dist/client/rich-markdown-editor/index.d.ts +1 -0
  451. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
  452. package/dist/client/rich-markdown-editor/index.js +1 -0
  453. package/dist/client/rich-markdown-editor/index.js.map +1 -1
  454. package/dist/client/rich-markdown-editor/surgical-apply.d.ts +66 -0
  455. package/dist/client/rich-markdown-editor/surgical-apply.d.ts.map +1 -0
  456. package/dist/client/rich-markdown-editor/surgical-apply.js +147 -0
  457. package/dist/client/rich-markdown-editor/surgical-apply.js.map +1 -0
  458. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +18 -2
  459. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  460. package/dist/client/rich-markdown-editor/useCollabReconcile.js +39 -8
  461. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  462. package/dist/client/session-replay.d.ts +10 -1
  463. package/dist/client/session-replay.d.ts.map +1 -1
  464. package/dist/client/session-replay.js +134 -7
  465. package/dist/client/session-replay.js.map +1 -1
  466. package/dist/client/sse-event-processor.d.ts.map +1 -1
  467. package/dist/client/sse-event-processor.js +81 -1
  468. package/dist/client/sse-event-processor.js.map +1 -1
  469. package/dist/client/use-action.d.ts +24 -0
  470. package/dist/client/use-action.d.ts.map +1 -1
  471. package/dist/client/use-action.js +109 -27
  472. package/dist/client/use-action.js.map +1 -1
  473. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  474. package/dist/client/use-agent-engine-configured.js +7 -1
  475. package/dist/client/use-agent-engine-configured.js.map +1 -1
  476. package/dist/client/use-chat-threads.d.ts.map +1 -1
  477. package/dist/client/use-chat-threads.js +11 -3
  478. package/dist/client/use-chat-threads.js.map +1 -1
  479. package/dist/client/use-db-sync.d.ts +36 -0
  480. package/dist/client/use-db-sync.d.ts.map +1 -1
  481. package/dist/client/use-db-sync.js +68 -12
  482. package/dist/client/use-db-sync.js.map +1 -1
  483. package/dist/client/visual-style-controls.d.ts +79 -0
  484. package/dist/client/visual-style-controls.d.ts.map +1 -0
  485. package/dist/client/visual-style-controls.js +150 -0
  486. package/dist/client/visual-style-controls.js.map +1 -0
  487. package/dist/collab/agent-presence.d.ts +51 -5
  488. package/dist/collab/agent-presence.d.ts.map +1 -1
  489. package/dist/collab/agent-presence.js +144 -58
  490. package/dist/collab/agent-presence.js.map +1 -1
  491. package/dist/collab/awareness-store.d.ts +32 -0
  492. package/dist/collab/awareness-store.d.ts.map +1 -0
  493. package/dist/collab/awareness-store.js +0 -0
  494. package/dist/collab/awareness-store.js.map +1 -0
  495. package/dist/collab/awareness.d.ts +12 -1
  496. package/dist/collab/awareness.d.ts.map +1 -1
  497. package/dist/collab/awareness.js +53 -5
  498. package/dist/collab/awareness.js.map +1 -1
  499. package/dist/collab/client.d.ts +2 -0
  500. package/dist/collab/client.d.ts.map +1 -1
  501. package/dist/collab/client.js +79 -119
  502. package/dist/collab/client.js.map +1 -1
  503. package/dist/collab/index.d.ts +3 -1
  504. package/dist/collab/index.d.ts.map +1 -1
  505. package/dist/collab/index.js +5 -1
  506. package/dist/collab/index.js.map +1 -1
  507. package/dist/collab/recent-edits.d.ts +87 -0
  508. package/dist/collab/recent-edits.d.ts.map +1 -0
  509. package/dist/collab/recent-edits.js +116 -0
  510. package/dist/collab/recent-edits.js.map +1 -0
  511. package/dist/collab/routes.d.ts +2 -2
  512. package/dist/collab/struct-routes.d.ts +1 -1
  513. package/dist/collab/undo.d.ts +121 -0
  514. package/dist/collab/undo.d.ts.map +1 -0
  515. package/dist/collab/undo.js +244 -0
  516. package/dist/collab/undo.js.map +1 -0
  517. package/dist/collab/ydoc-manager.d.ts +10 -0
  518. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  519. package/dist/collab/ydoc-manager.js +57 -0
  520. package/dist/collab/ydoc-manager.js.map +1 -1
  521. package/dist/connections/catalog.d.ts +2 -2
  522. package/dist/connections/catalog.d.ts.map +1 -1
  523. package/dist/connections/catalog.js +1 -1
  524. package/dist/connections/catalog.js.map +1 -1
  525. package/dist/db/create-get-db.d.ts +22 -0
  526. package/dist/db/create-get-db.d.ts.map +1 -1
  527. package/dist/db/create-get-db.js +73 -1
  528. package/dist/db/create-get-db.js.map +1 -1
  529. package/dist/db/ensure-additive-columns.d.ts +93 -0
  530. package/dist/db/ensure-additive-columns.d.ts.map +1 -0
  531. package/dist/db/ensure-additive-columns.js +355 -0
  532. package/dist/db/ensure-additive-columns.js.map +1 -0
  533. package/dist/db/index.d.ts +1 -0
  534. package/dist/db/index.d.ts.map +1 -1
  535. package/dist/db/index.js +1 -0
  536. package/dist/db/index.js.map +1 -1
  537. package/dist/db/migrations.d.ts +70 -0
  538. package/dist/db/migrations.d.ts.map +1 -1
  539. package/dist/db/migrations.js +196 -33
  540. package/dist/db/migrations.js.map +1 -1
  541. package/dist/jobs/scheduler.js +17 -10
  542. package/dist/jobs/scheduler.js.map +1 -1
  543. package/dist/notifications/routes.d.ts +3 -3
  544. package/dist/observability/routes.d.ts +2 -2
  545. package/dist/observability/traces.d.ts.map +1 -1
  546. package/dist/observability/traces.js +155 -1
  547. package/dist/observability/traces.js.map +1 -1
  548. package/dist/org/context.d.ts +7 -0
  549. package/dist/org/context.d.ts.map +1 -1
  550. package/dist/org/context.js +54 -2
  551. package/dist/org/context.js.map +1 -1
  552. package/dist/resources/handlers.d.ts +1 -1
  553. package/dist/secrets/routes.d.ts +9 -9
  554. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  555. package/dist/server/agent-chat-plugin.js +10 -6
  556. package/dist/server/agent-chat-plugin.js.map +1 -1
  557. package/dist/server/auth-marketing.d.ts.map +1 -1
  558. package/dist/server/auth-marketing.js +0 -10
  559. package/dist/server/auth-marketing.js.map +1 -1
  560. package/dist/server/auth.d.ts.map +1 -1
  561. package/dist/server/auth.js +6 -4
  562. package/dist/server/auth.js.map +1 -1
  563. package/dist/server/collab-plugin.d.ts.map +1 -1
  564. package/dist/server/collab-plugin.js +45 -13
  565. package/dist/server/collab-plugin.js.map +1 -1
  566. package/dist/server/design-token-utils.d.ts +1 -1
  567. package/dist/server/design-token-utils.js +1 -1
  568. package/dist/server/design-token-utils.js.map +1 -1
  569. package/dist/server/fusion-app.d.ts +107 -0
  570. package/dist/server/fusion-app.d.ts.map +1 -0
  571. package/dist/server/fusion-app.js +371 -0
  572. package/dist/server/fusion-app.js.map +1 -0
  573. package/dist/server/index.d.ts +1 -0
  574. package/dist/server/index.d.ts.map +1 -1
  575. package/dist/server/index.js +1 -0
  576. package/dist/server/index.js.map +1 -1
  577. package/dist/server/onboarding-html.d.ts.map +1 -1
  578. package/dist/server/onboarding-html.js +3 -4
  579. package/dist/server/onboarding-html.js.map +1 -1
  580. package/dist/server/poll-events.d.ts +2 -0
  581. package/dist/server/poll-events.d.ts.map +1 -1
  582. package/dist/server/poll-events.js +7 -2
  583. package/dist/server/poll-events.js.map +1 -1
  584. package/dist/server/poll.d.ts +47 -3
  585. package/dist/server/poll.d.ts.map +1 -1
  586. package/dist/server/poll.js +176 -10
  587. package/dist/server/poll.js.map +1 -1
  588. package/dist/server/schema-prompt.d.ts.map +1 -1
  589. package/dist/server/schema-prompt.js +24 -7
  590. package/dist/server/schema-prompt.js.map +1 -1
  591. package/dist/server/transcribe-voice.d.ts +1 -1
  592. package/dist/settings/store.d.ts.map +1 -1
  593. package/dist/settings/store.js +32 -3
  594. package/dist/settings/store.js.map +1 -1
  595. package/dist/sharing/actions/set-resource-visibility.js +2 -0
  596. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  597. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  598. package/dist/sharing/actions/share-resource.js +3 -0
  599. package/dist/sharing/actions/share-resource.js.map +1 -1
  600. package/dist/sharing/actions/unshare-resource.js +2 -0
  601. package/dist/sharing/actions/unshare-resource.js.map +1 -1
  602. package/dist/styles/agent-native.css +0 -5
  603. package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
  604. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
  605. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
  606. package/dist/templates/default/package.json +3 -3
  607. package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
  608. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
  609. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
  610. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
  611. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
  612. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
  613. package/dist/tracking/providers.d.ts.map +1 -1
  614. package/dist/tracking/providers.js +17 -1
  615. package/dist/tracking/providers.js.map +1 -1
  616. package/docs/content/cloneable-saas.mdx +0 -1
  617. package/docs/content/locales/ar-SA/cloneable-saas.mdx +0 -1
  618. package/docs/content/locales/ar-SA/plan-plugin.mdx +10 -9
  619. package/docs/content/locales/ar-SA/sharing.mdx +1 -2
  620. package/docs/content/locales/ar-SA/skills-guide.mdx +2 -3
  621. package/docs/content/locales/ar-SA/template-plan.mdx +23 -7
  622. package/docs/content/locales/ar-SA/tracking.mdx +1 -1
  623. package/docs/content/locales/ar-SA/workspace-connections.mdx +11 -11
  624. package/docs/content/locales/de-DE/cloneable-saas.mdx +0 -1
  625. package/docs/content/locales/de-DE/plan-plugin.mdx +10 -9
  626. package/docs/content/locales/de-DE/sharing.mdx +1 -2
  627. package/docs/content/locales/de-DE/skills-guide.mdx +2 -3
  628. package/docs/content/locales/de-DE/template-plan.mdx +23 -7
  629. package/docs/content/locales/de-DE/tracking.mdx +1 -1
  630. package/docs/content/locales/de-DE/workspace-connections.mdx +1 -1
  631. package/docs/content/locales/es-ES/cloneable-saas.mdx +0 -1
  632. package/docs/content/locales/es-ES/plan-plugin.mdx +10 -9
  633. package/docs/content/locales/es-ES/sharing.mdx +1 -2
  634. package/docs/content/locales/es-ES/skills-guide.mdx +2 -3
  635. package/docs/content/locales/es-ES/template-plan.mdx +23 -7
  636. package/docs/content/locales/es-ES/tracking.mdx +1 -1
  637. package/docs/content/locales/es-ES/workspace-connections.mdx +1 -1
  638. package/docs/content/locales/fr-FR/cloneable-saas.mdx +0 -1
  639. package/docs/content/locales/fr-FR/plan-plugin.mdx +10 -9
  640. package/docs/content/locales/fr-FR/sharing.mdx +1 -2
  641. package/docs/content/locales/fr-FR/skills-guide.mdx +2 -3
  642. package/docs/content/locales/fr-FR/template-plan.mdx +23 -7
  643. package/docs/content/locales/fr-FR/tracking.mdx +1 -1
  644. package/docs/content/locales/fr-FR/workspace-connections.mdx +1 -1
  645. package/docs/content/locales/hi-IN/cloneable-saas.mdx +0 -1
  646. package/docs/content/locales/hi-IN/plan-plugin.mdx +10 -9
  647. package/docs/content/locales/hi-IN/sharing.mdx +1 -2
  648. package/docs/content/locales/hi-IN/skills-guide.mdx +2 -3
  649. package/docs/content/locales/hi-IN/template-plan.mdx +23 -7
  650. package/docs/content/locales/hi-IN/tracking.mdx +1 -1
  651. package/docs/content/locales/hi-IN/workspace-connections.mdx +1 -1
  652. package/docs/content/locales/ja-JP/cloneable-saas.mdx +0 -1
  653. package/docs/content/locales/ja-JP/plan-plugin.mdx +10 -9
  654. package/docs/content/locales/ja-JP/sharing.mdx +1 -2
  655. package/docs/content/locales/ja-JP/skills-guide.mdx +2 -3
  656. package/docs/content/locales/ja-JP/template-plan.mdx +23 -7
  657. package/docs/content/locales/ja-JP/tracking.mdx +1 -1
  658. package/docs/content/locales/ja-JP/workspace-connections.mdx +1 -1
  659. package/docs/content/locales/ko-KR/cloneable-saas.mdx +0 -1
  660. package/docs/content/locales/ko-KR/plan-plugin.mdx +10 -9
  661. package/docs/content/locales/ko-KR/sharing.mdx +1 -2
  662. package/docs/content/locales/ko-KR/skills-guide.mdx +2 -3
  663. package/docs/content/locales/ko-KR/template-plan.mdx +23 -7
  664. package/docs/content/locales/ko-KR/tracking.mdx +1 -1
  665. package/docs/content/locales/ko-KR/workspace-connections.mdx +1 -1
  666. package/docs/content/locales/pt-BR/cloneable-saas.mdx +0 -1
  667. package/docs/content/locales/pt-BR/plan-plugin.mdx +10 -9
  668. package/docs/content/locales/pt-BR/sharing.mdx +1 -2
  669. package/docs/content/locales/pt-BR/skills-guide.mdx +2 -3
  670. package/docs/content/locales/pt-BR/template-plan.mdx +23 -7
  671. package/docs/content/locales/pt-BR/tracking.mdx +1 -1
  672. package/docs/content/locales/pt-BR/workspace-connections.mdx +1 -1
  673. package/docs/content/locales/zh-CN/cloneable-saas.mdx +0 -1
  674. package/docs/content/locales/zh-CN/plan-plugin.mdx +10 -9
  675. package/docs/content/locales/zh-CN/sharing.mdx +1 -2
  676. package/docs/content/locales/zh-CN/skills-guide.mdx +2 -3
  677. package/docs/content/locales/zh-CN/template-plan.mdx +23 -7
  678. package/docs/content/locales/zh-CN/tracking.mdx +1 -1
  679. package/docs/content/locales/zh-CN/workspace-connections.mdx +1 -1
  680. package/docs/content/locales/zh-TW/cloneable-saas.mdx +0 -1
  681. package/docs/content/locales/zh-TW/plan-plugin.mdx +10 -9
  682. package/docs/content/locales/zh-TW/sharing.mdx +1 -2
  683. package/docs/content/locales/zh-TW/skills-guide.mdx +2 -3
  684. package/docs/content/locales/zh-TW/template-plan.mdx +23 -7
  685. package/docs/content/locales/zh-TW/tracking.mdx +1 -1
  686. package/docs/content/locales/zh-TW/workspace-connections.mdx +1 -1
  687. package/docs/content/plan-plugin.mdx +12 -11
  688. package/docs/content/sharing.mdx +1 -2
  689. package/docs/content/skills-guide.mdx +4 -3
  690. package/docs/content/template-plan.mdx +37 -6
  691. package/docs/content/tracking.mdx +1 -1
  692. package/docs/content/workspace-connections.mdx +1 -1
  693. package/package.json +6 -6
  694. package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
  695. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
  696. package/src/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
  697. package/src/templates/default/package.json +3 -3
  698. package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
  699. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
  700. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
  701. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
  702. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
  703. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
  704. package/corpus/core/docs/content/locales/ar-SA/template-videos.mdx +0 -336
  705. package/corpus/core/docs/content/locales/de-DE/template-videos.mdx +0 -336
  706. package/corpus/core/docs/content/locales/es-ES/template-videos.mdx +0 -336
  707. package/corpus/core/docs/content/locales/fr-FR/template-videos.mdx +0 -336
  708. package/corpus/core/docs/content/locales/hi-IN/template-videos.mdx +0 -336
  709. package/corpus/core/docs/content/locales/ja-JP/template-videos.mdx +0 -336
  710. package/corpus/core/docs/content/locales/ko-KR/template-videos.mdx +0 -336
  711. package/corpus/core/docs/content/locales/pt-BR/template-videos.mdx +0 -336
  712. package/corpus/core/docs/content/locales/zh-CN/template-videos.mdx +0 -334
  713. package/corpus/core/docs/content/locales/zh-TW/template-videos.mdx +0 -334
  714. package/corpus/core/docs/content/template-videos.mdx +0 -332
  715. package/corpus/templates/design/app/components/design/CodeWorkbenchHost.tsx +0 -697
  716. package/corpus/templates/slides/app/components/editor/CodeEditor.tsx +0 -49
  717. package/corpus/templates/videos/.agents/skills/actions/SKILL.md +0 -432
  718. package/corpus/templates/videos/.agents/skills/animation-tracks/SKILL.md +0 -99
  719. package/corpus/templates/videos/.agents/skills/capture-learnings/SKILL.md +0 -76
  720. package/corpus/templates/videos/.agents/skills/composition-management/SKILL.md +0 -106
  721. package/corpus/templates/videos/.agents/skills/create-skill/SKILL.md +0 -221
  722. package/corpus/templates/videos/.agents/skills/delegate-to-agent/SKILL.md +0 -263
  723. package/corpus/templates/videos/.agents/skills/frontend-design/SKILL.md +0 -112
  724. package/corpus/templates/videos/.agents/skills/security/SKILL.md +0 -263
  725. package/corpus/templates/videos/.agents/skills/self-modifying-code/SKILL.md +0 -88
  726. package/corpus/templates/videos/.agents/skills/shadcn-ui/SKILL.md +0 -95
  727. package/corpus/templates/videos/.builder/ANIMATED_PROPERTIES.md +0 -335
  728. package/corpus/templates/videos/.builder/KEYFRAME_SYNC.md +0 -166
  729. package/corpus/templates/videos/.builder/SEAMLESS_SYNC.md +0 -211
  730. package/corpus/templates/videos/.builder/rules/deploy-app.mdc +0 -22
  731. package/corpus/templates/videos/.builder/rules/organize-ui.mdc +0 -9
  732. package/corpus/templates/videos/.builder/skills/remotion/SKILL.md +0 -29
  733. package/corpus/templates/videos/.builder/skills/remotion/rules/animations.md +0 -27
  734. package/corpus/templates/videos/.builder/skills/remotion/rules/assets.md +0 -43
  735. package/corpus/templates/videos/.builder/skills/remotion/rules/audio.md +0 -58
  736. package/corpus/templates/videos/.builder/skills/remotion/rules/compositions.md +0 -129
  737. package/corpus/templates/videos/.builder/skills/remotion/rules/fonts.md +0 -47
  738. package/corpus/templates/videos/.builder/skills/remotion/rules/images.md +0 -41
  739. package/corpus/templates/videos/.builder/skills/remotion/rules/parameters.md +0 -59
  740. package/corpus/templates/videos/.builder/skills/remotion/rules/sequencing.md +0 -54
  741. package/corpus/templates/videos/.builder/skills/remotion/rules/tailwind.md +0 -11
  742. package/corpus/templates/videos/.builder/skills/remotion/rules/text-animations.md +0 -18
  743. package/corpus/templates/videos/.builder/skills/remotion/rules/timing.md +0 -103
  744. package/corpus/templates/videos/.builder/skills/remotion/rules/transparent-videos.md +0 -35
  745. package/corpus/templates/videos/.builder/skills/remotion/rules/trimming.md +0 -38
  746. package/corpus/templates/videos/.builder/skills/remotion/rules/videos.md +0 -54
  747. package/corpus/templates/videos/.dockerignore +0 -62
  748. package/corpus/templates/videos/.env.example +0 -4
  749. package/corpus/templates/videos/.oxfmtrc.json +0 -8
  750. package/corpus/templates/videos/AGENTS.md +0 -46
  751. package/corpus/templates/videos/CHANGELOG.md +0 -10
  752. package/corpus/templates/videos/DEVELOPING.md +0 -143
  753. package/corpus/templates/videos/README.md +0 -33
  754. package/corpus/templates/videos/actions/analyze-brand-assets.ts +0 -151
  755. package/corpus/templates/videos/actions/apply-design-system.ts +0 -35
  756. package/corpus/templates/videos/actions/create-design-system.ts +0 -84
  757. package/corpus/templates/videos/actions/create-folder.ts +0 -48
  758. package/corpus/templates/videos/actions/db-connect.ts +0 -45
  759. package/corpus/templates/videos/actions/db-health.ts +0 -24
  760. package/corpus/templates/videos/actions/db-status.ts +0 -28
  761. package/corpus/templates/videos/actions/delete-composition.ts +0 -272
  762. package/corpus/templates/videos/actions/delete-folder.ts +0 -27
  763. package/corpus/templates/videos/actions/generate-animated-component.ts +0 -470
  764. package/corpus/templates/videos/actions/get-composition.ts +0 -36
  765. package/corpus/templates/videos/actions/get-design-system.ts +0 -35
  766. package/corpus/templates/videos/actions/import-code.ts +0 -67
  767. package/corpus/templates/videos/actions/import-design-project.ts +0 -42
  768. package/corpus/templates/videos/actions/import-document.ts +0 -125
  769. package/corpus/templates/videos/actions/import-from-url.ts +0 -18
  770. package/corpus/templates/videos/actions/import-github.ts +0 -182
  771. package/corpus/templates/videos/actions/list-compositions.ts +0 -32
  772. package/corpus/templates/videos/actions/list-design-systems.ts +0 -66
  773. package/corpus/templates/videos/actions/list-folders.ts +0 -61
  774. package/corpus/templates/videos/actions/move-composition-to-folder.ts +0 -59
  775. package/corpus/templates/videos/actions/navigate.ts +0 -40
  776. package/corpus/templates/videos/actions/rename-folder.ts +0 -41
  777. package/corpus/templates/videos/actions/run.ts +0 -2
  778. package/corpus/templates/videos/actions/save-composition.ts +0 -114
  779. package/corpus/templates/videos/actions/set-default-design-system.ts +0 -40
  780. package/corpus/templates/videos/actions/update-composition.ts +0 -81
  781. package/corpus/templates/videos/actions/update-design-system.ts +0 -68
  782. package/corpus/templates/videos/actions/validate-compositions.ts +0 -502
  783. package/corpus/templates/videos/actions/view-screen.ts +0 -48
  784. package/corpus/templates/videos/app/components/CameraControls.tsx +0 -442
  785. package/corpus/templates/videos/app/components/CameraToolbar.tsx +0 -437
  786. package/corpus/templates/videos/app/components/CloudUpgrade.tsx +0 -287
  787. package/corpus/templates/videos/app/components/CollabPresenceBar.tsx +0 -81
  788. package/corpus/templates/videos/app/components/CompSettingsEditor.tsx +0 -107
  789. package/corpus/templates/videos/app/components/ComponentLibrarySidebar.tsx +0 -457
  790. package/corpus/templates/videos/app/components/ComponentPropsPanel.tsx +0 -227
  791. package/corpus/templates/videos/app/components/ComponentsSidebar.tsx +0 -70
  792. package/corpus/templates/videos/app/components/CompositionCard.tsx +0 -147
  793. package/corpus/templates/videos/app/components/CurrentElementPanel.tsx +0 -835
  794. package/corpus/templates/videos/app/components/CursorControls.tsx +0 -664
  795. package/corpus/templates/videos/app/components/CursorPositioningOverlay.tsx +0 -238
  796. package/corpus/templates/videos/app/components/LibraryFolderRow.tsx +0 -235
  797. package/corpus/templates/videos/app/components/MotionCurveSelect.tsx +0 -61
  798. package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +0 -192
  799. package/corpus/templates/videos/app/components/PropsEditor.tsx +0 -210
  800. package/corpus/templates/videos/app/components/QuestionFlow.tsx +0 -40
  801. package/corpus/templates/videos/app/components/Sidebar.tsx +0 -609
  802. package/corpus/templates/videos/app/components/StudioHeader.tsx +0 -109
  803. package/corpus/templates/videos/app/components/Timeline.tsx +0 -2067
  804. package/corpus/templates/videos/app/components/TrackPropertiesPanel.tsx +0 -922
  805. package/corpus/templates/videos/app/components/TweaksPanel.tsx +0 -277
  806. package/corpus/templates/videos/app/components/VideoPlayer.tsx +0 -487
  807. package/corpus/templates/videos/app/components/design-system/DesignSystemCard.tsx +0 -134
  808. package/corpus/templates/videos/app/components/design-system/DesignSystemPreview.tsx +0 -176
  809. package/corpus/templates/videos/app/components/design-system/DesignSystemSetup.tsx +0 -707
  810. package/corpus/templates/videos/app/components/keyframes/KeyframeActionButtons.tsx +0 -78
  811. package/corpus/templates/videos/app/components/keyframes/KeyframeNavigation.tsx +0 -59
  812. package/corpus/templates/videos/app/components/keyframes/PropertyNumberInput.tsx +0 -56
  813. package/corpus/templates/videos/app/components/layout/Header.tsx +0 -64
  814. package/corpus/templates/videos/app/components/layout/HeaderActions.tsx +0 -84
  815. package/corpus/templates/videos/app/components/layout/Layout.tsx +0 -132
  816. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -180
  817. package/corpus/templates/videos/app/components/ui/accordion.tsx +0 -56
  818. package/corpus/templates/videos/app/components/ui/alert-dialog.tsx +0 -139
  819. package/corpus/templates/videos/app/components/ui/alert.tsx +0 -59
  820. package/corpus/templates/videos/app/components/ui/aspect-ratio.tsx +0 -5
  821. package/corpus/templates/videos/app/components/ui/avatar.tsx +0 -48
  822. package/corpus/templates/videos/app/components/ui/badge.tsx +0 -37
  823. package/corpus/templates/videos/app/components/ui/breadcrumb.tsx +0 -115
  824. package/corpus/templates/videos/app/components/ui/button.tsx +0 -57
  825. package/corpus/templates/videos/app/components/ui/calendar.tsx +0 -68
  826. package/corpus/templates/videos/app/components/ui/card.tsx +0 -86
  827. package/corpus/templates/videos/app/components/ui/carousel.tsx +0 -260
  828. package/corpus/templates/videos/app/components/ui/chart.tsx +0 -375
  829. package/corpus/templates/videos/app/components/ui/checkbox.tsx +0 -28
  830. package/corpus/templates/videos/app/components/ui/collapsible.tsx +0 -9
  831. package/corpus/templates/videos/app/components/ui/command.tsx +0 -154
  832. package/corpus/templates/videos/app/components/ui/context-menu.tsx +0 -202
  833. package/corpus/templates/videos/app/components/ui/dialog.tsx +0 -130
  834. package/corpus/templates/videos/app/components/ui/drawer.tsx +0 -116
  835. package/corpus/templates/videos/app/components/ui/dropdown-menu.tsx +0 -212
  836. package/corpus/templates/videos/app/components/ui/form.tsx +0 -177
  837. package/corpus/templates/videos/app/components/ui/hover-card.tsx +0 -27
  838. package/corpus/templates/videos/app/components/ui/input-otp.tsx +0 -69
  839. package/corpus/templates/videos/app/components/ui/input.tsx +0 -22
  840. package/corpus/templates/videos/app/components/ui/label.tsx +0 -24
  841. package/corpus/templates/videos/app/components/ui/menubar.tsx +0 -234
  842. package/corpus/templates/videos/app/components/ui/navigation-menu.tsx +0 -128
  843. package/corpus/templates/videos/app/components/ui/pagination.tsx +0 -121
  844. package/corpus/templates/videos/app/components/ui/popover.tsx +0 -44
  845. package/corpus/templates/videos/app/components/ui/progress.tsx +0 -26
  846. package/corpus/templates/videos/app/components/ui/radio-group.tsx +0 -42
  847. package/corpus/templates/videos/app/components/ui/resizable.tsx +0 -43
  848. package/corpus/templates/videos/app/components/ui/scroll-area.tsx +0 -46
  849. package/corpus/templates/videos/app/components/ui/select.tsx +0 -158
  850. package/corpus/templates/videos/app/components/ui/separator.tsx +0 -29
  851. package/corpus/templates/videos/app/components/ui/sheet.tsx +0 -160
  852. package/corpus/templates/videos/app/components/ui/sidebar.tsx +0 -782
  853. package/corpus/templates/videos/app/components/ui/skeleton.tsx +0 -15
  854. package/corpus/templates/videos/app/components/ui/slider.tsx +0 -26
  855. package/corpus/templates/videos/app/components/ui/sonner.tsx +0 -58
  856. package/corpus/templates/videos/app/components/ui/spinner.tsx +0 -17
  857. package/corpus/templates/videos/app/components/ui/switch.tsx +0 -27
  858. package/corpus/templates/videos/app/components/ui/table.tsx +0 -117
  859. package/corpus/templates/videos/app/components/ui/tabs.tsx +0 -53
  860. package/corpus/templates/videos/app/components/ui/textarea.tsx +0 -23
  861. package/corpus/templates/videos/app/components/ui/toast.tsx +0 -127
  862. package/corpus/templates/videos/app/components/ui/toaster.tsx +0 -33
  863. package/corpus/templates/videos/app/components/ui/toggle-group.tsx +0 -59
  864. package/corpus/templates/videos/app/components/ui/toggle.tsx +0 -43
  865. package/corpus/templates/videos/app/components/ui/tooltip.tsx +0 -30
  866. package/corpus/templates/videos/app/components/ui/use-toast.ts +0 -3
  867. package/corpus/templates/videos/app/config/constants.ts +0 -204
  868. package/corpus/templates/videos/app/contexts/CompositionContext.tsx +0 -437
  869. package/corpus/templates/videos/app/contexts/CurrentElementContext.tsx +0 -247
  870. package/corpus/templates/videos/app/contexts/PlaybackContext.tsx +0 -65
  871. package/corpus/templates/videos/app/contexts/TimelineContext.tsx +0 -433
  872. package/corpus/templates/videos/app/entry.client.tsx +0 -19
  873. package/corpus/templates/videos/app/entry.server.tsx +0 -10
  874. package/corpus/templates/videos/app/global.css +0 -171
  875. package/corpus/templates/videos/app/hooks/use-composition-collab.ts +0 -269
  876. package/corpus/templates/videos/app/hooks/use-composition-design-system.ts +0 -47
  877. package/corpus/templates/videos/app/hooks/use-database-compositions.ts +0 -144
  878. package/corpus/templates/videos/app/hooks/use-db-status.ts +0 -30
  879. package/corpus/templates/videos/app/hooks/use-design-systems.ts +0 -21
  880. package/corpus/templates/videos/app/hooks/use-folders.ts +0 -199
  881. package/corpus/templates/videos/app/hooks/use-mobile.tsx +0 -21
  882. package/corpus/templates/videos/app/hooks/use-navigation-state.ts +0 -52
  883. package/corpus/templates/videos/app/hooks/use-question-flow.ts +0 -14
  884. package/corpus/templates/videos/app/hooks/use-toast.ts +0 -188
  885. package/corpus/templates/videos/app/hooks/useUnsavedChanges.ts +0 -48
  886. package/corpus/templates/videos/app/i18n/ar-SA.ts +0 -446
  887. package/corpus/templates/videos/app/i18n/de-DE.ts +0 -470
  888. package/corpus/templates/videos/app/i18n/en-US.ts +0 -452
  889. package/corpus/templates/videos/app/i18n/es-ES.ts +0 -468
  890. package/corpus/templates/videos/app/i18n/fr-FR.ts +0 -469
  891. package/corpus/templates/videos/app/i18n/hi-IN.ts +0 -446
  892. package/corpus/templates/videos/app/i18n/index.ts +0 -34
  893. package/corpus/templates/videos/app/i18n/ja-JP.ts +0 -460
  894. package/corpus/templates/videos/app/i18n/ko-KR.ts +0 -453
  895. package/corpus/templates/videos/app/i18n/pt-BR.ts +0 -461
  896. package/corpus/templates/videos/app/i18n/zh-CN.ts +0 -437
  897. package/corpus/templates/videos/app/i18n/zh-TW.ts +0 -437
  898. package/corpus/templates/videos/app/lib/database-compositions.ts +0 -67
  899. package/corpus/templates/videos/app/lib/design-systems.ts +0 -234
  900. package/corpus/templates/videos/app/lib/tab-id.ts +0 -1
  901. package/corpus/templates/videos/app/lib/utils.ts +0 -1
  902. package/corpus/templates/videos/app/pages/ComponentLibrary.tsx +0 -134
  903. package/corpus/templates/videos/app/pages/ComponentLibraryView.tsx +0 -362
  904. package/corpus/templates/videos/app/pages/CompositionView.tsx +0 -715
  905. package/corpus/templates/videos/app/pages/DesignSystems.tsx +0 -180
  906. package/corpus/templates/videos/app/pages/Index.tsx +0 -258
  907. package/corpus/templates/videos/app/pages/NewComposition.tsx +0 -95
  908. package/corpus/templates/videos/app/pages/NotFound.tsx +0 -36
  909. package/corpus/templates/videos/app/remotion/CameraHost.tsx +0 -223
  910. package/corpus/templates/videos/app/remotion/animations/useElementAnimations.ts +0 -231
  911. package/corpus/templates/videos/app/remotion/componentRegistry.ts +0 -473
  912. package/corpus/templates/videos/app/remotion/components/AnimatedElement.tsx +0 -436
  913. package/corpus/templates/videos/app/remotion/components/InteractiveElement.tsx +0 -159
  914. package/corpus/templates/videos/app/remotion/components/InteractiveZoneEditor.tsx +0 -273
  915. package/corpus/templates/videos/app/remotion/compositions/BlankComposition.tsx +0 -204
  916. package/corpus/templates/videos/app/remotion/compositions/index.ts +0 -2
  917. package/corpus/templates/videos/app/remotion/createComponentCursorTrack.ts +0 -132
  918. package/corpus/templates/videos/app/remotion/docs/CURSOR_TRACKS.md +0 -285
  919. package/corpus/templates/videos/app/remotion/easingFunctions.ts +0 -255
  920. package/corpus/templates/videos/app/remotion/hooks/createInteractiveComposition.tsx +0 -283
  921. package/corpus/templates/videos/app/remotion/hooks/useCursorHistory.ts +0 -72
  922. package/corpus/templates/videos/app/remotion/hooks/useCursorTypeFromHover.ts +0 -35
  923. package/corpus/templates/videos/app/remotion/hooks/useEditableZones.tsx +0 -267
  924. package/corpus/templates/videos/app/remotion/hooks/useHoverAnimation.ts +0 -90
  925. package/corpus/templates/videos/app/remotion/hooks/useHoverAnimationSmooth.ts +0 -146
  926. package/corpus/templates/videos/app/remotion/hooks/useInteractiveComponent.ts +0 -711
  927. package/corpus/templates/videos/app/remotion/hooks/useRegisterInteractiveElement.ts +0 -56
  928. package/corpus/templates/videos/app/remotion/library-components/Button.tsx +0 -252
  929. package/corpus/templates/videos/app/remotion/library-components/Card.tsx +0 -241
  930. package/corpus/templates/videos/app/remotion/library-components/CodePanel.tsx +0 -1005
  931. package/corpus/templates/videos/app/remotion/library-components/FileItem.tsx +0 -196
  932. package/corpus/templates/videos/app/remotion/library-components/FolderItem.tsx +0 -199
  933. package/corpus/templates/videos/app/remotion/library-components/PrimaryButton.tsx +0 -177
  934. package/corpus/templates/videos/app/remotion/library-components/SecondaryButton.tsx +0 -167
  935. package/corpus/templates/videos/app/remotion/library-components/SectionHeader.tsx +0 -108
  936. package/corpus/templates/videos/app/remotion/library-components/TEMPLATE.tsx +0 -211
  937. package/corpus/templates/videos/app/remotion/library-components/index.ts +0 -10
  938. package/corpus/templates/videos/app/remotion/registry.ts +0 -91
  939. package/corpus/templates/videos/app/remotion/testing/animationTestUtils.ts +0 -366
  940. package/corpus/templates/videos/app/remotion/trackAnimation.ts +0 -179
  941. package/corpus/templates/videos/app/remotion/trackHelpers.ts +0 -110
  942. package/corpus/templates/videos/app/remotion/ui-components/Cursor.tsx +0 -182
  943. package/corpus/templates/videos/app/remotion/ui-components/InteractiveButton.tsx +0 -116
  944. package/corpus/templates/videos/app/remotion/ui-components/InteractiveCard.tsx +0 -126
  945. package/corpus/templates/videos/app/remotion/ui-components/index.ts +0 -16
  946. package/corpus/templates/videos/app/remotion/utils/animationHelpers.ts +0 -444
  947. package/corpus/templates/videos/app/remotion/utils/interactiveElements.ts +0 -235
  948. package/corpus/templates/videos/app/remotion/utils/springAnimation.ts +0 -76
  949. package/corpus/templates/videos/app/root.tsx +0 -165
  950. package/corpus/templates/videos/app/routes/$.tsx +0 -10
  951. package/corpus/templates/videos/app/routes/_index.tsx +0 -25
  952. package/corpus/templates/videos/app/routes/c.$compositionId.tsx +0 -10
  953. package/corpus/templates/videos/app/routes/components.tsx +0 -10
  954. package/corpus/templates/videos/app/routes/design-systems.tsx +0 -10
  955. package/corpus/templates/videos/app/routes/extensions.$id.$slug.tsx +0 -2
  956. package/corpus/templates/videos/app/routes/extensions.$id.tsx +0 -5
  957. package/corpus/templates/videos/app/routes/extensions._index.tsx +0 -5
  958. package/corpus/templates/videos/app/routes/extensions.tsx +0 -5
  959. package/corpus/templates/videos/app/routes/settings.tsx +0 -88
  960. package/corpus/templates/videos/app/routes/team.tsx +0 -11
  961. package/corpus/templates/videos/app/routes.ts +0 -4
  962. package/corpus/templates/videos/app/state.ts +0 -77
  963. package/corpus/templates/videos/app/types/elementAnimations.ts +0 -121
  964. package/corpus/templates/videos/app/types.ts +0 -200
  965. package/corpus/templates/videos/app/utils/compositionHelpers.ts +0 -445
  966. package/corpus/templates/videos/app/utils/debug.ts +0 -63
  967. package/corpus/templates/videos/app/utils/keyframeUtils.ts +0 -331
  968. package/corpus/templates/videos/app/utils/timelineCoordinates.ts +0 -79
  969. package/corpus/templates/videos/app/vite-env.d.ts +0 -6
  970. package/corpus/templates/videos/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
  971. package/corpus/templates/videos/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
  972. package/corpus/templates/videos/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
  973. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +0 -6
  974. package/corpus/templates/videos/changelog/2026-06-29-video-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
  975. package/corpus/templates/videos/components.json +0 -20
  976. package/corpus/templates/videos/data/sync-config.json +0 -3
  977. package/corpus/templates/videos/docs/examples/create-composition.example.ts +0 -128
  978. package/corpus/templates/videos/drizzle.config.ts +0 -3
  979. package/corpus/templates/videos/learnings.defaults.md +0 -5
  980. package/corpus/templates/videos/package.json +0 -114
  981. package/corpus/templates/videos/public/agent-native-icon-dark.svg +0 -10
  982. package/corpus/templates/videos/public/agent-native-icon-light.svg +0 -10
  983. package/corpus/templates/videos/public/agent-native-logo-dark.svg +0 -21
  984. package/corpus/templates/videos/public/agent-native-logo-light.svg +0 -21
  985. package/corpus/templates/videos/public/favicon.svg +0 -1
  986. package/corpus/templates/videos/public/icon-180.svg +0 -1
  987. package/corpus/templates/videos/public/icon-192.svg +0 -1
  988. package/corpus/templates/videos/public/icon-512.svg +0 -1
  989. package/corpus/templates/videos/public/manifest.json +0 -21
  990. package/corpus/templates/videos/public/placeholder.svg +0 -1
  991. package/corpus/templates/videos/public/robots.txt +0 -14
  992. package/corpus/templates/videos/react-router.config.ts +0 -7
  993. package/corpus/templates/videos/server/db/index.ts +0 -37
  994. package/corpus/templates/videos/server/db/schema.ts +0 -55
  995. package/corpus/templates/videos/server/middleware/auth.ts +0 -15
  996. package/corpus/templates/videos/server/plugins/agent-chat.ts +0 -29
  997. package/corpus/templates/videos/server/plugins/auth.ts +0 -14
  998. package/corpus/templates/videos/server/plugins/collab.ts +0 -11
  999. package/corpus/templates/videos/server/plugins/core-routes.ts +0 -22
  1000. package/corpus/templates/videos/server/plugins/db.ts +0 -160
  1001. package/corpus/templates/videos/server/routes/[...page].get.ts +0 -5
  1002. package/corpus/templates/videos/server/routes/[...page].head.ts +0 -1
  1003. package/corpus/templates/videos/server/routes/api/save-composition-defaults.post.ts +0 -274
  1004. package/corpus/templates/videos/shared/api.ts +0 -75
  1005. package/corpus/templates/videos/ssr-entry.ts +0 -15
  1006. package/corpus/templates/videos/tsconfig.json +0 -21
  1007. package/corpus/templates/videos/vite.config.ts +0 -19
  1008. package/corpus/templates/videos/vitest.config.ts +0 -16
  1009. package/docs/content/locales/ar-SA/template-videos.mdx +0 -336
  1010. package/docs/content/locales/de-DE/template-videos.mdx +0 -336
  1011. package/docs/content/locales/es-ES/template-videos.mdx +0 -336
  1012. package/docs/content/locales/fr-FR/template-videos.mdx +0 -336
  1013. package/docs/content/locales/hi-IN/template-videos.mdx +0 -336
  1014. package/docs/content/locales/ja-JP/template-videos.mdx +0 -336
  1015. package/docs/content/locales/ko-KR/template-videos.mdx +0 -336
  1016. package/docs/content/locales/pt-BR/template-videos.mdx +0 -336
  1017. package/docs/content/locales/zh-CN/template-videos.mdx +0 -334
  1018. package/docs/content/locales/zh-TW/template-videos.mdx +0 -334
  1019. package/docs/content/template-videos.mdx +0 -332
@@ -2,10 +2,13 @@ import { agentChat } from "@agent-native/core";
2
2
  import {
3
3
  AgentPresenceChip,
4
4
  agentNativePath,
5
+ RecentEditHighlights,
5
6
  sendToAgentChat,
7
+ setClientAppState,
6
8
  usePinchZoom,
7
9
  useT,
8
10
  useAvatarUrl,
11
+ type AttributedRecentEdit,
9
12
  type CollabUser,
10
13
  } from "@agent-native/core/client";
11
14
  import { appStateKeyForBrowserTab } from "@shared/app-state-tabs";
@@ -23,8 +26,6 @@ import {
23
26
  type MouseEvent as ReactMouseEvent,
24
27
  } from "react";
25
28
  import { createPortal } from "react-dom";
26
- import type { Awareness } from "y-protocols/awareness";
27
- import type * as Y from "yjs";
28
29
 
29
30
  import { ExcalidrawSlide } from "@/components/deck/ExcalidrawSlide";
30
31
  import SlideRenderer from "@/components/deck/SlideRenderer";
@@ -56,8 +57,12 @@ import { enterSelectionMode } from "@/root";
56
57
 
57
58
  import type { DesignSystemData } from "../../../shared/api";
58
59
  import { BlockBubbleMenu } from "./BlockBubbleMenu";
59
- import CodeEditor from "./CodeEditor";
60
60
  import ImageOverlay from "./ImageOverlay";
61
+ import {
62
+ SlideStyleInspector,
63
+ type SlideStylePatch,
64
+ type SlideStyleSnapshot,
65
+ } from "./SlideStyleInspector";
61
66
  import { SpeakerNotesPanel } from "./SpeakerNotesPanel";
62
67
 
63
68
  let builderIdCounter = 0;
@@ -197,6 +202,147 @@ function stripBuilderIds(html: string): string {
197
202
  return cleaned.replace(/\s*data-builder-id="[^"]*"/g, "");
198
203
  }
199
204
 
205
+ function cssPx(value: string): number {
206
+ const parsed = Number.parseFloat(value);
207
+ return Number.isFinite(parsed) ? parsed : 0;
208
+ }
209
+
210
+ function normalizedColor(value: string): string {
211
+ return value === "rgba(0, 0, 0, 0)" ? "transparent" : value;
212
+ }
213
+
214
+ function normalizedFontWeight(value: string): string {
215
+ if (value === "normal") return "400";
216
+ if (value === "bold") return "700";
217
+ const parsed = Number.parseInt(value, 10);
218
+ if (!Number.isFinite(parsed)) return "400";
219
+ if (parsed >= 700) return "700";
220
+ if (parsed >= 600) return "600";
221
+ if (parsed >= 500) return "500";
222
+ return "400";
223
+ }
224
+
225
+ function normalizedTextAlign(value: string): string {
226
+ if (value === "start") return "left";
227
+ if (value === "end") return "right";
228
+ return ["left", "center", "right", "justify"].includes(value)
229
+ ? value
230
+ : "left";
231
+ }
232
+
233
+ function stylePropertyName(property: string): string {
234
+ return property.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
235
+ }
236
+
237
+ function elementPathFromRoot(
238
+ root: HTMLElement,
239
+ element: HTMLElement,
240
+ ): number[] {
241
+ const path: number[] = [];
242
+ let current: HTMLElement | null = element;
243
+ while (current && current !== root) {
244
+ const parent: HTMLElement | null = current.parentElement;
245
+ if (!parent) return [];
246
+ path.unshift(Array.prototype.indexOf.call(parent.children, current));
247
+ current = parent;
248
+ }
249
+ return path;
250
+ }
251
+
252
+ function resolveElementPath(
253
+ root: HTMLElement | null,
254
+ path: number[],
255
+ ): HTMLElement | null {
256
+ let current: Element | null = root;
257
+ for (const index of path) {
258
+ if (!current?.children[index]) return null;
259
+ current = current.children[index];
260
+ }
261
+ return current instanceof HTMLElement ? current : null;
262
+ }
263
+
264
+ function buildStyleSnapshot(
265
+ element: HTMLElement,
266
+ selector: string,
267
+ ): SlideStyleSnapshot {
268
+ const computed = window.getComputedStyle(element);
269
+ const textPreview = (element.textContent ?? "").trim().slice(0, 80);
270
+ const fontSize = cssPx(computed.fontSize);
271
+ const rawLineHeight = cssPx(computed.lineHeight);
272
+ const lineHeight =
273
+ rawLineHeight > 0 && fontSize > 0
274
+ ? Number((rawLineHeight / fontSize).toFixed(2))
275
+ : 1.2;
276
+ const paddingLeft = cssPx(computed.paddingLeft);
277
+ const paddingRight = cssPx(computed.paddingRight);
278
+ const paddingTop = cssPx(computed.paddingTop);
279
+ const paddingBottom = cssPx(computed.paddingBottom);
280
+
281
+ return {
282
+ selector,
283
+ label: element.getAttribute("aria-label") || element.tagName.toLowerCase(),
284
+ tagName: element.tagName.toLowerCase(),
285
+ textPreview,
286
+ isText: element.tagName !== "IMG" && !!textPreview,
287
+ isImage: element.tagName === "IMG",
288
+ color: normalizedColor(computed.color),
289
+ backgroundColor: normalizedColor(computed.backgroundColor),
290
+ fontSize,
291
+ fontWeight: normalizedFontWeight(computed.fontWeight),
292
+ lineHeight,
293
+ textAlign: normalizedTextAlign(computed.textAlign),
294
+ opacity: Math.round(Number(computed.opacity || 1) * 100),
295
+ borderRadius: cssPx(computed.borderTopLeftRadius),
296
+ borderWidth: cssPx(computed.borderTopWidth),
297
+ borderColor: normalizedColor(computed.borderTopColor),
298
+ paddingX: Math.round((paddingLeft + paddingRight) / 2),
299
+ paddingY: Math.round((paddingTop + paddingBottom) / 2),
300
+ };
301
+ }
302
+
303
+ interface SlideSelectionItem {
304
+ selector: string;
305
+ text?: string;
306
+ kind?: string;
307
+ tagName?: string;
308
+ imageSrc?: string;
309
+ style?: Partial<SlideStyleSnapshot>;
310
+ }
311
+
312
+ interface SlidesSelectionState {
313
+ deckId?: string;
314
+ slideId: string;
315
+ slideIndex: number;
316
+ slideNumber: number;
317
+ mode: "single" | "multi" | "image" | "editing";
318
+ activeTool?: "select" | "draw" | "pin";
319
+ items: SlideSelectionItem[];
320
+ }
321
+
322
+ function syncSelectionToAppState(state: SlidesSelectionState | null) {
323
+ const slidesKeys = [
324
+ appStateKeyForBrowserTab("slides-selection", TAB_ID),
325
+ "slides-selection",
326
+ ];
327
+ const genericKeys = [
328
+ appStateKeyForBrowserTab("selection", TAB_ID),
329
+ "selection",
330
+ ];
331
+ for (const key of slidesKeys) {
332
+ setClientAppState(key, state, {
333
+ keepalive: true,
334
+ requestSource: TAB_ID,
335
+ }).catch(() => {});
336
+ }
337
+ const generic = state ? { items: state.items } : null;
338
+ for (const key of genericKeys) {
339
+ setClientAppState(key, generic, {
340
+ keepalive: true,
341
+ requestSource: TAB_ID,
342
+ }).catch(() => {});
343
+ }
344
+ }
345
+
200
346
  interface SlideEditorProps {
201
347
  slide: Slide;
202
348
  onUpdateSlide: (
@@ -207,7 +353,6 @@ interface SlideEditorProps {
207
353
  * navigable but contentEditable / image overlays don't activate.
208
354
  * Mirrors Google Slides' viewer experience. */
209
355
  readOnly?: boolean;
210
- activeTab: "visual" | "code";
211
356
  onGenerateImage: () => void;
212
357
  onOpenAssetLibrary: (replaceSrc: string) => void;
213
358
  onUploadImage: (replaceSrc: string) => void;
@@ -219,14 +364,13 @@ interface SlideEditorProps {
219
364
  position?: { x: number; y: number },
220
365
  ) => void;
221
366
  onToggleObjectFit: (imgSrc: string, newFit: string) => void;
222
- /** Yjs document for collaborative editing */
223
- ydoc?: Y.Doc | null;
224
- /** Yjs Awareness for cursor/presence sync */
225
- awareness?: Awareness | null;
226
367
  /** Current user display info for cursor caret */
227
368
  collabUser?: { name: string; color: string };
228
369
  /** True briefly when AI agent is making edits */
229
370
  agentActive?: boolean;
371
+ /** Lingering recent edits (e.g. agent edits) to highlight over the canvas
372
+ * when they target the currently-active slide. */
373
+ recentEdits?: AttributedRecentEdit[];
230
374
  /** Called when the user selects text and clicks the comment button */
231
375
  onComment?: (quotedText: string) => void;
232
376
  /** Zero-based index of the current slide */
@@ -351,6 +495,47 @@ function ImageSelectionOutline({ rect }: { rect: DOMRect }) {
351
495
  );
352
496
  }
353
497
 
498
+ function ElementSelectionOutline({ rect }: { rect: DOMRect }) {
499
+ const pad = 2;
500
+ const handle = 7;
501
+ const handleClass =
502
+ "absolute size-[7px] rounded-sm border border-background bg-[#609FF8] shadow-sm";
503
+ return createPortal(
504
+ <div
505
+ style={{
506
+ position: "fixed",
507
+ top: rect.top - pad,
508
+ left: rect.left - pad,
509
+ width: rect.width + pad * 2,
510
+ height: rect.height + pad * 2,
511
+ pointerEvents: "none",
512
+ zIndex: 51,
513
+ border: "1.5px solid #609FF8",
514
+ borderRadius: 3,
515
+ boxShadow: "0 0 0 1px rgba(96, 159, 248, 0.2)",
516
+ }}
517
+ >
518
+ <span
519
+ className={handleClass}
520
+ style={{ left: -handle / 2, top: -handle / 2 }}
521
+ />
522
+ <span
523
+ className={handleClass}
524
+ style={{ right: -handle / 2, top: -handle / 2 }}
525
+ />
526
+ <span
527
+ className={handleClass}
528
+ style={{ left: -handle / 2, bottom: -handle / 2 }}
529
+ />
530
+ <span
531
+ className={handleClass}
532
+ style={{ right: -handle / 2, bottom: -handle / 2 }}
533
+ />
534
+ </div>,
535
+ document.body,
536
+ );
537
+ }
538
+
354
539
  /** Outline rendered around a multi-select element */
355
540
  function MultiSelectOutline({ rect }: { rect: DOMRect }) {
356
541
  const pad = 1;
@@ -411,33 +596,6 @@ function rectsIntersect(
411
596
  );
412
597
  }
413
598
 
414
- /**
415
- * Push the multi-selection to application_state under "selection" so the
416
- * agent can read it. Empty array clears the key entirely.
417
- */
418
- function syncSelectionToAppState(
419
- items: Array<{ selector: string; text: string }>,
420
- ) {
421
- const url = agentNativePath("/_agent-native/application-state/selection");
422
- if (items.length === 0) {
423
- fetch(url, {
424
- method: "DELETE",
425
- keepalive: true,
426
- headers: { "X-Request-Source": TAB_ID },
427
- }).catch(() => {});
428
- return;
429
- }
430
- fetch(url, {
431
- method: "PUT",
432
- keepalive: true,
433
- headers: {
434
- "Content-Type": "application/json",
435
- "X-Request-Source": TAB_ID,
436
- },
437
- body: JSON.stringify({ items }),
438
- }).catch(() => {});
439
- }
440
-
441
599
  /**
442
600
  * Push the current slide's vertical-fit measurement to application_state.
443
601
  * Browser-tab requests read the tab-scoped key; the legacy global key stays
@@ -494,7 +652,6 @@ export default function SlideEditor({
494
652
  slide,
495
653
  onUpdateSlide,
496
654
  readOnly = false,
497
- activeTab,
498
655
  onGenerateImage,
499
656
  onOpenAssetLibrary,
500
657
  onUploadImage,
@@ -516,6 +673,7 @@ export default function SlideEditor({
516
673
  deckId,
517
674
  onInlineEditStart,
518
675
  presentUsers = [],
676
+ recentEdits = [],
519
677
  }: SlideEditorProps) {
520
678
  const t = useT();
521
679
  const content = typeof slide.content === "string" ? slide.content : "";
@@ -534,6 +692,27 @@ export default function SlideEditor({
534
692
  const [selectionRect, setSelectionRect] = useState<DOMRect | null>(null);
535
693
  const containerRef = useRef<HTMLDivElement>(null);
536
694
  const scrollContainerRef = useRef<HTMLDivElement>(null);
695
+ // Wraps the rendered slide; used as the positioning container for the
696
+ // lingering "AI edited" ring when the active slide was just edited.
697
+ const slideCanvasRef = useRef<HTMLDivElement>(null);
698
+
699
+ // Recent edits (usually the agent's) that target THIS slide. The ring is
700
+ // drawn around the whole canvas since a slide-level `slides.<id>` descriptor
701
+ // refers to the entire slide.
702
+ const activeSlideId = slideId || slide.id;
703
+ const activeSlideEdits = recentEdits.filter((edit) => {
704
+ const d = edit.descriptor;
705
+ return (
706
+ d.kind === "paths" &&
707
+ Array.isArray(d.paths) &&
708
+ d.paths.some((p) => p === `slides.${activeSlideId}`)
709
+ );
710
+ });
711
+ const resolveCanvasRect = useCallback(
712
+ (): DOMRect | null =>
713
+ slideCanvasRef.current?.getBoundingClientRect() ?? null,
714
+ [],
715
+ );
537
716
 
538
717
  // --- Multi-select state ---
539
718
  /** Set of data-builder-id values currently in the multi-select */
@@ -544,6 +723,16 @@ export default function SlideEditor({
544
723
  const [multiSelectionRects, setMultiSelectionRects] = useState<
545
724
  Map<string, { rect: DOMRect; text: string; selector: string }>
546
725
  >(() => new Map());
726
+ const [selectedElementPath, setSelectedElementPath] = useState<
727
+ number[] | null
728
+ >(null);
729
+ const [selectedElementSelector, setSelectedElementSelector] = useState<
730
+ string | null
731
+ >(null);
732
+ const [selectedElementRect, setSelectedElementRect] =
733
+ useState<DOMRect | null>(null);
734
+ const [selectedStyleSnapshot, setSelectedStyleSnapshot] =
735
+ useState<SlideStyleSnapshot | null>(null);
547
736
  /** Anchor rect for the floating chip (the slide canvas) */
548
737
  const [chipAnchorRect, setChipAnchorRect] = useState<DOMRect | null>(null);
549
738
  /** Active marquee rectangle (viewport coords). null = not dragging. */
@@ -756,6 +945,78 @@ export default function SlideEditor({
756
945
  [readCurrentSlideContentHtml, slide.id],
757
946
  );
758
947
 
948
+ /** Resolve the slide-content root element (where selectable items live) */
949
+ const getSlideContent = useCallback((): HTMLElement | null => {
950
+ return (
951
+ (containerRef.current?.querySelector(
952
+ ".slide-content",
953
+ ) as HTMLElement | null) || null
954
+ );
955
+ }, []);
956
+
957
+ const resolveSelectedElement = useCallback((): HTMLElement | null => {
958
+ if (!selectedElementPath) return null;
959
+ return resolveElementPath(getSlideContent(), selectedElementPath);
960
+ }, [getSlideContent, selectedElementPath]);
961
+
962
+ const buildSelectionState = useCallback(
963
+ (
964
+ mode: SlidesSelectionState["mode"],
965
+ items: SlideSelectionItem[],
966
+ activeTool: SlidesSelectionState["activeTool"] = drawMode
967
+ ? "draw"
968
+ : pinMode
969
+ ? "pin"
970
+ : "select",
971
+ ): SlidesSelectionState => ({
972
+ deckId,
973
+ slideId: slide.id,
974
+ slideIndex,
975
+ slideNumber: slideIndex + 1,
976
+ mode,
977
+ activeTool,
978
+ items,
979
+ }),
980
+ [deckId, drawMode, pinMode, slide.id, slideIndex],
981
+ );
982
+
983
+ const clearSelectedElement = useCallback(() => {
984
+ setSelectedElementPath(null);
985
+ setSelectedElementSelector(null);
986
+ setSelectedElementRect(null);
987
+ setSelectedStyleSnapshot(null);
988
+ }, []);
989
+
990
+ const selectElementForStyling = useCallback(
991
+ (element: HTMLElement, selector: string) => {
992
+ const slideContent = getSlideContent();
993
+ if (!slideContent) return;
994
+ const path = elementPathFromRoot(slideContent, element);
995
+ if (path.length === 0) return;
996
+ const snapshot = buildStyleSnapshot(element, selector);
997
+ setSelectedElementPath(path);
998
+ setSelectedElementSelector(selector);
999
+ setSelectedElementRect(element.getBoundingClientRect());
1000
+ setSelectedStyleSnapshot(snapshot);
1001
+ syncSelectionToAppState(
1002
+ buildSelectionState(snapshot.isImage ? "image" : "single", [
1003
+ {
1004
+ selector,
1005
+ kind: snapshot.isImage ? "image" : "element",
1006
+ tagName: snapshot.tagName,
1007
+ text: snapshot.textPreview,
1008
+ imageSrc:
1009
+ element instanceof HTMLImageElement
1010
+ ? (element.getAttribute("src") ?? undefined)
1011
+ : undefined,
1012
+ style: snapshot,
1013
+ },
1014
+ ]),
1015
+ );
1016
+ },
1017
+ [buildSelectionState, getSlideContent],
1018
+ );
1019
+
759
1020
  /** Exit edit mode, saving changes to slide.content */
760
1021
  const exitInlineEdit = useCallback(() => {
761
1022
  setEditingEl((el) => {
@@ -768,6 +1029,7 @@ export default function SlideEditor({
768
1029
  onUpdateSlideRef.current({ content: html });
769
1030
  }
770
1031
  inlineEditDraftRef.current = null;
1032
+ syncSelectionToAppState(null);
771
1033
  return null;
772
1034
  });
773
1035
  }, [readCurrentSlideContentHtml]);
@@ -775,8 +1037,10 @@ export default function SlideEditor({
775
1037
  /** Enter edit mode on a smart block (text leaf or smart group) */
776
1038
  const enterInlineEdit = useCallback(
777
1039
  (el: HTMLElement) => {
1040
+ const selector = getBuilderSelector(el);
778
1041
  el.contentEditable = "true";
779
1042
  el.setAttribute("data-editing-block", "true");
1043
+ clearSelectedElement();
780
1044
  captureInlineEditDraft(slide.id);
781
1045
  // Mark the deck dirty immediately so SSE/poll refreshes do not replace
782
1046
  // the deck under an active contentEditable edit, even before the user
@@ -789,8 +1053,26 @@ export default function SlideEditor({
789
1053
  // browsers, so it's safe to keep for keyboard delivery.
790
1054
  el.focus({ preventScroll: true });
791
1055
  setEditingEl(el);
1056
+ if (selector) {
1057
+ syncSelectionToAppState(
1058
+ buildSelectionState("editing", [
1059
+ {
1060
+ selector,
1061
+ kind: "text",
1062
+ tagName: el.tagName.toLowerCase(),
1063
+ text: (el.textContent ?? "").trim().slice(0, 200),
1064
+ },
1065
+ ]),
1066
+ );
1067
+ }
792
1068
  },
793
- [captureInlineEditDraft, onInlineEditStart, slide.id],
1069
+ [
1070
+ buildSelectionState,
1071
+ captureInlineEditDraft,
1072
+ clearSelectedElement,
1073
+ onInlineEditStart,
1074
+ slide.id,
1075
+ ],
794
1076
  );
795
1077
 
796
1078
  // Exit edit mode when switching slides — save pending content first so
@@ -891,6 +1173,50 @@ export default function SlideEditor({
891
1173
  };
892
1174
  }, [selectedImg]);
893
1175
 
1176
+ useEffect(() => {
1177
+ if (!selectedElementPath || !selectedElementSelector) return;
1178
+ const update = () => {
1179
+ const element = resolveSelectedElement();
1180
+ if (!element) {
1181
+ clearSelectedElement();
1182
+ syncSelectionToAppState(null);
1183
+ return;
1184
+ }
1185
+ const snapshot = buildStyleSnapshot(element, selectedElementSelector);
1186
+ setSelectedElementRect(element.getBoundingClientRect());
1187
+ setSelectedStyleSnapshot(snapshot);
1188
+ syncSelectionToAppState(
1189
+ buildSelectionState(snapshot.isImage ? "image" : "single", [
1190
+ {
1191
+ selector: selectedElementSelector,
1192
+ kind: snapshot.isImage ? "image" : "element",
1193
+ tagName: snapshot.tagName,
1194
+ text: snapshot.textPreview,
1195
+ imageSrc:
1196
+ element instanceof HTMLImageElement
1197
+ ? (element.getAttribute("src") ?? undefined)
1198
+ : undefined,
1199
+ style: snapshot,
1200
+ },
1201
+ ]),
1202
+ );
1203
+ };
1204
+ update();
1205
+ window.addEventListener("resize", update);
1206
+ window.addEventListener("scroll", update, true);
1207
+ return () => {
1208
+ window.removeEventListener("resize", update);
1209
+ window.removeEventListener("scroll", update, true);
1210
+ };
1211
+ }, [
1212
+ buildSelectionState,
1213
+ clearSelectedElement,
1214
+ resolveSelectedElement,
1215
+ selectedElementPath,
1216
+ selectedElementSelector,
1217
+ slide.content,
1218
+ ]);
1219
+
894
1220
  // Deselect when clicking outside
895
1221
  useEffect(() => {
896
1222
  if (!selectedImg) return;
@@ -928,15 +1254,6 @@ export default function SlideEditor({
928
1254
 
929
1255
  // --- Multi-select helpers ---
930
1256
 
931
- /** Resolve the slide-content root element (where selectable items live) */
932
- const getSlideContent = useCallback((): HTMLElement | null => {
933
- return (
934
- (containerRef.current?.querySelector(
935
- ".slide-content",
936
- ) as HTMLElement | null) || null
937
- );
938
- }, []);
939
-
940
1257
  /**
941
1258
  * Apply a new multi-selection: caches rects + selectors and pushes to
942
1259
  * application_state. Pass an empty set to clear.
@@ -948,7 +1265,7 @@ export default function SlideEditor({
948
1265
  string,
949
1266
  { rect: DOMRect; text: string; selector: string }
950
1267
  >();
951
- const items: Array<{ selector: string; text: string }> = [];
1268
+ const items: SlideSelectionItem[] = [];
952
1269
  if (slideContent) {
953
1270
  ids.forEach((id) => {
954
1271
  const el = slideContent.querySelector(
@@ -958,19 +1275,27 @@ export default function SlideEditor({
958
1275
  const selector = `[data-builder-id="${id}"]`;
959
1276
  const text = (el.textContent || "").trim().slice(0, 200);
960
1277
  rects.set(id, { rect: el.getBoundingClientRect(), text, selector });
961
- items.push({ selector, text });
1278
+ items.push({
1279
+ selector,
1280
+ text,
1281
+ kind: el.tagName === "IMG" ? "image" : "element",
1282
+ tagName: el.tagName.toLowerCase(),
1283
+ });
962
1284
  });
963
1285
  }
964
1286
  setMultiSelection(ids);
965
1287
  setMultiSelectionRects(rects);
1288
+ if (ids.size > 0) clearSelectedElement();
966
1289
  // Anchor the chip to the slide canvas (clickable wrapper)
967
1290
  const canvas = containerRef.current?.querySelector(
968
1291
  ".slide-image-clickable",
969
1292
  ) as HTMLElement | null;
970
1293
  setChipAnchorRect(canvas?.getBoundingClientRect() || null);
971
- syncSelectionToAppState(items);
1294
+ syncSelectionToAppState(
1295
+ items.length > 0 ? buildSelectionState("multi", items) : null,
1296
+ );
972
1297
  },
973
- [getSlideContent],
1298
+ [buildSelectionState, clearSelectedElement, getSlideContent],
974
1299
  );
975
1300
 
976
1301
  const clearMultiSelection = useCallback(() => {
@@ -1048,8 +1373,9 @@ export default function SlideEditor({
1048
1373
  setMultiSelection(new Set());
1049
1374
  setMultiSelectionRects(new Map());
1050
1375
  setChipAnchorRect(null);
1051
- syncSelectionToAppState([]);
1052
- }, [slide.id]);
1376
+ clearSelectedElement();
1377
+ syncSelectionToAppState(null);
1378
+ }, [clearSelectedElement, slide.id]);
1053
1379
 
1054
1380
  // Escape key clears multi-selection (only when not inline-editing)
1055
1381
  useEffect(() => {
@@ -1084,6 +1410,18 @@ export default function SlideEditor({
1084
1410
  [],
1085
1411
  );
1086
1412
 
1413
+ const findSelectableElement = useCallback(
1414
+ (target: HTMLElement, slideContent: HTMLElement): HTMLElement | null => {
1415
+ let el: HTMLElement | null = target;
1416
+ while (el && slideContent.contains(el) && el !== slideContent) {
1417
+ if (el.getAttribute("data-builder-id")) return el;
1418
+ el = el.parentElement;
1419
+ }
1420
+ return null;
1421
+ },
1422
+ [],
1423
+ );
1424
+
1087
1425
  /** True if the click is on "whitespace" inside the slide (not on any leaf) */
1088
1426
  const isSlideWhitespaceTarget = useCallback(
1089
1427
  (target: HTMLElement, slideContent: HTMLElement): boolean => {
@@ -1120,8 +1458,12 @@ export default function SlideEditor({
1120
1458
 
1121
1459
  // Clear single-select feedback when starting a marquee on whitespace
1122
1460
  // (non-additive). Additive marquee preserves the existing selection.
1123
- if (!marqueeAdditiveRef.current && multiSelection.size > 0) {
1124
- applyMultiSelection(new Set());
1461
+ if (!marqueeAdditiveRef.current) {
1462
+ clearSelectedElement();
1463
+ syncSelectionToAppState(null);
1464
+ if (multiSelection.size > 0) {
1465
+ applyMultiSelection(new Set());
1466
+ }
1125
1467
  }
1126
1468
  },
1127
1469
  [
@@ -1130,6 +1472,7 @@ export default function SlideEditor({
1130
1472
  isSlideWhitespaceTarget,
1131
1473
  multiSelection,
1132
1474
  applyMultiSelection,
1475
+ clearSelectedElement,
1133
1476
  ],
1134
1477
  );
1135
1478
 
@@ -1294,6 +1637,8 @@ export default function SlideEditor({
1294
1637
  // with zero movement won't trigger pointerup with a real rect).
1295
1638
  if (slideContent && isSlideWhitespaceTarget(target, slideContent)) {
1296
1639
  if (multiSelection.size > 0) clearMultiSelection();
1640
+ clearSelectedElement();
1641
+ syncSelectionToAppState(null);
1297
1642
  return;
1298
1643
  }
1299
1644
 
@@ -1304,8 +1649,12 @@ export default function SlideEditor({
1304
1649
  showImageOverlay(target);
1305
1650
 
1306
1651
  // Send style-editing postMessage with a unique selector for the clicked element
1307
- const selector = getBuilderSelector(target);
1308
- if (selector) {
1652
+ const selectableEl = slideContent
1653
+ ? findSelectableElement(target, slideContent)
1654
+ : null;
1655
+ const selector = selectableEl ? getBuilderSelector(selectableEl) : null;
1656
+ if (selector && selectableEl) {
1657
+ selectElementForStyling(selectableEl, selector);
1309
1658
  enterSelectionMode("agentNative.enterStyleEditing", { selector });
1310
1659
  }
1311
1660
  },
@@ -1314,10 +1663,13 @@ export default function SlideEditor({
1314
1663
  editingEl,
1315
1664
  getSlideContent,
1316
1665
  findSelectableId,
1666
+ findSelectableElement,
1317
1667
  isSlideWhitespaceTarget,
1318
1668
  multiSelection,
1319
1669
  applyMultiSelection,
1320
1670
  clearMultiSelection,
1671
+ clearSelectedElement,
1672
+ selectElementForStyling,
1321
1673
  ],
1322
1674
  );
1323
1675
 
@@ -1332,6 +1684,57 @@ export default function SlideEditor({
1332
1684
  [showImageOverlay],
1333
1685
  );
1334
1686
 
1687
+ const applySelectedStylePatch = useCallback(
1688
+ (patch: SlideStylePatch) => {
1689
+ const element = resolveSelectedElement();
1690
+ if (!element || !selectedElementSelector) return;
1691
+
1692
+ for (const [property, value] of Object.entries(patch)) {
1693
+ if (value === undefined) continue;
1694
+ element.style.setProperty(stylePropertyName(property), value);
1695
+ }
1696
+
1697
+ if (
1698
+ patch.borderWidth &&
1699
+ patch.borderWidth !== "0" &&
1700
+ patch.borderWidth !== "0px" &&
1701
+ window.getComputedStyle(element).borderStyle === "none"
1702
+ ) {
1703
+ element.style.borderStyle = "solid";
1704
+ }
1705
+
1706
+ const html = readCurrentSlideContentHtml();
1707
+ if (html !== null) {
1708
+ onUpdateSlideRef.current({ content: html });
1709
+ }
1710
+
1711
+ const snapshot = buildStyleSnapshot(element, selectedElementSelector);
1712
+ setSelectedElementRect(element.getBoundingClientRect());
1713
+ setSelectedStyleSnapshot(snapshot);
1714
+ syncSelectionToAppState(
1715
+ buildSelectionState(snapshot.isImage ? "image" : "single", [
1716
+ {
1717
+ selector: selectedElementSelector,
1718
+ kind: snapshot.isImage ? "image" : "element",
1719
+ tagName: snapshot.tagName,
1720
+ text: snapshot.textPreview,
1721
+ imageSrc:
1722
+ element instanceof HTMLImageElement
1723
+ ? (element.getAttribute("src") ?? undefined)
1724
+ : undefined,
1725
+ style: snapshot,
1726
+ },
1727
+ ]),
1728
+ );
1729
+ },
1730
+ [
1731
+ buildSelectionState,
1732
+ readCurrentSlideContentHtml,
1733
+ resolveSelectedElement,
1734
+ selectedElementSelector,
1735
+ ],
1736
+ );
1737
+
1335
1738
  // --- Pending visual updates ---
1336
1739
  const [pendingUpdateCount, setPendingUpdateCount] = useState(0);
1337
1740
 
@@ -1383,173 +1786,196 @@ export default function SlideEditor({
1383
1786
  [showImageOverlay, enterInlineEdit, isHtmlSlide, readOnly],
1384
1787
  );
1385
1788
 
1386
- const slideElementSelected = !!selectedImg || !!editingEl;
1789
+ const slideElementSelected =
1790
+ !!selectedImg || !!editingEl || !!selectedStyleSnapshot;
1387
1791
 
1388
1792
  return (
1389
1793
  <div
1390
- className="flex-1 flex flex-col h-full overflow-hidden"
1794
+ className="relative flex-1 flex flex-col h-full overflow-hidden"
1391
1795
  data-slide-element-selected={slideElementSelected ? "true" : undefined}
1392
1796
  >
1393
1797
  <div className="flex-1 overflow-hidden">
1394
- {activeTab === "visual" ? (
1395
- slide.excalidrawData ? (
1396
- <div className="h-full bg-background">
1397
- <ExcalidrawSlide
1398
- initialData={slide.excalidrawData}
1399
- onChange={(data) => onUpdateSlide({ excalidrawData: data })}
1400
- />
1798
+ {slide.excalidrawData ? (
1799
+ <div className="h-full bg-background">
1800
+ <ExcalidrawSlide
1801
+ initialData={slide.excalidrawData}
1802
+ onChange={(data) => onUpdateSlide({ excalidrawData: data })}
1803
+ />
1804
+ </div>
1805
+ ) : (
1806
+ <div className="relative h-full bg-background">
1807
+ <div className="absolute right-3 top-3 z-20 flex h-8 items-center gap-0.5 rounded-md border border-border bg-popover/95 px-1 shadow-lg backdrop-blur">
1808
+ <Tooltip>
1809
+ <TooltipTrigger asChild>
1810
+ <Button
1811
+ variant="ghost"
1812
+ size="icon"
1813
+ className="h-6 w-6 cursor-pointer"
1814
+ onClick={canvasZoomOut}
1815
+ disabled={canvasZoom <= MIN_CANVAS_ZOOM}
1816
+ aria-label={t("raw.zoomOut")}
1817
+ >
1818
+ <IconZoomOut className="h-3.5 w-3.5" />
1819
+ </Button>
1820
+ </TooltipTrigger>
1821
+ <TooltipContent>{t("raw.zoomOut")}</TooltipContent>
1822
+ </Tooltip>
1823
+ <span className="w-11 text-center text-xs tabular-nums text-muted-foreground">
1824
+ {canvasZoom}%
1825
+ </span>
1826
+ <Tooltip>
1827
+ <TooltipTrigger asChild>
1828
+ <Button
1829
+ variant="ghost"
1830
+ size="icon"
1831
+ className="h-6 w-6 cursor-pointer"
1832
+ onClick={canvasZoomIn}
1833
+ disabled={
1834
+ canvasZoom >=
1835
+ CANVAS_ZOOM_PRESETS[CANVAS_ZOOM_PRESETS.length - 1]
1836
+ }
1837
+ aria-label={t("raw.zoomIn")}
1838
+ >
1839
+ <IconZoomIn className="h-3.5 w-3.5" />
1840
+ </Button>
1841
+ </TooltipTrigger>
1842
+ <TooltipContent>{t("raw.zoomIn")}</TooltipContent>
1843
+ </Tooltip>
1844
+ <div className="mx-0.5 h-4 w-px bg-border" />
1845
+ <Tooltip>
1846
+ <TooltipTrigger asChild>
1847
+ <Button
1848
+ variant="ghost"
1849
+ size="icon"
1850
+ className="h-6 w-6 cursor-pointer"
1851
+ onClick={fitCanvasToScreen}
1852
+ aria-label={t("raw.fitSlideToScreen")}
1853
+ >
1854
+ <IconMaximize className="h-3.5 w-3.5" />
1855
+ </Button>
1856
+ </TooltipTrigger>
1857
+ <TooltipContent>{t("raw.fitToScreen")}</TooltipContent>
1858
+ </Tooltip>
1401
1859
  </div>
1402
- ) : (
1403
- <div className="relative h-full bg-background">
1404
- <div className="absolute right-3 top-3 z-20 flex h-8 items-center gap-0.5 rounded-md border border-border bg-popover/95 px-1 shadow-lg backdrop-blur">
1405
- <Tooltip>
1406
- <TooltipTrigger asChild>
1407
- <Button
1408
- variant="ghost"
1409
- size="icon"
1410
- className="h-6 w-6 cursor-pointer"
1411
- onClick={canvasZoomOut}
1412
- disabled={canvasZoom <= MIN_CANVAS_ZOOM}
1413
- aria-label={t("raw.zoomOut")}
1414
- >
1415
- <IconZoomOut className="h-3.5 w-3.5" />
1416
- </Button>
1417
- </TooltipTrigger>
1418
- <TooltipContent>{t("raw.zoomOut")}</TooltipContent>
1419
- </Tooltip>
1420
- <span className="w-11 text-center text-xs tabular-nums text-muted-foreground">
1421
- {canvasZoom}%
1422
- </span>
1423
- <Tooltip>
1424
- <TooltipTrigger asChild>
1425
- <Button
1426
- variant="ghost"
1427
- size="icon"
1428
- className="h-6 w-6 cursor-pointer"
1429
- onClick={canvasZoomIn}
1430
- disabled={
1431
- canvasZoom >=
1432
- CANVAS_ZOOM_PRESETS[CANVAS_ZOOM_PRESETS.length - 1]
1433
- }
1434
- aria-label={t("raw.zoomIn")}
1435
- >
1436
- <IconZoomIn className="h-3.5 w-3.5" />
1437
- </Button>
1438
- </TooltipTrigger>
1439
- <TooltipContent>{t("raw.zoomIn")}</TooltipContent>
1440
- </Tooltip>
1441
- <div className="mx-0.5 h-4 w-px bg-border" />
1442
- <Tooltip>
1443
- <TooltipTrigger asChild>
1444
- <Button
1445
- variant="ghost"
1446
- size="icon"
1447
- className="h-6 w-6 cursor-pointer"
1448
- onClick={fitCanvasToScreen}
1449
- aria-label={t("raw.fitSlideToScreen")}
1450
- >
1451
- <IconMaximize className="h-3.5 w-3.5" />
1452
- </Button>
1453
- </TooltipTrigger>
1454
- <TooltipContent>{t("raw.fitToScreen")}</TooltipContent>
1455
- </Tooltip>
1456
- </div>
1860
+ <div
1861
+ ref={scrollContainerRef}
1862
+ className={`h-full overflow-auto ${
1863
+ drawMode ? "pb-24 sm:pb-28" : ""
1864
+ }`}
1865
+ >
1457
1866
  <div
1458
- ref={scrollContainerRef}
1459
- className={`h-full overflow-auto ${
1460
- drawMode ? "pb-24 sm:pb-28" : ""
1461
- }`}
1867
+ ref={canvasTrackRef}
1868
+ className="flex min-h-full w-max min-w-full items-center justify-center p-2 pt-14 sm:p-4 sm:pt-14 md:p-8 md:pt-16"
1462
1869
  >
1463
1870
  <div
1464
- ref={canvasTrackRef}
1465
- className="flex min-h-full w-max min-w-full items-center justify-center p-2 pt-14 sm:p-4 sm:pt-14 md:p-8 md:pt-16"
1871
+ ref={containerRef}
1872
+ data-main-slide-canvas="true"
1873
+ className="shrink-0"
1874
+ style={{ width: canvasWidth, maxWidth: canvasWidth }}
1466
1875
  >
1467
1876
  <div
1468
- ref={containerRef}
1469
- data-main-slide-canvas="true"
1470
- className="shrink-0"
1471
- style={{ width: canvasWidth, maxWidth: canvasWidth }}
1877
+ ref={slideCanvasRef}
1878
+ className="slide-image-clickable relative"
1879
+ data-editable={!readOnly ? "true" : undefined}
1880
+ onClick={handleSlideClick}
1881
+ onContextMenu={handleSlideContextMenu}
1882
+ onDoubleClick={handleSlideDoubleClick}
1883
+ onPointerDown={handleSlidePointerDown}
1884
+ onDragOver={handleSlideDragOver}
1885
+ onDrop={handleSlideDrop}
1886
+ onMouseEnter={() => setIsHoveringText(true)}
1887
+ onMouseLeave={() => setIsHoveringText(false)}
1472
1888
  >
1473
- <div
1474
- className="slide-image-clickable relative"
1475
- onClick={handleSlideClick}
1476
- onContextMenu={handleSlideContextMenu}
1477
- onDoubleClick={handleSlideDoubleClick}
1478
- onPointerDown={handleSlidePointerDown}
1479
- onDragOver={handleSlideDragOver}
1480
- onDrop={handleSlideDrop}
1481
- onMouseEnter={() => setIsHoveringText(true)}
1482
- onMouseLeave={() => setIsHoveringText(false)}
1483
- >
1484
- <SlideRenderer
1485
- slide={slide}
1486
- className={`shadow-2xl shadow-black/40 ${isHoveringText ? "ring-2 ring-[#609FF8]/60" : ""}`}
1487
- designSystem={designSystem}
1488
- aspectRatio={aspectRatio}
1489
- onOverflowChange={handleOverflowChange}
1889
+ <SlideRenderer
1890
+ slide={slide}
1891
+ className={`shadow-2xl shadow-black/40 ${isHoveringText ? "ring-2 ring-[#609FF8]/60" : ""}`}
1892
+ designSystem={designSystem}
1893
+ aspectRatio={aspectRatio}
1894
+ onOverflowChange={handleOverflowChange}
1895
+ />
1896
+ {/* Fading "AI edited" ring around the canvas when the
1897
+ agent just edited THIS slide (component handles fade). */}
1898
+ {activeSlideEdits.length > 0 && (
1899
+ <RecentEditHighlights
1900
+ edits={activeSlideEdits}
1901
+ resolveRect={resolveCanvasRect}
1902
+ containerRef={slideCanvasRef}
1490
1903
  />
1491
- {/* Double-click hint — only shown for HTML slides that support inline editing */}
1492
- {isHoveringText && !editingEl && isHtmlSlide && (
1493
- <div className="absolute bottom-2 left-1/2 -translate-x-1/2 rounded bg-black/60 px-2 py-0.5 text-xs text-white/40 pointer-events-none select-none">
1494
- {t("raw.doubleClickEdit")}
1495
- </div>
1496
- )}
1497
- {agentActive && (
1498
- <div className="absolute top-2 right-2 z-10 pointer-events-none">
1499
- <AgentPresenceChip active={agentActive} />
1500
- </div>
1501
- )}
1502
- {presentUsers.length > 0 && (
1503
- <div
1504
- className={`absolute right-2 z-10 ${
1505
- agentActive ? "top-11" : "top-2"
1506
- }`}
1904
+ )}
1905
+ {/* Double-click hint only shown for HTML slides that support inline editing */}
1906
+ {isHoveringText && !editingEl && isHtmlSlide && (
1907
+ <div className="absolute bottom-2 left-1/2 -translate-x-1/2 rounded bg-black/60 px-2 py-0.5 text-xs text-white/40 pointer-events-none select-none">
1908
+ {t("raw.doubleClickEdit")}
1909
+ </div>
1910
+ )}
1911
+ {agentActive && (
1912
+ <div className="absolute top-2 right-2 z-10 pointer-events-none">
1913
+ <AgentPresenceChip active={agentActive} />
1914
+ </div>
1915
+ )}
1916
+ {presentUsers.length > 0 && (
1917
+ <div
1918
+ className={`absolute right-2 z-10 ${
1919
+ agentActive ? "top-11" : "top-2"
1920
+ }`}
1921
+ >
1922
+ <SameSlidePresenceIndicator users={presentUsers} />
1923
+ </div>
1924
+ )}
1925
+ {overflowInfo && !readOnly && !agentActive && (
1926
+ <div className="absolute top-3 left-3 z-20 flex items-center gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 backdrop-blur px-2.5 py-1.5 text-xs text-amber-100 shadow-lg">
1927
+ <IconAlertTriangle
1928
+ className="h-3.5 w-3.5 flex-shrink-0"
1929
+ stroke={2}
1930
+ />
1931
+ <span className="leading-tight">
1932
+ Layout overflows by {overflowInfo.verticalOverflow}
1933
+ px
1934
+ </span>
1935
+ <Button
1936
+ size="sm"
1937
+ variant="ghost"
1938
+ className="ml-1 h-6 cursor-pointer px-2 text-[11px] font-medium text-amber-100 hover:bg-amber-500/20 hover:text-white"
1939
+ onClick={handleAskAgentToFixLayout}
1940
+ disabled={isAskingAgentToFix}
1507
1941
  >
1508
- <SameSlidePresenceIndicator users={presentUsers} />
1509
- </div>
1510
- )}
1511
- {overflowInfo && !readOnly && !agentActive && (
1512
- <div className="absolute top-3 left-3 z-20 flex items-center gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 backdrop-blur px-2.5 py-1.5 text-xs text-amber-100 shadow-lg">
1513
- <IconAlertTriangle
1514
- className="h-3.5 w-3.5 flex-shrink-0"
1515
- stroke={2}
1516
- />
1517
- <span className="leading-tight">
1518
- Layout overflows by {overflowInfo.verticalOverflow}
1519
- px
1520
- </span>
1521
- <Button
1522
- size="sm"
1523
- variant="ghost"
1524
- className="ml-1 h-6 cursor-pointer px-2 text-[11px] font-medium text-amber-100 hover:bg-amber-500/20 hover:text-white"
1525
- onClick={handleAskAgentToFixLayout}
1526
- disabled={isAskingAgentToFix}
1527
- >
1528
- {isAskingAgentToFix ? "Asking…" : "Fix with AI"}
1529
- </Button>
1530
- </div>
1531
- )}
1532
- </div>
1942
+ {isAskingAgentToFix ? "Asking…" : "Fix with AI"}
1943
+ </Button>
1944
+ </div>
1945
+ )}
1533
1946
  </div>
1534
1947
  </div>
1535
1948
  </div>
1536
1949
  </div>
1537
- )
1538
- ) : (
1539
- <CodeEditor slide={slide} onUpdateSlide={onUpdateSlide} />
1950
+ </div>
1540
1951
  )}
1541
1952
  </div>
1542
1953
 
1543
- {activeTab === "visual" && (
1544
- <SpeakerNotesPanel
1545
- notes={slide.notes}
1546
- onChange={(notes) => onUpdateSlide({ notes })}
1547
- slideIndex={slideIndex}
1548
- slideCount={slideCount}
1549
- />
1550
- )}
1954
+ <SpeakerNotesPanel
1955
+ notes={slide.notes}
1956
+ onChange={(notes) => onUpdateSlide({ notes })}
1957
+ slideIndex={slideIndex}
1958
+ slideCount={slideCount}
1959
+ />
1551
1960
 
1552
1961
  {selectionRect && <ImageSelectionOutline rect={selectionRect} />}
1962
+ {selectedElementRect && (
1963
+ <ElementSelectionOutline rect={selectedElementRect} />
1964
+ )}
1965
+
1966
+ {selectedStyleSnapshot && !readOnly && (
1967
+ <div className="pointer-events-none absolute right-3 top-14 z-[80] hidden md:block">
1968
+ <SlideStyleInspector
1969
+ snapshot={selectedStyleSnapshot}
1970
+ designSystem={designSystem}
1971
+ onChange={applySelectedStylePatch}
1972
+ onClose={() => {
1973
+ clearSelectedElement();
1974
+ syncSelectionToAppState(null);
1975
+ }}
1976
+ />
1977
+ </div>
1978
+ )}
1553
1979
 
1554
1980
  {/* Multi-select outlines */}
1555
1981
  {Array.from(multiSelectionRects.entries()).map(([id, v]) => (