@agent-native/core 0.80.7 → 0.80.9

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 (302) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +18 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +6 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +8 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +10 -2
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +10 -2
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +7 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +7 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +7 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +9 -2
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +6 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +6 -0
  13. package/corpus/core/docs/content/template-design.mdx +9 -2
  14. package/corpus/core/package.json +1 -1
  15. package/corpus/core/src/cli/mcp.ts +10 -0
  16. package/corpus/core/src/cli/skills.ts +58 -12
  17. package/corpus/core/src/client/AssistantChat.tsx +70 -27
  18. package/corpus/core/src/client/analytics.ts +3 -1
  19. package/corpus/core/src/client/error-format.ts +25 -0
  20. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +13 -11
  21. package/corpus/core/src/client/guided-questions.tsx +32 -4
  22. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +33 -1
  23. package/corpus/core/src/client/resources/BuiltinCapabilityDetail.tsx +8 -0
  24. package/corpus/core/src/client/resources/use-builtin-capabilities.ts +4 -2
  25. package/corpus/core/src/client/session-replay.ts +34 -0
  26. package/corpus/core/src/client/sharing/ShareButton.tsx +106 -21
  27. package/corpus/core/src/coding-tools/index.ts +1 -1
  28. package/corpus/core/src/mcp/index.ts +2 -0
  29. package/corpus/core/src/mcp/screen-memory-stdio.ts +290 -0
  30. package/corpus/core/src/mcp-client/builtin-capabilities.ts +13 -1
  31. package/corpus/core/src/mcp-client/index.ts +9 -0
  32. package/corpus/core/src/mcp-client/screen-memory-local.ts +461 -0
  33. package/corpus/core/src/onboarding/types.ts +7 -0
  34. package/corpus/core/src/server/agent-chat-plugin.ts +25 -0
  35. package/corpus/core/src/server/agents-bundle.ts +35 -7
  36. package/corpus/core/src/styles/agent-native.css +5 -0
  37. package/corpus/core/src/templates/default/app/global.css +35 -35
  38. package/corpus/templates/analytics/AGENTS.md +6 -0
  39. package/corpus/templates/analytics/actions/github-repo-files.ts +9 -0
  40. package/corpus/templates/analytics/app/components/layout/Layout.tsx +4 -4
  41. package/corpus/templates/analytics/app/global.css +144 -40
  42. package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +1 -1
  43. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +1 -1
  44. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
  45. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +4 -4
  46. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +9 -9
  47. package/corpus/templates/analytics/changelog/2026-06-29-agents-can-search-and-read-connected-github-repositories-whe.md +6 -0
  48. package/corpus/templates/analytics/changelog/2026-06-29-sessions-and-explorer-layouts-adapt-when-the-agent-sidebar-is.md +6 -0
  49. package/corpus/templates/assets/app/components/layout/Layout.tsx +3 -1
  50. package/corpus/templates/assets/app/components/library/LibraryPresetGrid.tsx +1 -1
  51. package/corpus/templates/assets/app/global.css +99 -35
  52. package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -2
  53. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +4 -4
  54. package/corpus/templates/assets/app/routes/library.tsx +4 -4
  55. package/corpus/templates/assets/changelog/2026-06-29-asset-library-and-detail-layouts-adapt-when-the-agent-sidebar.md +6 -0
  56. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
  57. package/corpus/templates/brain/app/global.css +63 -35
  58. package/corpus/templates/brain/app/routes/search.tsx +1 -1
  59. package/corpus/templates/brain/app/routes/settings.tsx +1 -1
  60. package/corpus/templates/brain/app/routes/sources.tsx +2 -2
  61. package/corpus/templates/brain/changelog/2026-06-29-search-settings-and-source-layouts-adapt-when-the-agent-sidebar.md +6 -0
  62. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +4 -4
  63. package/corpus/templates/calendar/app/components/calendar/FindTimePanel.tsx +3 -2
  64. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +4 -2
  65. package/corpus/templates/calendar/app/global.css +69 -35
  66. package/corpus/templates/calendar/changelog/2026-06-29-event-and-find-time-layouts-adapt-when-the-agent-sidebar-is.md +6 -0
  67. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  68. package/corpus/templates/chat/app/global.css +35 -35
  69. package/corpus/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  70. package/corpus/templates/clips/AGENTS.md +13 -0
  71. package/corpus/templates/clips/actions/get-screen-memory-status.ts +12 -0
  72. package/corpus/templates/clips/actions/query-screen-memory-context.ts +29 -0
  73. package/corpus/templates/clips/actions/view-screen.ts +2 -2
  74. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  75. package/corpus/templates/clips/app/global.css +47 -35
  76. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +3 -3
  77. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +45 -18
  78. package/corpus/templates/clips/changelog/2026-06-29-meeting-detail-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-06-29-screen-memory-keeps-a-local-rolling-screen-buffer-for-agent-context.md +5 -0
  80. package/corpus/templates/clips/changelog/2026-06-29-video-chat-is-easier-to-find-on-recording-pages-and-s3-setup.md +6 -0
  81. package/corpus/templates/clips/chrome-extension/src/styles.css +39 -39
  82. package/corpus/templates/clips/desktop/src/app.tsx +290 -1
  83. package/corpus/templates/clips/desktop/src/shared/config.ts +83 -0
  84. package/corpus/templates/clips/desktop/src/styles.css +67 -52
  85. package/corpus/templates/clips/desktop/src-tauri/src/config.rs +50 -0
  86. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +17 -0
  87. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +13 -13
  88. package/corpus/templates/clips/desktop/src-tauri/src/screen_memory.rs +990 -0
  89. package/corpus/templates/clips/server/plugins/onboarding.ts +2 -0
  90. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +69 -16
  91. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +3 -3
  92. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
  93. package/corpus/templates/content/app/global.css +29 -15
  94. package/corpus/templates/content/changelog/2026-06-29-database-gallery-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  95. package/corpus/templates/content/changelog/2026-06-29-read-only-pages-no-longer-try-to-autosave-or-open-editor-onl.md +6 -0
  96. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +25 -20
  97. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -0
  98. package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +8 -0
  99. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +13 -0
  100. package/corpus/templates/design/AGENTS.md +24 -14
  101. package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1054 -0
  102. package/corpus/templates/design/actions/apply-visual-edit.ts +24 -4
  103. package/corpus/templates/design/actions/edit-design.ts +6 -3
  104. package/corpus/templates/design/actions/export-coding-handoff.ts +12 -4
  105. package/corpus/templates/design/actions/generate-design.ts +6 -21
  106. package/corpus/templates/design/actions/generate-screens.ts +48 -5
  107. package/corpus/templates/design/actions/get-design.ts +1 -0
  108. package/corpus/templates/design/actions/present-design-variants.ts +355 -30
  109. package/corpus/templates/design/actions/update-design.ts +47 -10
  110. package/corpus/templates/design/actions/update-file.ts +33 -8
  111. package/corpus/templates/design/actions/view-screen.ts +89 -31
  112. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +389 -71
  113. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +1 -1
  114. package/corpus/templates/design/app/components/design/EditPanel.tsx +596 -95
  115. package/corpus/templates/design/app/components/design/LayersPanel.tsx +428 -221
  116. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1197 -228
  117. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +94 -217
  118. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +28 -14
  119. package/corpus/templates/design/app/components/design/index.ts +0 -1
  120. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +228 -170
  121. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +140 -13
  122. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +39 -8
  123. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +4 -2
  124. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +75 -5
  125. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +37 -12
  126. package/corpus/templates/design/app/components/design/inspector/index.ts +1 -0
  127. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +17 -4
  128. package/corpus/templates/design/app/components/design/types.ts +9 -0
  129. package/corpus/templates/design/app/components/layout/Layout.tsx +23 -5
  130. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +448 -259
  131. package/corpus/templates/design/app/global.css +77 -49
  132. package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
  133. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +8 -1
  134. package/corpus/templates/design/app/i18n/zh-TW.ts +4 -0
  135. package/corpus/templates/design/app/i18n-data.ts +55 -3
  136. package/corpus/templates/design/app/pages/DesignEditor.tsx +2783 -658
  137. package/corpus/templates/design/app/root.tsx +1 -1
  138. package/corpus/templates/design/changelog/2026-06-29-agent-edits-to-a-design-are-no-longer-occasionally-dropped-o.md +6 -0
  139. package/corpus/templates/design/changelog/2026-06-29-box-shadow-and-gradient-colors-keep-named-css-colors-like-re.md +6 -0
  140. package/corpus/templates/design/changelog/2026-06-29-containers-no-longer-block-selecting-nested-elements-and-nor.md +6 -0
  141. package/corpus/templates/design/changelog/2026-06-29-cut-cmd-ctrl-x-now-removes-the-selected-element-to-the-clipb.md +6 -0
  142. package/corpus/templates/design/changelog/2026-06-29-deleting-with-multiple-layers-selected-in-the-layers-panel-n.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-generate-and-refine-variants-from-stronger.md +6 -0
  144. package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +6 -0
  145. package/corpus/templates/design/changelog/2026-06-29-design-questions-now-appear-as-a-cleaner-canvas-intake-with-.md +6 -0
  146. package/corpus/templates/design/changelog/2026-06-29-design-variant-directions-now-appear-as-board-screens-with-chat-buttons.md +5 -0
  147. package/corpus/templates/design/changelog/2026-06-29-duplicating-a-screen-now-gives-the-copy-its-own-layer-ids-so.md +6 -0
  148. package/corpus/templates/design/changelog/2026-06-29-element-selection-no-longer-snaps-back-to-the-previous-layer.md +6 -0
  149. package/corpus/templates/design/changelog/2026-06-29-frame-resize-measurements-now-stay-beside-the-cursor-while-d.md +6 -0
  150. package/corpus/templates/design/changelog/2026-06-29-hiding-and-re-showing-a-gradient-fill-now-preserves-each-sto.md +6 -0
  151. package/corpus/templates/design/changelog/2026-06-29-inspector-number-fields-have-cleaner-tooltips-and-draggable-.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-29-layer-locking-layer-nesting-generated-question-intake-and-im.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-29-layer-names-in-the-sidebar-can-scroll-horizontally-instead-o.md +6 -0
  154. package/corpus/templates/design/changelog/2026-06-29-layer-nesting-in-the-sidebar-now-uses-tighter-spacing-so-nam.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-29-layers-no-longer-repeat-document-wrapper-rows-when-a-screen-.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-29-overview-previews-now-keep-element-hover-and-selection-tied-.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-29-picking-a-design-direction-now-submits-to-the-agent-right-aw.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-29-pressing-escape-now-cancels-a-stuck-screen-drag-in-the-overv.md +6 -0
  159. package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +6 -0
  160. package/corpus/templates/design/changelog/2026-06-29-screen-overview-only-highlights-screens-when-the-frame-or-ti.md +6 -0
  161. package/corpus/templates/design/changelog/2026-06-29-screen-overview-previews-now-resize-to-match-the-selected-de.md +6 -0
  162. package/corpus/templates/design/changelog/2026-06-29-screen-overview-selection-now-uses-a-pointer-cursor-instead-.md +6 -0
  163. package/corpus/templates/design/changelog/2026-06-29-screen-overview-selection-outlines-now-stay-locked-to-the-se.md +6 -0
  164. package/corpus/templates/design/changelog/2026-06-29-screen-overview-zoom-now-reports-real-screen-scale-separatel.md +6 -0
  165. package/corpus/templates/design/changelog/2026-06-29-screen-overview-zooming-feels-smoother-and-selection-outline.md +6 -0
  166. package/corpus/templates/design/changelog/2026-06-29-screen-overview-zooming-now-stays-on-the-overview-canvas-ins.md +6 -0
  167. package/corpus/templates/design/changelog/2026-06-29-selecting-a-nested-layer-from-all-screens-now-keeps-you-in-a.md +6 -0
  168. package/corpus/templates/design/changelog/2026-06-29-share-now-groups-link-sharing-exports-and-agent-handoff.md +6 -0
  169. package/corpus/templates/design/changelog/2026-06-29-style-changes-that-set-several-properties-at-once-fixed-size.md +6 -0
  170. package/corpus/templates/design/changelog/2026-06-29-the-design-editor-loading-skeleton-now-uses-a-softer-charcoa.md +6 -0
  171. package/corpus/templates/design/changelog/2026-06-29-the-device-preview-menu-now-sits-next-to-the-preview-button-.md +6 -0
  172. package/corpus/templates/design/changelog/2026-06-29-the-editor-no-longer-crashes-when-a-screen-ends-up-with-dupl.md +6 -0
  173. package/corpus/templates/design/changelog/2026-06-29-the-inspector-stays-read-only-while-an-empty-design-is-still.md +6 -0
  174. package/corpus/templates/design/changelog/2026-06-29-the-missing-design-view-now-matches-the-rest-of-the-editor-c.md +6 -0
  175. package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-icon-and-tool-option-menus-better-match-the-edi.md +6 -0
  176. package/corpus/templates/design/changelog/2026-06-29-typography-controls-now-keep-the-font-name-visible-and-move-.md +6 -0
  177. package/corpus/templates/design/e2e/README.md +4 -3
  178. package/corpus/templates/design/e2e/global-setup.ts +24 -23
  179. package/corpus/templates/design/e2e/helpers.ts +122 -11
  180. package/corpus/templates/design/playwright.config.ts +19 -4
  181. package/corpus/templates/design/server/lib/coding-handoff.ts +126 -2
  182. package/corpus/templates/design/server/plugins/core-routes.ts +1 -2
  183. package/corpus/templates/design/server/routes/api/design-handoff/[id].zip.get.ts +86 -0
  184. package/corpus/templates/design/shared/code-layer.ts +125 -22
  185. package/corpus/templates/design/shared/color-utils.ts +159 -0
  186. package/corpus/templates/design/shared/generation-session.ts +42 -0
  187. package/corpus/templates/dispatch/app/global.css +79 -35
  188. package/corpus/templates/dispatch/app/routes/integrations.tsx +8 -7
  189. package/corpus/templates/dispatch/changelog/2026-06-29-integration-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  190. package/corpus/templates/forms/app/components/layout/Layout.tsx +6 -2
  191. package/corpus/templates/forms/app/global.css +64 -35
  192. package/corpus/templates/forms/app/pages/FormsListPage.tsx +2 -2
  193. package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +3 -3
  194. package/corpus/templates/forms/changelog/2026-06-29-form-list-and-insight-layouts-adapt-when-the-agent-sidebar.md +6 -0
  195. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +3 -1
  196. package/corpus/templates/macros/app/global.css +25 -9
  197. package/corpus/templates/macros/changelog/2026-06-29-macro-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  198. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -2
  199. package/corpus/templates/mail/app/global.css +42 -36
  200. package/corpus/templates/mail/app/pages/InboxPage.tsx +1 -1
  201. package/corpus/templates/mail/changelog/2026-06-29-the-contact-panel-now-adapts-to-the-available-mail-pane-width.md +6 -0
  202. package/corpus/templates/plan/app/components/layout/Layout.tsx +3 -1
  203. package/corpus/templates/plan/app/components/plan/DocumentArea.tsx +6 -7
  204. package/corpus/templates/plan/app/global.css +74 -42
  205. package/corpus/templates/plan/changelog/2026-06-29-plan-document-blocks-adapt-to-the-available-document-width.md +6 -0
  206. package/corpus/templates/plan/changelog/2026-06-29-plan-titles-and-summaries-can-be-edited-inline-without-focus.md +6 -0
  207. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -1
  208. package/corpus/templates/slides/app/global.css +49 -33
  209. package/corpus/templates/slides/changelog/2026-06-29-slide-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  210. package/corpus/templates/videos/app/components/layout/Layout.tsx +3 -1
  211. package/corpus/templates/videos/app/global.css +35 -35
  212. package/corpus/templates/videos/changelog/2026-06-29-video-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  213. package/dist/cli/mcp.d.ts.map +1 -1
  214. package/dist/cli/mcp.js +10 -0
  215. package/dist/cli/mcp.js.map +1 -1
  216. package/dist/cli/skills.d.ts.map +1 -1
  217. package/dist/cli/skills.js +58 -12
  218. package/dist/cli/skills.js.map +1 -1
  219. package/dist/client/AssistantChat.d.ts.map +1 -1
  220. package/dist/client/AssistantChat.js +54 -24
  221. package/dist/client/AssistantChat.js.map +1 -1
  222. package/dist/client/analytics.d.ts.map +1 -1
  223. package/dist/client/analytics.js +2 -1
  224. package/dist/client/analytics.js.map +1 -1
  225. package/dist/client/error-format.d.ts.map +1 -1
  226. package/dist/client/error-format.js +17 -0
  227. package/dist/client/error-format.js.map +1 -1
  228. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  229. package/dist/client/extensions/ExtensionViewer.js +3 -4
  230. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  231. package/dist/client/guided-questions.d.ts +4 -0
  232. package/dist/client/guided-questions.d.ts.map +1 -1
  233. package/dist/client/guided-questions.js +16 -7
  234. package/dist/client/guided-questions.js.map +1 -1
  235. package/dist/client/onboarding/OnboardingPanel.js +26 -1
  236. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  237. package/dist/client/resources/BuiltinCapabilityDetail.d.ts.map +1 -1
  238. package/dist/client/resources/BuiltinCapabilityDetail.js +1 -1
  239. package/dist/client/resources/BuiltinCapabilityDetail.js.map +1 -1
  240. package/dist/client/resources/use-builtin-capabilities.d.ts +1 -1
  241. package/dist/client/resources/use-builtin-capabilities.d.ts.map +1 -1
  242. package/dist/client/resources/use-builtin-capabilities.js +2 -1
  243. package/dist/client/resources/use-builtin-capabilities.js.map +1 -1
  244. package/dist/client/session-replay.d.ts.map +1 -1
  245. package/dist/client/session-replay.js +31 -0
  246. package/dist/client/session-replay.js.map +1 -1
  247. package/dist/client/sharing/ShareButton.d.ts +14 -0
  248. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  249. package/dist/client/sharing/ShareButton.js +36 -7
  250. package/dist/client/sharing/ShareButton.js.map +1 -1
  251. package/dist/coding-tools/index.js +1 -1
  252. package/dist/coding-tools/index.js.map +1 -1
  253. package/dist/collab/routes.d.ts +1 -1
  254. package/dist/mcp/index.d.ts +2 -0
  255. package/dist/mcp/index.d.ts.map +1 -1
  256. package/dist/mcp/index.js +1 -0
  257. package/dist/mcp/index.js.map +1 -1
  258. package/dist/mcp/screen-memory-stdio.d.ts +6 -0
  259. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -0
  260. package/dist/mcp/screen-memory-stdio.js +213 -0
  261. package/dist/mcp/screen-memory-stdio.js.map +1 -0
  262. package/dist/mcp-client/builtin-capabilities.d.ts +1 -1
  263. package/dist/mcp-client/builtin-capabilities.d.ts.map +1 -1
  264. package/dist/mcp-client/builtin-capabilities.js +10 -0
  265. package/dist/mcp-client/builtin-capabilities.js.map +1 -1
  266. package/dist/mcp-client/index.d.ts +1 -0
  267. package/dist/mcp-client/index.d.ts.map +1 -1
  268. package/dist/mcp-client/index.js +1 -0
  269. package/dist/mcp-client/index.js.map +1 -1
  270. package/dist/mcp-client/screen-memory-local.d.ts +61 -0
  271. package/dist/mcp-client/screen-memory-local.d.ts.map +1 -0
  272. package/dist/mcp-client/screen-memory-local.js +336 -0
  273. package/dist/mcp-client/screen-memory-local.js.map +1 -0
  274. package/dist/onboarding/types.d.ts +7 -0
  275. package/dist/onboarding/types.d.ts.map +1 -1
  276. package/dist/onboarding/types.js.map +1 -1
  277. package/dist/resources/handlers.d.ts +2 -2
  278. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  279. package/dist/server/agent-chat-plugin.js +26 -0
  280. package/dist/server/agent-chat-plugin.js.map +1 -1
  281. package/dist/server/agents-bundle.d.ts.map +1 -1
  282. package/dist/server/agents-bundle.js +22 -7
  283. package/dist/server/agents-bundle.js.map +1 -1
  284. package/dist/server/transcribe-voice.d.ts +1 -1
  285. package/dist/styles/agent-native.css +5 -0
  286. package/dist/templates/default/app/global.css +35 -35
  287. package/docs/content/locales/ar-SA/template-design.mdx +6 -0
  288. package/docs/content/locales/de-DE/template-design.mdx +8 -0
  289. package/docs/content/locales/es-ES/template-design.mdx +10 -2
  290. package/docs/content/locales/fr-FR/template-design.mdx +10 -2
  291. package/docs/content/locales/hi-IN/template-design.mdx +7 -0
  292. package/docs/content/locales/ja-JP/template-design.mdx +7 -0
  293. package/docs/content/locales/ko-KR/template-design.mdx +7 -0
  294. package/docs/content/locales/pt-BR/template-design.mdx +9 -2
  295. package/docs/content/locales/zh-CN/template-design.mdx +6 -0
  296. package/docs/content/locales/zh-TW/template-design.mdx +6 -0
  297. package/docs/content/template-design.mdx +9 -2
  298. package/package.json +1 -1
  299. package/src/templates/default/app/global.css +35 -35
  300. package/corpus/templates/design/app/components/design/VariantGrid.tsx +0 -189
  301. package/corpus/templates/design/app/components/design/VariantHandoffCard.tsx +0 -115
  302. package/corpus/templates/design/app/hooks/use-variant-flow.ts +0 -258
@@ -9,18 +9,10 @@ import {
9
9
  type GuidedQuestionOption,
10
10
  } from "@agent-native/core/client";
11
11
  import type { QuestionFlowQuestion } from "@shared/api";
12
- import {
13
- IconCheck,
14
- IconChevronRight,
15
- IconPalette,
16
- IconSparkles,
17
- IconUpload,
18
- IconX,
19
- } from "@tabler/icons-react";
12
+ import { IconCheck, IconPalette, IconUpload, IconX } from "@tabler/icons-react";
20
13
  import { useCallback, useEffect, useMemo, useState } from "react";
21
14
 
22
15
  import { Button } from "@/components/ui/button";
23
- import { Progress } from "@/components/ui/progress";
24
16
  import { Slider } from "@/components/ui/slider";
25
17
  import { Textarea } from "@/components/ui/textarea";
26
18
  import { cn } from "@/lib/utils";
@@ -60,15 +52,17 @@ export function QuestionFlow({
60
52
  setAnswers((prev) => ({ ...prev, [id]: value }));
61
53
  }, []);
62
54
 
63
- const answeredCount = guidedQuestions.filter((question) =>
64
- hasGuidedAnswer(answers[question.id]),
65
- ).length;
55
+ const isAnswered = (q: GuidedQuestion) => {
56
+ const v = answers[q.id];
57
+ if (q.type === "freeform" && typeof v === "string")
58
+ return v.trim().length > 0;
59
+ return hasGuidedAnswer(v);
60
+ };
61
+ const answeredCount = guidedQuestions.filter(isAnswered).length;
66
62
  const requiredQuestions = guidedQuestions.filter(
67
63
  (question) => question.required,
68
64
  );
69
- const requiredAnswered = requiredQuestions.filter((question) =>
70
- hasGuidedAnswer(answers[question.id]),
71
- ).length;
65
+ const requiredAnswered = requiredQuestions.filter(isAnswered).length;
72
66
  const allRequiredAnswered = requiredAnswered === requiredQuestions.length;
73
67
  const progress =
74
68
  guidedQuestions.length === 0
@@ -76,188 +70,77 @@ export function QuestionFlow({
76
70
  : Math.round((answeredCount / guidedQuestions.length) * 100);
77
71
 
78
72
  return (
79
- <div className="flex h-full w-full items-center justify-center bg-background px-4 py-5 text-foreground sm:px-8 sm:py-8">
80
- <div className="grid h-full max-h-[820px] w-full max-w-6xl overflow-hidden rounded-lg border border-border bg-card shadow-2xl lg:grid-cols-[280px_minmax(0,1fr)]">
81
- <aside className="flex min-h-0 flex-col border-b border-border bg-muted/25 p-4 lg:border-b-0 lg:border-e lg:p-5">
82
- <div className="flex items-start gap-3">
83
- <div className="flex size-9 shrink-0 items-center justify-center rounded-md border border-border bg-background text-primary shadow-sm">
84
- <IconSparkles className="size-5" />
85
- </div>
86
- <div className="min-w-0">
87
- <h2 className="text-lg font-semibold tracking-normal text-foreground">
88
- {title ?? t("questionFlow.defaultTitle")}
89
- </h2>
90
- <p className="mt-1 text-sm leading-5 text-muted-foreground">
91
- {description ?? t("questionFlow.defaultDescription")}
92
- </p>
93
- </div>
94
- </div>
95
-
96
- <div className="mt-5">
97
- <div className="mb-2 flex items-center justify-between text-xs text-muted-foreground">
98
- <span>
99
- {t("questionFlow.answeredCount", {
100
- answered: answeredCount,
101
- total: guidedQuestions.length,
102
- })}
103
- </span>
104
- {requiredQuestions.length > 0 && (
105
- <span>
106
- {t("questionFlow.requiredCount", {
107
- answered: requiredAnswered,
108
- total: requiredQuestions.length,
109
- })}
110
- </span>
111
- )}
112
- </div>
113
- <Progress value={progress} className="h-1.5 bg-muted" />
114
- </div>
115
-
116
- <ol className="mt-5 hidden min-h-0 flex-1 overflow-y-auto pe-1 lg:block">
117
- {guidedQuestions.map((question, index) => {
118
- const answered = hasGuidedAnswer(answers[question.id]);
119
- return (
120
- <li
121
- key={question.id}
122
- className={cn(
123
- "mb-2 flex items-start gap-2 rounded-md border px-2.5 py-2 text-xs",
124
- answered
125
- ? "border-primary/25 bg-primary/5 text-foreground"
126
- : "border-transparent bg-background/45 text-muted-foreground",
127
- )}
128
- >
129
- <span
130
- className={cn(
131
- "mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border text-[10px]",
132
- answered
133
- ? "border-primary bg-primary text-primary-foreground"
134
- : "border-border bg-muted text-muted-foreground",
135
- )}
136
- >
137
- {answered ? <IconCheck className="size-3" /> : index + 1}
138
- </span>
139
- <span className="line-clamp-2">
140
- {question.header ?? question.question}
141
- </span>
142
- </li>
143
- );
144
- })}
145
- </ol>
146
-
147
- <div className="mt-4 hidden rounded-md border border-border bg-background/60 p-3 text-xs leading-5 text-muted-foreground lg:block">
148
- {t("questionFlow.multiSelectHelp")}
149
- </div>
150
- </aside>
151
-
152
- <main className="flex min-h-0 flex-col">
153
- <div className="min-h-0 flex-1 overflow-y-auto px-4 py-4 sm:px-6 sm:py-6">
154
- <div className="grid gap-3 xl:grid-cols-2">
155
- {guidedQuestions.map((question, index) => (
156
- <QuestionCard
157
- key={question.id}
158
- index={index}
159
- question={question}
160
- value={answers[question.id]}
161
- onChange={(value) => setAnswer(question.id, value)}
162
- />
163
- ))}
164
- </div>
165
- </div>
73
+ <div className="flex h-full w-full justify-center overflow-y-auto bg-transparent px-6 py-10 text-foreground sm:px-10 lg:px-14">
74
+ <main className="w-full max-w-4xl pb-10">
75
+ <div className="mb-9">
76
+ <h2 className="text-3xl font-semibold tracking-normal text-foreground sm:text-4xl">
77
+ {title ?? t("questionFlow.defaultTitle")}
78
+ </h2>
79
+ {description ? (
80
+ <p className="mt-3 max-w-2xl text-sm leading-6 text-muted-foreground">
81
+ {description}
82
+ </p>
83
+ ) : null}
84
+ </div>
166
85
 
167
- <div className="flex shrink-0 flex-col gap-3 border-t border-border bg-background/80 px-4 py-3 sm:flex-row sm:items-center sm:justify-between sm:px-6">
168
- <div className="text-xs text-muted-foreground">
169
- {allRequiredAnswered
170
- ? t("questionFlow.ready")
171
- : t("questionFlow.answerRequired")}
172
- </div>
173
- <div className="flex items-center justify-end gap-2">
174
- <Button
175
- type="button"
176
- variant="ghost"
177
- size="sm"
178
- onClick={onSkip}
179
- className="cursor-pointer"
180
- >
181
- {skipLabel ?? t("questionFlow.skip")}
182
- </Button>
183
- <Button
184
- type="button"
185
- size="sm"
186
- onClick={() => onSubmit(normalizeGuidedAnswers(answers))}
187
- disabled={!allRequiredAnswered}
188
- className="cursor-pointer"
189
- >
190
- {submitLabel ?? t("questionFlow.continue")}
191
- <IconChevronRight className="size-4 rtl:-scale-x-100" />
192
- </Button>
193
- </div>
194
- </div>
195
- </main>
196
- </div>
86
+ <div className="space-y-10">
87
+ {guidedQuestions.map((question) => (
88
+ <QuestionCard
89
+ key={question.id}
90
+ question={question}
91
+ value={answers[question.id]}
92
+ onChange={(value) => setAnswer(question.id, value)}
93
+ />
94
+ ))}
95
+ </div>
96
+
97
+ <div className="mt-10 flex flex-wrap items-center gap-3">
98
+ <Button
99
+ type="button"
100
+ size="sm"
101
+ onClick={() => onSubmit(normalizeGuidedAnswers(answers))}
102
+ disabled={!allRequiredAnswered}
103
+ className="cursor-pointer"
104
+ >
105
+ {submitLabel ?? t("questionFlow.continue")}
106
+ </Button>
107
+ <Button
108
+ type="button"
109
+ variant="ghost"
110
+ size="sm"
111
+ onClick={onSkip}
112
+ className="cursor-pointer"
113
+ >
114
+ {skipLabel ?? t("questionFlow.skip")}
115
+ </Button>
116
+ </div>
117
+ </main>
197
118
  </div>
198
119
  );
199
120
  }
200
121
 
201
122
  function QuestionCard({
202
- index,
203
123
  question,
204
124
  value,
205
125
  onChange,
206
126
  }: {
207
- index: number;
208
127
  question: GuidedQuestion;
209
128
  value: unknown;
210
129
  onChange: (value: unknown) => void;
211
130
  }) {
212
131
  const t = useT();
213
- const answered = hasGuidedAnswer(value);
214
- const guidance = question.multiSelect
215
- ? t("questionFlow.chooseAny")
216
- : t("questionFlow.chooseOne");
217
132
 
218
133
  return (
219
- <section
220
- className={cn(
221
- "min-w-0 rounded-lg border bg-background p-4 shadow-sm transition-colors",
222
- answered ? "border-primary/35" : "border-border",
223
- )}
224
- >
225
- <div className="mb-3 flex items-start gap-3">
226
- <div
227
- className={cn(
228
- "flex size-7 shrink-0 items-center justify-center rounded-md border text-xs font-medium",
229
- answered
230
- ? "border-primary bg-primary text-primary-foreground"
231
- : "border-border bg-muted text-muted-foreground",
232
- )}
233
- >
234
- {answered ? <IconCheck className="size-4" /> : index + 1}
235
- </div>
236
- <div className="min-w-0 flex-1">
237
- <div className="mb-1 flex flex-wrap items-center gap-1.5">
238
- {question.header && (
239
- <p className="text-[11px] font-medium uppercase text-muted-foreground">
240
- {question.header}
241
- </p>
242
- )}
243
- <span className="rounded-full border border-border bg-muted/40 px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
244
- {guidance}
245
- </span>
246
- {question.required && (
247
- <span className="rounded-full border border-destructive/25 bg-destructive/10 px-2 py-0.5 text-[10px] font-medium text-destructive">
248
- {t("questionFlow.required")}
249
- </span>
250
- )}
251
- </div>
252
- <h3 className="text-sm font-semibold leading-5 text-foreground">
253
- {question.question}
254
- </h3>
255
- {question.description && (
256
- <p className="mt-1 text-xs leading-5 text-muted-foreground">
257
- {question.description}
258
- </p>
259
- )}
260
- </div>
134
+ <section className="min-w-0">
135
+ <div className="mb-3">
136
+ <h3 className="text-lg font-semibold leading-6 text-foreground">
137
+ {question.question}
138
+ </h3>
139
+ {question.description && (
140
+ <p className="mt-1 max-w-2xl text-sm leading-5 text-muted-foreground">
141
+ {question.description}
142
+ </p>
143
+ )}
261
144
  </div>
262
145
 
263
146
  {question.type === "text-options" && (
@@ -279,7 +162,7 @@ function QuestionCard({
279
162
  placeholder={
280
163
  question.placeholder ?? t("questionFlow.textPlaceholder")
281
164
  }
282
- className="min-h-[92px] resize-none bg-muted/35 text-sm"
165
+ className="min-h-[92px] resize-none bg-transparent text-sm shadow-none"
283
166
  />
284
167
  )}
285
168
  </section>
@@ -314,7 +197,7 @@ function TextOptions({
314
197
  const compact = options.every(
315
198
  (option) =>
316
199
  // i18n-ignore scanner false positive
317
- !option.description && !option.preview && option.label.length <= 24, // i18n-ignore scanner false positive
200
+ !option.preview && option.label.length <= 32, // i18n-ignore scanner false positive
318
201
  );
319
202
 
320
203
  const isSelected = (optionValue: string) =>
@@ -358,7 +241,7 @@ function TextOptions({
358
241
  return (
359
242
  <div className="space-y-3">
360
243
  {multiSelect && (
361
- <p className="text-[11px] leading-4 text-muted-foreground">
244
+ <p className="sr-only">
362
245
  {selectedCount > 0
363
246
  ? t("questionFlow.selectedCount", { count: selectedCount })
364
247
  : t("questionFlow.selectUseful")}
@@ -366,8 +249,8 @@ function TextOptions({
366
249
  )}
367
250
  <div
368
251
  className={cn(
369
- "grid gap-2",
370
- compact ? "grid-cols-2 sm:grid-cols-3" : "grid-cols-1 sm:grid-cols-2",
252
+ "flex flex-wrap gap-2",
253
+ compact ? "max-w-3xl" : "max-w-4xl",
371
254
  )}
372
255
  >
373
256
  {options.map((option) => (
@@ -404,7 +287,7 @@ function TextOptions({
404
287
  placeholder={
405
288
  question.placeholder ?? t("questionFlow.customPlaceholder")
406
289
  }
407
- className="min-h-[72px] resize-none bg-muted/35 text-sm"
290
+ className="min-h-[72px] max-w-xl resize-none bg-transparent text-sm shadow-none"
408
291
  />
409
292
  )}
410
293
  </div>
@@ -431,20 +314,20 @@ function OptionButton({
431
314
  onClick={onClick}
432
315
  aria-pressed={selected}
433
316
  className={cn(
434
- "group flex min-w-0 cursor-pointer items-start gap-2 rounded-md border text-start transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
435
- compact ? "min-h-10 px-2.5 py-2" : "min-h-[68px] px-3 py-2.5",
317
+ "group inline-flex min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-full border text-start transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
318
+ compact ? "px-3 py-2" : "px-4 py-2.5",
436
319
  selected
437
- ? "border-primary bg-primary/10 text-foreground ring-1 ring-primary/25"
438
- : "border-border bg-muted/25 text-muted-foreground hover:border-muted-foreground/45 hover:bg-muted/45 hover:text-foreground",
320
+ ? "border-foreground bg-foreground text-background"
321
+ : "border-border bg-background/35 text-foreground hover:border-muted-foreground hover:bg-background/70",
439
322
  )}
440
323
  >
441
324
  <span
442
325
  className={cn(
443
- "mt-0.5 flex size-4 shrink-0 items-center justify-center border",
326
+ "flex size-4 shrink-0 items-center justify-center border",
444
327
  multiSelect ? "rounded-sm" : "rounded-full",
445
328
  selected
446
- ? "border-primary bg-primary text-primary-foreground"
447
- : "border-border bg-background",
329
+ ? "border-background bg-background text-foreground"
330
+ : "border-muted-foreground/40 bg-transparent",
448
331
  )}
449
332
  aria-hidden
450
333
  >
@@ -452,17 +335,15 @@ function OptionButton({
452
335
  </span>
453
336
  <span className="min-w-0 flex-1">
454
337
  <span className="flex min-w-0 flex-wrap items-center gap-1.5 text-sm font-medium leading-5">
455
- <span className="truncate">{option.label}</span>
338
+ <span className="min-w-0 truncate">{option.label}</span>
456
339
  {option.recommended && (
457
- <span className="rounded-full bg-primary/15 px-1.5 py-0.5 text-[10px] font-medium uppercase text-primary">
340
+ <span className="rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase text-muted-foreground">
458
341
  {t("questionFlow.recommended")}
459
342
  </span>
460
343
  )}
461
344
  </span>
462
345
  {option.description && (
463
- <span className="mt-0.5 block text-xs leading-4 text-muted-foreground">
464
- {option.description}
465
- </span>
346
+ <span className="sr-only">{option.description}</span>
466
347
  )}
467
348
  {option.preview && (
468
349
  <span className="mt-2 block max-h-36 overflow-auto whitespace-pre-wrap rounded-md border border-border/60 bg-background/70 px-2 py-1.5 font-mono text-[11px] leading-4 text-muted-foreground">
@@ -502,7 +383,7 @@ function ColorOptions({
502
383
  };
503
384
 
504
385
  return (
505
- <div className="grid grid-cols-3 gap-2 sm:grid-cols-4">
386
+ <div className="flex max-w-4xl flex-wrap gap-2">
506
387
  {options.map((option) => {
507
388
  const selected = isSelected(option.value);
508
389
  return (
@@ -512,26 +393,24 @@ function ColorOptions({
512
393
  onClick={() => toggleOption(option.value)}
513
394
  aria-pressed={selected}
514
395
  className={cn(
515
- "group flex min-w-0 cursor-pointer items-center gap-2 rounded-md border px-2.5 py-2 text-start transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
396
+ "group inline-flex min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-full border px-3 py-2 text-start transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
516
397
  selected
517
- ? "border-primary bg-primary/10"
518
- : "border-border bg-muted/25 hover:border-muted-foreground/45 hover:bg-muted/45",
398
+ ? "border-foreground bg-foreground text-background"
399
+ : "border-border bg-background/35 text-foreground hover:border-muted-foreground hover:bg-background/70",
519
400
  )}
520
401
  >
521
402
  <span
522
403
  className={cn(
523
- "size-7 shrink-0 rounded-full border border-border",
404
+ "size-6 shrink-0 rounded-full border border-border",
524
405
  selected &&
525
- "ring-2 ring-primary ring-offset-2 ring-offset-background",
406
+ "ring-2 ring-background/70 ring-offset-1 ring-offset-foreground",
526
407
  )}
527
408
  style={{ backgroundColor: option.color || option.value }}
528
409
  />
529
- <span className="min-w-0 flex-1 truncate text-xs font-medium text-foreground">
410
+ <span className="min-w-0 flex-1 truncate text-sm font-medium">
530
411
  {option.label}
531
412
  </span>
532
- {selected && (
533
- <IconPalette className="size-3.5 shrink-0 text-primary" />
534
- )}
413
+ {selected && <IconPalette className="size-3.5 shrink-0" />}
535
414
  </button>
536
415
  );
537
416
  })}
@@ -554,17 +433,15 @@ function SliderQuestion({
554
433
  const current =
555
434
  typeof value === "number" ? value : Math.round((min + max) / 2);
556
435
 
557
- useEffect(() => {
558
- if (typeof value !== "number") {
559
- onChange(Math.round((min + max) / 2));
560
- }
561
- }, []);
436
+ // Do not auto-fill on mount: a required slider must be explicitly moved by
437
+ // the user before it counts as answered. `current` already provides a
438
+ // display-only midpoint fallback for the rendered slider position.
562
439
 
563
440
  return (
564
- <div className="rounded-md border border-border bg-muted/25 px-3 py-3">
441
+ <div className="max-w-xl px-1 py-2">
565
442
  <div className="mb-3 flex items-center justify-between text-xs text-muted-foreground">
566
443
  <span>{min}</span>
567
- <span className="rounded-full bg-background px-2 py-0.5 font-medium tabular-nums text-foreground">
444
+ <span className="font-medium tabular-nums text-foreground">
568
445
  {current}
569
446
  </span>
570
447
  <span>{max}</span>
@@ -609,10 +486,10 @@ function FileDropZone({
609
486
  addFiles(Array.from(event.dataTransfer.files));
610
487
  }}
611
488
  className={cn(
612
- "flex cursor-pointer flex-col items-center justify-center rounded-md border-2 border-dashed p-5 transition-colors",
489
+ "flex max-w-xl cursor-pointer flex-col items-center justify-center rounded-md border border-dashed p-5 transition-colors",
613
490
  dragOver
614
491
  ? "border-primary bg-primary/5"
615
- : "border-border bg-muted/25 hover:border-muted-foreground/50",
492
+ : "border-border bg-transparent hover:border-muted-foreground/50",
616
493
  )}
617
494
  >
618
495
  <IconUpload className="mb-2 size-5 text-muted-foreground" />
@@ -66,7 +66,7 @@ export function TweaksPanelContent({
66
66
  type="button"
67
67
  variant="outline"
68
68
  size="sm"
69
- className="h-6 cursor-pointer px-2.5 text-[11px]"
69
+ className="h-6 cursor-pointer border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-2.5 text-[11px] text-foreground shadow-none hover:bg-[var(--design-editor-panel-raised-bg)] hover:text-foreground focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)] focus-visible:ring-offset-0"
70
70
  onClick={(e) => onRequestTweaks(e.currentTarget)}
71
71
  >
72
72
  <IconPlus className="size-3" />
@@ -285,19 +285,33 @@ function TweakControl({
285
285
 
286
286
  {tweak.type === "slider" && (
287
287
  <div className="flex h-6 items-center gap-1.5">
288
- <Slider
289
- min={tweak.min ?? 0}
290
- max={tweak.max ?? 100}
291
- step={tweak.step ?? 1}
292
- value={[typeof value === "number" ? value : 50]}
293
- onValueChange={([v]) => onChange(v)}
294
- className="flex-1"
295
- />
296
- <span className="min-w-[2ch] text-right text-[11px] tabular-nums text-muted-foreground">
297
- {typeof value === "number" ? value : 50}
298
- {tweak.unit ??
299
- (tweak.cssVar?.toLowerCase().includes("radius") ? "px" : "")}
300
- </span>
288
+ {(() => {
289
+ const sliderMin = tweak.min ?? 0;
290
+ const sliderMax = tweak.max ?? 100;
291
+ const rawNum = typeof value === "number" ? value : Number(value);
292
+ const sliderValue = Number.isFinite(rawNum)
293
+ ? Math.min(sliderMax, Math.max(sliderMin, rawNum))
294
+ : sliderMin;
295
+ return (
296
+ <>
297
+ <Slider
298
+ min={sliderMin}
299
+ max={sliderMax}
300
+ step={tweak.step ?? 1}
301
+ value={[sliderValue]}
302
+ onValueChange={([v]) => onChange(v)}
303
+ className="flex-1"
304
+ />
305
+ <span className="min-w-[2ch] text-right text-[11px] tabular-nums text-muted-foreground">
306
+ {sliderValue}
307
+ {tweak.unit ??
308
+ (tweak.cssVar?.toLowerCase().includes("radius")
309
+ ? "px"
310
+ : "")}
311
+ </span>
312
+ </>
313
+ );
314
+ })()}
301
315
  </div>
302
316
  )}
303
317
  </div>
@@ -4,7 +4,6 @@ export { DrawOverlay } from "./DrawOverlay";
4
4
  export { EditPanel } from "./EditPanel";
5
5
  export { QuestionFlow } from "./QuestionFlow";
6
6
  export { TweaksPanel } from "./TweaksPanel";
7
- export { VariantGrid } from "./VariantGrid";
8
7
  export type {
9
8
  DrawAnnotation,
10
9
  ElementInfo,