@agent-native/core 0.80.2 → 0.80.5

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 (322) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +66 -2
  3. package/corpus/core/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
  4. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -1
  5. package/corpus/core/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
  6. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -1
  7. package/corpus/core/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
  8. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -1
  9. package/corpus/core/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
  10. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -1
  11. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -1
  12. package/corpus/core/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
  13. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -1
  14. package/corpus/core/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
  15. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -1
  16. package/corpus/core/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
  17. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -1
  18. package/corpus/core/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
  19. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -1
  20. package/corpus/core/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
  21. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -1
  22. package/corpus/core/docs/content/real-time-collaboration.mdx +2 -2
  23. package/corpus/core/docs/content/template-design.mdx +1 -1
  24. package/corpus/core/package.json +3 -7
  25. package/corpus/core/src/action.ts +32 -0
  26. package/corpus/core/src/agent/durable-background.ts +32 -11
  27. package/corpus/core/src/agent/production-agent.ts +14 -1
  28. package/corpus/core/src/agent/run-loop-with-resume.ts +3 -1
  29. package/corpus/core/src/brand-kit/fig/index.ts +17 -37
  30. package/corpus/core/src/cli/index.ts +1 -1
  31. package/corpus/core/src/cli/mcp-config-writers.ts +187 -51
  32. package/corpus/core/src/cli/plan-local.ts +445 -108
  33. package/corpus/core/src/cli/skills.ts +32 -8
  34. package/corpus/core/src/client/AssistantChat.tsx +11 -1
  35. package/corpus/core/src/client/agent-chat.ts +12 -1
  36. package/corpus/core/src/client/composer/PromptComposer.tsx +100 -41
  37. package/corpus/core/src/client/org/OrgSwitcher.tsx +1 -1
  38. package/corpus/core/src/client/sharing/ShareButton.tsx +3 -27
  39. package/corpus/core/src/collab/presence.ts +1 -1
  40. package/corpus/core/src/mcp/connect-route.ts +34 -5
  41. package/corpus/core/src/server/action-discovery.ts +4 -0
  42. package/corpus/core/src/server/action-routes.ts +14 -0
  43. package/corpus/core/src/server/agent-chat-plugin.ts +20 -0
  44. package/corpus/core/src/vite/client.ts +15 -1
  45. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -0
  46. package/corpus/templates/analytics/actions/update-dashboard.ts +8 -0
  47. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
  48. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +117 -33
  49. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +4 -0
  50. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +7 -0
  51. package/corpus/templates/analytics/changelog/2026-06-27-dashboards-can-now-nest-under-a-parent-in-the-sidebar-via-a-.md +6 -0
  52. package/corpus/templates/analytics/changelog/2026-06-29-analytics-pages-now-sit-closer-under-the-header-with-tighter.md +6 -0
  53. package/corpus/templates/assets/actions/generate-image-batch.ts +3 -0
  54. package/corpus/templates/assets/actions/generate-image.ts +3 -0
  55. package/corpus/templates/assets/changelog/2026-06-29-longer-agent-generation-window.md +6 -0
  56. package/corpus/templates/assets/netlify.toml +3 -3
  57. package/corpus/templates/assets/server/plugins/agent-chat.ts +4 -1
  58. package/corpus/templates/clips/app/components/capture-install-options.tsx +7 -8
  59. package/corpus/templates/clips/app/components/player/timestamped-comment-button.tsx +162 -0
  60. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +1 -1
  61. package/corpus/templates/clips/app/i18n/ar-SA.ts +4 -0
  62. package/corpus/templates/clips/app/i18n/de-DE.ts +4 -0
  63. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  64. package/corpus/templates/clips/app/i18n/es-ES.ts +4 -0
  65. package/corpus/templates/clips/app/i18n/fr-FR.ts +4 -0
  66. package/corpus/templates/clips/app/i18n/hi-IN.ts +4 -0
  67. package/corpus/templates/clips/app/i18n/ja-JP.ts +4 -0
  68. package/corpus/templates/clips/app/i18n/ko-KR.ts +4 -0
  69. package/corpus/templates/clips/app/i18n/pt-BR.ts +4 -0
  70. package/corpus/templates/clips/app/i18n/zh-CN.ts +4 -0
  71. package/corpus/templates/clips/app/i18n/zh-TW.ts +4 -0
  72. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +42 -18
  73. package/corpus/templates/content/AGENTS.md +12 -0
  74. package/corpus/templates/content/app/blocks/BuilderDocsBlocks.tsx +10 -0
  75. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +1 -0
  76. package/corpus/templates/content/app/components/editor/ContentReferencePreview.tsx +185 -0
  77. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -0
  78. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +19 -0
  79. package/corpus/templates/content/app/components/editor/extensions/ContentReferenceNode.tsx +82 -0
  80. package/corpus/templates/content/app/global.css +9 -0
  81. package/corpus/templates/content/app/i18n/zh-TW.ts +12 -0
  82. package/corpus/templates/content/app/i18n-data.ts +140 -0
  83. package/corpus/templates/content/changelog/2026-06-29-reusable-mdx-references-now-preview-linked-local-documents-i.md +6 -0
  84. package/corpus/templates/content/shared/builder-docs-blocks.ts +8 -0
  85. package/corpus/templates/content/shared/builder-mdx.ts +141 -4
  86. package/corpus/templates/content/shared/nfm.ts +62 -0
  87. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +10 -11
  88. package/corpus/templates/design/AGENTS.md +5 -0
  89. package/corpus/templates/design/_gitignore +7 -0
  90. package/corpus/templates/design/actions/apply-visual-edit.ts +22 -12
  91. package/corpus/templates/design/actions/create-design-system.ts +15 -4
  92. package/corpus/templates/design/actions/create-file.ts +20 -1
  93. package/corpus/templates/design/actions/delete-design-system.ts +2 -2
  94. package/corpus/templates/design/actions/duplicate-design.ts +35 -9
  95. package/corpus/templates/design/actions/generate-design.ts +146 -69
  96. package/corpus/templates/design/actions/generate-screens.ts +51 -19
  97. package/corpus/templates/design/actions/get-design-snapshot.ts +5 -1
  98. package/corpus/templates/design/actions/get-design.ts +2 -0
  99. package/corpus/templates/design/actions/import-design-project.ts +28 -9
  100. package/corpus/templates/design/actions/import-document.ts +22 -8
  101. package/corpus/templates/design/actions/index-design-system-with-builder.ts +6 -153
  102. package/corpus/templates/design/actions/navigate.ts +105 -54
  103. package/corpus/templates/design/actions/set-default-design-system.ts +17 -3
  104. package/corpus/templates/design/actions/show-design-questions.ts +2 -0
  105. package/corpus/templates/design/actions/update-design.ts +2 -1
  106. package/corpus/templates/design/actions/view-screen.ts +12 -6
  107. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +4 -4
  108. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +159 -41
  109. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +8 -4
  110. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +37 -42
  111. package/corpus/templates/design/app/components/design/EditPanel.tsx +336 -183
  112. package/corpus/templates/design/app/components/design/LayersPanel.tsx +153 -34
  113. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +135 -33
  114. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +6 -0
  115. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
  116. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +4 -10
  117. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +84 -43
  118. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +4 -4
  119. package/corpus/templates/design/app/components/design/inspector/{FigmaColorPicker.tsx → DesignColorPicker.tsx} +89 -62
  120. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +14 -26
  121. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +40 -12
  122. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +13 -4
  123. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +13 -13
  124. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -9
  125. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +13 -4
  126. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +6 -6
  127. package/corpus/templates/design/app/components/design/inspector/{figma-icons.tsx → design-icons.tsx} +2 -2
  128. package/corpus/templates/design/app/components/design/inspector/index.ts +12 -12
  129. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +5 -2
  130. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -3
  131. package/corpus/templates/design/app/components/layout/Layout.tsx +5 -2
  132. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  133. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +167 -91
  134. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +16 -3
  135. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +15 -0
  136. package/corpus/templates/design/app/global.css +4 -0
  137. package/corpus/templates/design/app/hooks/use-design-system.ts +4 -1
  138. package/corpus/templates/design/app/hooks/use-navigation-state.ts +38 -3
  139. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +9 -2
  140. package/corpus/templates/design/app/i18n/zh-TW.ts +22 -0
  141. package/corpus/templates/design/app/i18n-data.ts +527 -0
  142. package/corpus/templates/design/app/lib/design-systems.ts +6 -4
  143. package/corpus/templates/design/app/lib/design-templates.ts +15 -3
  144. package/corpus/templates/design/app/pages/DesignEditor.tsx +641 -158
  145. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +42 -34
  146. package/corpus/templates/design/app/pages/VisualEdit.tsx +100 -0
  147. package/corpus/templates/design/app/root.tsx +42 -9
  148. package/corpus/templates/design/app/routes/visual-edit.tsx +7 -0
  149. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +1 -1
  150. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +1 -1
  151. package/corpus/templates/design/changelog/2026-06-28-visual-code-design-mode.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-29-design-generation-prompts-now-show-connect-ai-before-sending.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +1 -1
  154. package/corpus/templates/design/changelog/2026-06-29-fixed-design-editor-exports-and-gradient-edits-so-multi-scre.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-29-png-export-handles-modern-css-color-functions-more-reliably.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-29-png-export-now-ignores-duplicate-clicks-while-a-download-is-.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-29-public-visual-edit-and-shared-design-links-now-invite-visito.md +6 -0
  159. package/corpus/templates/design/changelog/2026-06-29-visual-edit-actions-now-reject-missing-design-targets-before.md +6 -0
  160. package/corpus/templates/design/e2e/README.md +71 -0
  161. package/corpus/templates/design/e2e/global-setup.ts +157 -0
  162. package/corpus/templates/design/e2e/helpers.ts +148 -0
  163. package/corpus/templates/design/netlify.toml +3 -4
  164. package/corpus/templates/design/package.json +5 -1
  165. package/corpus/templates/design/playwright.config.ts +51 -0
  166. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +121 -0
  167. package/corpus/templates/design/server/handlers/uploads.ts +89 -38
  168. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +181 -0
  169. package/corpus/templates/design/server/lib/coding-handoff.ts +33 -4
  170. package/corpus/templates/design/server/lib/design-export.ts +35 -8
  171. package/corpus/templates/design/server/plugins/agent-chat.ts +4 -0
  172. package/corpus/templates/design/server/plugins/auth.ts +10 -1
  173. package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +1 -0
  174. package/corpus/templates/design/shared/api.ts +2 -0
  175. package/corpus/templates/design/shared/apply-edits.ts +12 -8
  176. package/corpus/templates/design/shared/canvas-math.ts +19 -1
  177. package/corpus/templates/design/shared/code-layer.ts +87 -28
  178. package/corpus/templates/design/shared/generation-session.ts +1 -0
  179. package/corpus/templates/design/shared/resolve-tweaks.ts +4 -3
  180. package/corpus/templates/design/shared/shader-presets.ts +10 -0
  181. package/corpus/templates/design/shared/source-mode.ts +9 -0
  182. package/corpus/templates/design/vitest.config.ts +2 -1
  183. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
  184. package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +1 -1
  185. package/corpus/templates/plan/.agents/skills/visual-plan/references/local-files.md +14 -5
  186. package/corpus/templates/plan/.agents/skills/visual-recap/references/local-files.md +14 -5
  187. package/corpus/templates/plan/AGENTS.md +1 -1
  188. package/corpus/templates/plan/actions/create-plan-design.ts +1 -1
  189. package/corpus/templates/plan/actions/validate-local-plan-source.ts +110 -0
  190. package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -0
  191. package/corpus/templates/plan/docs/commenting-ux-plan.md +2 -2
  192. package/corpus/templates/plan/server/lib/plan-connector-catalog.ts +1 -0
  193. package/corpus/templates/plan/server/lib/public-action-paths.ts +1 -0
  194. package/corpus/templates/plan/server/plan-content.ts +1 -1
  195. package/corpus/templates/plan/server/ui-plan-html.ts +2 -2
  196. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +6 -153
  197. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +53 -38
  198. package/corpus/templates/slides/app/components/design-system/{fig-import-response.ts → builder-index-response.ts} +9 -6
  199. package/corpus/templates/slides/app/components/visual-editor/MultiSelectChip.tsx +1 -1
  200. package/corpus/templates/slides/changelog/2026-06-29-design-system-setup-now-indexes-uploaded-design-files-throug.md +6 -0
  201. package/corpus/templates/slides/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
  202. package/corpus/templates/slides/netlify.toml +3 -6
  203. package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +116 -0
  204. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +179 -0
  205. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -1
  206. package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +1 -0
  207. package/dist/action.d.ts +23 -0
  208. package/dist/action.d.ts.map +1 -1
  209. package/dist/action.js +9 -0
  210. package/dist/action.js.map +1 -1
  211. package/dist/agent/durable-background.d.ts +9 -7
  212. package/dist/agent/durable-background.d.ts.map +1 -1
  213. package/dist/agent/durable-background.js +27 -11
  214. package/dist/agent/durable-background.js.map +1 -1
  215. package/dist/agent/production-agent.d.ts +10 -0
  216. package/dist/agent/production-agent.d.ts.map +1 -1
  217. package/dist/agent/production-agent.js +4 -1
  218. package/dist/agent/production-agent.js.map +1 -1
  219. package/dist/agent/run-loop-with-resume.d.ts +2 -1
  220. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  221. package/dist/agent/run-loop-with-resume.js +2 -2
  222. package/dist/agent/run-loop-with-resume.js.map +1 -1
  223. package/dist/brand-kit/fig/index.d.ts +4 -4
  224. package/dist/brand-kit/fig/index.d.ts.map +1 -1
  225. package/dist/brand-kit/fig/index.js +14 -27
  226. package/dist/brand-kit/fig/index.js.map +1 -1
  227. package/dist/cli/index.js +1 -1
  228. package/dist/cli/index.js.map +1 -1
  229. package/dist/cli/mcp-config-writers.d.ts +15 -7
  230. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  231. package/dist/cli/mcp-config-writers.js +198 -45
  232. package/dist/cli/mcp-config-writers.js.map +1 -1
  233. package/dist/cli/plan-local.d.ts +30 -0
  234. package/dist/cli/plan-local.d.ts.map +1 -1
  235. package/dist/cli/plan-local.js +281 -56
  236. package/dist/cli/plan-local.js.map +1 -1
  237. package/dist/cli/skills.d.ts +2 -2
  238. package/dist/cli/skills.d.ts.map +1 -1
  239. package/dist/cli/skills.js +32 -8
  240. package/dist/cli/skills.js.map +1 -1
  241. package/dist/client/AssistantChat.d.ts.map +1 -1
  242. package/dist/client/AssistantChat.js +11 -1
  243. package/dist/client/AssistantChat.js.map +1 -1
  244. package/dist/client/agent-chat.d.ts.map +1 -1
  245. package/dist/client/agent-chat.js +15 -2
  246. package/dist/client/agent-chat.js.map +1 -1
  247. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  248. package/dist/client/composer/PromptComposer.js +35 -1
  249. package/dist/client/composer/PromptComposer.js.map +1 -1
  250. package/dist/client/org/OrgSwitcher.js +1 -1
  251. package/dist/client/org/OrgSwitcher.js.map +1 -1
  252. package/dist/client/sharing/ShareButton.d.ts +1 -1
  253. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  254. package/dist/client/sharing/ShareButton.js +2 -15
  255. package/dist/client/sharing/ShareButton.js.map +1 -1
  256. package/dist/collab/presence.d.ts +1 -1
  257. package/dist/collab/presence.js +1 -1
  258. package/dist/collab/presence.js.map +1 -1
  259. package/dist/collab/routes.d.ts +1 -1
  260. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  261. package/dist/mcp/connect-route.d.ts.map +1 -1
  262. package/dist/mcp/connect-route.js +34 -5
  263. package/dist/mcp/connect-route.js.map +1 -1
  264. package/dist/observability/routes.d.ts +2 -2
  265. package/dist/progress/routes.d.ts +1 -1
  266. package/dist/resources/handlers.d.ts +1 -1
  267. package/dist/server/action-discovery.d.ts.map +1 -1
  268. package/dist/server/action-discovery.js +5 -0
  269. package/dist/server/action-discovery.js.map +1 -1
  270. package/dist/server/action-routes.d.ts.map +1 -1
  271. package/dist/server/action-routes.js +14 -0
  272. package/dist/server/action-routes.js.map +1 -1
  273. package/dist/server/agent-chat-plugin.d.ts +6 -0
  274. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  275. package/dist/server/agent-chat-plugin.js +12 -3
  276. package/dist/server/agent-chat-plugin.js.map +1 -1
  277. package/dist/vite/client.d.ts.map +1 -1
  278. package/dist/vite/client.js +12 -1
  279. package/dist/vite/client.js.map +1 -1
  280. package/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
  281. package/docs/content/locales/ar-SA/template-design.mdx +1 -1
  282. package/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
  283. package/docs/content/locales/de-DE/template-design.mdx +1 -1
  284. package/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
  285. package/docs/content/locales/es-ES/template-design.mdx +1 -1
  286. package/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
  287. package/docs/content/locales/fr-FR/template-design.mdx +1 -1
  288. package/docs/content/locales/hi-IN/template-design.mdx +1 -1
  289. package/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
  290. package/docs/content/locales/ja-JP/template-design.mdx +1 -1
  291. package/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
  292. package/docs/content/locales/ko-KR/template-design.mdx +1 -1
  293. package/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
  294. package/docs/content/locales/pt-BR/template-design.mdx +1 -1
  295. package/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
  296. package/docs/content/locales/zh-CN/template-design.mdx +1 -1
  297. package/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
  298. package/docs/content/locales/zh-TW/template-design.mdx +1 -1
  299. package/docs/content/real-time-collaboration.mdx +2 -2
  300. package/docs/content/template-design.mdx +1 -1
  301. package/package.json +3 -7
  302. package/corpus/core/src/brand-kit/fig/decode.ts +0 -410
  303. package/corpus/core/src/brand-kit/fig/extract-design-system.ts +0 -947
  304. package/corpus/core/src/brand-kit/fig/fig-to-html.ts +0 -1906
  305. package/corpus/templates/design/actions/import-figma.ts +0 -55
  306. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +0 -6
  307. package/corpus/templates/design/server/handlers/import-figma-system.ts +0 -86
  308. package/corpus/templates/design/server/routes/api/import-figma-system.post.ts +0 -1
  309. package/corpus/templates/slides/server/handlers/import-figma-system.ts +0 -101
  310. package/corpus/templates/slides/server/routes/api/import-figma-system.post.ts +0 -1
  311. package/dist/brand-kit/fig/decode.d.ts +0 -33
  312. package/dist/brand-kit/fig/decode.d.ts.map +0 -1
  313. package/dist/brand-kit/fig/decode.js +0 -358
  314. package/dist/brand-kit/fig/decode.js.map +0 -1
  315. package/dist/brand-kit/fig/extract-design-system.d.ts +0 -44
  316. package/dist/brand-kit/fig/extract-design-system.d.ts.map +0 -1
  317. package/dist/brand-kit/fig/extract-design-system.js +0 -752
  318. package/dist/brand-kit/fig/extract-design-system.js.map +0 -1
  319. package/dist/brand-kit/fig/fig-to-html.d.ts +0 -246
  320. package/dist/brand-kit/fig/fig-to-html.d.ts.map +0 -1
  321. package/dist/brand-kit/fig/fig-to-html.js +0 -1506
  322. package/dist/brand-kit/fig/fig-to-html.js.map +0 -1
@@ -152,6 +152,7 @@ export interface LayersPanelProps {
152
152
  onHoverLayer?: (id: string) => void;
153
153
  onLeaveLayer?: (id: string) => void;
154
154
  onMoveLayer?: (intent: LayersPanelMoveIntent) => void;
155
+ canMoveLayer?: (intent: LayersPanelMoveIntent) => boolean;
155
156
  }
156
157
 
157
158
  interface FlatLayerRow {
@@ -165,6 +166,10 @@ interface FlatLayerRow {
165
166
  const SECTION_CODE_ID = "__design_layers_code__";
166
167
  const SECTION_ELEMENT_ID = "__design_layers_elements__";
167
168
 
169
+ // Module-level drag state: dataTransfer.getData() returns "" during dragover
170
+ // per spec; the source row stores the drag payload here on dragstart instead.
171
+ let activeDragState: { sourceId: string; draggedIds: string[] } | null = null;
172
+
168
173
  function defaultLabels(t: ReturnType<typeof useT>): LayersPanelLabels {
169
174
  return {
170
175
  title: t("layersPanel.title"),
@@ -390,6 +395,7 @@ export function LayersPanel({
390
395
  onHoverLayer,
391
396
  onLeaveLayer,
392
397
  onMoveLayer,
398
+ canMoveLayer,
393
399
  }: LayersPanelProps) {
394
400
  const t = useT();
395
401
  const labels = useMemo(() => mergeLabels(labelsProp, t), [labelsProp, t]);
@@ -400,6 +406,7 @@ export function LayersPanel({
400
406
  const rowElementRefs = useRef(new Map<string, HTMLDivElement>());
401
407
  const [renamingId, setRenamingId] = useState<string | null>(null);
402
408
  const [renameDraft, setRenameDraft] = useState("");
409
+ const renameOriginalNameRef = useRef<string>("");
403
410
  const [dropIndicator, setDropIndicator] =
404
411
  useState<LayersPanelMoveIntent | null>(null);
405
412
  const [searchOpen, setSearchOpen] = useState(Boolean(searchQuery));
@@ -501,7 +508,11 @@ export function LayersPanel({
501
508
  nextIds = [id];
502
509
  }
503
510
 
504
- lastSelectionAnchorRef.current = id;
511
+ // Only advance the anchor on plain clicks; Shift+clicks extend from the
512
+ // existing anchor so the pivot stays fixed across consecutive range clicks.
513
+ if (!options.range) {
514
+ lastSelectionAnchorRef.current = id;
515
+ }
505
516
  onSelectionChange(nextIds, { id, selectedIds: nextIds, ...options });
506
517
  },
507
518
  [onSelectionChange, selectableVisibleIds, selectedIdSet, selectedIds],
@@ -512,9 +523,14 @@ export function LayersPanel({
512
523
  const nextName = renameDraft.trim();
513
524
  // The panel only emits rename intent. Code-backed DOM layer renames must
514
525
  // persist through a safe source edit that updates data-agent-native-layer-name.
515
- if (nextName) onRename?.(id, nextName);
526
+ if (nextName) {
527
+ onRename?.(id, nextName);
528
+ }
529
+ // When the draft is empty, silently revert rather than saving an empty name.
530
+ // This matches Figma's behavior of restoring the previous name on empty commit.
516
531
  setRenamingId(null);
517
532
  setRenameDraft("");
533
+ renameOriginalNameRef.current = "";
518
534
  },
519
535
  [onRename, renameDraft],
520
536
  );
@@ -522,6 +538,7 @@ export function LayersPanel({
522
538
  const startRename = useCallback(
523
539
  (node: LayersPanelNode) => {
524
540
  if (!onRename || node.renamable === false) return;
541
+ renameOriginalNameRef.current = node.name;
525
542
  setRenamingId(node.id);
526
543
  setRenameDraft(node.name);
527
544
  },
@@ -717,9 +734,11 @@ export function LayersPanel({
717
734
  onHoverLayer={onHoverLayer}
718
735
  onLeaveLayer={onLeaveLayer}
719
736
  onMoveLayer={onMoveLayer}
737
+ canMoveLayer={canMoveLayer}
720
738
  dropIndicator={dropIndicator}
721
739
  onDropIndicatorChange={setDropIndicator}
722
740
  selectedIds={selectedIds}
741
+ visibleRows={visibleRows}
723
742
  />
724
743
  ))}
725
744
  </div>
@@ -754,9 +773,11 @@ function LayerRow({
754
773
  onHoverLayer,
755
774
  onLeaveLayer,
756
775
  onMoveLayer,
776
+ canMoveLayer,
757
777
  dropIndicator,
758
778
  onDropIndicatorChange,
759
779
  selectedIds,
780
+ visibleRows,
760
781
  }: {
761
782
  row: FlatLayerRow;
762
783
  labels: LayersPanelLabels;
@@ -785,9 +806,11 @@ function LayerRow({
785
806
  onHoverLayer?: (id: string) => void;
786
807
  onLeaveLayer?: (id: string) => void;
787
808
  onMoveLayer?: (intent: LayersPanelMoveIntent) => void;
809
+ canMoveLayer?: (intent: LayersPanelMoveIntent) => boolean;
788
810
  dropIndicator: LayersPanelMoveIntent | null;
789
811
  onDropIndicatorChange: (intent: LayersPanelMoveIntent | null) => void;
790
812
  selectedIds: readonly string[];
813
+ visibleRows: FlatLayerRow[];
791
814
  }) {
792
815
  const { node, depth, hasChildren } = row;
793
816
  const selectable = node.selectable !== false;
@@ -796,6 +819,9 @@ function LayerRow({
796
819
  const draggable = selectable && Boolean(onMoveLayer);
797
820
  const activeDrop =
798
821
  dropIndicator?.targetId === node.id ? dropIndicator.placement : null;
822
+ // Tracks whether the user pressed Escape to cancel rename so that the
823
+ // subsequent blur event does not commit the edit.
824
+ const renameCancelledRef = useRef(false);
799
825
 
800
826
  const handlePointerSelect = (event: MouseEvent<HTMLButtonElement>) => {
801
827
  if (!selectable) return;
@@ -807,19 +833,87 @@ function LayerRow({
807
833
  };
808
834
 
809
835
  const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {
810
- if (event.key === "Enter") {
836
+ const focusVisibleButton = (nextIndex: number) => {
837
+ const tree = event.currentTarget.closest('[role="tree"]');
838
+ if (!tree) return false;
839
+ const buttons = Array.from(
840
+ tree.querySelectorAll<HTMLButtonElement>("[data-layer-row-button]"),
841
+ ).filter((button) => !button.disabled);
842
+ const target =
843
+ buttons[Math.max(0, Math.min(buttons.length - 1, nextIndex))];
844
+ target?.focus();
845
+ return Boolean(target);
846
+ };
847
+ const focusNodeButton = (nodeId: string) => {
848
+ const tree = event.currentTarget.closest('[role="tree"]');
849
+ const target = tree?.querySelector<HTMLButtonElement>(
850
+ `[data-layer-node-id="${CSS.escape(nodeId)}"]`,
851
+ );
852
+ if (!target || target.disabled) return false;
853
+ target.focus();
854
+ return true;
855
+ };
856
+ const currentIndex = visibleRows.findIndex(
857
+ (visibleRow) => visibleRow.rowKey === row.rowKey,
858
+ );
859
+
860
+ if (event.key === "Enter" || event.key === " ") {
861
+ event.preventDefault();
862
+ if (!selectable) return;
863
+ onSelect(node.id, {
864
+ additive: event.metaKey || event.ctrlKey,
865
+ range: event.shiftKey,
866
+ source: "keyboard",
867
+ });
868
+ return;
869
+ }
870
+ if (event.key === "F2") {
811
871
  event.preventDefault();
812
872
  onStartRename(node);
813
873
  return;
814
874
  }
875
+ if (event.key === "ArrowDown") {
876
+ event.preventDefault();
877
+ focusVisibleButton(currentIndex + 1);
878
+ return;
879
+ }
880
+ if (event.key === "ArrowUp") {
881
+ event.preventDefault();
882
+ focusVisibleButton(currentIndex - 1);
883
+ return;
884
+ }
885
+ if (event.key === "Home") {
886
+ event.preventDefault();
887
+ focusVisibleButton(0);
888
+ return;
889
+ }
890
+ if (event.key === "End") {
891
+ event.preventDefault();
892
+ focusVisibleButton(visibleRows.length - 1);
893
+ return;
894
+ }
815
895
  if (event.key === "ArrowRight" && hasChildren && !isExpanded) {
816
896
  event.preventDefault();
817
897
  onToggleExpanded(true);
818
898
  return;
819
899
  }
900
+ if (event.key === "ArrowRight" && hasChildren && isExpanded) {
901
+ event.preventDefault();
902
+ const child = visibleRows[currentIndex + 1];
903
+ if (child?.ancestorIds.includes(node.id)) {
904
+ focusVisibleButton(currentIndex + 1);
905
+ }
906
+ return;
907
+ }
820
908
  if (event.key === "ArrowLeft" && hasChildren && isExpanded) {
821
909
  event.preventDefault();
822
910
  onToggleExpanded(false);
911
+ return;
912
+ }
913
+ if (event.key === "ArrowLeft" && row.ancestorIds.length > 0) {
914
+ event.preventDefault();
915
+ const parentId = row.ancestorIds[row.ancestorIds.length - 1];
916
+ if (parentId) focusNodeButton(parentId);
823
917
  }
824
918
  };
825
919
 
@@ -828,58 +922,58 @@ function LayerRow({
828
922
  event.preventDefault();
829
923
  return;
830
924
  }
831
- const draggedIds = selectedIds.includes(node.id)
925
+ const rawDraggedIds = selectedIds.includes(node.id)
832
926
  ? selectedIds.filter((id) => !id.startsWith("__"))
833
927
  : [node.id];
928
+ // Remove any node whose ancestor is also being dragged to avoid double-moves.
929
+ // When a parent is moved, its children move with it automatically.
930
+ const draggedIdSet = new Set(rawDraggedIds);
931
+ const draggedIds = rawDraggedIds.filter((id) => {
932
+ const rowForId = visibleRows.find((r) => r.node.id === id);
933
+ return !rowForId?.ancestorIds.some((ancestorId) =>
934
+ draggedIdSet.has(ancestorId),
935
+ );
936
+ });
834
937
  event.dataTransfer.effectAllowed = "move";
835
938
  event.dataTransfer.setData("application/x-design-layer-id", node.id);
836
939
  event.dataTransfer.setData(
837
940
  "application/x-design-layer-ids",
838
941
  JSON.stringify(draggedIds),
839
942
  );
943
+ // Store drag state at module level so handleDragOver can read it.
944
+ // dataTransfer.getData() returns "" during dragover per the HTML spec.
945
+ activeDragState = { sourceId: node.id, draggedIds };
840
946
  };
841
947
 
842
948
  const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
843
949
  if (!onMoveLayer || !selectable) return;
844
- const sourceId =
845
- event.dataTransfer.getData("application/x-design-layer-id") || "";
950
+ // dataTransfer.getData() always returns "" during dragover per spec.
951
+ // Read from the module-level activeDragState set in handleDragStart instead.
952
+ if (!activeDragState) return;
953
+ const { sourceId, draggedIds } = activeDragState;
846
954
  if (sourceId === node.id) return;
847
- const rawIds = event.dataTransfer.getData("application/x-design-layer-ids");
848
- let draggedIds = [sourceId];
849
- try {
850
- const parsed = JSON.parse(rawIds);
851
- if (Array.isArray(parsed)) {
852
- draggedIds = parsed.filter(
853
- (id): id is string => typeof id === "string",
854
- );
855
- }
856
- } catch {
857
- // Ignore malformed drag payloads and fall back to the primary id.
858
- }
859
955
  const cleanedIds = draggedIds.filter(
860
956
  (id) => id && id !== node.id && !id.startsWith("__"),
861
957
  );
862
958
  if (cleanedIds.length === 0) return;
863
- event.preventDefault();
864
- event.dataTransfer.dropEffect = "move";
865
- onDropIndicatorChange({
959
+ const intent = {
866
960
  draggedIds: cleanedIds,
867
961
  targetId: node.id,
868
962
  placement: dropPlacementForEvent(event, hasChildren),
869
- });
963
+ } satisfies LayersPanelMoveIntent;
964
+ if (canMoveLayer && !canMoveLayer(intent)) return;
965
+ event.preventDefault();
966
+ event.dataTransfer.dropEffect = "move";
967
+ onDropIndicatorChange(intent);
870
968
  };
871
969
 
872
970
  const handleDrop = (event: DragEvent<HTMLDivElement>) => {
873
- if (
874
- !onMoveLayer ||
875
- !selectable ||
876
- !dropIndicator ||
877
- dropIndicator.targetId !== node.id
878
- ) {
971
+ if (!onMoveLayer || !selectable) {
879
972
  onDropIndicatorChange(null);
880
973
  return;
881
974
  }
882
975
  event.preventDefault();
976
+ // getData() is safe in the drop handler (unlike dragover).
883
977
  const rawIds = event.dataTransfer.getData("application/x-design-layer-ids");
884
978
  let draggedIds = [
885
979
  event.dataTransfer.getData("application/x-design-layer-id"),
@@ -898,11 +992,16 @@ function LayerRow({
898
992
  (id) => id && id !== node.id && !id.startsWith("__"),
899
993
  );
900
994
  if (cleanedIds.length > 0) {
901
- onMoveLayer({
995
+ // Recompute placement from the drop event position rather than relying on
996
+ // React state (dropIndicator) which may be stale or null.
997
+ const intent = {
902
998
  draggedIds: cleanedIds,
903
999
  targetId: node.id,
904
- placement: dropIndicator.placement,
905
- });
1000
+ placement: dropPlacementForEvent(event, hasChildren),
1001
+ } satisfies LayersPanelMoveIntent;
1002
+ if (!canMoveLayer || canMoveLayer(intent)) {
1003
+ onMoveLayer(intent);
1004
+ }
906
1005
  }
907
1006
  onDropIndicatorChange(null);
908
1007
  };
@@ -918,9 +1017,19 @@ function LayerRow({
918
1017
  draggable={draggable}
919
1018
  onDragStart={handleDragStart}
920
1019
  onDragOver={handleDragOver}
921
- onDragLeave={() => onDropIndicatorChange(null)}
1020
+ onDragLeave={(event) => {
1021
+ // Only clear the indicator when the pointer truly leaves this row.
1022
+ // Moving into a child element fires dragleave on the outer div too, so
1023
+ // we suppress the clear when relatedTarget is still within this row.
1024
+ if (event.currentTarget.contains(event.relatedTarget as Node | null))
1025
+ return;
1026
+ onDropIndicatorChange(null);
1027
+ }}
922
1028
  onDrop={handleDrop}
923
- onDragEnd={() => onDropIndicatorChange(null)}
1029
+ onDragEnd={() => {
1030
+ activeDragState = null;
1031
+ onDropIndicatorChange(null);
1032
+ }}
924
1033
  onMouseEnter={() => onHoverLayer?.(node.id)}
925
1034
  onMouseLeave={() => onLeaveLayer?.(node.id)}
926
1035
  >
@@ -976,6 +1085,8 @@ function LayerRow({
976
1085
  <button
977
1086
  type="button"
978
1087
  disabled={!selectable}
1088
+ data-layer-row-button
1089
+ data-layer-node-id={node.id}
979
1090
  className={cn(
980
1091
  "flex min-w-0 flex-1 items-center gap-2 overflow-hidden rounded-sm px-0.5 py-0 text-left outline-none focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]",
981
1092
  selectable ? "cursor-default" : "cursor-default opacity-80",
@@ -1004,13 +1115,21 @@ function LayerRow({
1004
1115
  value={renameDraft}
1005
1116
  onClick={(event) => event.stopPropagation()}
1006
1117
  onChange={(event) => onRenameDraftChange(event.target.value)}
1007
- onBlur={() => onCommitRename(node.id)}
1118
+ onBlur={() => {
1119
+ // Escape sets renameCancelledRef before blur fires; skip commit.
1120
+ if (renameCancelledRef.current) {
1121
+ renameCancelledRef.current = false;
1122
+ return;
1123
+ }
1124
+ onCommitRename(node.id);
1125
+ }}
1008
1126
  onKeyDown={(event) => {
1009
1127
  if (event.key === "Enter") {
1010
1128
  event.preventDefault();
1011
1129
  onCommitRename(node.id);
1012
1130
  } else if (event.key === "Escape") {
1013
1131
  event.preventDefault();
1132
+ renameCancelledRef.current = true;
1014
1133
  onCancelRename();
1015
1134
  }
1016
1135
  }}