@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.
- package/README.md +2 -2
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +28 -0
- package/corpus/core/README.md +2 -2
- package/corpus/core/docs/content/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/de-DE/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/hi-IN/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/template-chat.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/faq.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/template-chat.mdx +1 -1
- package/corpus/core/docs/content/template-chat.mdx +1 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/engine/builtin.ts +1 -1
- package/corpus/core/src/agent/engine/output-tokens.ts +1 -1
- package/corpus/core/src/agent/harness/acp-adapter.ts +28 -4
- package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +3 -0
- package/corpus/core/src/agent/harness/translate.ts +3 -0
- package/corpus/core/src/agent/harness/types.ts +1 -0
- package/corpus/core/src/agent/model-config.ts +34 -13
- package/corpus/core/src/agent/production-agent.ts +87 -10
- package/corpus/core/src/agent/thread-data-builder.ts +29 -4
- package/corpus/core/src/agent/tool-call-journal.ts +109 -48
- package/corpus/core/src/agent/types.ts +6 -1
- package/corpus/core/src/cli/design-connect.ts +106 -0
- package/corpus/core/src/cli/gateway-helpers.ts +17 -0
- package/corpus/core/src/cli/recap.ts +0 -2
- package/corpus/core/src/cli/skills.ts +54 -16
- package/corpus/core/src/cli/workspace-dev.ts +29 -5
- package/corpus/core/src/client/AssistantChat.tsx +89 -42
- package/corpus/core/src/client/DefaultSpinner.tsx +8 -1
- package/corpus/core/src/client/chat/message-components.tsx +49 -1
- package/corpus/core/src/client/chat/repo-helpers.ts +71 -0
- package/corpus/core/src/client/chat/run-recovery.tsx +15 -5
- package/corpus/core/src/client/components/ApiKeySettings.tsx +8 -8
- package/corpus/core/src/client/components/CodeRequiredDialog.tsx +26 -15
- package/corpus/core/src/client/components/MissingKeyCard.tsx +13 -6
- package/corpus/core/src/client/composer/TiptapComposer.tsx +4 -3
- package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +0 -1
- package/corpus/core/src/client/guided-questions.tsx +21 -27
- package/corpus/core/src/client/integrations/IntegrationCard.tsx +1 -1
- package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +1 -1
- package/corpus/core/src/client/onboarding/OnboardingBanner.tsx +2 -2
- package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +23 -19
- package/corpus/core/src/client/resources/ResourceEditor.tsx +18 -10
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
- package/corpus/core/src/client/settings/SettingsPanel.tsx +8 -3
- package/corpus/core/src/client/settings/useBuilderStatus.ts +8 -41
- package/corpus/core/src/client/useProductionAgent.ts +6 -2
- package/corpus/core/src/deploy/build.ts +1 -1
- package/corpus/core/src/observability/traces.ts +3 -3
- package/corpus/core/src/onboarding/default-steps.ts +1 -1
- package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
- package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +177 -81
- package/corpus/core/src/server/core-routes-plugin.ts +7 -1
- package/corpus/core/src/server/open-route.ts +59 -40
- package/corpus/core/src/shared/reasoning-effort.ts +2 -0
- package/corpus/core/src/sharing/access.ts +22 -2
- package/corpus/core/src/sharing/registry.ts +18 -0
- package/corpus/core/src/styles/agent-native.css +104 -20
- package/corpus/core/src/styles/rich-markdown-editor.css +11 -10
- package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +10 -10
- package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +10 -10
- package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +6 -5
- package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +9 -9
- package/corpus/templates/analytics/app/global.css +4 -0
- package/corpus/templates/analytics/app/lib/chart-theme.ts +13 -0
- package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +22 -24
- package/corpus/templates/analytics/changelog/2026-06-30-dashboard-charts-now-use-theme-aware-tooltip-and-grid-colors.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-fixed-ask-composer-spacing-so-the-chat-field-has-a-comfortab.md +6 -0
- package/corpus/templates/calendar/AGENTS.md +4 -0
- package/corpus/templates/calendar/actions/connect-google-calendar.ts +80 -0
- package/corpus/templates/calendar/changelog/2026-06-30-calendar-now-gives-the-agent-a-safe-google-connection-link-i.md +6 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +5 -5
- package/corpus/templates/content/app/global.css +6 -5
- package/corpus/templates/content/changelog/2026-06-30-editor-floating-toolbars-now-use-theme-aware-colors-in-light.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +6 -1
- package/corpus/templates/design/actions/add-localhost-screens.ts +63 -8
- package/corpus/templates/design/actions/apply-motion-edit.ts +12 -46
- package/corpus/templates/design/actions/list-design-native-assets.ts +2 -1
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +49 -1
- package/corpus/templates/design/actions/navigate.ts +3 -12
- package/corpus/templates/design/actions/open-visual-edit.ts +341 -0
- package/corpus/templates/design/actions/view-screen.ts +1 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -14
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +71 -91
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +25 -27
- package/corpus/templates/design/app/components/design/DeviceFrame.tsx +1 -1
- package/corpus/templates/design/app/components/design/DrawOverlay.tsx +2 -2
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1111 -570
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +162 -32
- package/corpus/templates/design/app/components/design/MotionDock.tsx +268 -240
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1038 -150
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -1
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +81 -102
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +6 -6
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +11 -11
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -7
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1129 -155
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +130 -37
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +24 -11
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +184 -162
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +137 -79
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +13 -13
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +8 -8
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +4 -4
- package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +3 -3
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -7
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +14 -11
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +4 -4
- package/corpus/templates/design/app/components/design/inspector/index.ts +2 -0
- package/corpus/templates/design/app/components/design/types.ts +19 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +61 -78
- package/corpus/templates/design/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/design/app/components/layout/Layout.tsx +3 -2
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +5 -4
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +2 -2
- package/corpus/templates/design/app/global.css +56 -0
- package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -5
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -7
- package/corpus/templates/design/app/hooks/use-question-flow.ts +3 -2
- package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +6 -4
- package/corpus/templates/design/app/i18n/zh-TW.ts +5 -14
- package/corpus/templates/design/app/i18n-data.ts +63 -188
- package/corpus/templates/design/app/lib/agent-chat.ts +13 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +1428 -384
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +9 -5
- package/corpus/templates/design/app/pages/DesignSystems.tsx +2 -2
- package/corpus/templates/design/app/pages/Index.tsx +49 -26
- package/corpus/templates/design/app/pages/NotFound.tsx +25 -8
- package/corpus/templates/design/app/pages/VisualEdit.tsx +17 -5
- package/corpus/templates/design/app/routes/examples.tsx +1 -7
- package/corpus/templates/design/app/routes/templates.tsx +7 -4
- package/corpus/templates/design/changelog/2026-06-30-board-shapes-and-auto-layout-controls-are-clearer.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-component-selections-now-use-purple-component-chrome-and-sho.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-constraints-now-stay-tucked-into-a-compact-inspector-preview.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-creating-a-component-now-opens-in-a-compact-inspector-popove.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-cards-no-longer-show-legacy-project-type-badges.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-chat-now-keeps-new-turns-in-the-visible-design-agent-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-editor-panels-now-keep-their-compact-text-sizing-cons.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-no-longer-shows-the-connected-local-code-warning-bann.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-now-opens-to-the-files-panel-unless-a-generation-is-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-opens-with-a-cleaner-empty-canvas-and-loading-preview.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-tools-use-simpler-less-decorative-icons.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-dragging-absolute-elements-no-longer-shows-coordinate-labels.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-all-screens-opening-too-zoomed-in-by-default.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-the-public-design-assets-sidebar-so-native-components-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-the-screen-overview-board-so-empty-board-space-no-long.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-full-view-screens-can-now-scroll-while-remaining-editable.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-inspector-element-headers-show-the-selected-html-tag-and-the.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-inspector-inputs-stay-compact-across-desktop-breakpoints.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-layers-can-be-multi-selected-from-the-canvas-and-edited-toge.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-local-visual-edit-links-can-edit-localhost-frames-without-si.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-localhost-visual-edit-frames-can-now-be-selected-and-edited.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-marquee-selection-now-works-inside-screens-multi-selected-la.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-motion-is-now-available-from-the-persistent-left-rail-and-th.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-motion-timeline-collapse-and-reopen-animations-feel-smoother.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-new-board-shapes-now-start-with-neutral-gray-styling.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-new-designs-open-into-a-steadier-loading-state-before-the-ed.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-new-designs-show-a-loading-state-during-handoff-and-keep-edi.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-public-visual-edit-design-links-now-open-directly-instead-of.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-removed-the-confusing-states-section-from-the-design-editor-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-removed-the-templates-gallery-from-design-navigation.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-share-stays-visible-as-soon-as-editable-designs-load.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-signed-out-save-and-share-controls-use-simpler-labels-and-op.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-text-added-on-the-canvas-now-focuses-cleanly-with-the-right-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-is-simpler-and-its-bottom.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-now-follows-the-current-t.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-child-layout-controls-o.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-the-ask-ai-section-abov.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-review-panel-no-longer-shows-a-separate-inline-au.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-empty-designs-page-now-focuses-on-a-single-primary-new-d.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-layers-panel-header-stays-as-layers-while-multiple-items.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-missing-design-screen-now-uses-a-neutral-back-button.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-now-closes-without-squeezing-the-canvas-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-new-design-connect-ai-setup-now-lines-up-with-the-compos.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-screen-overview-board-now-blends-into-the-canvas-and-new.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-drops-now-show-screen-guides.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-keep-a-transparent-backdrop-and-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-select-reliably-from-all-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-visual-edit-can-open-and-refresh-localhost-screens-in-one-au.md +6 -0
- package/corpus/templates/design/e2e/helpers.ts +15 -4
- package/corpus/templates/design/server/db/index.ts +52 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/design/server/plugins/auth.ts +1 -0
- package/corpus/templates/design/server/plugins/core-routes.ts +4 -0
- package/corpus/templates/design/shared/board-file.ts +380 -5
- package/corpus/templates/design/shared/board-objects.ts +2 -2
- package/corpus/templates/design/shared/code-layer.ts +50 -6
- package/corpus/templates/design/shared/motion-compiler.ts +27 -0
- package/corpus/templates/macros/app/components/DailyProgress.tsx +41 -37
- package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
- package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
- package/corpus/templates/macros/app/components/VoiceDictation.tsx +1 -1
- package/corpus/templates/macros/app/components/WeeklyCaloriesChart.tsx +1 -1
- package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
- package/corpus/templates/macros/app/components/WeightTracker.tsx +1 -1
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/macros/app/routes/_index.tsx +5 -5
- package/corpus/templates/macros/app/routes/analytics.tsx +1 -1
- package/corpus/templates/macros/changelog/2026-06-30-dashboard-loading-and-chart-surfaces-now-use-theme-aware-col.md +6 -0
- package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +14 -11
- package/corpus/templates/mail/app/global.css +3 -2
- package/corpus/templates/mail/changelog/2026-06-30-compose-floating-toolbars-now-use-theme-aware-colors-in-ligh.md +6 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +3 -3
- package/corpus/templates/slides/app/global.css +10 -0
- package/corpus/templates/slides/app/pages/Index.tsx +55 -51
- package/corpus/templates/slides/changelog/2026-06-30-deck-thumbnails-collapse-cleanly-to-one-column-when-the-chat.md +6 -0
- package/dist/agent/engine/anthropic-engine.d.ts +2 -2
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +2 -2
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builtin.js +1 -1
- package/dist/agent/engine/builtin.js.map +1 -1
- package/dist/agent/engine/output-tokens.js +1 -1
- package/dist/agent/engine/output-tokens.js.map +1 -1
- package/dist/agent/harness/acp-adapter.d.ts +4 -1
- package/dist/agent/harness/acp-adapter.d.ts.map +1 -1
- package/dist/agent/harness/acp-adapter.js +19 -2
- package/dist/agent/harness/acp-adapter.js.map +1 -1
- package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
- package/dist/agent/harness/ai-sdk-adapter.js +3 -0
- package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
- package/dist/agent/harness/translate.d.ts.map +1 -1
- package/dist/agent/harness/translate.js +3 -0
- package/dist/agent/harness/translate.js.map +1 -1
- package/dist/agent/harness/types.d.ts +1 -0
- package/dist/agent/harness/types.d.ts.map +1 -1
- package/dist/agent/harness/types.js.map +1 -1
- package/dist/agent/model-config.d.ts +21 -20
- package/dist/agent/model-config.d.ts.map +1 -1
- package/dist/agent/model-config.js +31 -13
- package/dist/agent/model-config.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +85 -10
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +27 -6
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/tool-call-journal.d.ts +11 -9
- package/dist/agent/tool-call-journal.d.ts.map +1 -1
- package/dist/agent/tool-call-journal.js +92 -40
- package/dist/agent/tool-call-journal.js.map +1 -1
- package/dist/agent/types.d.ts +5 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +84 -0
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/gateway-helpers.d.ts +4 -0
- package/dist/cli/gateway-helpers.d.ts.map +1 -1
- package/dist/cli/gateway-helpers.js +9 -0
- package/dist/cli/gateway-helpers.js.map +1 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +0 -2
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +54 -16
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +33 -6
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +72 -26
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/DefaultSpinner.d.ts.map +1 -1
- package/dist/client/DefaultSpinner.js +8 -1
- package/dist/client/DefaultSpinner.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +7 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +37 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/repo-helpers.d.ts +1 -0
- package/dist/client/chat/repo-helpers.d.ts.map +1 -1
- package/dist/client/chat/repo-helpers.js +59 -0
- package/dist/client/chat/repo-helpers.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +4 -4
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/components/ApiKeySettings.js +8 -8
- package/dist/client/components/ApiKeySettings.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +24 -15
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
- package/dist/client/components/MissingKeyCard.js +11 -6
- package/dist/client/components/MissingKeyCard.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +4 -3
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +6 -6
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +1 -1
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +1 -1
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/onboarding/OnboardingBanner.js +2 -2
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +23 -19
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +13 -10
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +2 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +8 -3
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +6 -38
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts +2 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/deploy/build.js +1 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js.map +1 -1
- package/dist/onboarding/default-steps.js +1 -1
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
- package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +3 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +134 -72
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +3 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +4 -1
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/open-route.d.ts +9 -0
- package/dist/server/open-route.d.ts.map +1 -1
- package/dist/server/open-route.js +48 -38
- package/dist/server/open-route.js.map +1 -1
- package/dist/shared/reasoning-effort.js +3 -0
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +18 -2
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/registry.d.ts +10 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/styles/agent-native.css +104 -20
- package/dist/styles/rich-markdown-editor.css +11 -10
- package/docs/content/cloneable-saas.mdx +2 -2
- package/docs/content/faq.mdx +1 -1
- package/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
- package/docs/content/locales/ar-SA/faq.mdx +1 -1
- package/docs/content/locales/ar-SA/template-chat.mdx +1 -1
- package/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
- package/docs/content/locales/de-DE/faq.mdx +1 -1
- package/docs/content/locales/de-DE/template-chat.mdx +1 -1
- package/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
- package/docs/content/locales/es-ES/faq.mdx +1 -1
- package/docs/content/locales/es-ES/template-chat.mdx +1 -1
- package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
- package/docs/content/locales/fr-FR/faq.mdx +1 -1
- package/docs/content/locales/fr-FR/template-chat.mdx +1 -1
- package/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
- package/docs/content/locales/hi-IN/faq.mdx +1 -1
- package/docs/content/locales/hi-IN/template-chat.mdx +1 -1
- package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
- package/docs/content/locales/ja-JP/faq.mdx +1 -1
- package/docs/content/locales/ja-JP/template-chat.mdx +1 -1
- package/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
- package/docs/content/locales/ko-KR/faq.mdx +1 -1
- package/docs/content/locales/ko-KR/template-chat.mdx +1 -1
- package/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
- package/docs/content/locales/pt-BR/faq.mdx +1 -1
- package/docs/content/locales/pt-BR/template-chat.mdx +1 -1
- package/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
- package/docs/content/locales/zh-CN/faq.mdx +1 -1
- package/docs/content/locales/zh-CN/template-chat.mdx +1 -1
- package/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
- package/docs/content/locales/zh-TW/faq.mdx +1 -1
- package/docs/content/locales/zh-TW/template-chat.mdx +1 -1
- package/docs/content/template-chat.mdx +1 -1
- package/package.json +1 -1
- package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +0 -157
- package/corpus/templates/design/app/lib/design-templates.ts +0 -1305
- 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
|
-
.
|
|
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
|
-
.
|
|
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 ??
|
|
337
|
-
const height = input.height ??
|
|
338
|
-
const
|
|
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<
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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:
|
|
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,
|
|
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,
|
|
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,
|
|
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 () => {
|