@agent-native/core 0.82.0 → 0.84.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 (474) hide show
  1. package/README.md +2 -2
  2. package/corpus/README.md +1 -1
  3. package/corpus/core/CHANGELOG.md +34 -0
  4. package/corpus/core/README.md +2 -2
  5. package/corpus/core/docs/content/cloneable-saas.mdx +2 -2
  6. package/corpus/core/docs/content/faq.mdx +1 -1
  7. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  8. package/corpus/core/docs/content/locales/ar-SA/faq.mdx +1 -1
  9. package/corpus/core/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  10. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  11. package/corpus/core/docs/content/locales/de-DE/faq.mdx +1 -1
  12. package/corpus/core/docs/content/locales/de-DE/template-chat.mdx +1 -1
  13. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  14. package/corpus/core/docs/content/locales/es-ES/faq.mdx +1 -1
  15. package/corpus/core/docs/content/locales/es-ES/template-chat.mdx +1 -1
  16. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  17. package/corpus/core/docs/content/locales/fr-FR/faq.mdx +1 -1
  18. package/corpus/core/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  19. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  20. package/corpus/core/docs/content/locales/hi-IN/faq.mdx +1 -1
  21. package/corpus/core/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  22. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  23. package/corpus/core/docs/content/locales/ja-JP/faq.mdx +1 -1
  24. package/corpus/core/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  25. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  26. package/corpus/core/docs/content/locales/ko-KR/faq.mdx +1 -1
  27. package/corpus/core/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  28. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  29. package/corpus/core/docs/content/locales/pt-BR/faq.mdx +1 -1
  30. package/corpus/core/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  31. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  32. package/corpus/core/docs/content/locales/zh-CN/faq.mdx +1 -1
  33. package/corpus/core/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  34. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  35. package/corpus/core/docs/content/locales/zh-TW/faq.mdx +1 -1
  36. package/corpus/core/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  37. package/corpus/core/docs/content/template-chat.mdx +1 -1
  38. package/corpus/core/package.json +1 -1
  39. package/corpus/core/src/agent/engine/builtin.ts +1 -1
  40. package/corpus/core/src/agent/engine/output-tokens.ts +1 -1
  41. package/corpus/core/src/agent/harness/acp-adapter.ts +28 -4
  42. package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +3 -0
  43. package/corpus/core/src/agent/harness/translate.ts +3 -0
  44. package/corpus/core/src/agent/harness/types.ts +1 -0
  45. package/corpus/core/src/agent/model-config.ts +34 -13
  46. package/corpus/core/src/agent/production-agent.ts +87 -10
  47. package/corpus/core/src/agent/thread-data-builder.ts +29 -4
  48. package/corpus/core/src/agent/tool-call-journal.ts +109 -48
  49. package/corpus/core/src/agent/types.ts +6 -1
  50. package/corpus/core/src/cli/design-connect.ts +106 -0
  51. package/corpus/core/src/cli/gateway-helpers.ts +17 -0
  52. package/corpus/core/src/cli/recap.ts +0 -2
  53. package/corpus/core/src/cli/skills.ts +54 -16
  54. package/corpus/core/src/cli/workspace-dev.ts +29 -5
  55. package/corpus/core/src/client/AssistantChat.tsx +89 -42
  56. package/corpus/core/src/client/CommandMenu.tsx +34 -12
  57. package/corpus/core/src/client/DefaultSpinner.tsx +8 -1
  58. package/corpus/core/src/client/chat/message-components.tsx +49 -1
  59. package/corpus/core/src/client/chat/repo-helpers.ts +71 -0
  60. package/corpus/core/src/client/chat/run-recovery.tsx +15 -5
  61. package/corpus/core/src/client/components/ApiKeySettings.tsx +8 -8
  62. package/corpus/core/src/client/components/CodeRequiredDialog.tsx +26 -15
  63. package/corpus/core/src/client/components/MissingKeyCard.tsx +13 -6
  64. package/corpus/core/src/client/composer/TiptapComposer.tsx +4 -3
  65. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +0 -1
  66. package/corpus/core/src/client/guided-questions.tsx +21 -27
  67. package/corpus/core/src/client/integrations/IntegrationCard.tsx +1 -1
  68. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +1 -1
  69. package/corpus/core/src/client/onboarding/OnboardingBanner.tsx +2 -2
  70. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +23 -19
  71. package/corpus/core/src/client/resources/ResourceEditor.tsx +18 -10
  72. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  73. package/corpus/core/src/client/settings/SettingsPanel.tsx +8 -3
  74. package/corpus/core/src/client/settings/useBuilderStatus.ts +8 -41
  75. package/corpus/core/src/client/useProductionAgent.ts +6 -2
  76. package/corpus/core/src/deploy/build.ts +1 -1
  77. package/corpus/core/src/observability/traces.ts +3 -3
  78. package/corpus/core/src/onboarding/default-steps.ts +1 -1
  79. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
  80. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
  81. package/corpus/core/src/server/agent-chat-plugin.ts +177 -81
  82. package/corpus/core/src/server/core-routes-plugin.ts +7 -1
  83. package/corpus/core/src/server/open-route.ts +59 -40
  84. package/corpus/core/src/shared/reasoning-effort.ts +2 -0
  85. package/corpus/core/src/sharing/access.ts +22 -2
  86. package/corpus/core/src/sharing/registry.ts +18 -0
  87. package/corpus/core/src/styles/agent-native.css +104 -20
  88. package/corpus/core/src/styles/rich-markdown-editor.css +11 -10
  89. package/corpus/templates/analytics/actions/hubspot-deals.ts +64 -4
  90. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +10 -10
  91. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +10 -10
  92. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +6 -5
  93. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +9 -9
  94. package/corpus/templates/analytics/app/global.css +4 -0
  95. package/corpus/templates/analytics/app/lib/chart-theme.ts +13 -0
  96. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +22 -24
  97. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-charts-now-use-theme-aware-tooltip-and-grid-colors.md +6 -0
  98. package/corpus/templates/analytics/changelog/2026-06-30-fixed-ask-composer-spacing-so-the-chat-field-has-a-comfortab.md +6 -0
  99. package/corpus/templates/calendar/AGENTS.md +4 -0
  100. package/corpus/templates/calendar/actions/connect-google-calendar.ts +80 -0
  101. package/corpus/templates/calendar/changelog/2026-06-30-calendar-now-gives-the-agent-a-safe-google-connection-link-i.md +6 -0
  102. package/corpus/templates/calendar/server/plugins/agent-chat.ts +4 -0
  103. package/corpus/templates/content/.env.local.example +6 -0
  104. package/corpus/templates/content/AGENTS.md +10 -1
  105. package/corpus/templates/content/actions/_builder-cms-read-client.ts +14 -1
  106. package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +43 -0
  107. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +79 -7
  108. package/corpus/templates/content/actions/_database-source-utils.ts +987 -22
  109. package/corpus/templates/content/actions/_database-utils.ts +41 -0
  110. package/corpus/templates/content/actions/_local-file-documents.ts +74 -1
  111. package/corpus/templates/content/actions/attach-content-database-source.ts +33 -8
  112. package/corpus/templates/content/actions/change-content-database-source-role.ts +14 -0
  113. package/corpus/templates/content/actions/disconnect-content-database-source.ts +3 -0
  114. package/corpus/templates/content/actions/execute-builder-source-execution.ts +71 -3
  115. package/corpus/templates/content/actions/list-content-databases.ts +41 -33
  116. package/corpus/templates/content/actions/process-builder-body-hydration.ts +47 -0
  117. package/corpus/templates/content/actions/update-document.ts +93 -0
  118. package/corpus/templates/content/app/blocks/SourceComponentBlock.tsx +277 -0
  119. package/corpus/templates/content/app/blocks/contentBlockRegistry.tsx +2 -0
  120. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +5 -5
  121. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +45 -4
  122. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +5 -1
  123. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +92 -0
  124. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +5 -3
  125. package/corpus/templates/content/app/components/editor/extensions/registryBlocks.ts +41 -0
  126. package/corpus/templates/content/app/components/editor/registrySlashItems.ts +4 -0
  127. package/corpus/templates/content/app/global.css +16 -8
  128. package/corpus/templates/content/app/hooks/use-content-database.ts +24 -0
  129. package/corpus/templates/content/app/i18n/zh-TW.ts +24 -0
  130. package/corpus/templates/content/app/i18n-data.ts +212 -0
  131. package/corpus/templates/content/app/lib/content-command-search.ts +64 -0
  132. package/corpus/templates/content/app/root.tsx +236 -8
  133. package/corpus/templates/content/changelog/2026-06-29-builder-cms-sources-now-sync-article-bodies-through-content.md +6 -0
  134. package/corpus/templates/content/changelog/2026-06-30-builder-article-media-now-render-as-images-and-embeds-when-r.md +6 -0
  135. package/corpus/templates/content/changelog/2026-06-30-builder-source-components-now-render-as-preserved-preview-bl.md +6 -0
  136. package/corpus/templates/content/changelog/2026-06-30-cmd-k-search-now-opens-from-the-editor-and-finds-real-content.md +6 -0
  137. package/corpus/templates/content/changelog/2026-06-30-editor-floating-toolbars-now-use-theme-aware-colors-in-light.md +6 -0
  138. package/corpus/templates/content/package.json +3 -1
  139. package/corpus/templates/content/scripts/check-native-deps.mjs +57 -0
  140. package/corpus/templates/content/scripts/dev-database.mjs +83 -0
  141. package/corpus/templates/content/scripts/seed-demo-user.mjs +107 -0
  142. package/corpus/templates/content/server/db/schema.ts +27 -0
  143. package/corpus/templates/content/server/plugins/db.ts +33 -0
  144. package/corpus/templates/content/shared/api.ts +45 -0
  145. package/corpus/templates/content/shared/builder-mdx.ts +905 -5
  146. package/corpus/templates/content/shared/nfm-registry.ts +2 -0
  147. package/corpus/templates/content/shared/source-component-block.ts +141 -0
  148. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +6 -1
  149. package/corpus/templates/design/actions/add-localhost-screens.ts +63 -8
  150. package/corpus/templates/design/actions/apply-motion-edit.ts +12 -46
  151. package/corpus/templates/design/actions/list-design-native-assets.ts +2 -1
  152. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +49 -1
  153. package/corpus/templates/design/actions/navigate.ts +3 -12
  154. package/corpus/templates/design/actions/open-visual-edit.ts +341 -0
  155. package/corpus/templates/design/actions/view-screen.ts +1 -1
  156. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
  157. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +350 -15
  158. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +71 -91
  159. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +25 -27
  160. package/corpus/templates/design/app/components/design/DeviceFrame.tsx +1 -1
  161. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +2 -2
  162. package/corpus/templates/design/app/components/design/EditPanel.tsx +1111 -570
  163. package/corpus/templates/design/app/components/design/LayersPanel.tsx +162 -32
  164. package/corpus/templates/design/app/components/design/MotionDock.tsx +268 -240
  165. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1193 -207
  166. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -1
  167. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +81 -102
  168. package/corpus/templates/design/app/components/design/StatesPanel.tsx +6 -6
  169. package/corpus/templates/design/app/components/design/TokensPanel.tsx +11 -11
  170. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -7
  171. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1225 -154
  172. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +130 -37
  173. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +24 -11
  174. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +184 -162
  175. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +137 -79
  176. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +13 -13
  177. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +8 -8
  178. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
  179. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +4 -4
  180. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +3 -3
  181. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -7
  182. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +14 -11
  183. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +4 -4
  184. package/corpus/templates/design/app/components/design/inspector/index.ts +2 -0
  185. package/corpus/templates/design/app/components/design/types.ts +19 -0
  186. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +61 -78
  187. package/corpus/templates/design/app/components/layout/Header.tsx +0 -1
  188. package/corpus/templates/design/app/components/layout/Layout.tsx +3 -2
  189. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  190. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +5 -4
  191. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
  192. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +2 -2
  193. package/corpus/templates/design/app/global.css +56 -0
  194. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -5
  195. package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -7
  196. package/corpus/templates/design/app/hooks/use-question-flow.ts +3 -2
  197. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +6 -4
  198. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +6 -3
  199. package/corpus/templates/design/app/i18n/zh-TW.ts +5 -14
  200. package/corpus/templates/design/app/i18n-data.ts +63 -188
  201. package/corpus/templates/design/app/lib/agent-chat.ts +13 -0
  202. package/corpus/templates/design/app/pages/DesignEditor.tsx +1755 -401
  203. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +9 -5
  204. package/corpus/templates/design/app/pages/DesignSystems.tsx +2 -2
  205. package/corpus/templates/design/app/pages/Index.tsx +49 -26
  206. package/corpus/templates/design/app/pages/NotFound.tsx +25 -8
  207. package/corpus/templates/design/app/pages/VisualEdit.tsx +17 -5
  208. package/corpus/templates/design/app/routes/examples.tsx +1 -7
  209. package/corpus/templates/design/app/routes/templates.tsx +7 -4
  210. package/corpus/templates/design/changelog/2026-06-30-board-shapes-and-auto-layout-controls-are-clearer.md +6 -0
  211. package/corpus/templates/design/changelog/2026-06-30-canvas-editing-now-keeps-undo-redo-and-cross-screen-layer-mo.md +6 -0
  212. package/corpus/templates/design/changelog/2026-06-30-component-selections-now-use-purple-component-chrome-and-sho.md +6 -0
  213. package/corpus/templates/design/changelog/2026-06-30-constraints-now-stay-tucked-into-a-compact-inspector-preview.md +6 -0
  214. package/corpus/templates/design/changelog/2026-06-30-creating-a-component-now-opens-in-a-compact-inspector-popove.md +6 -0
  215. package/corpus/templates/design/changelog/2026-06-30-design-cards-no-longer-show-legacy-project-type-badges.md +6 -0
  216. package/corpus/templates/design/changelog/2026-06-30-design-chat-now-keeps-new-turns-in-the-visible-design-agent-.md +6 -0
  217. package/corpus/templates/design/changelog/2026-06-30-design-editor-panels-now-keep-their-compact-text-sizing-cons.md +6 -0
  218. package/corpus/templates/design/changelog/2026-06-30-design-no-longer-shows-the-connected-local-code-warning-bann.md +6 -0
  219. package/corpus/templates/design/changelog/2026-06-30-design-now-opens-to-the-files-panel-unless-a-generation-is-a.md +6 -0
  220. package/corpus/templates/design/changelog/2026-06-30-design-opens-with-a-cleaner-empty-canvas-and-loading-preview.md +6 -0
  221. package/corpus/templates/design/changelog/2026-06-30-design-tools-use-simpler-less-decorative-icons.md +6 -0
  222. package/corpus/templates/design/changelog/2026-06-30-dragging-absolute-elements-no-longer-shows-coordinate-labels.md +6 -0
  223. package/corpus/templates/design/changelog/2026-06-30-fixed-all-screens-opening-too-zoomed-in-by-default.md +6 -0
  224. package/corpus/templates/design/changelog/2026-06-30-fixed-the-public-design-assets-sidebar-so-native-components-.md +6 -0
  225. package/corpus/templates/design/changelog/2026-06-30-fixed-the-screen-overview-board-so-empty-board-space-no-long.md +6 -0
  226. package/corpus/templates/design/changelog/2026-06-30-full-view-screens-can-now-scroll-while-remaining-editable.md +6 -0
  227. package/corpus/templates/design/changelog/2026-06-30-inspector-element-headers-show-the-selected-html-tag-and-the.md +6 -0
  228. package/corpus/templates/design/changelog/2026-06-30-inspector-inputs-stay-compact-across-desktop-breakpoints.md +6 -0
  229. package/corpus/templates/design/changelog/2026-06-30-layers-can-be-multi-selected-from-the-canvas-and-edited-toge.md +6 -0
  230. package/corpus/templates/design/changelog/2026-06-30-local-visual-edit-links-can-edit-localhost-frames-without-si.md +6 -0
  231. package/corpus/templates/design/changelog/2026-06-30-localhost-visual-edit-frames-can-now-be-selected-and-edited.md +6 -0
  232. package/corpus/templates/design/changelog/2026-06-30-marquee-selection-now-works-inside-screens-multi-selected-la.md +6 -0
  233. package/corpus/templates/design/changelog/2026-06-30-motion-is-now-available-from-the-persistent-left-rail-and-th.md +6 -0
  234. package/corpus/templates/design/changelog/2026-06-30-motion-timeline-collapse-and-reopen-animations-feel-smoother.md +6 -0
  235. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +6 -0
  236. package/corpus/templates/design/changelog/2026-06-30-new-board-shapes-now-start-with-neutral-gray-styling.md +6 -0
  237. package/corpus/templates/design/changelog/2026-06-30-new-designs-open-into-a-steadier-loading-state-before-the-ed.md +6 -0
  238. package/corpus/templates/design/changelog/2026-06-30-new-designs-show-a-loading-state-during-handoff-and-keep-edi.md +6 -0
  239. package/corpus/templates/design/changelog/2026-06-30-public-visual-edit-design-links-now-open-directly-instead-of.md +6 -0
  240. package/corpus/templates/design/changelog/2026-06-30-removed-the-confusing-states-section-from-the-design-editor-.md +6 -0
  241. package/corpus/templates/design/changelog/2026-06-30-removed-the-templates-gallery-from-design-navigation.md +6 -0
  242. package/corpus/templates/design/changelog/2026-06-30-share-stays-visible-as-soon-as-editable-designs-load.md +6 -0
  243. package/corpus/templates/design/changelog/2026-06-30-signed-out-save-and-share-controls-use-simpler-labels-and-op.md +6 -0
  244. package/corpus/templates/design/changelog/2026-06-30-text-added-on-the-canvas-now-focuses-cleanly-with-the-right-.md +6 -0
  245. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-is-simpler-and-its-bottom.md +6 -0
  246. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-now-follows-the-current-t.md +6 -0
  247. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-child-layout-controls-o.md +6 -0
  248. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-the-ask-ai-section-abov.md +6 -0
  249. package/corpus/templates/design/changelog/2026-06-30-the-design-review-panel-no-longer-shows-a-separate-inline-au.md +6 -0
  250. package/corpus/templates/design/changelog/2026-06-30-the-empty-designs-page-now-focuses-on-a-single-primary-new-d.md +6 -0
  251. package/corpus/templates/design/changelog/2026-06-30-the-layers-panel-header-stays-as-layers-while-multiple-items.md +6 -0
  252. package/corpus/templates/design/changelog/2026-06-30-the-missing-design-screen-now-uses-a-neutral-back-button.md +6 -0
  253. package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-now-closes-without-squeezing-the-canvas-.md +6 -0
  254. package/corpus/templates/design/changelog/2026-06-30-the-new-design-connect-ai-setup-now-lines-up-with-the-compos.md +6 -0
  255. package/corpus/templates/design/changelog/2026-06-30-the-screen-overview-board-now-blends-into-the-canvas-and-new.md +6 -0
  256. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-drops-now-show-screen-guides.md +6 -0
  257. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-keep-a-transparent-backdrop-and-.md +6 -0
  258. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-select-reliably-from-all-screens.md +6 -0
  259. package/corpus/templates/design/changelog/2026-06-30-visual-edit-can-open-and-refresh-localhost-screens-in-one-au.md +6 -0
  260. package/corpus/templates/design/e2e/helpers.ts +15 -4
  261. package/corpus/templates/design/server/db/index.ts +52 -0
  262. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -0
  263. package/corpus/templates/design/server/plugins/auth.ts +1 -0
  264. package/corpus/templates/design/server/plugins/core-routes.ts +4 -0
  265. package/corpus/templates/design/shared/board-file.ts +380 -5
  266. package/corpus/templates/design/shared/board-objects.ts +2 -2
  267. package/corpus/templates/design/shared/code-layer.ts +50 -6
  268. package/corpus/templates/design/shared/motion-compiler.ts +27 -0
  269. package/corpus/templates/macros/app/components/DailyProgress.tsx +41 -37
  270. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  271. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  272. package/corpus/templates/macros/app/components/VoiceDictation.tsx +1 -1
  273. package/corpus/templates/macros/app/components/WeeklyCaloriesChart.tsx +1 -1
  274. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  275. package/corpus/templates/macros/app/components/WeightTracker.tsx +1 -1
  276. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -1
  277. package/corpus/templates/macros/app/routes/_index.tsx +5 -5
  278. package/corpus/templates/macros/app/routes/analytics.tsx +1 -1
  279. package/corpus/templates/macros/changelog/2026-06-30-dashboard-loading-and-chart-surfaces-now-use-theme-aware-col.md +6 -0
  280. package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +14 -11
  281. package/corpus/templates/mail/app/global.css +3 -2
  282. package/corpus/templates/mail/changelog/2026-06-30-compose-floating-toolbars-now-use-theme-aware-colors-in-ligh.md +6 -0
  283. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
  284. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +3 -3
  285. package/corpus/templates/slides/app/global.css +10 -0
  286. package/corpus/templates/slides/app/pages/Index.tsx +55 -51
  287. package/corpus/templates/slides/changelog/2026-06-30-deck-thumbnails-collapse-cleanly-to-one-column-when-the-chat.md +6 -0
  288. package/dist/agent/engine/anthropic-engine.d.ts +2 -2
  289. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  290. package/dist/agent/engine/builder-engine.d.ts +2 -2
  291. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  292. package/dist/agent/engine/builtin.js +1 -1
  293. package/dist/agent/engine/builtin.js.map +1 -1
  294. package/dist/agent/engine/output-tokens.js +1 -1
  295. package/dist/agent/engine/output-tokens.js.map +1 -1
  296. package/dist/agent/harness/acp-adapter.d.ts +4 -1
  297. package/dist/agent/harness/acp-adapter.d.ts.map +1 -1
  298. package/dist/agent/harness/acp-adapter.js +19 -2
  299. package/dist/agent/harness/acp-adapter.js.map +1 -1
  300. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  301. package/dist/agent/harness/ai-sdk-adapter.js +3 -0
  302. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  303. package/dist/agent/harness/translate.d.ts.map +1 -1
  304. package/dist/agent/harness/translate.js +3 -0
  305. package/dist/agent/harness/translate.js.map +1 -1
  306. package/dist/agent/harness/types.d.ts +1 -0
  307. package/dist/agent/harness/types.d.ts.map +1 -1
  308. package/dist/agent/harness/types.js.map +1 -1
  309. package/dist/agent/model-config.d.ts +21 -20
  310. package/dist/agent/model-config.d.ts.map +1 -1
  311. package/dist/agent/model-config.js +31 -13
  312. package/dist/agent/model-config.js.map +1 -1
  313. package/dist/agent/production-agent.d.ts.map +1 -1
  314. package/dist/agent/production-agent.js +85 -10
  315. package/dist/agent/production-agent.js.map +1 -1
  316. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  317. package/dist/agent/thread-data-builder.js +27 -6
  318. package/dist/agent/thread-data-builder.js.map +1 -1
  319. package/dist/agent/tool-call-journal.d.ts +11 -9
  320. package/dist/agent/tool-call-journal.d.ts.map +1 -1
  321. package/dist/agent/tool-call-journal.js +92 -40
  322. package/dist/agent/tool-call-journal.js.map +1 -1
  323. package/dist/agent/types.d.ts +5 -1
  324. package/dist/agent/types.d.ts.map +1 -1
  325. package/dist/agent/types.js.map +1 -1
  326. package/dist/cli/design-connect.d.ts.map +1 -1
  327. package/dist/cli/design-connect.js +84 -0
  328. package/dist/cli/design-connect.js.map +1 -1
  329. package/dist/cli/gateway-helpers.d.ts +4 -0
  330. package/dist/cli/gateway-helpers.d.ts.map +1 -1
  331. package/dist/cli/gateway-helpers.js +9 -0
  332. package/dist/cli/gateway-helpers.js.map +1 -1
  333. package/dist/cli/recap.d.ts.map +1 -1
  334. package/dist/cli/recap.js +0 -2
  335. package/dist/cli/recap.js.map +1 -1
  336. package/dist/cli/skills.d.ts.map +1 -1
  337. package/dist/cli/skills.js +54 -16
  338. package/dist/cli/skills.js.map +1 -1
  339. package/dist/cli/workspace-dev.d.ts.map +1 -1
  340. package/dist/cli/workspace-dev.js +33 -6
  341. package/dist/cli/workspace-dev.js.map +1 -1
  342. package/dist/client/AssistantChat.d.ts.map +1 -1
  343. package/dist/client/AssistantChat.js +72 -26
  344. package/dist/client/AssistantChat.js.map +1 -1
  345. package/dist/client/CommandMenu.d.ts +6 -2
  346. package/dist/client/CommandMenu.d.ts.map +1 -1
  347. package/dist/client/CommandMenu.js +25 -14
  348. package/dist/client/CommandMenu.js.map +1 -1
  349. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  350. package/dist/client/DefaultSpinner.js +8 -1
  351. package/dist/client/DefaultSpinner.js.map +1 -1
  352. package/dist/client/chat/message-components.d.ts +7 -1
  353. package/dist/client/chat/message-components.d.ts.map +1 -1
  354. package/dist/client/chat/message-components.js +37 -1
  355. package/dist/client/chat/message-components.js.map +1 -1
  356. package/dist/client/chat/repo-helpers.d.ts +1 -0
  357. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  358. package/dist/client/chat/repo-helpers.js +59 -0
  359. package/dist/client/chat/repo-helpers.js.map +1 -1
  360. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  361. package/dist/client/chat/run-recovery.js +4 -4
  362. package/dist/client/chat/run-recovery.js.map +1 -1
  363. package/dist/client/components/ApiKeySettings.js +8 -8
  364. package/dist/client/components/ApiKeySettings.js.map +1 -1
  365. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  366. package/dist/client/components/CodeRequiredDialog.js +24 -15
  367. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  368. package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
  369. package/dist/client/components/MissingKeyCard.js +11 -6
  370. package/dist/client/components/MissingKeyCard.js.map +1 -1
  371. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  372. package/dist/client/composer/TiptapComposer.js +4 -3
  373. package/dist/client/composer/TiptapComposer.js.map +1 -1
  374. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  375. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  376. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  377. package/dist/client/guided-questions.d.ts.map +1 -1
  378. package/dist/client/guided-questions.js +6 -6
  379. package/dist/client/guided-questions.js.map +1 -1
  380. package/dist/client/integrations/IntegrationCard.js +1 -1
  381. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  382. package/dist/client/integrations/IntegrationsPanel.js +1 -1
  383. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  384. package/dist/client/onboarding/OnboardingBanner.js +2 -2
  385. package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
  386. package/dist/client/onboarding/OnboardingPanel.js +23 -19
  387. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  388. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  389. package/dist/client/resources/ResourceEditor.js +13 -10
  390. package/dist/client/resources/ResourceEditor.js.map +1 -1
  391. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  392. package/dist/client/resources/ResourcesPanel.js +2 -1
  393. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  394. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  395. package/dist/client/settings/SettingsPanel.js +8 -3
  396. package/dist/client/settings/SettingsPanel.js.map +1 -1
  397. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  398. package/dist/client/settings/useBuilderStatus.js +6 -38
  399. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  400. package/dist/client/useProductionAgent.d.ts +2 -1
  401. package/dist/client/useProductionAgent.d.ts.map +1 -1
  402. package/dist/client/useProductionAgent.js.map +1 -1
  403. package/dist/deploy/build.js +1 -1
  404. package/dist/deploy/build.js.map +1 -1
  405. package/dist/notifications/routes.d.ts +3 -3
  406. package/dist/observability/routes.d.ts +3 -3
  407. package/dist/observability/traces.d.ts.map +1 -1
  408. package/dist/observability/traces.js.map +1 -1
  409. package/dist/onboarding/default-steps.js +1 -1
  410. package/dist/onboarding/default-steps.js.map +1 -1
  411. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  412. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  413. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  414. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  415. package/dist/server/agent-chat-plugin.d.ts +3 -0
  416. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  417. package/dist/server/agent-chat-plugin.js +134 -72
  418. package/dist/server/agent-chat-plugin.js.map +1 -1
  419. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  420. package/dist/server/core-routes-plugin.d.ts +3 -0
  421. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  422. package/dist/server/core-routes-plugin.js +4 -1
  423. package/dist/server/core-routes-plugin.js.map +1 -1
  424. package/dist/server/open-route.d.ts +9 -0
  425. package/dist/server/open-route.d.ts.map +1 -1
  426. package/dist/server/open-route.js +48 -38
  427. package/dist/server/open-route.js.map +1 -1
  428. package/dist/shared/reasoning-effort.js +3 -0
  429. package/dist/shared/reasoning-effort.js.map +1 -1
  430. package/dist/sharing/access.d.ts.map +1 -1
  431. package/dist/sharing/access.js +18 -2
  432. package/dist/sharing/access.js.map +1 -1
  433. package/dist/sharing/registry.d.ts +10 -0
  434. package/dist/sharing/registry.d.ts.map +1 -1
  435. package/dist/sharing/registry.js.map +1 -1
  436. package/dist/styles/agent-native.css +104 -20
  437. package/dist/styles/rich-markdown-editor.css +11 -10
  438. package/docs/content/cloneable-saas.mdx +2 -2
  439. package/docs/content/faq.mdx +1 -1
  440. package/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  441. package/docs/content/locales/ar-SA/faq.mdx +1 -1
  442. package/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  443. package/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  444. package/docs/content/locales/de-DE/faq.mdx +1 -1
  445. package/docs/content/locales/de-DE/template-chat.mdx +1 -1
  446. package/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  447. package/docs/content/locales/es-ES/faq.mdx +1 -1
  448. package/docs/content/locales/es-ES/template-chat.mdx +1 -1
  449. package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  450. package/docs/content/locales/fr-FR/faq.mdx +1 -1
  451. package/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  452. package/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  453. package/docs/content/locales/hi-IN/faq.mdx +1 -1
  454. package/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  455. package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  456. package/docs/content/locales/ja-JP/faq.mdx +1 -1
  457. package/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  458. package/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  459. package/docs/content/locales/ko-KR/faq.mdx +1 -1
  460. package/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  461. package/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  462. package/docs/content/locales/pt-BR/faq.mdx +1 -1
  463. package/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  464. package/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  465. package/docs/content/locales/zh-CN/faq.mdx +1 -1
  466. package/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  467. package/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  468. package/docs/content/locales/zh-TW/faq.mdx +1 -1
  469. package/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  470. package/docs/content/template-chat.mdx +1 -1
  471. package/package.json +1 -1
  472. package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +0 -157
  473. package/corpus/templates/design/app/lib/design-templates.ts +0 -1305
  474. package/corpus/templates/design/app/pages/Templates.tsx +0 -279
@@ -1,4 +1,5 @@
1
- import { sendToAgentChat, usePinchZoom, useT } from "@agent-native/core/client";
1
+ import { usePinchZoom, useT } from "@agent-native/core/client";
2
+ import { ensureCodeLayerNodeIdsInHtml } from "@shared/code-layer";
2
3
  import { useRef, useEffect, useCallback, useMemo, useState } from "react";
3
4
 
4
5
  // NOTE: This wires up the NEW shared visual-editor DrawOverlay + comment-pin
@@ -10,6 +11,7 @@ import {
10
11
  CanvasCommentPins,
11
12
  type CanvasPin,
12
13
  } from "@/components/visual-editor";
14
+ import { sendToDesignAgentChat } from "@/lib/agent-chat";
13
15
 
14
16
  import { editorChromeBridgeScript } from "../../../.generated/bridge/editor-chrome.generated";
15
17
  import { embeddedWheelBridgeScript } from "../../../.generated/bridge/embedded-wheel.generated";
@@ -21,7 +23,11 @@ import { tweakBridgeScript } from "../../../.generated/bridge/tweak.generated";
21
23
  import { zoomBridgeScript } from "../../../.generated/bridge/zoom.generated";
22
24
  import { isTrustedCanvasBridgeMessage } from "./bridge-security";
23
25
  import { DeviceFrame } from "./DeviceFrame";
24
- import type { ElementInfo, DeviceFrameType } from "./types";
26
+ import type {
27
+ ElementInfo,
28
+ ElementSelectionIntent,
29
+ DeviceFrameType,
30
+ } from "./types";
25
31
 
26
32
  /**
27
33
  * Allowlist check for Fusion (Builder-hosted) frame origins.
@@ -163,10 +169,14 @@ ${navBridgeScript}
163
169
  * Protocol (parent → iframe via postMessage):
164
170
  * { type: 'agent-native:hit-test', correlationId: string, x: number, y: number }
165
171
  * where x/y are in this iframe's viewport coordinate space.
172
+ * When preview is true, the iframe also renders its local insertion guide.
173
+ * { type: 'agent-native:hit-test-preview-clear' } hides that guide.
166
174
  *
167
175
  * Reply (iframe → window.parent):
168
176
  * { type: 'agent-native:hit-test-result', correlationId: string,
169
- * anchorNodeId: string, placement: 'before'|'after'|'inside' }
177
+ * anchorNodeId: string, placement: 'before'|'after'|'inside',
178
+ * axis: 'x'|'y',
179
+ * anchorRect: { left: number, top: number, width: number, height: number } }
170
180
  *
171
181
  * Reads DOM only — no mutations, no event interception. The container-drop and
172
182
  * placement logic is intentionally kept in sync with the corresponding helpers
@@ -210,6 +220,11 @@ const EDITOR_BRIDGE_VAR_NAMES = [
210
220
  "--design-editor-selection-color",
211
221
  "--design-editor-accent-strong-color",
212
222
  "--design-editor-accent-contrast-color",
223
+ "--design-editor-component-color",
224
+ "--design-editor-component-hover-color",
225
+ "--design-editor-component-selection-color",
226
+ "--design-editor-component-strong-color",
227
+ "--design-editor-component-contrast-color",
213
228
  "--design-editor-measure-color",
214
229
  "--background",
215
230
  "--foreground",
@@ -275,6 +290,20 @@ interface DesignCanvasProps {
275
290
  * model uses window-identity trust instead of same-origin trust.
276
291
  */
277
292
  sourceType?: "inline" | "localhost" | "fusion";
293
+ /** Local design-connect bridge URL used to fetch editable snapshots for URL-backed localhost screens. */
294
+ bridgeUrl?: string;
295
+ /**
296
+ * HTML snapshot for a URL-backed localhost screen. When present, DesignCanvas
297
+ * renders this as editable srcdoc while the persisted design file can remain
298
+ * the original URL.
299
+ */
300
+ externalSnapshotHtml?: string;
301
+ onExternalContentSnapshot?: (snapshot: {
302
+ url: string;
303
+ html: string;
304
+ status?: number;
305
+ contentType?: string;
306
+ }) => void;
278
307
  /**
279
308
  * Explicit Builder-hosted app URL for fusion source rendering.
280
309
  *
@@ -300,14 +329,23 @@ interface DesignCanvasProps {
300
329
  displayWidth: number;
301
330
  displayHeight: number;
302
331
  fluid?: boolean;
332
+ contentOffsetX?: number;
333
+ contentOffsetY?: number;
303
334
  };
335
+ boardSurface?: boolean;
336
+ embeddedFrameBackground?: string;
337
+ transparentBackground?: boolean;
304
338
  editorChromeScaleX?: number;
305
339
  editorChromeScaleY?: number;
306
340
  editMode: boolean;
307
341
  interactMode: boolean;
308
342
  readOnly?: boolean;
309
343
  scaleMode?: boolean;
310
- onElementSelect: (info: ElementInfo) => void;
344
+ onElementSelect: (info: ElementInfo, intent?: ElementSelectionIntent) => void;
345
+ onElementMarqueeSelect?: (
346
+ infos: ElementInfo[],
347
+ intent?: ElementSelectionIntent,
348
+ ) => void;
311
349
  onElementHover: (info: ElementInfo | null) => void;
312
350
  onClearSelection?: () => void;
313
351
  onVisualStyleChange?: (
@@ -360,6 +398,7 @@ interface DesignCanvasProps {
360
398
  pinMode?: boolean;
361
399
  selectedSelector?: string | null;
362
400
  selectedSelectorCandidates?: string[];
401
+ selectedSelectorGroups?: string[][];
363
402
  hoveredSelector?: string | null;
364
403
  hoveredSelectorCandidates?: string[];
365
404
  lockedSelectors?: string[];
@@ -448,6 +487,90 @@ function getExternalPreviewUrl(content: string): string | null {
448
487
  }
449
488
  }
450
489
 
490
+ function escapeHtmlAttribute(value: string): string {
491
+ return value
492
+ .replace(/&/g, "&")
493
+ .replace(/"/g, """)
494
+ .replace(/</g, "&lt;")
495
+ .replace(/>/g, "&gt;");
496
+ }
497
+
498
+ function addSnapshotBaseHref(html: string, href: string): string {
499
+ if (!html.trim()) return html;
500
+ if (/<base\b/i.test(html)) return html;
501
+ const baseTag = `<base href="${escapeHtmlAttribute(href)}">`;
502
+ if (/<head\b[^>]*>/i.test(html)) {
503
+ return html.replace(/<head\b[^>]*>/i, (match) => `${match}${baseTag}`);
504
+ }
505
+ if (/<html\b[^>]*>/i.test(html)) {
506
+ return html.replace(
507
+ /<html\b[^>]*>/i,
508
+ (match) => `${match}<head>${baseTag}</head>`,
509
+ );
510
+ }
511
+ return `<!DOCTYPE html><html><head>${baseTag}<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head><body>${html}</body></html>`;
512
+ }
513
+
514
+ function prepareStaticSnapshotHtml(html: string, href: string): string {
515
+ const withBase = addSnapshotBaseHref(html, href);
516
+ if (typeof DOMParser === "undefined") {
517
+ return withBase.replace(/<script\b[^>]*>.*?<\/script>/gis, "");
518
+ }
519
+
520
+ const document = new DOMParser().parseFromString(withBase, "text/html");
521
+ document.querySelectorAll("script").forEach((script) => script.remove());
522
+ return `<!DOCTYPE html>${document.documentElement.outerHTML}`;
523
+ }
524
+
525
+ function snapshotEndpointUrl(bridgeUrl: string, previewUrl: string): string {
526
+ const endpoint = new URL("/snapshot", bridgeUrl);
527
+ endpoint.searchParams.set("url", previewUrl);
528
+ return endpoint.toString();
529
+ }
530
+
531
+ const TRANSPARENT_EMBEDDED_FRAME_STYLE =
532
+ "<style data-agent-native-transparent-frame>html,body{background:transparent!important;}body{background-color:transparent!important;}</style>";
533
+
534
+ function embeddedFrameBackgroundStyle(background: string | undefined): string {
535
+ const trimmed = background?.trim();
536
+ if (!trimmed || /[;{}<>]/.test(trimmed)) return "";
537
+ return `<style data-agent-native-frame-background>html,body{background:${trimmed}!important;}body{background-color:${trimmed}!important;}</style>`;
538
+ }
539
+
540
+ export function getEmbeddedFrameBackgroundStyle(args: {
541
+ embeddedFrameBackground?: string;
542
+ transparentBackground?: boolean;
543
+ }): string {
544
+ return args.transparentBackground
545
+ ? TRANSPARENT_EMBEDDED_FRAME_STYLE
546
+ : embeddedFrameBackgroundStyle(args.embeddedFrameBackground);
547
+ }
548
+
549
+ export function getEmbeddedIframeBackgroundColor(args: {
550
+ embeddedFrameBackground?: string;
551
+ transparentBackground?: boolean;
552
+ }): string {
553
+ return args.transparentBackground
554
+ ? "transparent"
555
+ : (args.embeddedFrameBackground ?? "transparent");
556
+ }
557
+
558
+ function embeddedContentOffsetStyle(x: number, y: number): string {
559
+ if (x === 0 && y === 0) return "";
560
+ return `<style data-agent-native-content-offset>[data-agent-native-node-id]{translate:${Math.round(x)}px ${Math.round(y)}px;}</style>`;
561
+ }
562
+
563
+ function injectEmbeddedFrameStyle(content: string, style: string): string {
564
+ if (!style) return content;
565
+ if (/<\/head>/i.test(content)) {
566
+ return content.replace(/<\/head>/i, `${style}</head>`);
567
+ }
568
+ if (/<body\b/i.test(content)) {
569
+ return content.replace(/<body\b/i, `${style}<body`);
570
+ }
571
+ return `${style}${content}`;
572
+ }
573
+
451
574
  export interface IframeHotkeyPayload {
452
575
  key: string;
453
576
  code: string;
@@ -470,11 +593,17 @@ export function DesignCanvas({
470
593
  content,
471
594
  contentKey,
472
595
  sourceType,
596
+ bridgeUrl,
597
+ externalSnapshotHtml,
598
+ onExternalContentSnapshot,
473
599
  fusionUrl,
474
600
  zoom,
475
601
  onZoomChange,
476
602
  deviceFrame,
477
603
  embeddedFrame,
604
+ boardSurface = false,
605
+ embeddedFrameBackground,
606
+ transparentBackground = false,
478
607
  editorChromeScaleX = 1,
479
608
  editorChromeScaleY = editorChromeScaleX,
480
609
  editMode,
@@ -483,6 +612,7 @@ export function DesignCanvas({
483
612
  scaleMode = false,
484
613
  clearSelectionRequest,
485
614
  onElementSelect,
615
+ onElementMarqueeSelect,
486
616
  onElementHover,
487
617
  onClearSelection,
488
618
  onVisualStyleChange,
@@ -499,6 +629,7 @@ export function DesignCanvas({
499
629
  pinMode,
500
630
  selectedSelector,
501
631
  selectedSelectorCandidates = [],
632
+ selectedSelectorGroups = [],
502
633
  hoveredSelector,
503
634
  hoveredSelectorCandidates = [],
504
635
  lockedSelectors = [],
@@ -524,6 +655,18 @@ export function DesignCanvas({
524
655
  const [renderedContent, setRenderedContent] = useState(content);
525
656
  const [annotationPins, setAnnotationPins] = useState<CanvasPin[]>([]);
526
657
  const [pinSubmitSignal, setPinSubmitSignal] = useState(0);
658
+ const [fetchedExternalSnapshot, setFetchedExternalSnapshot] = useState<{
659
+ url: string;
660
+ html: string;
661
+ } | null>(null);
662
+ const [externalSnapshotState, setExternalSnapshotState] = useState<{
663
+ url: string;
664
+ status: "loading" | "error";
665
+ message?: string;
666
+ } | null>(null);
667
+ const [externalSnapshotRetryNonce, setExternalSnapshotRetryNonce] =
668
+ useState(0);
669
+ const onExternalContentSnapshotRef = useRef(onExternalContentSnapshot);
527
670
  const isEmbeddedFrame = Boolean(embeddedFrame);
528
671
  // Resolve the URL to render in the iframe:
529
672
  // 1. When sourceType === "fusion" and fusionUrl is set, prefer the explicit
@@ -532,7 +675,7 @@ export function DesignCanvas({
532
675
  // 2. Otherwise fall back to the content-based URL detection (handles the case
533
676
  // where the branch URL has been written into the design file content, or
534
677
  // where the localhost URL is the file content).
535
- const externalPreviewUrl = useMemo(() => {
678
+ const rawExternalPreviewUrl = useMemo(() => {
536
679
  if (sourceType === "fusion" && fusionUrl) {
537
680
  try {
538
681
  const url = new URL(fusionUrl);
@@ -544,8 +687,127 @@ export function DesignCanvas({
544
687
  }
545
688
  return getExternalPreviewUrl(renderedContent);
546
689
  }, [fusionUrl, renderedContent, sourceType]);
690
+ const activeExternalSnapshotHtml =
691
+ externalSnapshotHtml ??
692
+ (fetchedExternalSnapshot?.url === rawExternalPreviewUrl
693
+ ? fetchedExternalSnapshot.html
694
+ : undefined);
695
+ const requiresEditableExternalSnapshot =
696
+ sourceType === "localhost" &&
697
+ Boolean(bridgeUrl && rawExternalPreviewUrl) &&
698
+ !interactMode &&
699
+ !readOnly;
700
+ const iframeRenderContent =
701
+ activeExternalSnapshotHtml ??
702
+ (requiresEditableExternalSnapshot ? "" : renderedContent);
703
+ const externalPreviewUrl =
704
+ activeExternalSnapshotHtml || requiresEditableExternalSnapshot
705
+ ? null
706
+ : rawExternalPreviewUrl;
707
+ const waitingForEditableExternalSnapshot =
708
+ requiresEditableExternalSnapshot && !activeExternalSnapshotHtml;
547
709
  zoomRef.current = zoom;
548
710
 
711
+ useEffect(() => {
712
+ onExternalContentSnapshotRef.current = onExternalContentSnapshot;
713
+ }, [onExternalContentSnapshot]);
714
+
715
+ useEffect(() => {
716
+ const previewUrl = rawExternalPreviewUrl;
717
+ if (sourceType !== "localhost" || !bridgeUrl || !previewUrl) {
718
+ setFetchedExternalSnapshot((current) =>
719
+ current?.url === previewUrl ? current : null,
720
+ );
721
+ setExternalSnapshotState(null);
722
+ return;
723
+ }
724
+ if (externalSnapshotHtml) {
725
+ setExternalSnapshotState(null);
726
+ return;
727
+ }
728
+ let cancelled = false;
729
+ const controller = new AbortController();
730
+ let retryTimer: number | undefined;
731
+ const endpoint = snapshotEndpointUrl(bridgeUrl, previewUrl);
732
+ const scheduleRetry = () => {
733
+ if (!requiresEditableExternalSnapshot || cancelled) return;
734
+ retryTimer = window.setTimeout(() => {
735
+ setExternalSnapshotRetryNonce((nonce) => nonce + 1);
736
+ }, 1500);
737
+ };
738
+ setExternalSnapshotState({ url: previewUrl, status: "loading" });
739
+ void (async () => {
740
+ try {
741
+ const response = await fetch(endpoint, {
742
+ method: "GET",
743
+ headers: { accept: "application/json" },
744
+ signal: controller.signal,
745
+ });
746
+ const payload = (await response.json().catch(() => null)) as {
747
+ ok?: boolean;
748
+ url?: string;
749
+ html?: string;
750
+ status?: number;
751
+ contentType?: string;
752
+ error?: string;
753
+ } | null;
754
+ if (cancelled) return;
755
+ if (!response.ok || !payload?.ok) {
756
+ setExternalSnapshotState({
757
+ url: previewUrl,
758
+ status: "error",
759
+ message:
760
+ payload?.error ||
761
+ `Bridge snapshot failed (${payload?.status ?? response.status})`,
762
+ });
763
+ scheduleRetry();
764
+ return;
765
+ }
766
+ const sourceUrl = payload.url || previewUrl;
767
+ const html = prepareStaticSnapshotHtml(payload.html ?? "", sourceUrl);
768
+ const stamped = ensureCodeLayerNodeIdsInHtml(html, {
769
+ source: {
770
+ kind: "remote-url",
771
+ sourceType: "localhost",
772
+ url: sourceUrl,
773
+ bridgeUrl,
774
+ },
775
+ }).content;
776
+ if (cancelled) return;
777
+ setFetchedExternalSnapshot({ url: previewUrl, html: stamped });
778
+ setExternalSnapshotState(null);
779
+ onExternalContentSnapshotRef.current?.({
780
+ url: previewUrl,
781
+ html: stamped,
782
+ status: payload.status,
783
+ contentType: payload.contentType,
784
+ });
785
+ } catch (error) {
786
+ if (!cancelled && !(error instanceof DOMException)) {
787
+ console.warn("[DesignCanvas] preview snapshot failed", error);
788
+ setExternalSnapshotState({
789
+ url: previewUrl,
790
+ status: "error",
791
+ message: error instanceof Error ? error.message : String(error),
792
+ });
793
+ scheduleRetry();
794
+ }
795
+ }
796
+ })();
797
+ return () => {
798
+ cancelled = true;
799
+ controller.abort();
800
+ if (retryTimer) window.clearTimeout(retryTimer);
801
+ };
802
+ }, [
803
+ bridgeUrl,
804
+ externalSnapshotHtml,
805
+ externalSnapshotRetryNonce,
806
+ rawExternalPreviewUrl,
807
+ requiresEditableExternalSnapshot,
808
+ sourceType,
809
+ ]);
810
+
549
811
  const queuedAnnotationPins = useMemo(
550
812
  () =>
551
813
  annotationPins.filter(
@@ -596,7 +858,15 @@ export function DesignCanvas({
596
858
  )
597
859
  .replace("__TEXT_EDITING_ENABLED__", editMode ? "true" : "false")
598
860
  .replace("__EDITOR_CHROME_SCALE_X__", String(editorChromeScaleX))
599
- .replace("__EDITOR_CHROME_SCALE_Y__", String(editorChromeScaleY));
861
+ .replace("__EDITOR_CHROME_SCALE_Y__", String(editorChromeScaleY))
862
+ .replace(
863
+ "__DESIGN_CANVAS_SCREEN_ID__",
864
+ JSON.stringify(screenId ?? contentKey ?? ""),
865
+ )
866
+ .replace(
867
+ "__DESIGN_CANVAS_BOARD_SURFACE__",
868
+ boardSurface ? "true" : "false",
869
+ );
600
870
  const embeddedWheelBridge = EMBEDDED_WHEEL_BRIDGE_SCRIPT.replace(
601
871
  "__EMBEDDED_WHEEL_FORWARDING_ENABLED__",
602
872
  isEmbeddedFrame ? "true" : "false",
@@ -609,14 +879,28 @@ export function DesignCanvas({
609
879
  NAV_BRIDGE_SCRIPT +
610
880
  embeddedWheelBridge +
611
881
  editorChromeBridge;
612
- if (renderedContent.includes("</body>")) {
613
- return renderedContent.replace("</body>", bridgeToInject + "</body>"); // i18n-ignore generated iframe HTML injection
882
+ const frameStyle = [
883
+ getEmbeddedFrameBackgroundStyle({
884
+ embeddedFrameBackground,
885
+ transparentBackground,
886
+ }),
887
+ embeddedContentOffsetStyle(
888
+ embeddedFrame?.contentOffsetX ?? 0,
889
+ embeddedFrame?.contentOffsetY ?? 0,
890
+ ),
891
+ ].join("");
892
+ const frameContent = injectEmbeddedFrameStyle(
893
+ iframeRenderContent,
894
+ frameStyle,
895
+ );
896
+ if (frameContent.includes("</body>")) {
897
+ return frameContent.replace("</body>", bridgeToInject + "</body>"); // i18n-ignore generated iframe HTML injection
614
898
  }
615
- if (renderedContent.includes("</html>")) {
616
- return renderedContent.replace("</html>", bridgeToInject + "</html>"); // i18n-ignore generated iframe HTML injection
899
+ if (frameContent.includes("</html>")) {
900
+ return frameContent.replace("</html>", bridgeToInject + "</html>"); // i18n-ignore generated iframe HTML injection
617
901
  }
618
902
  // No body/html tags — wrap it
619
- return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head><body>${renderedContent}${bridgeToInject}</body></html>`;
903
+ return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">${frameStyle}</head><body>${iframeRenderContent}${bridgeToInject}</body></html>`;
620
904
  // editorChromeScaleX/Y are intentionally NOT deps: they only seed the initial
621
905
  // baked chrome scale. Live zoom updates flow through the set-editor-chrome-scale
622
906
  // postMessage above. Including them here rebuilds srcdoc on every zoom commit,
@@ -625,10 +909,15 @@ export function DesignCanvas({
625
909
  // eslint-disable-next-line react-hooks/exhaustive-deps
626
910
  }, [
627
911
  editMode,
912
+ boardSurface,
628
913
  externalPreviewUrl,
629
914
  interactMode,
630
915
  isEmbeddedFrame,
631
- renderedContent,
916
+ embeddedFrame?.contentOffsetX,
917
+ embeddedFrame?.contentOffsetY,
918
+ embeddedFrameBackground,
919
+ iframeRenderContent,
920
+ transparentBackground,
632
921
  ]);
633
922
 
634
923
  // Listen for messages from the iframe
@@ -663,7 +952,18 @@ export function DesignCanvas({
663
952
  return;
664
953
  }
665
954
  if (e.data.type === "element-select") {
666
- onElementSelect(e.data.payload);
955
+ onElementSelect(e.data.payload, e.data.intent);
956
+ return;
957
+ }
958
+ if (
959
+ e.data.type === "agent-native:layer-marquee-selection" ||
960
+ e.data.type === "element-marquee-select"
961
+ ) {
962
+ onElementMarqueeSelect?.(
963
+ Array.isArray(e.data.payload) ? e.data.payload : [],
964
+ e.data.intent,
965
+ );
966
+ return;
667
967
  }
668
968
  if (e.data.type === "element-hover") {
669
969
  onElementHover(e.data.payload);
@@ -900,6 +1200,7 @@ export function DesignCanvas({
900
1200
  return () => window.removeEventListener("message", handleMessage);
901
1201
  }, [
902
1202
  onElementSelect,
1203
+ onElementMarqueeSelect,
903
1204
  onElementHover,
904
1205
  onClearSelection,
905
1206
  onVisualStyleChange,
@@ -944,6 +1245,13 @@ export function DesignCanvas({
944
1245
  : { type: "clear-selection" },
945
1246
  "*",
946
1247
  );
1248
+ iframe.contentWindow?.postMessage(
1249
+ {
1250
+ type: "select-elements",
1251
+ selectorGroups: selectedSelectorGroups,
1252
+ },
1253
+ "*",
1254
+ );
947
1255
  iframe.contentWindow?.postMessage(
948
1256
  hoveredSelector
949
1257
  ? {
@@ -990,6 +1298,7 @@ export function DesignCanvas({
990
1298
  scaleMode,
991
1299
  selectedSelector,
992
1300
  selectedSelectorCandidates,
1301
+ selectedSelectorGroups,
993
1302
  shaderFillPreview,
994
1303
  tweakValues,
995
1304
  ]);
@@ -1187,7 +1496,12 @@ export function DesignCanvas({
1187
1496
  }, []);
1188
1497
 
1189
1498
  const replacePreviewContent = useCallback(
1190
- (nextContent: string, selector?: string | null, candidates?: string[]) => {
1499
+ (
1500
+ nextContent: string,
1501
+ selector?: string | null,
1502
+ candidates?: string[],
1503
+ options?: { forceFullDocument?: boolean },
1504
+ ) => {
1191
1505
  const iframe = iframeRef.current;
1192
1506
  if (!iframe?.contentWindow) return false;
1193
1507
  iframe.contentWindow.postMessage(
@@ -1196,6 +1510,7 @@ export function DesignCanvas({
1196
1510
  content: nextContent,
1197
1511
  selectedSelector: selector ?? "",
1198
1512
  selectorCandidates: candidates ?? [],
1513
+ forceFullDocument: options?.forceFullDocument === true,
1199
1514
  },
1200
1515
  "*",
1201
1516
  );
@@ -1306,6 +1621,10 @@ export function DesignCanvas({
1306
1621
  const { width: iframeWidth, height: iframeHeight } =
1307
1622
  deviceDimensions[deviceFrame];
1308
1623
  const embeddedFrameFluid = embeddedFrame?.fluid === true;
1624
+ const iframeBackgroundColor = getEmbeddedIframeBackgroundColor({
1625
+ embeddedFrameBackground,
1626
+ transparentBackground,
1627
+ });
1309
1628
 
1310
1629
  // Per-breakpoint override: when previewWidthPx is set it takes priority over
1311
1630
  // the deviceFrame width so the caller can render the same source at an
@@ -1355,9 +1674,25 @@ export function DesignCanvas({
1355
1674
  ? "localhost" // inferred — content is a URL
1356
1675
  : "inline")
1357
1676
  }
1677
+ allowTransparency={transparentBackground || undefined}
1358
1678
  className="block h-full w-full border-0 bg-transparent"
1679
+ style={{
1680
+ background: iframeBackgroundColor,
1681
+ backgroundColor: iframeBackgroundColor,
1682
+ }}
1359
1683
  title={t("designEditor.designPreview")}
1360
1684
  />
1685
+ {waitingForEditableExternalSnapshot ? (
1686
+ <div className="pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-background/85 px-4 text-center text-sm text-muted-foreground">
1687
+ <div className="max-w-[28rem] rounded-md border bg-card px-4 py-3 shadow-sm">
1688
+ {
1689
+ externalSnapshotState?.status === "error"
1690
+ ? "Waiting for localhost bridge snapshot..." /* i18n-ignore local dev bridge status */
1691
+ : "Preparing editable preview..." /* i18n-ignore local dev snapshot status */
1692
+ }
1693
+ </div>
1694
+ </div>
1695
+ ) : null}
1361
1696
  {/* Draw-to-prompt overlay — sits over the iframe, NOT inside it. */}
1362
1697
  <SharedDrawOverlay
1363
1698
  visible={!!drawMode}
@@ -1399,7 +1734,7 @@ export function DesignCanvas({
1399
1734
  instruction || "Apply these annotations to the design.",
1400
1735
  ];
1401
1736
  try {
1402
- sendToAgentChat({
1737
+ sendToDesignAgentChat({
1403
1738
  message: lines.join("\n"),
1404
1739
  submit: true,
1405
1740
  openSidebar: true,