@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
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The Design editor loading skeleton is simpler and its bottom toolbar uses one consistent surface.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The design editor loading skeleton now follows the current theme while designs load.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The Design inspector no longer shows child layout controls for empty layers or conversion prompts in Auto layout.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: removed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The design inspector no longer shows the Ask AI section above Export.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: removed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The Design review panel no longer shows a separate inline audit run button.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The empty Designs page now focuses on a single primary New Design action.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The Layers panel header stays as Layers while multiple items are selected.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The missing design screen now uses a neutral back button.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The motion timeline now closes without squeezing the canvas and saves animation edits with lighter responses.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The new-design Connect AI setup now lines up with the composer and keeps its actions compact.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The screen overview board now blends into the canvas and new rectangles use neutral gray defaults.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Top-level canvas layers now show screen drop guides before moving into a screen.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Top-level canvas layers now keep a transparent backdrop and drop into screens reliably.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Top-level canvas layers now select reliably from All screens.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Visual edit can open and refresh localhost screens in one authenticated step for faster chat-driven canvas updates.
@@ -174,10 +174,21 @@ async function waitForDesignBridgeReady(page: Page): Promise<void> {
174
174
  // Wait for the iframe bridge to stamp at least one selectable node.
175
175
  await expect
176
176
  .poll(
177
- async () =>
178
- designFrame(page)
179
- .locator("[data-agent-native-node-id], h1, h2, p, button")
180
- .count(),
177
+ async () => {
178
+ const previewIframes = await page
179
+ .locator(DESIGN_PREVIEW_IFRAME_SELECTOR)
180
+ .elementHandles();
181
+ let selectableNodeCount = 0;
182
+ for (const iframe of previewIframes) {
183
+ const frame = await iframe.contentFrame();
184
+ if (!frame) continue;
185
+ selectableNodeCount += await frame
186
+ .locator("[data-agent-native-node-id], h1, h2, p, button")
187
+ .count()
188
+ .catch(() => 0);
189
+ }
190
+ return selectableNodeCount;
191
+ },
181
192
  { timeout: 20_000 },
182
193
  )
183
194
  .toBeGreaterThan(0);
@@ -6,6 +6,56 @@ import * as schema from "./schema.js";
6
6
  export const getDb = createGetDb(schema);
7
7
  export { schema };
8
8
 
9
+ function isLocalDevRuntime(): boolean {
10
+ return (
11
+ process.env.NODE_ENV !== "production" &&
12
+ !process.env.NETLIFY &&
13
+ !process.env.VERCEL &&
14
+ !process.env.AWS_LAMBDA_FUNCTION_NAME &&
15
+ !process.env.CF_PAGES
16
+ );
17
+ }
18
+
19
+ function isLoopbackHttpUrl(value: unknown): boolean {
20
+ if (typeof value !== "string" || !value.trim()) return false;
21
+ try {
22
+ const url = new URL(value);
23
+ if (url.protocol !== "http:" && url.protocol !== "https:") return false;
24
+ const host = url.hostname.toLowerCase();
25
+ return (
26
+ host === "localhost" ||
27
+ host === "::1" ||
28
+ host === "[::1]" ||
29
+ /^127(?:\.\d{1,3}){3}$/.test(host)
30
+ );
31
+ } catch {
32
+ return false;
33
+ }
34
+ }
35
+
36
+ function isLoopbackLocalhostDesign(design: any): boolean {
37
+ if (!isLocalDevRuntime()) return false;
38
+ let data: any;
39
+ try {
40
+ data = typeof design?.data === "string" ? JSON.parse(design.data) : null;
41
+ } catch {
42
+ return false;
43
+ }
44
+ if (!data || data.sourceMode !== "localhost") return false;
45
+
46
+ const metadataEntries = Object.values(
47
+ data.localhostScreens ?? data.screenMetadata ?? {},
48
+ ) as any[];
49
+ if (metadataEntries.length === 0) return false;
50
+
51
+ return metadataEntries.every((entry) => {
52
+ if (!entry || entry.sourceType !== "localhost") return false;
53
+ const previewUrl = entry.previewUrl ?? entry.url;
54
+ if (!isLoopbackHttpUrl(previewUrl)) return false;
55
+ return !entry.bridgeUrl || isLoopbackHttpUrl(entry.bridgeUrl);
56
+ });
57
+ }
58
+
9
59
  registerShareableResource({
10
60
  type: "design",
11
61
  resourceTable: schema.designs,
@@ -14,6 +64,8 @@ registerShareableResource({
14
64
  titleColumn: "title",
15
65
  getResourcePath: (design) => `/design/${design.id}`,
16
66
  getDb,
67
+ publicAccessRole: (design) =>
68
+ isLoopbackLocalhostDesign(design) ? "editor" : "viewer",
17
69
  });
18
70
 
19
71
  registerShareableResource({
@@ -15,6 +15,9 @@ const INITIAL_TOOL_NAMES = [
15
15
  "get-design",
16
16
  "get-design-snapshot",
17
17
  "create-design",
18
+ "open-visual-edit",
19
+ "add-localhost-screens",
20
+ "list-localhost-connections",
18
21
  "edit-design",
19
22
  "generate-design",
20
23
  "present-design-variants",
@@ -46,6 +49,8 @@ export default createAgentChatPlugin({
46
49
 
47
50
  When the user asks you to refine an existing design, call view-screen if the open design is unclear, then read the live current file with get-design-snapshot before editing. For small localized changes, call edit-design with exact search/replace edits. For broad copy-only changes such as translating all visible text, call edit-design in replace-file mode with the complete updated file content from the snapshot so the HTML structure, scripts, styles, and tweaks are preserved without dozens of fragile search blocks. Do not claim the design is updated until the mutating action succeeds.
48
51
 
52
+ When the user asks to visually inspect or edit a running local app, use open-visual-edit. It registers the localhost bridge, creates or reuses the Design project, places URL-backed iframe screens, stores the active visual-edit context, and navigates to overview mode in one authenticated step. For follow-ups like adding a mobile viewport or another route state, reuse the current designId and connectionId and call open-visual-edit or add-localhost-screens with explicit routes/paths and viewport sizes.
53
+
49
54
  Provider-specific Design actions are shortcuts, not limits. If a first-class action cannot express the exact GitHub endpoint, repository tree query, code search, issue or pull request query, request body, pagination mode, payload shape, metadata field, or API version needed, call provider-api-catalog and provider-api-docs as needed, then call provider-api-request against the real GitHub API. Use the raw provider API escape hatch instead of weakening the answer or claiming Design cannot do something the underlying GitHub API can do.
50
55
 
51
56
  Design's GitHub provider API uses the saved GITHUB_TOKEN secret when present. Never ask the user to paste tokens into chat. For large GitHub search results or repository scans, pass stageAs and pagination options to provider-api-request, then use query-staged-dataset to count, filter, group, or project the staged rows.
@@ -28,5 +28,6 @@ export default createAuthPlugin({
28
28
  "/api/design-handoff",
29
29
  "/__manifest",
30
30
  "/_agent-native/actions/get-design",
31
+ "/_agent-native/actions/list-design-native-assets",
31
32
  ],
32
33
  });
@@ -16,4 +16,8 @@ export default createCoreRoutesPlugin({
16
16
  if (view === "editor") return "/";
17
17
  return null;
18
18
  },
19
+ allowUnauthenticatedOpen: ({ target }) => {
20
+ const path = target.split(/[?#]/, 1)[0] ?? "/";
21
+ return path.startsWith("/design/");
22
+ },
19
23
  });
@@ -21,6 +21,9 @@ import type { BoardObjectEntry } from "./board-objects.js";
21
21
  /** Reserved filename for the board overlay file. */
22
22
  export const BOARD_FILENAME = "__board__.html";
23
23
 
24
+ const DEFAULT_SHAPE_FILL = "rgb(218 218 218)";
25
+ const DEFAULT_SHAPE_STROKE = "rgb(168 168 168)";
26
+
24
27
  // ---------------------------------------------------------------------------
25
28
  // isBoardFile
26
29
  // ---------------------------------------------------------------------------
@@ -54,7 +57,8 @@ export function emptyBoardHtml(): string {
54
57
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
55
58
  <style>
56
59
  *, *::before, *::after { box-sizing: border-box; }
57
- body { margin: 0; position: relative; background: transparent; overflow: visible; }
60
+ html, body { background: transparent; }
61
+ body { margin: 0; position: relative; overflow: visible; }
58
62
  </style>
59
63
  </head>
60
64
  <body>
@@ -153,10 +157,10 @@ export function boardObjectEntryToHtmlFragment(
153
157
 
154
158
  // Ellipse kind uses a <div> with border-radius.
155
159
  if (kind === "ellipse") {
156
- const bgColor = fill ?? "var(--primary, #2563eb)";
160
+ const bgColor = fill ?? DEFAULT_SHAPE_FILL;
157
161
  const borderStyle = stroke
158
162
  ? `border:${strokeWidth ?? 1}px solid ${stroke};`
159
- : "";
163
+ : `border:1px solid ${DEFAULT_SHAPE_STROKE};`;
160
164
  const style = `${baseStyle};background:${bgColor};border-radius:50%;${borderStyle}`;
161
165
  return `<div style="${style}" ${dataAttrs}></div>`;
162
166
  }
@@ -170,10 +174,12 @@ export function boardObjectEntryToHtmlFragment(
170
174
 
171
175
  // Frame / rectangle / polygon / star / default — basic colored <div>.
172
176
  const bgColor =
173
- fill ?? (kind === "frame" ? "transparent" : "var(--primary, #2563eb)");
177
+ fill ?? (kind === "frame" ? "transparent" : DEFAULT_SHAPE_FILL);
174
178
  const borderStyle = stroke
175
179
  ? `border:${strokeWidth ?? 1}px solid ${stroke};`
176
- : "";
180
+ : kind === "frame"
181
+ ? ""
182
+ : `border:1px solid ${DEFAULT_SHAPE_STROKE};`;
177
183
  const style = `${baseStyle};background:${bgColor};${borderStyle}`;
178
184
 
179
185
  if (kind === "frame") {
@@ -212,6 +218,375 @@ function kindToLayerName(kind: BoardObjectEntry["kind"]): string {
212
218
  }
213
219
  }
214
220
 
221
+ // ---------------------------------------------------------------------------
222
+ // backfillBoardPrimitiveMarkers
223
+ // ---------------------------------------------------------------------------
224
+
225
+ /**
226
+ * Adds `data-an-primitive="<kind>"` to board primitive elements that are
227
+ * missing the marker.
228
+ *
229
+ * ## Scope
230
+ *
231
+ * Only elements that look like top-level board primitives are touched:
232
+ * - Must be a direct `<body>` child (depth-1 element)
233
+ * - Must carry `data-agent-native-node-id` (the bridge id stamp)
234
+ * - Must NOT already have `data-an-primitive`
235
+ *
236
+ * ## Kind inference (conservative)
237
+ *
238
+ * | Condition | Inferred kind |
239
+ * |--------------------------------------------------------|---------------|
240
+ * | `<svg>` whose path carries `marker-end` | `"arrow"` |
241
+ * | `<svg>` containing a `<polygon>` | `"polygon"` |
242
+ * | `<svg>` containing exactly one `<path>` and no other shape | `"path"` |
243
+ * | `<svg>` with no reliable vector signal | *(skip — left unmarked, still classifies as a generic shape via tag)* |
244
+ * | Inline style contains `border-radius:50%` | `"ellipse"` |
245
+ * | Inline style contains `background:transparent` or no background, but has `data-agent-native-layer-name` starting with "Frame" | `"frame"` |
246
+ * | Element has non-empty text content and no background color in style | `"text"` |
247
+ * | Otherwise | `"rectangle"` |
248
+ *
249
+ * The function is:
250
+ * - **Pure** — returns a new string, never mutates.
251
+ * - **Additive** — only inserts `data-an-primitive`; never alters geometry,
252
+ * structure, or any other attributes.
253
+ * - **Idempotent** — if the marker is already present on an element, that
254
+ * element is skipped.
255
+ *
256
+ * The implementation uses string-level parsing to remain dependency-free
257
+ * (no DOM parser, no JSDOM). It is intentionally conservative: when in doubt,
258
+ * an element is left as-is rather than mis-classified.
259
+ */
260
+ export function backfillBoardPrimitiveMarkers(html: string): string {
261
+ // Quick exit: if every node-id-bearing element already has the marker we
262
+ // have nothing to do.
263
+ if (!html.includes("data-agent-native-node-id=")) return html;
264
+
265
+ // We need to find direct <body> children only. We walk the raw HTML string
266
+ // looking for the opening of the <body> element, then iterate sibling-level
267
+ // opening tags until </body>.
268
+
269
+ const bodyStart = html.indexOf("<body");
270
+ if (bodyStart === -1) return html;
271
+ const bodyTagEnd = html.indexOf(">", bodyStart);
272
+ if (bodyTagEnd === -1) return html;
273
+
274
+ const bodyClose = html.lastIndexOf("</body>");
275
+ if (bodyClose === -1) return html;
276
+
277
+ // The direct-child region.
278
+ const before = html.slice(0, bodyTagEnd + 1);
279
+ const children = html.slice(bodyTagEnd + 1, bodyClose);
280
+ const after = html.slice(bodyClose);
281
+
282
+ const patched = _patchDirectChildren(children);
283
+ if (patched === children) return html; // nothing changed
284
+ return before + patched + after;
285
+ }
286
+
287
+ /**
288
+ * Walk the HTML fragment that represents the direct children of <body> and
289
+ * insert `data-an-primitive` on qualifying elements that lack it.
290
+ *
291
+ * We do NOT recurse into children — only sibling-level (depth-1) tags are
292
+ * touched.
293
+ */
294
+ function _patchDirectChildren(fragment: string): string {
295
+ let result = "";
296
+ let pos = 0;
297
+
298
+ while (pos < fragment.length) {
299
+ // Find the next '<'.
300
+ const tagStart = fragment.indexOf("<", pos);
301
+ if (tagStart === -1) {
302
+ result += fragment.slice(pos);
303
+ break;
304
+ }
305
+
306
+ // Copy any text / whitespace before this tag verbatim.
307
+ result += fragment.slice(pos, tagStart);
308
+ pos = tagStart;
309
+
310
+ // Peek: is this a comment, closing tag, or doctype? Copy verbatim.
311
+ const rest = fragment.slice(pos);
312
+ if (
313
+ rest.startsWith("<!--") ||
314
+ rest.startsWith("</") ||
315
+ rest.startsWith("<!") ||
316
+ rest.startsWith("<?")
317
+ ) {
318
+ const end = fragment.indexOf(">", pos);
319
+ if (end === -1) {
320
+ result += fragment.slice(pos);
321
+ pos = fragment.length;
322
+ } else {
323
+ result += fragment.slice(pos, end + 1);
324
+ pos = end + 1;
325
+ }
326
+ continue;
327
+ }
328
+
329
+ // Find the end of this opening tag (handling quoted attributes).
330
+ const tagEnd = _findTagEnd(fragment, pos);
331
+ if (tagEnd === -1) {
332
+ // Malformed — copy rest verbatim.
333
+ result += fragment.slice(pos);
334
+ break;
335
+ }
336
+
337
+ const openTag = fragment.slice(pos, tagEnd + 1);
338
+
339
+ // Skip the tag body + nested content and get to the matching close tag so
340
+ // we can copy the whole element and move past it.
341
+ // We need the tag name first.
342
+ const tagNameMatch = openTag.match(/^<([a-zA-Z][a-zA-Z0-9-]*)/);
343
+ if (!tagNameMatch) {
344
+ // Not an element tag — copy verbatim and advance.
345
+ result += openTag;
346
+ pos = tagEnd + 1;
347
+ continue;
348
+ }
349
+ const tagName = tagNameMatch[1].toLowerCase();
350
+
351
+ // SVG elements: vector primitives (line/path/arrow/polygon/star) render as
352
+ // <svg>. When the marker is missing we conservatively infer the kind from
353
+ // the SVG's inner geometry so the layers panel shows the right vector icon
354
+ // instead of the generic shape glyph. Geometry is never altered — only the
355
+ // marker attribute is inserted on the opening <svg> tag.
356
+ if (tagName === "svg") {
357
+ const closeTag = `</svg>`;
358
+ const closeIdx = fragment.indexOf(closeTag, tagEnd + 1);
359
+ if (closeIdx === -1) {
360
+ result += fragment.slice(pos);
361
+ pos = fragment.length;
362
+ continue;
363
+ }
364
+ const inner = fragment.slice(tagEnd + 1, closeIdx);
365
+ const shouldPatchSvg =
366
+ openTag.includes("data-agent-native-node-id=") &&
367
+ !openTag.includes("data-an-primitive=");
368
+ let patchedSvgOpenTag = openTag;
369
+ if (shouldPatchSvg) {
370
+ const kind = _inferSvgPrimitiveKind(inner);
371
+ if (kind) {
372
+ patchedSvgOpenTag = openTag.replace(
373
+ /(\s*\/?>)$/,
374
+ ` data-an-primitive="${kind}"$1`,
375
+ );
376
+ }
377
+ }
378
+ result += patchedSvgOpenTag + inner + closeTag;
379
+ pos = closeIdx + closeTag.length;
380
+ continue;
381
+ }
382
+
383
+ // For all other elements: decide whether to patch.
384
+ const shouldPatch =
385
+ openTag.includes("data-agent-native-node-id=") &&
386
+ !openTag.includes("data-an-primitive=");
387
+
388
+ let patchedOpenTag = openTag;
389
+ if (shouldPatch) {
390
+ const kind = _inferPrimitiveKind(openTag);
391
+ // Insert marker just before the closing `>` or `/>` of the opening tag.
392
+ patchedOpenTag = openTag.replace(
393
+ /(\s*\/?>)$/,
394
+ ` data-an-primitive="${kind}"$1`,
395
+ );
396
+ }
397
+
398
+ // Find the matching close tag (skip self-closing tags).
399
+ const isSelfClosing = openTag.endsWith("/>") || VOID_ELEMENTS.has(tagName);
400
+ if (isSelfClosing) {
401
+ result += patchedOpenTag;
402
+ pos = tagEnd + 1;
403
+ continue;
404
+ }
405
+
406
+ const closeTag = `</${tagName}>`;
407
+ const closeIdx = _findMatchingClose(fragment, tagEnd + 1, tagName);
408
+ if (closeIdx === -1) {
409
+ // Unmatched open tag — copy rest verbatim.
410
+ result += patchedOpenTag + fragment.slice(tagEnd + 1);
411
+ pos = fragment.length;
412
+ continue;
413
+ }
414
+
415
+ const innerContent = fragment.slice(tagEnd + 1, closeIdx);
416
+ result += patchedOpenTag + innerContent + closeTag;
417
+ pos = closeIdx + closeTag.length;
418
+ }
419
+
420
+ return result;
421
+ }
422
+
423
+ /** Void elements that have no closing tag. */
424
+ const VOID_ELEMENTS = new Set([
425
+ "area",
426
+ "base",
427
+ "br",
428
+ "col",
429
+ "embed",
430
+ "hr",
431
+ "img",
432
+ "input",
433
+ "link",
434
+ "meta",
435
+ "param",
436
+ "source",
437
+ "track",
438
+ "wbr",
439
+ ]);
440
+
441
+ /**
442
+ * Find the index of the `>` that closes the opening tag starting at `start`
443
+ * in `html`, skipping over quoted attribute values.
444
+ */
445
+ function _findTagEnd(html: string, start: number): number {
446
+ let i = start + 1; // Skip '<'
447
+ while (i < html.length) {
448
+ const ch = html[i];
449
+ if (ch === ">") return i;
450
+ if (ch === '"' || ch === "'") {
451
+ // Skip quoted attribute value.
452
+ const quote = ch;
453
+ i++;
454
+ while (i < html.length && html[i] !== quote) i++;
455
+ if (i < html.length) i++; // skip closing quote
456
+ continue;
457
+ }
458
+ i++;
459
+ }
460
+ return -1;
461
+ }
462
+
463
+ /**
464
+ * Find the index of the matching `</tagName>` for an element whose opening tag
465
+ * ended at `afterOpen`. Handles nesting by counting open/close pairs.
466
+ */
467
+ function _findMatchingClose(
468
+ html: string,
469
+ afterOpen: number,
470
+ tagName: string,
471
+ ): number {
472
+ const openRe = new RegExp(`<${tagName}[\\s/>]`, "gi");
473
+ const closeTag = `</${tagName}>`;
474
+ let depth = 1;
475
+ let pos = afterOpen;
476
+
477
+ while (pos < html.length && depth > 0) {
478
+ // Find the next candidate: open or close tag.
479
+ openRe.lastIndex = pos;
480
+ const nextOpen = openRe.exec(html);
481
+ const nextClose = html.indexOf(closeTag, pos);
482
+
483
+ if (nextClose === -1) return -1; // unmatched
484
+
485
+ if (nextOpen && nextOpen.index < nextClose) {
486
+ depth++;
487
+ pos = nextOpen.index + nextOpen[0].length;
488
+ } else {
489
+ depth--;
490
+ if (depth === 0) return nextClose;
491
+ pos = nextClose + closeTag.length;
492
+ }
493
+ }
494
+ return -1;
495
+ }
496
+
497
+ /**
498
+ * Infer the `data-an-primitive` kind value for a board element whose opening
499
+ * tag is `openTag` and which is known to lack the marker.
500
+ *
501
+ * Inference is conservative — only clear signals produce a non-"rectangle"
502
+ * kind.
503
+ */
504
+ function _inferPrimitiveKind(openTag: string): string {
505
+ // Extract the inline style value (first style="..." attribute).
506
+ const styleMatch = openTag.match(/\bstyle="([^"]*)"/i);
507
+ const style = styleMatch ? styleMatch[1] : "";
508
+
509
+ // Ellipse: CSS border-radius:50% (or border-radius: 50%).
510
+ if (/border-radius\s*:\s*50%/.test(style)) {
511
+ return "ellipse";
512
+ }
513
+
514
+ // Frame: transparent background.
515
+ if (/background\s*:\s*transparent/.test(style)) {
516
+ return "frame";
517
+ }
518
+
519
+ // Extract the layer name for additional hints.
520
+ const layerNameMatch = openTag.match(
521
+ /\bdata-agent-native-layer-name="([^"]*)"/i,
522
+ );
523
+ const layerName = layerNameMatch ? layerNameMatch[1] : "";
524
+
525
+ // Frame: layer name starts with "Frame".
526
+ if (/^frame/i.test(layerName)) {
527
+ return "frame";
528
+ }
529
+
530
+ // Text: the element has no background-color-like value in the style, yet has
531
+ // a color property — we detect this via the presence of "color:" without a
532
+ // "background:" in the style. Also check for the white-space:pre-wrap
533
+ // pattern that text nodes emit.
534
+ if (
535
+ /white-space\s*:\s*pre-wrap/.test(style) ||
536
+ (/\bcolor\s*:/.test(style) && !/\bbackground\s*:/.test(style))
537
+ ) {
538
+ return "text";
539
+ }
540
+
541
+ // Default: rectangle.
542
+ return "rectangle";
543
+ }
544
+
545
+ /**
546
+ * Infer the `data-an-primitive` kind value for a marker-less board `<svg>`
547
+ * primitive from its inner geometry. Returns `null` when no reliable signal
548
+ * is present, in which case the SVG is left unmarked (it still classifies as a
549
+ * generic shape via tag heuristics) rather than mis-classified.
550
+ *
551
+ * Conservative signals (in priority order):
552
+ * - The path carries `marker-end` (the arrowhead reference) → `"arrow"`
553
+ * - The SVG contains a `<polygon>` element → `"polygon"`
554
+ * - The SVG contains exactly a single `<path>` and nothing
555
+ * else shape-like → `"path"`
556
+ *
557
+ * Geometry (points, path data, polygon points) is never inspected for sizing
558
+ * and never altered — only the presence/type of child elements is consulted.
559
+ */
560
+ function _inferSvgPrimitiveKind(inner: string): string | null {
561
+ // Arrow: a path with a marker-end reference (the arrowhead). The arrowhead
562
+ // marker itself lives in <defs> as a separate path, so detect the consuming
563
+ // `marker-end="url(...)"` attribute rather than the marker definition.
564
+ if (/marker-end\s*=/.test(inner)) {
565
+ return "arrow";
566
+ }
567
+
568
+ // Polygon / star: rendered with a <polygon> element. Both kinds use the same
569
+ // SVG element, so we conservatively report "polygon" (star geometry is a
570
+ // polygon at the markup level and cannot be distinguished without sizing).
571
+ if (/<polygon\b/i.test(inner)) {
572
+ return "polygon";
573
+ }
574
+
575
+ // Pen-tool vector: a single <path> and no other shape elements.
576
+ const pathCount = (inner.match(/<path\b/gi) ?? []).length;
577
+ const hasOtherShape = /<(rect|circle|ellipse|line|polyline)\b/i.test(inner);
578
+ if (pathCount === 1 && !hasOtherShape) {
579
+ return "path";
580
+ }
581
+
582
+ // No reliable signal — leave unmarked.
583
+ return null;
584
+ }
585
+
586
+ // ---------------------------------------------------------------------------
587
+ // Private helpers
588
+ // ---------------------------------------------------------------------------
589
+
215
590
  function escapeAttr(value: string): string {
216
591
  return value
217
592
  .replace(/&/g, "&amp;")