@agent-native/core 0.79.27 → 0.80.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +26 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
- package/corpus/core/docs/content/template-design.mdx +45 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/engine/index.ts +1 -0
- package/corpus/core/src/agent/engine/registry.ts +40 -0
- package/corpus/core/src/agent/production-agent.ts +6 -2
- package/corpus/core/src/cli/design-connect.ts +490 -0
- package/corpus/core/src/cli/index.ts +16 -0
- package/corpus/core/src/cli/skills.ts +126 -3
- package/corpus/core/src/client/AssistantChat.tsx +43 -7
- package/corpus/core/src/client/agent-chat.ts +27 -3
- package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
- package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
- package/corpus/core/src/client/chat/message-components.tsx +1 -1
- package/corpus/core/src/client/chat-model-groups.ts +1 -2
- package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
- package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
- package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
- package/corpus/core/src/client/frame-protocol.ts +17 -2
- package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
- package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
- package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
- package/corpus/core/src/server/transcribe-voice.ts +57 -22
- package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
- package/corpus/core/src/styles/agent-native.css +56 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/core/src/vite/client.ts +2 -0
- package/corpus/core/src/voice/index.ts +18 -0
- package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
- package/corpus/core/src/voice/voice-context.ts +217 -0
- package/corpus/core/src/voice/voice-replacements.ts +75 -0
- package/corpus/templates/analytics/AGENTS.md +4 -3
- package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
- package/corpus/templates/analytics/app/global.css +0 -4
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/analytics/app/i18n-data.ts +20 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
- package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
- package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
- package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/brain/app/i18n-data.ts +20 -0
- package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
- package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
- package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
- package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
- package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
- package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
- package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
- package/corpus/templates/design/AGENTS.md +95 -5
- package/corpus/templates/design/DESIGN.md +82 -0
- package/corpus/templates/design/DEVELOPING.md +43 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
- package/corpus/templates/design/actions/apply-shader.ts +277 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
- package/corpus/templates/design/actions/connect-localhost.ts +183 -0
- package/corpus/templates/design/actions/edit-design.ts +195 -42
- package/corpus/templates/design/actions/generate-design.ts +71 -1
- package/corpus/templates/design/actions/generate-screens.ts +193 -0
- package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
- package/corpus/templates/design/actions/get-shader.ts +119 -0
- package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
- package/corpus/templates/design/actions/navigate.ts +55 -2
- package/corpus/templates/design/actions/view-screen.ts +68 -1
- package/corpus/templates/design/agent-native.app-skill.json +10 -0
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
- package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
- package/corpus/templates/design/app/components/design/index.ts +0 -5
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
- package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
- package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
- package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
- package/corpus/templates/design/app/components/design/types.ts +23 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
- package/corpus/templates/design/app/global.css +121 -3
- package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
- package/corpus/templates/design/app/i18n-data.ts +2790 -1
- package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
- package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/server/db/schema.ts +26 -0
- package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
- package/corpus/templates/design/shared/api.ts +27 -0
- package/corpus/templates/design/shared/canvas-frames.ts +103 -0
- package/corpus/templates/design/shared/canvas-math.ts +1058 -0
- package/corpus/templates/design/shared/code-layer.ts +2212 -0
- package/corpus/templates/design/shared/color-utils.ts +180 -0
- package/corpus/templates/design/shared/generation-session.ts +61 -0
- package/corpus/templates/design/shared/shader-presets.ts +782 -0
- package/corpus/templates/design/shared/shader-safety.ts +137 -0
- package/corpus/templates/design/shared/source-mode.ts +237 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
- package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
- package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
- package/corpus/templates/plan/app/global.css +61 -78
- package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
- package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
- package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
- package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
- package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
- package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +9 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +37 -0
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +4 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts +52 -0
- package/dist/cli/design-connect.d.ts.map +1 -0
- package/dist/cli/design-connect.js +409 -0
- package/dist/cli/design-connect.js.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +121 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +17 -3
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.js +1 -1
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/wireframe.js +1 -1
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +1 -2
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
- package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
- package/dist/client/components/LiveCursorOverlay.js +19 -40
- package/dist/client/components/LiveCursorOverlay.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +86 -24
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +9 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +154 -32
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +17 -2
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +2 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -6
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts +5 -0
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +51 -25
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +8 -8
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +40 -24
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -0
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +20 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-native.css +56 -7
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/dist/voice/index.d.ts +5 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +4 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
- package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
- package/dist/voice/voice-cleanup-prompt.js +26 -0
- package/dist/voice/voice-cleanup-prompt.js.map +1 -0
- package/dist/voice/voice-context.d.ts +25 -0
- package/dist/voice/voice-context.d.ts.map +1 -0
- package/dist/voice/voice-context.js +156 -0
- package/dist/voice/voice-context.js.map +1 -0
- package/dist/voice/voice-replacements.d.ts +4 -0
- package/dist/voice/voice-replacements.d.ts.map +1 -0
- package/dist/voice/voice-replacements.js +52 -0
- package/dist/voice/voice-replacements.js.map +1 -0
- package/docs/content/locales/ar-SA/template-design.mdx +41 -0
- package/docs/content/locales/de-DE/template-design.mdx +51 -0
- package/docs/content/locales/es-ES/template-design.mdx +50 -0
- package/docs/content/locales/fr-FR/template-design.mdx +49 -0
- package/docs/content/locales/hi-IN/template-design.mdx +44 -0
- package/docs/content/locales/ja-JP/template-design.mdx +46 -0
- package/docs/content/locales/ko-KR/template-design.mdx +44 -0
- package/docs/content/locales/pt-BR/template-design.mdx +48 -0
- package/docs/content/locales/zh-CN/template-design.mdx +36 -0
- package/docs/content/locales/zh-TW/template-design.mdx +38 -0
- package/docs/content/template-design.mdx +45 -0
- package/package.json +2 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
- package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
- package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
- package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
|
@@ -13,53 +13,192 @@ import { and, eq } from "drizzle-orm";
|
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
15
|
import { getDb, schema } from "../server/db/index.js";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
applyOneEdit,
|
|
18
|
+
type ApplyEditsResult,
|
|
19
|
+
type DesignEdit,
|
|
20
|
+
} from "../shared/apply-edits.js";
|
|
21
|
+
|
|
22
|
+
const editBlocksSchema = z.preprocess(
|
|
23
|
+
(v) => {
|
|
24
|
+
if (typeof v !== "string") return v;
|
|
25
|
+
// Don't let malformed JSON throw an uncaught SyntaxError — return the
|
|
26
|
+
// raw value so Zod produces a clean validation error instead.
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(v);
|
|
29
|
+
} catch {
|
|
30
|
+
return v;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
z
|
|
34
|
+
.array(
|
|
35
|
+
z.object({
|
|
36
|
+
search: z
|
|
37
|
+
.string()
|
|
38
|
+
.min(1)
|
|
39
|
+
.describe(
|
|
40
|
+
"Exact text to find, with enough surrounding context to be unique",
|
|
41
|
+
),
|
|
42
|
+
replace: z.string().describe("Replacement text"),
|
|
43
|
+
}),
|
|
44
|
+
)
|
|
45
|
+
.min(1),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
function stripStableNodeIdAttributes(value: string): {
|
|
49
|
+
content: string;
|
|
50
|
+
indexMap: number[];
|
|
51
|
+
} {
|
|
52
|
+
const stableIdPattern =
|
|
53
|
+
/\sdata-agent-native-node-id\s*=\s*(?:"[^"]*"|'[^']*'|[^\s/>]+)/gi;
|
|
54
|
+
let content = "";
|
|
55
|
+
const indexMap: number[] = [];
|
|
56
|
+
let cursor = 0;
|
|
57
|
+
let match: RegExpExecArray | null;
|
|
58
|
+
while ((match = stableIdPattern.exec(value))) {
|
|
59
|
+
const chunk = value.slice(cursor, match.index);
|
|
60
|
+
for (let i = 0; i < chunk.length; i += 1) {
|
|
61
|
+
content += chunk[i];
|
|
62
|
+
indexMap.push(cursor + i);
|
|
63
|
+
}
|
|
64
|
+
cursor = match.index + match[0].length;
|
|
65
|
+
}
|
|
66
|
+
const tail = value.slice(cursor);
|
|
67
|
+
for (let i = 0; i < tail.length; i += 1) {
|
|
68
|
+
content += tail[i];
|
|
69
|
+
indexMap.push(cursor + i);
|
|
70
|
+
}
|
|
71
|
+
indexMap.push(value.length);
|
|
72
|
+
return { content, indexMap };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function findUniqueStableIdAgnosticSpan(
|
|
76
|
+
content: string,
|
|
77
|
+
search: string,
|
|
78
|
+
): { start: number; end: number } | null {
|
|
79
|
+
const strippedContent = stripStableNodeIdAttributes(content);
|
|
80
|
+
const strippedSearch = stripStableNodeIdAttributes(search).content;
|
|
81
|
+
if (!strippedSearch) return null;
|
|
82
|
+
|
|
83
|
+
let count = 0;
|
|
84
|
+
let onlyIndex = -1;
|
|
85
|
+
let index = strippedContent.content.indexOf(strippedSearch);
|
|
86
|
+
while (index !== -1) {
|
|
87
|
+
count += 1;
|
|
88
|
+
onlyIndex = index;
|
|
89
|
+
if (count > 1) return null;
|
|
90
|
+
index = strippedContent.content.indexOf(strippedSearch, index + 1);
|
|
91
|
+
}
|
|
92
|
+
if (count !== 1) return null;
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
start: strippedContent.indexMap[onlyIndex] ?? 0,
|
|
96
|
+
end:
|
|
97
|
+
strippedContent.indexMap[onlyIndex + strippedSearch.length] ??
|
|
98
|
+
content.length,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function applyOneEditWithStableIdFallback(
|
|
103
|
+
content: string,
|
|
104
|
+
edit: DesignEdit,
|
|
105
|
+
index: number,
|
|
106
|
+
): string {
|
|
107
|
+
try {
|
|
108
|
+
return applyOneEdit(content, edit, index);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const span = findUniqueStableIdAgnosticSpan(content, edit.search);
|
|
111
|
+
if (!span) throw error;
|
|
112
|
+
return `${content.slice(0, span.start)}${edit.replace}${content.slice(span.end)}`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function applySearchReplaceEdits(
|
|
117
|
+
content: string,
|
|
118
|
+
edits: DesignEdit[],
|
|
119
|
+
): ApplyEditsResult {
|
|
120
|
+
let next = content;
|
|
121
|
+
edits.forEach((edit, index) => {
|
|
122
|
+
next = applyOneEditWithStableIdFallback(next, edit, index);
|
|
123
|
+
});
|
|
124
|
+
return { content: next, applied: edits.length };
|
|
125
|
+
}
|
|
17
126
|
|
|
18
127
|
export default defineAction({
|
|
19
128
|
description:
|
|
20
|
-
"
|
|
129
|
+
"Edit ONE file in a design after reading it with get-design-snapshot. " +
|
|
130
|
+
"For small localized refinements, apply surgical search/replace edits — the " +
|
|
21
131
|
"preferred way to refine an existing design without regenerating the whole " +
|
|
22
132
|
"file (cheaper, faster, and it preserves everything you don't touch). Each " +
|
|
23
133
|
"edit's `search` must match the current file exactly and uniquely, so " +
|
|
24
134
|
"include enough surrounding context. Read the file first with " +
|
|
25
135
|
"`get-design-snapshot`. Wrapping an element is just a search/replace whose " +
|
|
26
|
-
"`replace` adds the wrapper around the original text.
|
|
136
|
+
"`replace` adds the wrapper around the original text. For broad copy-only " +
|
|
137
|
+
'changes such as translating all visible text, use `mode: "replace-file"` ' +
|
|
138
|
+
"with `replacementContent`: the complete updated file content copied from " +
|
|
139
|
+
"the snapshot with only the requested copy changed. Use `generate-design` " +
|
|
27
140
|
"instead only for brand-new files or large structural rewrites.",
|
|
28
|
-
schema: z
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
141
|
+
schema: z
|
|
142
|
+
.object({
|
|
143
|
+
designId: z.string().describe("Design project ID"),
|
|
144
|
+
filename: z
|
|
145
|
+
.string()
|
|
146
|
+
.default("index.html")
|
|
147
|
+
.describe("File to edit (e.g. 'index.html')"),
|
|
148
|
+
mode: z
|
|
149
|
+
.enum(["search-replace", "replace-file"])
|
|
150
|
+
.optional()
|
|
151
|
+
.describe(
|
|
152
|
+
"Defaults to search-replace. Use replace-file for broad copy-only edits like translating the whole page after reading get-design-snapshot.",
|
|
153
|
+
),
|
|
154
|
+
edits: editBlocksSchema
|
|
155
|
+
.optional()
|
|
156
|
+
.describe(
|
|
157
|
+
"Search/replace blocks, applied in order. Use for small localized edits.",
|
|
158
|
+
),
|
|
159
|
+
replacementContent: z
|
|
160
|
+
.string()
|
|
161
|
+
.min(1)
|
|
162
|
+
.optional()
|
|
163
|
+
.describe(
|
|
164
|
+
"Complete updated file content. Use only with mode=replace-file for broad copy-only changes; preserve all HTML structure, CSS, scripts, and tweaks from get-design-snapshot.",
|
|
165
|
+
),
|
|
166
|
+
})
|
|
167
|
+
.superRefine((value, ctx) => {
|
|
168
|
+
const mode =
|
|
169
|
+
value.mode ??
|
|
170
|
+
(value.replacementContent !== undefined
|
|
171
|
+
? "replace-file"
|
|
172
|
+
: "search-replace");
|
|
173
|
+
|
|
174
|
+
if (value.edits && value.replacementContent !== undefined) {
|
|
175
|
+
ctx.addIssue({
|
|
176
|
+
code: z.ZodIssueCode.custom,
|
|
177
|
+
message:
|
|
178
|
+
"Use either edits or replacementContent in one edit-design call, not both.",
|
|
179
|
+
path: ["replacementContent"],
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (mode === "search-replace" && !value.edits) {
|
|
184
|
+
ctx.addIssue({
|
|
185
|
+
code: z.ZodIssueCode.custom,
|
|
186
|
+
message:
|
|
187
|
+
"search-replace mode requires at least one edit block in edits.",
|
|
188
|
+
path: ["edits"],
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (mode === "replace-file" && value.replacementContent === undefined) {
|
|
193
|
+
ctx.addIssue({
|
|
194
|
+
code: z.ZodIssueCode.custom,
|
|
195
|
+
message:
|
|
196
|
+
"replace-file mode requires replacementContent with the complete updated file.",
|
|
197
|
+
path: ["replacementContent"],
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}),
|
|
201
|
+
run: async ({ designId, filename, edits, mode, replacementContent }) => {
|
|
63
202
|
await assertAccess("design", designId, "editor");
|
|
64
203
|
|
|
65
204
|
const db = getDb();
|
|
@@ -104,21 +243,34 @@ export default defineAction({
|
|
|
104
243
|
// Collab read is best-effort; fall back to stored content.
|
|
105
244
|
}
|
|
106
245
|
|
|
107
|
-
const
|
|
246
|
+
const resolvedMode =
|
|
247
|
+
mode ??
|
|
248
|
+
(replacementContent !== undefined ? "replace-file" : "search-replace");
|
|
249
|
+
const { content: nextContent, applied } =
|
|
250
|
+
resolvedMode === "replace-file"
|
|
251
|
+
? { content: replacementContent ?? "", applied: 0 }
|
|
252
|
+
: applySearchReplaceEdits(base, edits ?? []);
|
|
108
253
|
const changed = nextContent !== base;
|
|
109
254
|
|
|
110
255
|
if (changed) {
|
|
111
256
|
// Mark agent presence + selection so live viewers can see where the
|
|
112
257
|
// agent is working before the update arrives via collab.
|
|
113
258
|
agentEnterDocument(file.id);
|
|
114
|
-
if (applied > 0) {
|
|
259
|
+
if (resolvedMode === "search-replace" && applied > 0) {
|
|
260
|
+
const firstSearch = edits?.[0]?.search;
|
|
115
261
|
agentUpdateSelection(file.id, {
|
|
116
|
-
selection:
|
|
117
|
-
? `[data-edit-target="${
|
|
262
|
+
selection: firstSearch
|
|
263
|
+
? `[data-edit-target="${firstSearch.slice(0, 40)}"]`
|
|
118
264
|
: null,
|
|
119
265
|
editingFile: filename,
|
|
120
266
|
designId,
|
|
121
267
|
});
|
|
268
|
+
} else {
|
|
269
|
+
agentUpdateSelection(file.id, {
|
|
270
|
+
selection: null,
|
|
271
|
+
editingFile: filename,
|
|
272
|
+
designId,
|
|
273
|
+
});
|
|
122
274
|
}
|
|
123
275
|
|
|
124
276
|
try {
|
|
@@ -148,6 +300,7 @@ export default defineAction({
|
|
|
148
300
|
designId,
|
|
149
301
|
filename,
|
|
150
302
|
fileId: file.id,
|
|
303
|
+
mode: resolvedMode,
|
|
151
304
|
editsApplied: applied,
|
|
152
305
|
changed,
|
|
153
306
|
bytesBefore: base.length,
|
|
@@ -14,6 +14,10 @@ import { nanoid } from "nanoid";
|
|
|
14
14
|
import { z } from "zod";
|
|
15
15
|
|
|
16
16
|
import { getDb, schema } from "../server/db/index.js";
|
|
17
|
+
import {
|
|
18
|
+
mergeCanvasFramePlacements,
|
|
19
|
+
type CanvasFramePlacement,
|
|
20
|
+
} from "../shared/canvas-frames.js";
|
|
17
21
|
|
|
18
22
|
/** Editor deep link so external agents can surface "Open design". */
|
|
19
23
|
function designDeepLink(designId: string): string {
|
|
@@ -34,7 +38,9 @@ export default defineAction({
|
|
|
34
38
|
"version then refine individual files with `edit-design` (search/replace) rather " +
|
|
35
39
|
"than resending a big multi-file payload — a single oversized payload can get cut " +
|
|
36
40
|
"off mid-stream and stall the turn. " +
|
|
37
|
-
"Do not report a design as ready until this action succeeds."
|
|
41
|
+
"Do not report a design as ready until this action succeeds. " +
|
|
42
|
+
"When adding multiple screens or states, pass canvasFrames with filenames " +
|
|
43
|
+
"and x/y/width/height so the new screens appear placed on the overview canvas.",
|
|
38
44
|
schema: z.object({
|
|
39
45
|
designId: z.string().describe("Design project ID to save content to"),
|
|
40
46
|
prompt: z.string().describe("The generation prompt (stored for reference)"),
|
|
@@ -106,6 +112,34 @@ export default defineAction({
|
|
|
106
112
|
"radius, dark mode, font choice). Each must reference a CSS var " +
|
|
107
113
|
"the design's `:root` block actually uses.",
|
|
108
114
|
),
|
|
115
|
+
canvasFrames: z
|
|
116
|
+
.preprocess(
|
|
117
|
+
(v) => (typeof v === "string" ? JSON.parse(v) : v),
|
|
118
|
+
z
|
|
119
|
+
.array(
|
|
120
|
+
z
|
|
121
|
+
.object({
|
|
122
|
+
fileId: z.string().optional(),
|
|
123
|
+
filename: z.string().optional(),
|
|
124
|
+
x: z.number().optional(),
|
|
125
|
+
y: z.number().optional(),
|
|
126
|
+
width: z.number().optional(),
|
|
127
|
+
height: z.number().optional(),
|
|
128
|
+
rotation: z.number().optional(),
|
|
129
|
+
z: z.number().optional(),
|
|
130
|
+
})
|
|
131
|
+
.refine((frame) => frame.fileId || frame.filename, {
|
|
132
|
+
message: "canvasFrames entries require fileId or filename",
|
|
133
|
+
}),
|
|
134
|
+
)
|
|
135
|
+
.optional(),
|
|
136
|
+
)
|
|
137
|
+
.optional()
|
|
138
|
+
.describe(
|
|
139
|
+
"Optional overview-canvas placements for generated screens. " +
|
|
140
|
+
"Reference each screen by filename or fileId and include x/y/width/height " +
|
|
141
|
+
"from generate-screens regions or your planned canvas layout.",
|
|
142
|
+
),
|
|
109
143
|
}),
|
|
110
144
|
mcpApp: {
|
|
111
145
|
compactCatalog: true,
|
|
@@ -124,6 +158,7 @@ export default defineAction({
|
|
|
124
158
|
designSystemId,
|
|
125
159
|
projectType,
|
|
126
160
|
tweaks,
|
|
161
|
+
canvasFrames,
|
|
127
162
|
}) => {
|
|
128
163
|
await assertAccess("design", designId, "editor");
|
|
129
164
|
if (designSystemId) {
|
|
@@ -280,6 +315,40 @@ export default defineAction({
|
|
|
280
315
|
type: tweak.type === "color-swatches" ? "color-swatch" : tweak.type,
|
|
281
316
|
}));
|
|
282
317
|
}
|
|
318
|
+
let placedFrames:
|
|
319
|
+
| Array<{
|
|
320
|
+
fileId: string;
|
|
321
|
+
filename?: string;
|
|
322
|
+
frame: CanvasFramePlacement;
|
|
323
|
+
}>
|
|
324
|
+
| undefined;
|
|
325
|
+
if (canvasFrames !== undefined) {
|
|
326
|
+
const savedByFileId = new Map(savedFiles.map((file) => [file.id, file]));
|
|
327
|
+
const savedByFilename = new Map(
|
|
328
|
+
savedFiles.map((file) => [file.filename, file]),
|
|
329
|
+
);
|
|
330
|
+
const existingByFileId = new Map(
|
|
331
|
+
existingFiles.map((file) => [file.id, file]),
|
|
332
|
+
);
|
|
333
|
+
const merged = mergeCanvasFramePlacements({
|
|
334
|
+
existing: prevData.canvasFrames,
|
|
335
|
+
placements: canvasFrames,
|
|
336
|
+
resolveFileId: (placement) => {
|
|
337
|
+
if (placement.fileId) {
|
|
338
|
+
return savedByFileId.has(placement.fileId) ||
|
|
339
|
+
existingByFileId.has(placement.fileId)
|
|
340
|
+
? placement.fileId
|
|
341
|
+
: undefined;
|
|
342
|
+
}
|
|
343
|
+
return placement.filename
|
|
344
|
+
? (savedByFilename.get(placement.filename)?.id ??
|
|
345
|
+
existingByName.get(placement.filename)?.id)
|
|
346
|
+
: undefined;
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
mergedData.canvasFrames = merged.canvasFrames;
|
|
350
|
+
placedFrames = merged.placedFrames;
|
|
351
|
+
}
|
|
283
352
|
designUpdates.data = JSON.stringify(mergedData);
|
|
284
353
|
|
|
285
354
|
await db
|
|
@@ -292,6 +361,7 @@ export default defineAction({
|
|
|
292
361
|
urlPath: `/design/${designId}`,
|
|
293
362
|
renderable: true,
|
|
294
363
|
savedFiles,
|
|
364
|
+
placedFrames,
|
|
295
365
|
fileCount: savedFiles.length,
|
|
296
366
|
};
|
|
297
367
|
},
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { defineAction, embedApp } from "@agent-native/core";
|
|
2
|
+
import { writeAppState } from "@agent-native/core/application-state";
|
|
3
|
+
import { buildDeepLink } from "@agent-native/core/server";
|
|
4
|
+
import { assertAccess } from "@agent-native/core/sharing";
|
|
5
|
+
import { nanoid } from "nanoid";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import "../server/db/index.js";
|
|
9
|
+
import { assignRegions } from "../shared/canvas-math.js";
|
|
10
|
+
import {
|
|
11
|
+
designGenerationSessionKey,
|
|
12
|
+
type DesignGenerationFrame,
|
|
13
|
+
type DesignGenerationSession,
|
|
14
|
+
} from "../shared/generation-session.js";
|
|
15
|
+
|
|
16
|
+
const AGENT_NAMES = [
|
|
17
|
+
"Atlas",
|
|
18
|
+
"Nova",
|
|
19
|
+
"Kai",
|
|
20
|
+
"Mira",
|
|
21
|
+
"Sol",
|
|
22
|
+
"Vega",
|
|
23
|
+
"Rune",
|
|
24
|
+
"Iris",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const AGENT_COLORS = [
|
|
28
|
+
"var(--design-editor-accent-color)",
|
|
29
|
+
"hsl(var(--chart-2))",
|
|
30
|
+
"hsl(var(--chart-3))",
|
|
31
|
+
"hsl(var(--chart-4))",
|
|
32
|
+
"hsl(var(--chart-5))",
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
function designDeepLink(designId: string): string {
|
|
36
|
+
const path = `/design/${encodeURIComponent(designId)}?view=overview`;
|
|
37
|
+
return buildDeepLink({
|
|
38
|
+
app: "design",
|
|
39
|
+
view: "editor",
|
|
40
|
+
params: { designId },
|
|
41
|
+
to: path,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const requestedScreenSchema = z.object({
|
|
46
|
+
frameId: z.string().optional(),
|
|
47
|
+
title: z.string().min(1),
|
|
48
|
+
filename: z
|
|
49
|
+
.string()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Target filename for this screen, such as onboarding.html"),
|
|
52
|
+
role: z.enum(["screen", "variant"]).optional().default("screen"),
|
|
53
|
+
variantOf: z.string().optional(),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export default defineAction({
|
|
57
|
+
description:
|
|
58
|
+
"Start a visible multi-agent generation session on the Design canvas. " +
|
|
59
|
+
"Use this before generating multiple screens or variations in parallel: it " +
|
|
60
|
+
"assigns non-overlapping canvas regions, publishes named agent/frame " +
|
|
61
|
+
"status to application state, and returns per-frame generation instructions. " +
|
|
62
|
+
"After this action, fan out calls to generate-design for each returned " +
|
|
63
|
+
"frame, passing the returned canvasFrame values to generate-design so " +
|
|
64
|
+
"screens appear in the infinite overview canvas.",
|
|
65
|
+
schema: z.object({
|
|
66
|
+
designId: z.string().describe("Design project ID to generate into"),
|
|
67
|
+
prompt: z.string().min(1).describe("Overall generation prompt"),
|
|
68
|
+
screens: z
|
|
69
|
+
.preprocess(
|
|
70
|
+
(value) => (typeof value === "string" ? JSON.parse(value) : value),
|
|
71
|
+
z.array(requestedScreenSchema).min(1).max(8),
|
|
72
|
+
)
|
|
73
|
+
.describe("Screens or variants that should be generated on the canvas"),
|
|
74
|
+
designSystemId: z
|
|
75
|
+
.string()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("Locked design system/token set for every worker"),
|
|
78
|
+
contextRefs: z
|
|
79
|
+
.array(z.string())
|
|
80
|
+
.optional()
|
|
81
|
+
.default([])
|
|
82
|
+
.describe("Selected frame/image/reference ids attached as context"),
|
|
83
|
+
}),
|
|
84
|
+
mcpApp: {
|
|
85
|
+
compactCatalog: true,
|
|
86
|
+
resource: embedApp({
|
|
87
|
+
title: "Design generation session",
|
|
88
|
+
description: "Open the Design editor with agent generation visible.",
|
|
89
|
+
iframeTitle: "Agent-Native Design",
|
|
90
|
+
openLabel: "Open generation session",
|
|
91
|
+
height: 720,
|
|
92
|
+
}),
|
|
93
|
+
},
|
|
94
|
+
run: async ({ designId, prompt, screens, designSystemId, contextRefs }) => {
|
|
95
|
+
await assertAccess("design", designId, "editor");
|
|
96
|
+
if (designSystemId) {
|
|
97
|
+
await assertAccess("design-system", designSystemId, "viewer");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const regions = assignRegions(screens.length, {
|
|
101
|
+
origin: { x: 0, y: 0 },
|
|
102
|
+
columns: screens.length <= 3 ? screens.length : 3,
|
|
103
|
+
});
|
|
104
|
+
const frames: DesignGenerationFrame[] = screens.map((screen, index) => {
|
|
105
|
+
const frameId = screen.frameId ?? nanoid();
|
|
106
|
+
return {
|
|
107
|
+
frameId,
|
|
108
|
+
agentId: `agent-${frameId}`,
|
|
109
|
+
agentName: AGENT_NAMES[index % AGENT_NAMES.length] ?? "Agent",
|
|
110
|
+
agentColor:
|
|
111
|
+
AGENT_COLORS[index % AGENT_COLORS.length] ??
|
|
112
|
+
"var(--design-editor-accent-color)",
|
|
113
|
+
region: regions[index]!,
|
|
114
|
+
role: screen.role,
|
|
115
|
+
variantOf: screen.variantOf,
|
|
116
|
+
status: "queued",
|
|
117
|
+
step: "Queued",
|
|
118
|
+
progress: 0,
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const session: DesignGenerationSession = {
|
|
123
|
+
id: nanoid(),
|
|
124
|
+
designId,
|
|
125
|
+
status: "planning",
|
|
126
|
+
designSystemId,
|
|
127
|
+
prompt,
|
|
128
|
+
contextRefs,
|
|
129
|
+
frames,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
await writeAppState(
|
|
133
|
+
designGenerationSessionKey(designId),
|
|
134
|
+
session as unknown as Record<string, unknown>,
|
|
135
|
+
);
|
|
136
|
+
await writeAppState("navigate", {
|
|
137
|
+
view: "editor",
|
|
138
|
+
designId,
|
|
139
|
+
editorView: "overview",
|
|
140
|
+
path: `/design/${encodeURIComponent(designId)}?view=overview`,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const targets = frames.map((frame, index) => {
|
|
144
|
+
const requested = screens[index]!;
|
|
145
|
+
const filename =
|
|
146
|
+
requested.filename ??
|
|
147
|
+
`${
|
|
148
|
+
requested.title
|
|
149
|
+
.toLowerCase()
|
|
150
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
151
|
+
.replace(/^-+|-+$/g, "")
|
|
152
|
+
.slice(0, 48) || `screen-${index + 1}`
|
|
153
|
+
}.html`;
|
|
154
|
+
return {
|
|
155
|
+
frameId: frame.frameId,
|
|
156
|
+
title: requested.title,
|
|
157
|
+
filename,
|
|
158
|
+
role: frame.role,
|
|
159
|
+
variantOf: frame.variantOf,
|
|
160
|
+
canvasFrame: {
|
|
161
|
+
filename,
|
|
162
|
+
x: frame.region.x,
|
|
163
|
+
y: frame.region.y,
|
|
164
|
+
width: frame.region.width,
|
|
165
|
+
height: frame.region.height,
|
|
166
|
+
z: index,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
designId,
|
|
173
|
+
sessionId: session.id,
|
|
174
|
+
status: session.status,
|
|
175
|
+
frames,
|
|
176
|
+
targets,
|
|
177
|
+
path: `/design/${encodeURIComponent(designId)}?view=overview`,
|
|
178
|
+
embed: true,
|
|
179
|
+
nextRequiredAction:
|
|
180
|
+
"Generate each target with generate-design, using the target filename and canvasFrame placement, the same designSystemId, and contextRefs for coherence.",
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
link: ({ result }) => {
|
|
184
|
+
if (!result || typeof result !== "object") return null;
|
|
185
|
+
const designId = (result as { designId?: string }).designId;
|
|
186
|
+
if (!designId) return null;
|
|
187
|
+
return {
|
|
188
|
+
url: designDeepLink(designId),
|
|
189
|
+
label: "Open generation session",
|
|
190
|
+
view: "editor",
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
});
|