@agent-native/core 0.83.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 (424) hide show
  1. package/README.md +2 -2
  2. package/corpus/README.md +1 -1
  3. package/corpus/core/CHANGELOG.md +28 -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/DefaultSpinner.tsx +8 -1
  57. package/corpus/core/src/client/chat/message-components.tsx +49 -1
  58. package/corpus/core/src/client/chat/repo-helpers.ts +71 -0
  59. package/corpus/core/src/client/chat/run-recovery.tsx +15 -5
  60. package/corpus/core/src/client/components/ApiKeySettings.tsx +8 -8
  61. package/corpus/core/src/client/components/CodeRequiredDialog.tsx +26 -15
  62. package/corpus/core/src/client/components/MissingKeyCard.tsx +13 -6
  63. package/corpus/core/src/client/composer/TiptapComposer.tsx +4 -3
  64. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +0 -1
  65. package/corpus/core/src/client/guided-questions.tsx +21 -27
  66. package/corpus/core/src/client/integrations/IntegrationCard.tsx +1 -1
  67. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +1 -1
  68. package/corpus/core/src/client/onboarding/OnboardingBanner.tsx +2 -2
  69. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +23 -19
  70. package/corpus/core/src/client/resources/ResourceEditor.tsx +18 -10
  71. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  72. package/corpus/core/src/client/settings/SettingsPanel.tsx +8 -3
  73. package/corpus/core/src/client/settings/useBuilderStatus.ts +8 -41
  74. package/corpus/core/src/client/useProductionAgent.ts +6 -2
  75. package/corpus/core/src/deploy/build.ts +1 -1
  76. package/corpus/core/src/observability/traces.ts +3 -3
  77. package/corpus/core/src/onboarding/default-steps.ts +1 -1
  78. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
  79. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
  80. package/corpus/core/src/server/agent-chat-plugin.ts +177 -81
  81. package/corpus/core/src/server/core-routes-plugin.ts +7 -1
  82. package/corpus/core/src/server/open-route.ts +59 -40
  83. package/corpus/core/src/shared/reasoning-effort.ts +2 -0
  84. package/corpus/core/src/sharing/access.ts +22 -2
  85. package/corpus/core/src/sharing/registry.ts +18 -0
  86. package/corpus/core/src/styles/agent-native.css +104 -20
  87. package/corpus/core/src/styles/rich-markdown-editor.css +11 -10
  88. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +10 -10
  89. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +10 -10
  90. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +6 -5
  91. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +9 -9
  92. package/corpus/templates/analytics/app/global.css +4 -0
  93. package/corpus/templates/analytics/app/lib/chart-theme.ts +13 -0
  94. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +22 -24
  95. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-charts-now-use-theme-aware-tooltip-and-grid-colors.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-06-30-fixed-ask-composer-spacing-so-the-chat-field-has-a-comfortab.md +6 -0
  97. package/corpus/templates/calendar/AGENTS.md +4 -0
  98. package/corpus/templates/calendar/actions/connect-google-calendar.ts +80 -0
  99. package/corpus/templates/calendar/changelog/2026-06-30-calendar-now-gives-the-agent-a-safe-google-connection-link-i.md +6 -0
  100. package/corpus/templates/calendar/server/plugins/agent-chat.ts +4 -0
  101. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +5 -5
  102. package/corpus/templates/content/app/global.css +6 -5
  103. package/corpus/templates/content/changelog/2026-06-30-editor-floating-toolbars-now-use-theme-aware-colors-in-light.md +6 -0
  104. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +6 -1
  105. package/corpus/templates/design/actions/add-localhost-screens.ts +63 -8
  106. package/corpus/templates/design/actions/apply-motion-edit.ts +12 -46
  107. package/corpus/templates/design/actions/list-design-native-assets.ts +2 -1
  108. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +49 -1
  109. package/corpus/templates/design/actions/navigate.ts +3 -12
  110. package/corpus/templates/design/actions/open-visual-edit.ts +341 -0
  111. package/corpus/templates/design/actions/view-screen.ts +1 -1
  112. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
  113. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -14
  114. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +71 -91
  115. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +25 -27
  116. package/corpus/templates/design/app/components/design/DeviceFrame.tsx +1 -1
  117. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +2 -2
  118. package/corpus/templates/design/app/components/design/EditPanel.tsx +1111 -570
  119. package/corpus/templates/design/app/components/design/LayersPanel.tsx +162 -32
  120. package/corpus/templates/design/app/components/design/MotionDock.tsx +268 -240
  121. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1038 -150
  122. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -1
  123. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +81 -102
  124. package/corpus/templates/design/app/components/design/StatesPanel.tsx +6 -6
  125. package/corpus/templates/design/app/components/design/TokensPanel.tsx +11 -11
  126. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -7
  127. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1129 -155
  128. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +130 -37
  129. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +24 -11
  130. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +184 -162
  131. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +137 -79
  132. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +13 -13
  133. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +8 -8
  134. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
  135. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +4 -4
  136. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +3 -3
  137. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -7
  138. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +14 -11
  139. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +4 -4
  140. package/corpus/templates/design/app/components/design/inspector/index.ts +2 -0
  141. package/corpus/templates/design/app/components/design/types.ts +19 -0
  142. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +61 -78
  143. package/corpus/templates/design/app/components/layout/Header.tsx +0 -1
  144. package/corpus/templates/design/app/components/layout/Layout.tsx +3 -2
  145. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  146. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +5 -4
  147. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
  148. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +2 -2
  149. package/corpus/templates/design/app/global.css +56 -0
  150. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -5
  151. package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -7
  152. package/corpus/templates/design/app/hooks/use-question-flow.ts +3 -2
  153. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +6 -4
  154. package/corpus/templates/design/app/i18n/zh-TW.ts +5 -14
  155. package/corpus/templates/design/app/i18n-data.ts +63 -188
  156. package/corpus/templates/design/app/lib/agent-chat.ts +13 -0
  157. package/corpus/templates/design/app/pages/DesignEditor.tsx +1428 -384
  158. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +9 -5
  159. package/corpus/templates/design/app/pages/DesignSystems.tsx +2 -2
  160. package/corpus/templates/design/app/pages/Index.tsx +49 -26
  161. package/corpus/templates/design/app/pages/NotFound.tsx +25 -8
  162. package/corpus/templates/design/app/pages/VisualEdit.tsx +17 -5
  163. package/corpus/templates/design/app/routes/examples.tsx +1 -7
  164. package/corpus/templates/design/app/routes/templates.tsx +7 -4
  165. package/corpus/templates/design/changelog/2026-06-30-board-shapes-and-auto-layout-controls-are-clearer.md +6 -0
  166. package/corpus/templates/design/changelog/2026-06-30-component-selections-now-use-purple-component-chrome-and-sho.md +6 -0
  167. package/corpus/templates/design/changelog/2026-06-30-constraints-now-stay-tucked-into-a-compact-inspector-preview.md +6 -0
  168. package/corpus/templates/design/changelog/2026-06-30-creating-a-component-now-opens-in-a-compact-inspector-popove.md +6 -0
  169. package/corpus/templates/design/changelog/2026-06-30-design-cards-no-longer-show-legacy-project-type-badges.md +6 -0
  170. package/corpus/templates/design/changelog/2026-06-30-design-chat-now-keeps-new-turns-in-the-visible-design-agent-.md +6 -0
  171. package/corpus/templates/design/changelog/2026-06-30-design-editor-panels-now-keep-their-compact-text-sizing-cons.md +6 -0
  172. package/corpus/templates/design/changelog/2026-06-30-design-no-longer-shows-the-connected-local-code-warning-bann.md +6 -0
  173. package/corpus/templates/design/changelog/2026-06-30-design-now-opens-to-the-files-panel-unless-a-generation-is-a.md +6 -0
  174. package/corpus/templates/design/changelog/2026-06-30-design-opens-with-a-cleaner-empty-canvas-and-loading-preview.md +6 -0
  175. package/corpus/templates/design/changelog/2026-06-30-design-tools-use-simpler-less-decorative-icons.md +6 -0
  176. package/corpus/templates/design/changelog/2026-06-30-dragging-absolute-elements-no-longer-shows-coordinate-labels.md +6 -0
  177. package/corpus/templates/design/changelog/2026-06-30-fixed-all-screens-opening-too-zoomed-in-by-default.md +6 -0
  178. package/corpus/templates/design/changelog/2026-06-30-fixed-the-public-design-assets-sidebar-so-native-components-.md +6 -0
  179. package/corpus/templates/design/changelog/2026-06-30-fixed-the-screen-overview-board-so-empty-board-space-no-long.md +6 -0
  180. package/corpus/templates/design/changelog/2026-06-30-full-view-screens-can-now-scroll-while-remaining-editable.md +6 -0
  181. package/corpus/templates/design/changelog/2026-06-30-inspector-element-headers-show-the-selected-html-tag-and-the.md +6 -0
  182. package/corpus/templates/design/changelog/2026-06-30-inspector-inputs-stay-compact-across-desktop-breakpoints.md +6 -0
  183. package/corpus/templates/design/changelog/2026-06-30-layers-can-be-multi-selected-from-the-canvas-and-edited-toge.md +6 -0
  184. package/corpus/templates/design/changelog/2026-06-30-local-visual-edit-links-can-edit-localhost-frames-without-si.md +6 -0
  185. package/corpus/templates/design/changelog/2026-06-30-localhost-visual-edit-frames-can-now-be-selected-and-edited.md +6 -0
  186. package/corpus/templates/design/changelog/2026-06-30-marquee-selection-now-works-inside-screens-multi-selected-la.md +6 -0
  187. package/corpus/templates/design/changelog/2026-06-30-motion-is-now-available-from-the-persistent-left-rail-and-th.md +6 -0
  188. package/corpus/templates/design/changelog/2026-06-30-motion-timeline-collapse-and-reopen-animations-feel-smoother.md +6 -0
  189. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +6 -0
  190. package/corpus/templates/design/changelog/2026-06-30-new-board-shapes-now-start-with-neutral-gray-styling.md +6 -0
  191. package/corpus/templates/design/changelog/2026-06-30-new-designs-open-into-a-steadier-loading-state-before-the-ed.md +6 -0
  192. package/corpus/templates/design/changelog/2026-06-30-new-designs-show-a-loading-state-during-handoff-and-keep-edi.md +6 -0
  193. package/corpus/templates/design/changelog/2026-06-30-public-visual-edit-design-links-now-open-directly-instead-of.md +6 -0
  194. package/corpus/templates/design/changelog/2026-06-30-removed-the-confusing-states-section-from-the-design-editor-.md +6 -0
  195. package/corpus/templates/design/changelog/2026-06-30-removed-the-templates-gallery-from-design-navigation.md +6 -0
  196. package/corpus/templates/design/changelog/2026-06-30-share-stays-visible-as-soon-as-editable-designs-load.md +6 -0
  197. package/corpus/templates/design/changelog/2026-06-30-signed-out-save-and-share-controls-use-simpler-labels-and-op.md +6 -0
  198. package/corpus/templates/design/changelog/2026-06-30-text-added-on-the-canvas-now-focuses-cleanly-with-the-right-.md +6 -0
  199. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-is-simpler-and-its-bottom.md +6 -0
  200. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-now-follows-the-current-t.md +6 -0
  201. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-child-layout-controls-o.md +6 -0
  202. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-the-ask-ai-section-abov.md +6 -0
  203. package/corpus/templates/design/changelog/2026-06-30-the-design-review-panel-no-longer-shows-a-separate-inline-au.md +6 -0
  204. package/corpus/templates/design/changelog/2026-06-30-the-empty-designs-page-now-focuses-on-a-single-primary-new-d.md +6 -0
  205. package/corpus/templates/design/changelog/2026-06-30-the-layers-panel-header-stays-as-layers-while-multiple-items.md +6 -0
  206. package/corpus/templates/design/changelog/2026-06-30-the-missing-design-screen-now-uses-a-neutral-back-button.md +6 -0
  207. package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-now-closes-without-squeezing-the-canvas-.md +6 -0
  208. package/corpus/templates/design/changelog/2026-06-30-the-new-design-connect-ai-setup-now-lines-up-with-the-compos.md +6 -0
  209. package/corpus/templates/design/changelog/2026-06-30-the-screen-overview-board-now-blends-into-the-canvas-and-new.md +6 -0
  210. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-drops-now-show-screen-guides.md +6 -0
  211. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-keep-a-transparent-backdrop-and-.md +6 -0
  212. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-select-reliably-from-all-screens.md +6 -0
  213. package/corpus/templates/design/changelog/2026-06-30-visual-edit-can-open-and-refresh-localhost-screens-in-one-au.md +6 -0
  214. package/corpus/templates/design/e2e/helpers.ts +15 -4
  215. package/corpus/templates/design/server/db/index.ts +52 -0
  216. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -0
  217. package/corpus/templates/design/server/plugins/auth.ts +1 -0
  218. package/corpus/templates/design/server/plugins/core-routes.ts +4 -0
  219. package/corpus/templates/design/shared/board-file.ts +380 -5
  220. package/corpus/templates/design/shared/board-objects.ts +2 -2
  221. package/corpus/templates/design/shared/code-layer.ts +50 -6
  222. package/corpus/templates/design/shared/motion-compiler.ts +27 -0
  223. package/corpus/templates/macros/app/components/DailyProgress.tsx +41 -37
  224. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  225. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  226. package/corpus/templates/macros/app/components/VoiceDictation.tsx +1 -1
  227. package/corpus/templates/macros/app/components/WeeklyCaloriesChart.tsx +1 -1
  228. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  229. package/corpus/templates/macros/app/components/WeightTracker.tsx +1 -1
  230. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -1
  231. package/corpus/templates/macros/app/routes/_index.tsx +5 -5
  232. package/corpus/templates/macros/app/routes/analytics.tsx +1 -1
  233. package/corpus/templates/macros/changelog/2026-06-30-dashboard-loading-and-chart-surfaces-now-use-theme-aware-col.md +6 -0
  234. package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +14 -11
  235. package/corpus/templates/mail/app/global.css +3 -2
  236. package/corpus/templates/mail/changelog/2026-06-30-compose-floating-toolbars-now-use-theme-aware-colors-in-ligh.md +6 -0
  237. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
  238. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +3 -3
  239. package/corpus/templates/slides/app/global.css +10 -0
  240. package/corpus/templates/slides/app/pages/Index.tsx +55 -51
  241. package/corpus/templates/slides/changelog/2026-06-30-deck-thumbnails-collapse-cleanly-to-one-column-when-the-chat.md +6 -0
  242. package/dist/agent/engine/anthropic-engine.d.ts +2 -2
  243. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  244. package/dist/agent/engine/builder-engine.d.ts +2 -2
  245. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  246. package/dist/agent/engine/builtin.js +1 -1
  247. package/dist/agent/engine/builtin.js.map +1 -1
  248. package/dist/agent/engine/output-tokens.js +1 -1
  249. package/dist/agent/engine/output-tokens.js.map +1 -1
  250. package/dist/agent/harness/acp-adapter.d.ts +4 -1
  251. package/dist/agent/harness/acp-adapter.d.ts.map +1 -1
  252. package/dist/agent/harness/acp-adapter.js +19 -2
  253. package/dist/agent/harness/acp-adapter.js.map +1 -1
  254. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  255. package/dist/agent/harness/ai-sdk-adapter.js +3 -0
  256. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  257. package/dist/agent/harness/translate.d.ts.map +1 -1
  258. package/dist/agent/harness/translate.js +3 -0
  259. package/dist/agent/harness/translate.js.map +1 -1
  260. package/dist/agent/harness/types.d.ts +1 -0
  261. package/dist/agent/harness/types.d.ts.map +1 -1
  262. package/dist/agent/harness/types.js.map +1 -1
  263. package/dist/agent/model-config.d.ts +21 -20
  264. package/dist/agent/model-config.d.ts.map +1 -1
  265. package/dist/agent/model-config.js +31 -13
  266. package/dist/agent/model-config.js.map +1 -1
  267. package/dist/agent/production-agent.d.ts.map +1 -1
  268. package/dist/agent/production-agent.js +85 -10
  269. package/dist/agent/production-agent.js.map +1 -1
  270. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  271. package/dist/agent/thread-data-builder.js +27 -6
  272. package/dist/agent/thread-data-builder.js.map +1 -1
  273. package/dist/agent/tool-call-journal.d.ts +11 -9
  274. package/dist/agent/tool-call-journal.d.ts.map +1 -1
  275. package/dist/agent/tool-call-journal.js +92 -40
  276. package/dist/agent/tool-call-journal.js.map +1 -1
  277. package/dist/agent/types.d.ts +5 -1
  278. package/dist/agent/types.d.ts.map +1 -1
  279. package/dist/agent/types.js.map +1 -1
  280. package/dist/cli/design-connect.d.ts.map +1 -1
  281. package/dist/cli/design-connect.js +84 -0
  282. package/dist/cli/design-connect.js.map +1 -1
  283. package/dist/cli/gateway-helpers.d.ts +4 -0
  284. package/dist/cli/gateway-helpers.d.ts.map +1 -1
  285. package/dist/cli/gateway-helpers.js +9 -0
  286. package/dist/cli/gateway-helpers.js.map +1 -1
  287. package/dist/cli/recap.d.ts.map +1 -1
  288. package/dist/cli/recap.js +0 -2
  289. package/dist/cli/recap.js.map +1 -1
  290. package/dist/cli/skills.d.ts.map +1 -1
  291. package/dist/cli/skills.js +54 -16
  292. package/dist/cli/skills.js.map +1 -1
  293. package/dist/cli/workspace-dev.d.ts.map +1 -1
  294. package/dist/cli/workspace-dev.js +33 -6
  295. package/dist/cli/workspace-dev.js.map +1 -1
  296. package/dist/client/AssistantChat.d.ts.map +1 -1
  297. package/dist/client/AssistantChat.js +72 -26
  298. package/dist/client/AssistantChat.js.map +1 -1
  299. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  300. package/dist/client/DefaultSpinner.js +8 -1
  301. package/dist/client/DefaultSpinner.js.map +1 -1
  302. package/dist/client/chat/message-components.d.ts +7 -1
  303. package/dist/client/chat/message-components.d.ts.map +1 -1
  304. package/dist/client/chat/message-components.js +37 -1
  305. package/dist/client/chat/message-components.js.map +1 -1
  306. package/dist/client/chat/repo-helpers.d.ts +1 -0
  307. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  308. package/dist/client/chat/repo-helpers.js +59 -0
  309. package/dist/client/chat/repo-helpers.js.map +1 -1
  310. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  311. package/dist/client/chat/run-recovery.js +4 -4
  312. package/dist/client/chat/run-recovery.js.map +1 -1
  313. package/dist/client/components/ApiKeySettings.js +8 -8
  314. package/dist/client/components/ApiKeySettings.js.map +1 -1
  315. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  316. package/dist/client/components/CodeRequiredDialog.js +24 -15
  317. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  318. package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
  319. package/dist/client/components/MissingKeyCard.js +11 -6
  320. package/dist/client/components/MissingKeyCard.js.map +1 -1
  321. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  322. package/dist/client/composer/TiptapComposer.js +4 -3
  323. package/dist/client/composer/TiptapComposer.js.map +1 -1
  324. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  325. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  326. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  327. package/dist/client/guided-questions.d.ts.map +1 -1
  328. package/dist/client/guided-questions.js +6 -6
  329. package/dist/client/guided-questions.js.map +1 -1
  330. package/dist/client/integrations/IntegrationCard.js +1 -1
  331. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  332. package/dist/client/integrations/IntegrationsPanel.js +1 -1
  333. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  334. package/dist/client/onboarding/OnboardingBanner.js +2 -2
  335. package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
  336. package/dist/client/onboarding/OnboardingPanel.js +23 -19
  337. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  338. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  339. package/dist/client/resources/ResourceEditor.js +13 -10
  340. package/dist/client/resources/ResourceEditor.js.map +1 -1
  341. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  342. package/dist/client/resources/ResourcesPanel.js +2 -1
  343. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  344. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  345. package/dist/client/settings/SettingsPanel.js +8 -3
  346. package/dist/client/settings/SettingsPanel.js.map +1 -1
  347. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  348. package/dist/client/settings/useBuilderStatus.js +6 -38
  349. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  350. package/dist/client/useProductionAgent.d.ts +2 -1
  351. package/dist/client/useProductionAgent.d.ts.map +1 -1
  352. package/dist/client/useProductionAgent.js.map +1 -1
  353. package/dist/deploy/build.js +1 -1
  354. package/dist/deploy/build.js.map +1 -1
  355. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  356. package/dist/notifications/routes.d.ts +1 -1
  357. package/dist/observability/routes.d.ts +5 -5
  358. package/dist/observability/traces.d.ts.map +1 -1
  359. package/dist/observability/traces.js.map +1 -1
  360. package/dist/onboarding/default-steps.js +1 -1
  361. package/dist/onboarding/default-steps.js.map +1 -1
  362. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  363. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  364. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  365. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  366. package/dist/server/agent-chat-plugin.d.ts +3 -0
  367. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  368. package/dist/server/agent-chat-plugin.js +134 -72
  369. package/dist/server/agent-chat-plugin.js.map +1 -1
  370. package/dist/server/core-routes-plugin.d.ts +3 -0
  371. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  372. package/dist/server/core-routes-plugin.js +4 -1
  373. package/dist/server/core-routes-plugin.js.map +1 -1
  374. package/dist/server/open-route.d.ts +9 -0
  375. package/dist/server/open-route.d.ts.map +1 -1
  376. package/dist/server/open-route.js +48 -38
  377. package/dist/server/open-route.js.map +1 -1
  378. package/dist/shared/reasoning-effort.js +3 -0
  379. package/dist/shared/reasoning-effort.js.map +1 -1
  380. package/dist/sharing/access.d.ts.map +1 -1
  381. package/dist/sharing/access.js +18 -2
  382. package/dist/sharing/access.js.map +1 -1
  383. package/dist/sharing/registry.d.ts +10 -0
  384. package/dist/sharing/registry.d.ts.map +1 -1
  385. package/dist/sharing/registry.js.map +1 -1
  386. package/dist/styles/agent-native.css +104 -20
  387. package/dist/styles/rich-markdown-editor.css +11 -10
  388. package/docs/content/cloneable-saas.mdx +2 -2
  389. package/docs/content/faq.mdx +1 -1
  390. package/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  391. package/docs/content/locales/ar-SA/faq.mdx +1 -1
  392. package/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  393. package/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  394. package/docs/content/locales/de-DE/faq.mdx +1 -1
  395. package/docs/content/locales/de-DE/template-chat.mdx +1 -1
  396. package/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  397. package/docs/content/locales/es-ES/faq.mdx +1 -1
  398. package/docs/content/locales/es-ES/template-chat.mdx +1 -1
  399. package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  400. package/docs/content/locales/fr-FR/faq.mdx +1 -1
  401. package/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  402. package/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  403. package/docs/content/locales/hi-IN/faq.mdx +1 -1
  404. package/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  405. package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  406. package/docs/content/locales/ja-JP/faq.mdx +1 -1
  407. package/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  408. package/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  409. package/docs/content/locales/ko-KR/faq.mdx +1 -1
  410. package/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  411. package/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  412. package/docs/content/locales/pt-BR/faq.mdx +1 -1
  413. package/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  414. package/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  415. package/docs/content/locales/zh-CN/faq.mdx +1 -1
  416. package/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  417. package/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  418. package/docs/content/locales/zh-TW/faq.mdx +1 -1
  419. package/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  420. package/docs/content/template-chat.mdx +1 -1
  421. package/package.json +1 -1
  422. package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +0 -157
  423. package/corpus/templates/design/app/lib/design-templates.ts +0 -1305
  424. package/corpus/templates/design/app/pages/Templates.tsx +0 -279
@@ -17,6 +17,7 @@ import { z } from "zod";
17
17
  import { getDb, schema } from "../server/db/index.js";
18
18
  import {
19
19
  mergeCanvasFramePlacements,
20
+ parseCanvasFrameGeometryById,
20
21
  type CanvasFramePlacement,
21
22
  } from "../shared/canvas-frames.js";
22
23
  import {
@@ -148,6 +149,25 @@ function uniqueFilename(
148
149
  return filename;
149
150
  }
150
151
 
152
+ export function viewportFilename(
153
+ pathOrUrl: string,
154
+ width: number,
155
+ height: number,
156
+ ) {
157
+ const viewport = `${Math.round(width)}x${Math.round(height)}`;
158
+ return `localhost-${slugForPath(pathOrUrl)}-${viewport}.html`;
159
+ }
160
+
161
+ function metadataNumber(
162
+ metadata: Record<string, unknown> | undefined,
163
+ key: "width" | "height",
164
+ ) {
165
+ const value = metadata?.[key];
166
+ return typeof value === "number" && Number.isFinite(value)
167
+ ? value
168
+ : undefined;
169
+ }
170
+
151
171
  export default defineAction({
152
172
  description:
153
173
  "Create or refresh URL-backed localhost screens in a design project. " +
@@ -179,14 +199,12 @@ export default defineAction({
179
199
  .number()
180
200
  .positive()
181
201
  .optional()
182
- .default(1280)
183
- .describe("Default iframe viewport width."),
202
+ .describe("Default iframe viewport width. Defaults to 1280."),
184
203
  defaultHeight: z
185
204
  .number()
186
205
  .positive()
187
206
  .optional()
188
- .default(900)
189
- .describe("Default iframe viewport height."),
207
+ .describe("Default iframe viewport height. Defaults to 900."),
190
208
  startX: z.number().optional().default(0),
191
209
  startY: z.number().optional().default(0),
192
210
  gap: z.number().optional().default(160),
@@ -292,6 +310,13 @@ export default defineAction({
292
310
  .from(schema.designs)
293
311
  .where(eq(schema.designs.id, designId))
294
312
  .limit(1);
313
+ const prevData = parseJson<Record<string, unknown>>(design?.data, {});
314
+ const existingCanvasFrames = parseCanvasFrameGeometryById(
315
+ prevData.canvasFrames,
316
+ );
317
+ const existingMetadata = isRecord(prevData.screenMetadata)
318
+ ? (prevData.screenMetadata as Record<string, unknown>)
319
+ : {};
295
320
  const existingFiles = await db
296
321
  .select()
297
322
  .from(schema.designFiles)
@@ -301,6 +326,8 @@ export default defineAction({
301
326
  );
302
327
  const usedFilenames = new Set(existingFiles.map((file) => file.filename));
303
328
  const now = new Date().toISOString();
329
+ const effectiveDefaultWidth = defaultWidth ?? 1280;
330
+ const effectiveDefaultHeight = defaultHeight ?? 900;
304
331
  const savedScreens: Array<{
305
332
  id: string;
306
333
  filename: string;
@@ -333,9 +360,38 @@ export default defineAction({
333
360
  const title =
334
361
  input.title ?? manifestRoute?.title ?? titleFromRoutePath(path);
335
362
  const sourceFile = input.sourceFile ?? manifestRoute?.sourceFile;
336
- const width = input.width ?? defaultWidth;
337
- const height = input.height ?? defaultHeight;
338
- const preferredFilename = `localhost-${slugForPath(path)}.html`;
363
+ const width = input.width ?? effectiveDefaultWidth;
364
+ const height = input.height ?? effectiveDefaultHeight;
365
+ const basePreferredFilename = `localhost-${slugForPath(path)}.html`;
366
+ const existingBase = existingByFilename.get(basePreferredFilename);
367
+ const requestedViewportExplicitly =
368
+ input.width !== undefined ||
369
+ input.height !== undefined ||
370
+ defaultWidth !== undefined ||
371
+ defaultHeight !== undefined;
372
+ const existingBaseMetadata = isRecord(
373
+ existingBase ? existingMetadata[existingBase.id] : undefined,
374
+ )
375
+ ? (existingMetadata[existingBase!.id] as Record<string, unknown>)
376
+ : undefined;
377
+ const existingBaseFrame = existingBase
378
+ ? existingCanvasFrames[existingBase.id]
379
+ : undefined;
380
+ const existingBaseWidth =
381
+ existingBaseFrame?.width ??
382
+ metadataNumber(existingBaseMetadata, "width");
383
+ const existingBaseHeight =
384
+ existingBaseFrame?.height ??
385
+ metadataNumber(existingBaseMetadata, "height");
386
+ const viewportDiffersFromBase =
387
+ (typeof existingBaseWidth === "number" &&
388
+ existingBaseWidth !== width) ||
389
+ (typeof existingBaseHeight === "number" &&
390
+ existingBaseHeight !== height);
391
+ const preferredFilename =
392
+ existingBase && requestedViewportExplicitly && viewportDiffersFromBase
393
+ ? viewportFilename(path, width, height)
394
+ : basePreferredFilename;
339
395
  const existing = existingByFilename.get(preferredFilename);
340
396
  const filename =
341
397
  existing?.filename ??
@@ -387,7 +443,6 @@ export default defineAction({
387
443
  });
388
444
  }
389
445
 
390
- const prevData = parseJson<Record<string, unknown>>(design?.data, {});
391
446
  const mergedFrames = mergeCanvasFramePlacements({
392
447
  existing: prevData.canvasFrames,
393
448
  placements,
@@ -31,6 +31,7 @@ import {
31
31
  assertSafeMotionCssProperty,
32
32
  assertSafeMotionCssToken,
33
33
  compile,
34
+ injectManagedMotionCss,
34
35
  } from "../shared/motion-compiler.js";
35
36
  import type { MotionTrack } from "../shared/motion-timeline.js";
36
37
 
@@ -69,55 +70,12 @@ const trackSchema = z.object({
69
70
 
70
71
  // ─── Helpers ──────────────────────────────────────────────────────────────────
71
72
 
72
- const MOTION_STYLE_OPEN = "<style data-agent-native-motion>";
73
- const MOTION_STYLE_CLOSE = "</style>";
74
-
75
- /**
76
- * Bounded, case-insensitive matcher for any HTML `</style>` end tag
77
- * (`</style >`, `</STYLE>`, …). Used to locate the close of the managed block
78
- * without a naive `indexOf("</style>")` that would miss case/whitespace
79
- * variants — and to detect any `</style` sequence smuggled into compiled CSS.
80
- */
81
- const STYLE_CLOSE_RE = /<\s*\/\s*style\b[^>]*>/i;
82
-
83
- /**
84
- * Inject or replace the managed `<style data-agent-native-motion>` block in
85
- * the HTML content. Inserts before `</head>` when not already present.
86
- */
87
- function injectMotionStyle(html: string, css: string): string {
88
- const open = MOTION_STYLE_OPEN;
89
- const close = MOTION_STYLE_CLOSE;
90
- const openIdx = html.indexOf(open);
91
-
92
- if (openIdx !== -1) {
93
- // Find the matching closing tag after the open tag using a bounded regex
94
- // (tolerates `</style >`, `</STYLE>`, etc.) instead of a literal indexOf.
95
- const after = html.slice(openIdx + open.length);
96
- const closeMatch = STYLE_CLOSE_RE.exec(after);
97
- if (closeMatch) {
98
- const closeIdx = openIdx + open.length + closeMatch.index;
99
- // Replace the existing block.
100
- return (
101
- html.slice(0, openIdx) + open + "\n" + css + "\n" + html.slice(closeIdx)
102
- );
103
- }
104
- }
105
-
106
- // Not found — insert before </head> or, if there is no <head>, at the top.
107
- const headClose = html.lastIndexOf("</head>");
108
- const block = `${open}\n${css}\n${close}`;
109
- if (headClose !== -1) {
110
- return html.slice(0, headClose) + block + "\n" + html.slice(headClose);
111
- }
112
- return block + "\n" + html;
113
- }
114
-
115
73
  async function persistFileContent(
116
74
  fileId: string,
117
75
  designId: string,
118
76
  content: string,
119
77
  now: string,
120
- ): Promise<void> {
78
+ ): Promise<string> {
121
79
  const db = getDb();
122
80
  await db
123
81
  .update(schema.designFiles)
@@ -134,6 +92,8 @@ async function persistFileContent(
134
92
  .update(schema.designs)
135
93
  .set({ updatedAt: now })
136
94
  .where(eq(schema.designs.id, designId));
95
+
96
+ return now;
137
97
  }
138
98
 
139
99
  // ─── Action ───────────────────────────────────────────────────────────────────
@@ -296,7 +256,7 @@ export default defineAction({
296
256
  });
297
257
 
298
258
  // ── 3. Inject the managed CSS block into the HTML ───────────────────────
299
- const patchedContent = injectMotionStyle(currentContent, css);
259
+ const patchedContent = injectManagedMotionCss(currentContent, css);
300
260
  const bytesBefore = currentContent.length;
301
261
  const bytesAfter = patchedContent.length;
302
262
 
@@ -392,7 +352,12 @@ export default defineAction({
392
352
  // Written after the row so a SQL failure here leaves the timeline row
393
353
  // accurate (correct tracks + hash) and the stale HTML can be recompiled on
394
354
  // the next apply-motion-edit call via compiledHash drift detection.
395
- await persistFileContent(fileId, designId, patchedContent, now);
355
+ const updatedAt = await persistFileContent(
356
+ fileId,
357
+ designId,
358
+ patchedContent,
359
+ now,
360
+ );
396
361
 
397
362
  return {
398
363
  timelineId: resolvedTimelineId,
@@ -401,6 +366,7 @@ export default defineAction({
401
366
  sourceRef: resolvedSourceRef,
402
367
  trackCount: typedTracks.length,
403
368
  compiledHash: hash,
369
+ updatedAt,
404
370
  bytesBefore,
405
371
  bytesAfter,
406
372
  bytesDelta: bytesAfter - bytesBefore,
@@ -90,7 +90,8 @@ export default defineAction({
90
90
  }),
91
91
  http: { method: "GET" },
92
92
  readOnly: true,
93
- publicAgent: { expose: true, readOnly: true, requiresAuth: true },
93
+ requiresAuth: false,
94
+ publicAgent: { expose: true, readOnly: true, requiresAuth: false },
94
95
  run: ({ category }) => {
95
96
  const assets = category
96
97
  ? DESIGN_NATIVE_ASSETS.filter((asset) => asset.category === category)
@@ -39,6 +39,7 @@ import { z } from "zod";
39
39
  import { getDb, schema } from "../server/db/index.js";
40
40
  import {
41
41
  BOARD_FILENAME,
42
+ backfillBoardPrimitiveMarkers,
42
43
  boardObjectEntryToHtmlFragment,
43
44
  emptyBoardHtml,
44
45
  } from "../shared/board-file.js";
@@ -91,10 +92,57 @@ export default defineAction({
91
92
  typeof parsed["boardFileId"] === "string" &&
92
93
  parsed["boardFileId"].length > 0
93
94
  ) {
95
+ // ── Marker backfill path ───────────────────────────────────────────────
96
+ // The board file exists (boardFileId set), but it may have been created
97
+ // before the data-an-primitive marker was introduced. Run the additive
98
+ // backfill so the layers-panel renders the correct icon (ellipse / text /
99
+ // frame / rectangle) instead of the generic code glyph.
100
+ const existingBoardFileId = parsed["boardFileId"] as string;
101
+
102
+ const [boardFileRow] = await db
103
+ .select({ content: schema.designFiles.content })
104
+ .from(schema.designFiles)
105
+ .where(eq(schema.designFiles.id, existingBoardFileId))
106
+ .limit(1);
107
+
108
+ if (boardFileRow) {
109
+ const originalContent = boardFileRow.content ?? "";
110
+ // Only run backfill when the board file has node-id elements but is
111
+ // missing at least one data-an-primitive marker.
112
+ const needsBackfill =
113
+ originalContent.includes("data-agent-native-node-id=") &&
114
+ !originalContent.includes("data-an-primitive=");
115
+
116
+ if (needsBackfill) {
117
+ const backfilledContent =
118
+ backfillBoardPrimitiveMarkers(originalContent);
119
+ const now = new Date().toISOString();
120
+ await db
121
+ .update(schema.designFiles)
122
+ .set({ content: backfilledContent, updatedAt: now })
123
+ .where(eq(schema.designFiles.id, existingBoardFileId));
124
+
125
+ // Best-effort collab re-seed.
126
+ try {
127
+ await seedFromText(existingBoardFileId, backfilledContent);
128
+ } catch {
129
+ // Non-fatal.
130
+ }
131
+
132
+ return {
133
+ designId,
134
+ migrated: false,
135
+ boardFileId: existingBoardFileId,
136
+ reason:
137
+ "boardFileId already set — backfilled missing data-an-primitive markers.",
138
+ };
139
+ }
140
+ }
141
+
94
142
  return {
95
143
  designId,
96
144
  migrated: false,
97
- boardFileId: parsed["boardFileId"] as string,
145
+ boardFileId: existingBoardFileId,
98
146
  reason: "boardFileId already set — migration already complete.",
99
147
  };
100
148
  }
@@ -10,12 +10,11 @@
10
10
  * pnpm action navigate --view=editor --designId=abc123 --filename=checkout.html
11
11
  * pnpm action navigate --view=design-systems
12
12
  * pnpm action navigate --view=design-systems --designSystemId=abc123
13
- * pnpm action navigate --view=templates
14
13
  * pnpm action navigate --view=settings
15
14
  * pnpm action navigate --path=/some/route
16
15
  *
17
16
  * Options:
18
- * --view View name (list, editor, design-systems, present, templates, settings)
17
+ * --view View name (list, editor, design-systems, present, settings)
19
18
  * --designId Design ID (for editor/present views)
20
19
  * --editorView Editor mode for designs: single or overview
21
20
  * --inspectorTab Inspector tab for designs: design or tweaks (extensions opens Tools for compatibility)
@@ -58,19 +57,11 @@ const designLeftPanelSchema = z.enum([
58
57
 
59
58
  export default defineAction({
60
59
  description:
61
- "Navigate the UI to a specific view or path. Views: list, editor, design-systems, present, templates, settings. Use --designId with editor/present views and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use leftPanel=file|agent|assets|tools|tokens to focus the Figma-style left rail. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
60
+ "Navigate the UI to a specific view or path. Views: list, editor, design-systems, present, settings. Use --designId with editor/present views and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use leftPanel=file|agent|assets|tools|tokens to focus the Figma-style left rail. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
62
61
  schema: z
63
62
  .object({
64
63
  view: z
65
- .enum([
66
- "list",
67
- "editor",
68
- "design-systems",
69
- "present",
70
- "templates",
71
- "examples",
72
- "settings",
73
- ])
64
+ .enum(["list", "editor", "design-systems", "present", "settings"])
74
65
  .optional()
75
66
  .describe("View name to navigate to"),
76
67
  designId: z.string().optional().describe("Design ID for editor/present"),
@@ -0,0 +1,341 @@
1
+ import crypto from "node:crypto";
2
+
3
+ import { defineAction, embedApp } from "@agent-native/core";
4
+ import { writeAppState } from "@agent-native/core/application-state";
5
+ import { buildDeepLink } from "@agent-native/core/server";
6
+ import { eq } from "drizzle-orm";
7
+ import { z } from "zod";
8
+
9
+ import { getDb, schema } from "../server/db/index.js";
10
+ import {
11
+ DESIGN_BRIDGE_OPERATIONS,
12
+ makeLocalhostRouteId,
13
+ titleFromRoutePath,
14
+ } from "../shared/source-mode.js";
15
+ import addLocalhostScreensAction, {
16
+ pathFromUrl,
17
+ routeUrl,
18
+ } from "./add-localhost-screens.js";
19
+ import connectLocalhostAction from "./connect-localhost.js";
20
+ import createDesignAction from "./create-design.js";
21
+ import navigateAction from "./navigate.js";
22
+
23
+ const connectionRouteSchema = z.object({
24
+ id: z.string().optional(),
25
+ path: z.string().min(1),
26
+ title: z.string().optional(),
27
+ sourceFile: z.string().optional(),
28
+ sourceKind: z.enum(["react-router", "html", "manual"]).optional(),
29
+ screenshotUrl: z.string().optional(),
30
+ metadata: z.record(z.string(), z.unknown()).optional(),
31
+ });
32
+
33
+ const screenRouteSchema = z.object({
34
+ routeId: z.string().optional(),
35
+ path: z.string().optional(),
36
+ url: z.string().optional(),
37
+ title: z.string().optional(),
38
+ sourceFile: z.string().optional(),
39
+ width: z.number().positive().optional(),
40
+ height: z.number().positive().optional(),
41
+ x: z.number().optional(),
42
+ y: z.number().optional(),
43
+ z: z.number().optional(),
44
+ });
45
+
46
+ const capabilitySchema = z.object({
47
+ operation: z.enum(DESIGN_BRIDGE_OPERATIONS),
48
+ status: z.enum(["available", "planned", "disabled"]),
49
+ reason: z.string().optional(),
50
+ });
51
+
52
+ const routeManifestSchema = z.object({
53
+ version: z.literal(1).optional().default(1),
54
+ sourceType: z.literal("localhost").optional().default("localhost"),
55
+ devServerUrl: z.string().optional(),
56
+ rootPath: z.string().optional(),
57
+ routes: z.array(connectionRouteSchema),
58
+ generatedAt: z.string().optional(),
59
+ });
60
+
61
+ const jsonArray = <T extends z.ZodTypeAny>(schema: T) =>
62
+ z.preprocess(
63
+ (value) => (typeof value === "string" ? JSON.parse(value) : value),
64
+ schema,
65
+ );
66
+
67
+ function normalizeBaseUrl(value: string): string {
68
+ const raw = value.trim();
69
+ const withProtocol = /^[a-z]+:\/\//i.test(raw) ? raw : `http://${raw}`;
70
+ const parsed = new URL(withProtocol);
71
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
72
+ throw new Error("devServerUrl must be an http(s) URL");
73
+ }
74
+ parsed.hash = "";
75
+ return parsed.toString().replace(/\/$/, "");
76
+ }
77
+
78
+ function isLoopbackUrl(value: string): boolean {
79
+ const hostname = new URL(value).hostname.toLowerCase();
80
+ if (hostname === "localhost" || hostname === "::1" || hostname === "[::1]") {
81
+ return true;
82
+ }
83
+ const parts = hostname.split(".");
84
+ return (
85
+ parts.length === 4 &&
86
+ parts[0] === "127" &&
87
+ parts.every((part) => /^\d+$/.test(part) && Number(part) <= 255)
88
+ );
89
+ }
90
+
91
+ function stableConnectionId(devServerUrl: string, rootPath?: string) {
92
+ const hash = crypto
93
+ .createHash("sha256")
94
+ .update(`${devServerUrl}\n${rootPath ?? ""}`)
95
+ .digest("base64url")
96
+ .slice(0, 16);
97
+ return `localhost_${hash}`;
98
+ }
99
+
100
+ function designOverviewDeepLink(designId: string): string {
101
+ return buildDeepLink({
102
+ app: "design",
103
+ view: "editor",
104
+ params: { designId, editorView: "overview" },
105
+ to: `/design/${encodeURIComponent(designId)}?editorView=overview`,
106
+ });
107
+ }
108
+
109
+ function routeManifestFromScreens(args: {
110
+ devServerUrl: string;
111
+ routes?: Array<z.infer<typeof screenRouteSchema>>;
112
+ paths?: string[];
113
+ }) {
114
+ const screenInputs: Array<z.infer<typeof screenRouteSchema>> = args.routes
115
+ ?.length
116
+ ? args.routes
117
+ : (args.paths?.map((path) => ({ path })) ?? []);
118
+ if (screenInputs.length === 0) return undefined;
119
+
120
+ return screenInputs.map((input) => {
121
+ const url = routeUrl(args.devServerUrl, {
122
+ path: input.path,
123
+ url: input.url,
124
+ });
125
+ const path = pathFromUrl(args.devServerUrl, url, input.path ?? "/");
126
+ return {
127
+ id: input.routeId ?? makeLocalhostRouteId(path),
128
+ path,
129
+ title: input.title ?? titleFromRoutePath(path),
130
+ sourceFile: input.sourceFile,
131
+ sourceKind: "manual" as const,
132
+ };
133
+ });
134
+ }
135
+
136
+ export default defineAction({
137
+ description:
138
+ "Open or refresh a running localhost app in Design overview mode in one authenticated step. Registers the local bridge, creates or reuses a design, places URL-backed screens, stores the active visual-edit context, and navigates the current Design session to the canvas. Use this for /visual-edit launches and follow-up requests like adding a mobile-size screen.",
139
+ schema: z.object({
140
+ designId: z
141
+ .string()
142
+ .optional()
143
+ .describe(
144
+ "Existing Design project to update. Omit to create a new visual-edit design.",
145
+ ),
146
+ connectionId: z
147
+ .string()
148
+ .optional()
149
+ .describe(
150
+ "Existing localhost connection. Omit to reuse a stable connection for devServerUrl + rootPath.",
151
+ ),
152
+ title: z
153
+ .string()
154
+ .optional()
155
+ .describe("Title for a newly created design project."),
156
+ description: z.string().optional(),
157
+ devServerUrl: z
158
+ .string()
159
+ .describe("Running local app URL, for example http://localhost:5173"),
160
+ bridgeUrl: z
161
+ .string()
162
+ .optional()
163
+ .describe("Local bridge URL printed by agent-native design connect."),
164
+ rootPath: z.string().optional().describe("Repository root for the app."),
165
+ name: z.string().optional().describe("Human-readable connection name."),
166
+ routeManifest: jsonArray(routeManifestSchema)
167
+ .optional()
168
+ .describe("Route manifest from the local Design bridge."),
169
+ capabilities: jsonArray(z.array(capabilitySchema))
170
+ .optional()
171
+ .describe("Bridge operation capabilities."),
172
+ bridgeToken: z
173
+ .string()
174
+ .optional()
175
+ .describe(
176
+ "Real bridge token from the running bridge. Stored server-side only; never returned.",
177
+ ),
178
+ routes: jsonArray(z.array(screenRouteSchema))
179
+ .optional()
180
+ .describe(
181
+ "Screens to place. Each route may include path, url, title, viewport width/height, and x/y/z.",
182
+ ),
183
+ paths: jsonArray(z.array(z.string()))
184
+ .optional()
185
+ .describe("Shortcut for routes when only paths/URLs are needed."),
186
+ defaultWidth: z
187
+ .number()
188
+ .positive()
189
+ .optional()
190
+ .describe("Default screen width. Defaults to 1280 when omitted."),
191
+ defaultHeight: z
192
+ .number()
193
+ .positive()
194
+ .optional()
195
+ .describe("Default screen height. Defaults to 900 when omitted."),
196
+ startX: z.number().optional().default(0),
197
+ startY: z.number().optional().default(0),
198
+ gap: z.number().optional().default(160),
199
+ navigate: z
200
+ .boolean()
201
+ .optional()
202
+ .default(true)
203
+ .describe("Write a navigate app-state command to open overview mode."),
204
+ publicReadOnly: z
205
+ .boolean()
206
+ .optional()
207
+ .default(true)
208
+ .describe(
209
+ "For newly created loopback localhost designs, make the design public viewer-access so existing browser sessions do not see a false 404. Writes still require editor access.",
210
+ ),
211
+ }),
212
+ mcpApp: {
213
+ compactCatalog: true,
214
+ resource: embedApp({
215
+ title: "Local visual edit",
216
+ description: "Open local URL-backed screens in Design overview mode.",
217
+ iframeTitle: "Agent-Native Design",
218
+ openLabel: "Open overview",
219
+ height: 680,
220
+ }),
221
+ },
222
+ run: async (args) => {
223
+ const devServerUrl = normalizeBaseUrl(args.devServerUrl);
224
+ const routeManifest = args.routeManifest
225
+ ? {
226
+ ...args.routeManifest,
227
+ devServerUrl: args.routeManifest.devServerUrl ?? devServerUrl,
228
+ rootPath: args.routeManifest.rootPath ?? args.rootPath,
229
+ }
230
+ : {
231
+ version: 1 as const,
232
+ sourceType: "localhost" as const,
233
+ devServerUrl,
234
+ rootPath: args.rootPath,
235
+ routes:
236
+ routeManifestFromScreens({
237
+ devServerUrl,
238
+ routes: args.routes,
239
+ paths: args.paths,
240
+ }) ?? [],
241
+ generatedAt: new Date().toISOString(),
242
+ };
243
+ const connectionId =
244
+ args.connectionId ?? stableConnectionId(devServerUrl, args.rootPath);
245
+
246
+ const connection = await connectLocalhostAction.run({
247
+ id: connectionId,
248
+ name: args.name,
249
+ devServerUrl,
250
+ bridgeUrl: args.bridgeUrl,
251
+ rootPath: routeManifest.rootPath ?? args.rootPath,
252
+ routeManifest,
253
+ capabilities: args.capabilities,
254
+ bridgeToken: args.bridgeToken,
255
+ status: "connected",
256
+ });
257
+
258
+ let designId = args.designId;
259
+ let createdDesign = false;
260
+ let publicReadOnly = false;
261
+ if (!designId) {
262
+ const design = await createDesignAction.run({
263
+ title: args.title ?? `${new URL(devServerUrl).host} visual edit`,
264
+ description:
265
+ args.description ??
266
+ "URL-backed localhost screens prepared by visual-edit.",
267
+ projectType: "prototype",
268
+ });
269
+ designId = design.id;
270
+ createdDesign = true;
271
+ if (args.publicReadOnly && isLoopbackUrl(devServerUrl)) {
272
+ publicReadOnly = true;
273
+ await getDb()
274
+ .update(schema.designs)
275
+ .set({ visibility: "public" })
276
+ .where(eq(schema.designs.id, designId));
277
+ }
278
+ }
279
+
280
+ const screens = await addLocalhostScreensAction.run({
281
+ designId,
282
+ connectionId: connection.id,
283
+ routes: args.routes,
284
+ paths: args.paths,
285
+ defaultWidth: args.defaultWidth,
286
+ defaultHeight: args.defaultHeight,
287
+ startX: args.startX,
288
+ startY: args.startY,
289
+ gap: args.gap,
290
+ });
291
+
292
+ const urlPath = `/design/${encodeURIComponent(
293
+ designId,
294
+ )}?editorView=overview`;
295
+ await writeAppState("visual-edit", {
296
+ designId,
297
+ connectionId: connection.id,
298
+ devServerUrl,
299
+ bridgeUrl: connection.bridgeUrl,
300
+ rootPath: connection.rootPath,
301
+ urlPath,
302
+ screens: screens.screens,
303
+ updatedAt: new Date().toISOString(),
304
+ });
305
+
306
+ if (args.navigate) {
307
+ await navigateAction.run({
308
+ view: "editor",
309
+ designId,
310
+ editorView: "overview",
311
+ path: urlPath,
312
+ });
313
+ }
314
+
315
+ return {
316
+ designId,
317
+ connectionId: connection.id,
318
+ createdDesign,
319
+ publicReadOnly,
320
+ devServerUrl,
321
+ bridgeUrl: connection.bridgeUrl,
322
+ rootPath: connection.rootPath,
323
+ screenCount: screens.screenCount,
324
+ screens: screens.screens,
325
+ placedFrames: screens.placedFrames,
326
+ overview: true,
327
+ urlPath,
328
+ openUrl: designOverviewDeepLink(designId),
329
+ };
330
+ },
331
+ link: ({ result }) => {
332
+ if (!result || typeof result !== "object") return null;
333
+ const designId = (result as { designId?: string }).designId;
334
+ if (!designId) return null;
335
+ return {
336
+ url: designOverviewDeepLink(designId),
337
+ label: "Open overview",
338
+ view: "editor",
339
+ };
340
+ },
341
+ });
@@ -95,7 +95,7 @@ function resolveActiveScreen(
95
95
 
96
96
  export default defineAction({
97
97
  description:
98
- "See what the user is currently looking at on screen. Returns the current navigation state including which design is open, which view they are on (list, editor, design-systems, present, templates, settings), active/focused design screen, selected element, active inspector tab (design or tweaks), active left rail panel (file, agent, assets, tools, or tokens), overview canvas state, plus any pending question overlay. Always call this first before taking any action.",
98
+ "See what the user is currently looking at on screen. Returns the current navigation state including which design is open, which view they are on (list, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design or tweaks), active left rail panel (file, agent, assets, tools, or tokens), overview canvas state, plus any pending question overlay. Always call this first before taking any action.",
99
99
  schema: z.object({}),
100
100
  http: false,
101
101
  run: async () => {