@agent-native/core 0.129.1 → 0.130.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 +78 -0
- package/corpus/core/docs/content/cloneable-saas.mdx +114 -0
- package/corpus/core/docs/content/creating-templates.mdx +28 -2
- package/corpus/core/docs/content/syncing-template-changes.mdx +7 -0
- package/corpus/core/docs/content/template-clips-developers.mdx +12 -5
- package/corpus/core/docs/content/template-dispatch-developers.mdx +1 -1
- package/corpus/core/docs/content/template-dispatch.mdx +1 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/action-ui.ts +1 -0
- package/corpus/core/src/action.ts +5 -1
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +15 -5
- package/corpus/core/src/agent/harness/runner.ts +5 -0
- package/corpus/core/src/agent/production-agent.ts +33 -0
- package/corpus/core/src/agent/run-loop-with-resume.ts +5 -0
- package/corpus/core/src/agent/run-manager.ts +126 -1
- package/corpus/core/src/agent/thread-data-builder.ts +47 -2
- package/corpus/core/src/agent/types.ts +2 -0
- package/corpus/core/src/chat-threads/store.ts +4 -5
- package/corpus/core/src/cli/create.ts +1139 -65
- package/corpus/core/src/cli/design-connect.ts +3 -7
- package/corpus/core/src/cli/index.ts +5 -3
- package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
- package/corpus/core/src/client/AssistantChat.tsx +27 -16
- package/corpus/core/src/client/agent-chat-adapter.ts +24 -0
- package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +17 -2
- package/corpus/core/src/client/chat/index.ts +1 -0
- package/corpus/core/src/client/chat/message-components.tsx +104 -1
- package/corpus/core/src/client/chat/run-recovery.tsx +15 -3
- package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +10 -29
- package/corpus/core/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
- package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
- package/corpus/core/src/client/chat/widgets/workspace-file-result.ts +49 -0
- package/corpus/core/src/client/embed-auth.ts +2 -0
- package/corpus/core/src/client/org/InvitationBanner.tsx +14 -1
- package/corpus/core/src/client/org/OrgSwitcher.tsx +23 -0
- package/corpus/core/src/client/org/TeamPage.tsx +130 -0
- package/corpus/core/src/client/org/WorkspaceNotice.tsx +85 -0
- package/corpus/core/src/client/org/hooks.ts +14 -0
- package/corpus/core/src/client/org/index.ts +2 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +27 -40
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +134 -51
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -0
- package/corpus/core/src/client/resources/use-resources.ts +6 -0
- package/corpus/core/src/client/use-action.ts +3 -1
- package/corpus/core/src/client/widgets/index.ts +1 -0
- package/corpus/core/src/coding-tools/run-code.ts +2 -1
- package/corpus/core/src/db/client.ts +28 -4
- package/corpus/core/src/deploy/build.ts +31 -3
- package/corpus/core/src/eject/remote-mcp-presets.ts +1 -1
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/index.ts +1 -0
- package/corpus/core/src/integrations/google-docs-poller.ts +3 -0
- package/corpus/core/src/integrations/webhook-handler.ts +28 -11
- package/corpus/core/src/jobs/scheduler.ts +4 -0
- package/corpus/core/src/localization/default-messages.ts +3 -2
- package/corpus/core/src/mcp/build-server.ts +20 -2
- package/corpus/core/src/observability/traces.ts +48 -12
- package/corpus/core/src/org/handlers.ts +52 -1
- package/corpus/core/src/org/migrations.ts +4 -0
- package/corpus/core/src/org/plugin.ts +14 -0
- package/corpus/core/src/org/schema.ts +1 -0
- package/corpus/core/src/org/types.ts +8 -0
- package/corpus/core/src/org/workspace-url.ts +74 -0
- package/corpus/core/src/resources/handlers.ts +35 -5
- package/corpus/core/src/scripts/runner.ts +183 -5
- package/corpus/core/src/server/action-routes.ts +32 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +29 -0
- package/corpus/core/src/server/agent-teams.ts +10 -1
- package/corpus/core/src/server/auth.ts +33 -7
- package/corpus/core/src/server/embed-route.ts +9 -0
- package/corpus/core/src/server/embed-session.ts +62 -3
- package/corpus/core/src/server/open-route.ts +20 -6
- package/corpus/core/src/server/prompts/framework-core-compact.ts +1 -1
- package/corpus/core/src/server/prompts/framework-core.ts +1 -0
- package/corpus/core/src/server/request-context.ts +36 -1
- package/corpus/core/src/shared/embed-auth.ts +1 -0
- package/corpus/core/src/shared/html-document.ts +115 -0
- package/corpus/core/src/shared/index.ts +1 -0
- package/corpus/core/src/sharing/access.ts +8 -1
- package/corpus/core/src/sharing/registry.ts +11 -2
- package/corpus/core/src/workspace-files/actions.ts +100 -0
- package/corpus/core/src/workspace-files/tool.ts +4 -0
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +4 -0
- package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +9 -1
- package/corpus/templates/analytics/AGENTS.md +17 -24
- package/corpus/templates/analytics/actions/data-source-status.ts +11 -1
- package/corpus/templates/analytics/app/i18n-data.ts +34 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +86 -0
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +9 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +184 -20
- package/corpus/templates/analytics/changelog/2026-07-28-native-analytics-data-sources-no-longer-show-duplicate-mc.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-exports-now-appear-in-chat-with-a-direct-download-instead-of.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-queued-chat-prompts-no-longer-resend-after-analytics-navigat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-scheduled-dashboard-emails-load-every-panel-reliably-without.md +6 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +6 -3
- package/corpus/templates/analytics/server/lib/credential-keys.ts +1 -1
- package/corpus/templates/analytics/server/lib/hubspot.ts +1 -1
- package/corpus/templates/analytics/server/lib/provider-credentials.ts +55 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +123 -27
- package/corpus/templates/analytics/server/routes/[...page].get.ts +2 -7
- package/corpus/templates/analytics/vite.config.ts +7 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +100 -2
- package/corpus/templates/brain/app/lib/brain.ts +10 -0
- package/corpus/templates/brain/app/routes/sources.tsx +15 -4
- package/corpus/templates/brain/changelog/2026-07-29-brain-automatically-retries-failed-source-syncs-and-guides-y.md +6 -0
- package/corpus/templates/brain/jobs/process-ingest-queue.ts +13 -0
- package/corpus/templates/brain/server/jobs/sync-sources.ts +27 -22
- package/corpus/templates/brain/server/plugins/agent-chat.ts +2 -1
- package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +7 -1
- package/corpus/templates/clips/AGENTS.md +1 -1
- package/corpus/templates/clips/actions/create-recording-agent-link.ts +11 -1
- package/corpus/templates/clips/actions/update-comment.ts +68 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +0 -1
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +221 -65
- package/corpus/templates/clips/app/components/player/video-player.tsx +101 -27
- package/corpus/templates/clips/app/i18n/en-US.ts +2 -1
- package/corpus/templates/clips/app/routes/bug-report.done.tsx +48 -27
- package/corpus/templates/clips/app/routes/bug-report.tsx +43 -4
- package/corpus/templates/clips/app/routes/record.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-29-clip-playback-now-recovers-instead-of-getting-stuck-when-a-b.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-comments-can-now-be-edited-after-posting.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-download-actions-now-use-a-shorter-clearer-label.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-embedded-bug-reports-now-return-a-temporary-agent-readable.md +6 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +21 -1
- package/corpus/templates/clips/shared/bug-report.ts +99 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +7 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +5 -2
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +20 -8
- package/corpus/templates/content/changelog/2026-07-29-missing-databases-no-longer-trigger-repeated-personal-view-e.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +83 -47
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +474 -55
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +3 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +18 -1
- package/corpus/templates/design/.generated/bridge/source-location.generated.ts +348 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +2 -7
- package/corpus/templates/design/actions/apply-visual-edit.ts +7 -1
- package/corpus/templates/design/actions/connect-localhost.ts +5 -9
- package/corpus/templates/design/actions/create-component.ts +16 -13
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +2 -7
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +4 -7
- package/corpus/templates/design/actions/list-local-files.ts +26 -50
- package/corpus/templates/design/actions/list-localhost-connections.ts +2 -7
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +2 -2
- package/corpus/templates/design/actions/open-visual-edit.ts +234 -135
- package/corpus/templates/design/actions/read-local-file.ts +26 -50
- package/corpus/templates/design/actions/request-localhost-write-consent.ts +2 -7
- package/corpus/templates/design/actions/write-local-file.ts +31 -73
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +307 -133
- package/corpus/templates/design/app/components/design/EditPanel.tsx +94 -22
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +137 -60
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +75 -14
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +755 -97
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +8 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +24 -1
- package/corpus/templates/design/app/components/design/bridge/source-location.bridge.ts +530 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbenchLoader.tsx +278 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +32 -12
- package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +14 -3
- package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +87 -24
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +36 -0
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +2 -1
- package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +48 -8
- package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +3 -13
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +4 -2
- package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +3 -13
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/inspect-code-source.ts +93 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -2
- package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +35 -0
- package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +24 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -0
- package/corpus/templates/design/app/components/design/types.ts +29 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -4
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +153 -46
- package/corpus/templates/design/app/i18n-responsive-interact.ts +12 -12
- package/corpus/templates/design/app/lib/design-editor-route.ts +23 -0
- package/corpus/templates/design/app/pages/VisualEdit.tsx +19 -6
- package/corpus/templates/design/app/pages/design-editor/action-error.ts +19 -0
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +29 -0
- package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +6 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +277 -15
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +75 -9
- package/corpus/templates/design/app/pages/design-editor/layer-state-scope.ts +28 -0
- package/corpus/templates/design/app/pages/design-editor/live-screen-layer-drop.ts +41 -0
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +496 -41
- package/corpus/templates/design/app/pages/design-editor/pending-live-edit-unload-guard.ts +27 -0
- package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +168 -9
- package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +41 -3
- package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +5 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +42 -13
- package/corpus/templates/design/app/pages/design-editor/source-location.ts +180 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +17 -0
- package/corpus/templates/design/app/public-routes.ts +1 -0
- package/corpus/templates/design/app/routes/visual-edit.$id.tsx +15 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +1 -1
- package/corpus/templates/design/changelog/2026-07-28-deleting-a-selected-element-now-removes-it-from-the-live-pre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-deleting-an-element-on-a-connected-localhost-screen-now-queu.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-shows-a-responsive-device-preview-with-pre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-layer-hide-and-lock-now-apply-to-the-live-preview-instead-of.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-layers-panel-selections-on-a-connected-localhost-screen-can-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-locked-layers-now-show-a-subtle-dashed-outline-in-the-live-p.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-the-apply-design-updates-button-now-counts-pending-live-text.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-the-design-canvas-no-longer-stalls-on-a-render-loop-while-a-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-visual-edit-on-a-local-dev-server-no-longer-requires-signing.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-visual-edits-on-a-react-19-app-no-longer-report-a-source-lin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-an-edit-that-cannot-be-written-to-source-now-names-the-reaso.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-applying-a-primitive-dropped-onto-a-connected-localhost-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-changing-a-style-in-the-inspector-now-updates-a-connected-lo.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-choosing-edit-or-annotate-from-a-focused-screen-now-returns-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-concurrent-source-edits-now-return-a-clear-conflict-response.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-creating-a-component-from-an-element-that-repeats-in-the-sou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-deleting-an-element-you-just-dropped-onto-a-live-screen-no-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-dragging-a-layer-across-screens-no-longer-dies-when-the-poin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-dragging-an-element-from-a-stored-screen-into-a-live-localho.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-drawing-a-box-on-the-canvas-and-dragging-it-into-a-connected.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-fixed-a-loading-screen-flicker-when-reopening-designs-with-a.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-interact-mode-has-edit-and-annotate-buttons-again-so-you-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-layer-groups-can-be-dropped-onto-live-localhost-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-localhost-source-errors-now-say-what-actually-went-wrong-whi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-opening-or-refreshing-a-live-localhost-screen-in-single-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-redo-after-undoing-a-drop-onto-a-live-screen-puts-the-elemen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-shapes-can-be-drawn-directly-onto-live-localhost-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-shapes-drawn-on-the-canvas-board-now-appear-immediately-inst.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-style-edits-on-a-running-localhost-screen-now-preview-live-a.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-the-apply-design-updates-control-now-appears-as-a-clean-conn.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-visual-edits-on-a-mapped-component-instance-now-tell-the-age.md +6 -0
- package/corpus/templates/design/server/lib/design-data-access.ts +21 -7
- package/corpus/templates/design/server/lib/localhost-connection.ts +240 -0
- package/corpus/templates/design/server/routes/[...page].get.ts +2 -5
- package/corpus/templates/design/server/source-workspace.ts +2 -0
- package/corpus/templates/design/shared/code-layer.ts +43 -0
- package/corpus/templates/design/shared/html-content.ts +26 -0
- package/corpus/templates/design/shared/html-integrity.ts +21 -1
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +15 -0
- package/corpus/templates/design/shared/source-mode.ts +76 -0
- package/corpus/templates/dispatch/changelog/2026-07-29-workspace-members-without-admin-access-now-see-a-clear-permi.md +6 -0
- package/corpus/templates/dispatch/server/lib/usage-metrics.ts +2 -1
- package/corpus/templates/plan/app/lib/plan-annotation-runtime.ts +3 -4
- package/corpus/templates/plan/server/routes/[...page].get.ts +2 -5
- package/corpus/templates/slides/actions/patch-deck.ts +29 -17
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +3 -2
- package/dist/action-ui.d.ts +1 -0
- package/dist/action-ui.d.ts.map +1 -1
- package/dist/action-ui.js +1 -0
- package/dist/action-ui.js.map +1 -1
- package/dist/action.d.ts +5 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +13 -5
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/harness/runner.d.ts.map +1 -1
- package/dist/agent/harness/runner.js +5 -0
- package/dist/agent/harness/runner.js.map +1 -1
- package/dist/agent/production-agent.d.ts +16 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +6 -0
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-manager.d.ts +14 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +91 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +3 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +35 -3
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +4 -6
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts +66 -6
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +765 -66
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +2 -7
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/index.js +5 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +83 -47
- package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +16 -9
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -0
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
- package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.js +8 -2
- package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +17 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +24 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts +6 -0
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +13 -3
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.js +2 -3
- package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
- package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts +5 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts.map +1 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.js +34 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.js.map +1 -0
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js +13 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/client/chat/widgets/workspace-file-result.d.ts +12 -0
- package/dist/client/chat/widgets/workspace-file-result.d.ts.map +1 -0
- package/dist/client/chat/widgets/workspace-file-result.js +34 -0
- package/dist/client/chat/widgets/workspace-file-result.js.map +1 -0
- package/dist/client/embed-auth.d.ts.map +1 -1
- package/dist/client/embed-auth.js +2 -1
- package/dist/client/embed-auth.js.map +1 -1
- package/dist/client/org/InvitationBanner.d.ts +5 -2
- package/dist/client/org/InvitationBanner.d.ts.map +1 -1
- package/dist/client/org/InvitationBanner.js +9 -2
- package/dist/client/org/InvitationBanner.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +27 -3
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/WorkspaceNotice.d.ts +18 -0
- package/dist/client/org/WorkspaceNotice.d.ts.map +1 -0
- package/dist/client/org/WorkspaceNotice.js +56 -0
- package/dist/client/org/WorkspaceNotice.js.map +1 -0
- package/dist/client/org/hooks.d.ts +1 -0
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +12 -0
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/org/index.d.ts +2 -1
- package/dist/client/org/index.d.ts.map +1 -1
- package/dist/client/org/index.js +2 -1
- package/dist/client/org/index.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +8 -12
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +3 -0
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +49 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +3 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +1 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +3 -0
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/use-action.d.ts +3 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +3 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/widgets/index.d.ts +1 -1
- package/dist/client/widgets/index.d.ts.map +1 -1
- package/dist/client/widgets/index.js +1 -1
- package/dist/client/widgets/index.js.map +1 -1
- package/dist/coding-tools/run-code.js +2 -1
- package/dist/coding-tools/run-code.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/db/client.d.ts +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +24 -3
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +25 -3
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/remote-mcp-presets.js +1 -1
- package/dist/eject/remote-mcp-presets.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +4 -1
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +23 -11
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.js +4 -0
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -2
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -2
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +10 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +27 -7
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/handlers.d.ts +15 -0
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +45 -1
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +4 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/org/plugin.d.ts +1 -0
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +10 -1
- package/dist/org/plugin.js.map +1 -1
- package/dist/org/schema.d.ts +19 -0
- package/dist/org/schema.d.ts.map +1 -1
- package/dist/org/schema.js +1 -0
- package/dist/org/schema.js.map +1 -1
- package/dist/org/types.d.ts +8 -0
- package/dist/org/types.d.ts.map +1 -1
- package/dist/org/types.js.map +1 -1
- package/dist/org/workspace-url.d.ts +32 -0
- package/dist/org/workspace-url.d.ts.map +1 -0
- package/dist/org/workspace-url.js +63 -0
- package/dist/org/workspace-url.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/resources/handlers.d.ts +2 -3
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +25 -5
- package/dist/resources/handlers.js.map +1 -1
- package/dist/scripts/runner.d.ts +17 -0
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +130 -5
- package/dist/scripts/runner.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +24 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +26 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +10 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth.d.ts +22 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +33 -7
- package/dist/server/auth.js.map +1 -1
- package/dist/server/embed-route.d.ts.map +1 -1
- package/dist/server/embed-route.js +6 -1
- package/dist/server/embed-route.js.map +1 -1
- package/dist/server/embed-session.d.ts +7 -0
- package/dist/server/embed-session.d.ts.map +1 -1
- package/dist/server/embed-session.js +46 -4
- package/dist/server/embed-session.js.map +1 -1
- package/dist/server/open-route.d.ts.map +1 -1
- package/dist/server/open-route.js +17 -7
- package/dist/server/open-route.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +1 -1
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +1 -0
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/request-context.d.ts +26 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +18 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/shared/embed-auth.d.ts +1 -0
- package/dist/shared/embed-auth.d.ts.map +1 -1
- package/dist/shared/embed-auth.js +1 -0
- package/dist/shared/embed-auth.js.map +1 -1
- package/dist/shared/html-document.d.ts +12 -0
- package/dist/shared/html-document.d.ts.map +1 -0
- package/dist/shared/html-document.js +92 -0
- package/dist/shared/html-document.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/sharing/access.d.ts +1 -0
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +8 -2
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/registry.d.ts +3 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/workspace-files/actions.d.ts +28 -0
- package/dist/workspace-files/actions.d.ts.map +1 -0
- package/dist/workspace-files/actions.js +75 -0
- package/dist/workspace-files/actions.js.map +1 -0
- package/dist/workspace-files/tool.d.ts.map +1 -1
- package/dist/workspace-files/tool.js +4 -0
- package/dist/workspace-files/tool.js.map +1 -1
- package/docs/content/cloneable-saas.mdx +114 -0
- package/docs/content/creating-templates.mdx +28 -2
- package/docs/content/syncing-template-changes.mdx +7 -0
- package/docs/content/template-clips-developers.mdx +12 -5
- package/docs/content/template-dispatch-developers.mdx +1 -1
- package/docs/content/template-dispatch.mdx +1 -1
- package/package.json +2 -2
- package/src/action-ui.ts +1 -0
- package/src/action.ts +5 -1
- package/src/agent/engine/ai-sdk-engine.ts +15 -5
- package/src/agent/harness/runner.ts +5 -0
- package/src/agent/production-agent.ts +33 -0
- package/src/agent/run-loop-with-resume.ts +5 -0
- package/src/agent/run-manager.ts +126 -1
- package/src/agent/thread-data-builder.ts +47 -2
- package/src/agent/types.ts +2 -0
- package/src/chat-threads/store.ts +4 -5
- package/src/cli/create.ts +1139 -65
- package/src/cli/design-connect.ts +3 -7
- package/src/cli/index.ts +5 -3
- package/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
- package/src/client/AssistantChat.tsx +27 -16
- package/src/client/agent-chat-adapter.ts +24 -0
- package/src/client/blocks/library/wireframe-kit.tsx +17 -2
- package/src/client/chat/index.ts +1 -0
- package/src/client/chat/message-components.tsx +104 -1
- package/src/client/chat/run-recovery.tsx +15 -3
- package/src/client/chat/widgets/DataTableWidget.tsx +10 -29
- package/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
- package/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
- package/src/client/chat/widgets/workspace-file-result.ts +49 -0
- package/src/client/embed-auth.ts +2 -0
- package/src/client/org/InvitationBanner.tsx +14 -1
- package/src/client/org/OrgSwitcher.tsx +23 -0
- package/src/client/org/TeamPage.tsx +130 -0
- package/src/client/org/WorkspaceNotice.tsx +85 -0
- package/src/client/org/hooks.ts +14 -0
- package/src/client/org/index.ts +2 -0
- package/src/client/resources/McpIntegrationDialog.tsx +27 -40
- package/src/client/resources/ResourcesPanel.tsx +134 -51
- package/src/client/resources/mcp-integration-catalog.ts +7 -0
- package/src/client/resources/use-resources.ts +6 -0
- package/src/client/use-action.ts +3 -1
- package/src/client/widgets/index.ts +1 -0
- package/src/coding-tools/run-code.ts +2 -1
- package/src/db/client.ts +28 -4
- package/src/deploy/build.ts +31 -3
- package/src/eject/remote-mcp-presets.ts +1 -1
- package/src/index.browser.ts +1 -0
- package/src/index.ts +1 -0
- package/src/integrations/google-docs-poller.ts +3 -0
- package/src/integrations/webhook-handler.ts +28 -11
- package/src/jobs/scheduler.ts +4 -0
- package/src/localization/default-messages.ts +3 -2
- package/src/mcp/build-server.ts +20 -2
- package/src/observability/traces.ts +48 -12
- package/src/org/handlers.ts +52 -1
- package/src/org/migrations.ts +4 -0
- package/src/org/plugin.ts +14 -0
- package/src/org/schema.ts +1 -0
- package/src/org/types.ts +8 -0
- package/src/org/workspace-url.ts +74 -0
- package/src/resources/handlers.ts +35 -5
- package/src/scripts/runner.ts +183 -5
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +2 -1
- package/src/server/action-routes.ts +32 -2
- package/src/server/agent-chat-plugin.ts +29 -0
- package/src/server/agent-teams.ts +10 -1
- package/src/server/auth.ts +33 -7
- package/src/server/embed-route.ts +9 -0
- package/src/server/embed-session.ts +62 -3
- package/src/server/open-route.ts +20 -6
- package/src/server/prompts/framework-core-compact.ts +1 -1
- package/src/server/prompts/framework-core.ts +1 -0
- package/src/server/request-context.ts +36 -1
- package/src/shared/embed-auth.ts +1 -0
- package/src/shared/html-document.ts +115 -0
- package/src/shared/index.ts +1 -0
- package/src/sharing/access.ts +8 -1
- package/src/sharing/registry.ts +11 -2
- package/src/workspace-files/actions.ts +100 -0
- package/src/workspace-files/tool.ts +4 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +0 -6
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +0 -6
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { useT } from "@agent-native/core/client/i18n";
|
|
7
7
|
import { type ReviewThread } from "@agent-native/core/client/review";
|
|
8
8
|
import type { ReviewComment } from "@agent-native/core/review";
|
|
9
|
+
import { injectDocumentMarkup } from "@agent-native/core/shared";
|
|
9
10
|
import {
|
|
10
11
|
DEFAULT_CANVAS_MAX_ZOOM,
|
|
11
12
|
DEFAULT_CANVAS_MIN_ZOOM,
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
useDesktopDesignNativePreview,
|
|
55
56
|
} from "@/lib/desktop-design-preview";
|
|
56
57
|
import { cn } from "@/lib/utils";
|
|
58
|
+
import { runtimeStyleTarget } from "@/pages/design-editor/pending-edits";
|
|
57
59
|
|
|
58
60
|
import { editorChromeBridgeScript } from "../../../.generated/bridge/editor-chrome.generated";
|
|
59
61
|
import { embeddedWheelBridgeScript } from "../../../.generated/bridge/embedded-wheel.generated";
|
|
@@ -117,6 +119,7 @@ import type {
|
|
|
117
119
|
ElementInfo,
|
|
118
120
|
ElementSelectionIntent,
|
|
119
121
|
DeviceFrameType,
|
|
122
|
+
RuntimeStructureInsertRequest,
|
|
120
123
|
RuntimeStructureMoveRequest,
|
|
121
124
|
RuntimeVerificationRequest,
|
|
122
125
|
} from "./types";
|
|
@@ -325,6 +328,20 @@ const LIVE_REFLOW_ENABLED = true;
|
|
|
325
328
|
*/
|
|
326
329
|
const SELECTED_LAYER_DRAG_PRIORITY_ENABLED = true;
|
|
327
330
|
|
|
331
|
+
/**
|
|
332
|
+
* A style replay into the live iframe. `runtimeSelector`/`runtimeSourceId` are
|
|
333
|
+
* the only pair that resolves in a localhost document — see
|
|
334
|
+
* `runtimeStyleTarget` for the two-namespace problem they exist for.
|
|
335
|
+
*/
|
|
336
|
+
type StyleReplayPatch = {
|
|
337
|
+
selector: string;
|
|
338
|
+
sourceId?: string | null;
|
|
339
|
+
runtimeSelector?: string | null;
|
|
340
|
+
runtimeSourceId?: string | null;
|
|
341
|
+
styles: Record<string, string>;
|
|
342
|
+
interactionState?: string;
|
|
343
|
+
};
|
|
344
|
+
|
|
328
345
|
interface DesignCanvasProps {
|
|
329
346
|
content: string;
|
|
330
347
|
contentKey?: string;
|
|
@@ -419,13 +436,12 @@ interface DesignCanvasProps {
|
|
|
419
436
|
runtimeReplacementKey?: string;
|
|
420
437
|
styleRevertRequest?: {
|
|
421
438
|
requestId: number;
|
|
422
|
-
patches: Array<
|
|
423
|
-
selector: string;
|
|
424
|
-
sourceId?: string | null;
|
|
425
|
-
styles: Record<string, string>;
|
|
426
|
-
interactionState?: string;
|
|
427
|
-
}>;
|
|
439
|
+
patches: Array<StyleReplayPatch>;
|
|
428
440
|
} | null;
|
|
441
|
+
/** Steady-state live style previews replayed after this iframe document
|
|
442
|
+
* announces readiness. Entries are screen-scoped so a sibling canvas can
|
|
443
|
+
* never receive another screen's pending edit. */
|
|
444
|
+
pendingStylePreviewPatches?: Array<StyleReplayPatch & { screenId: string }>;
|
|
429
445
|
styleBaselineResetRequest?: number | null;
|
|
430
446
|
textRevertRequest?: {
|
|
431
447
|
requestId: number;
|
|
@@ -442,6 +458,10 @@ interface DesignCanvasProps {
|
|
|
442
458
|
} | null;
|
|
443
459
|
/** One-shot host request to optimistically move a runtime-only layer. */
|
|
444
460
|
runtimeStructureMoveRequest?: RuntimeStructureMoveRequest | null;
|
|
461
|
+
/** One-shot host request to insert new markup into the running DOM. */
|
|
462
|
+
runtimeStructureInsertRequest?: RuntimeStructureInsertRequest | null;
|
|
463
|
+
/** The bridge could not honor a runtimeStructureInsertRequest. */
|
|
464
|
+
onRuntimeStructureInsertRejected?: (reason: string) => void;
|
|
445
465
|
/** Mounts a separate hidden runtime only after a guarded source hash
|
|
446
466
|
* changes. The editable iframe remains untouched and fully undoable. */
|
|
447
467
|
runtimeVerificationRequest?: RuntimeVerificationRequest | null;
|
|
@@ -501,6 +521,9 @@ interface DesignCanvasProps {
|
|
|
501
521
|
sourceRect?: { x: number; y: number; width: number; height: number };
|
|
502
522
|
anchorRect?: { x: number; y: number; width: number; height: number };
|
|
503
523
|
anchorElementInfo?: ElementInfo;
|
|
524
|
+
/** Set when the subject is markup this change introduced, not an
|
|
525
|
+
* element the running app already had. */
|
|
526
|
+
insertedHtml?: string;
|
|
504
527
|
},
|
|
505
528
|
) => boolean | "pending" | void;
|
|
506
529
|
onVisualDuplicateChange?: (
|
|
@@ -630,6 +653,7 @@ interface DesignCanvasProps {
|
|
|
630
653
|
* 100% height.
|
|
631
654
|
*/
|
|
632
655
|
previewWidthPx?: number;
|
|
656
|
+
previewHeightPx?: number;
|
|
633
657
|
/**
|
|
634
658
|
* Shader-fill CSS preview to apply to a selected element inside the iframe.
|
|
635
659
|
*
|
|
@@ -875,7 +899,7 @@ const LIVE_EDIT_SAME_INSTANCE_MAX_REARM_DELAY_MS = 16_000;
|
|
|
875
899
|
const LIVE_EDIT_SAME_INSTANCE_ERROR_CEILING_MS = 48_000;
|
|
876
900
|
|
|
877
901
|
// Successful bridge registrations belong to the localhost bridge process,
|
|
878
|
-
// not to one React DesignCanvas instance.
|
|
902
|
+
// not to one React DesignCanvas instance. Canvas -> responsive Interact
|
|
879
903
|
// replaces the overview canvas component with a focused canvas component; a
|
|
880
904
|
// component-local registration flag made that transition mount an empty
|
|
881
905
|
// srcdoc first and then replace it with the live URL after an identical POST.
|
|
@@ -1037,10 +1061,13 @@ export function DesignCanvas({
|
|
|
1037
1061
|
runtimeReplacementContent,
|
|
1038
1062
|
runtimeReplacementKey,
|
|
1039
1063
|
styleRevertRequest,
|
|
1064
|
+
pendingStylePreviewPatches,
|
|
1040
1065
|
styleBaselineResetRequest,
|
|
1041
1066
|
textRevertRequest,
|
|
1042
1067
|
structureAckRequest,
|
|
1043
1068
|
runtimeStructureMoveRequest,
|
|
1069
|
+
runtimeStructureInsertRequest,
|
|
1070
|
+
onRuntimeStructureInsertRejected,
|
|
1044
1071
|
runtimeVerificationRequest,
|
|
1045
1072
|
embeddedFrameBackground,
|
|
1046
1073
|
transparentBackground = false,
|
|
@@ -1103,6 +1130,7 @@ export function DesignCanvas({
|
|
|
1103
1130
|
motionDefaultEase,
|
|
1104
1131
|
motionDurationMs,
|
|
1105
1132
|
previewWidthPx,
|
|
1133
|
+
previewHeightPx,
|
|
1106
1134
|
onComponentSourceJump,
|
|
1107
1135
|
shaderFillPreview,
|
|
1108
1136
|
gradientEditTarget,
|
|
@@ -1176,20 +1204,82 @@ export function DesignCanvas({
|
|
|
1176
1204
|
pendingOneShotMessagesRef.current = [];
|
|
1177
1205
|
queued.forEach((message) => win.postMessage(message, "*"));
|
|
1178
1206
|
}, []);
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1207
|
+
const bridgeReadinessProbeTimerRef = useRef<number | undefined>(undefined);
|
|
1208
|
+
const probeBridgeReadinessUntilDrained = useCallback(() => {
|
|
1209
|
+
if (bridgeReadinessProbeTimerRef.current !== undefined) return;
|
|
1210
|
+
let attempts = 0;
|
|
1211
|
+
const probe = () => {
|
|
1212
|
+
const win = iframeRef.current?.contentWindow;
|
|
1213
|
+
const drained = pendingOneShotMessagesRef.current.length === 0;
|
|
1214
|
+
// 20 x 250ms covers a frame still finishing navigation without leaving a
|
|
1215
|
+
// timer running against a frame that has no bridge at all (interact-mode
|
|
1216
|
+
// documents never inject one, and must keep queueing as before).
|
|
1217
|
+
if (!win || drained || attempts >= 20) {
|
|
1218
|
+
window.clearInterval(bridgeReadinessProbeTimerRef.current);
|
|
1219
|
+
bridgeReadinessProbeTimerRef.current = undefined;
|
|
1220
|
+
return;
|
|
1221
|
+
}
|
|
1222
|
+
attempts += 1;
|
|
1223
|
+
win.postMessage(
|
|
1224
|
+
{
|
|
1225
|
+
type: "agent-native:text-edit-status",
|
|
1226
|
+
correlationId: "",
|
|
1227
|
+
nodeId: "",
|
|
1228
|
+
},
|
|
1229
|
+
"*",
|
|
1230
|
+
);
|
|
1231
|
+
};
|
|
1232
|
+
probe();
|
|
1233
|
+
if (pendingOneShotMessagesRef.current.length === 0) return;
|
|
1234
|
+
bridgeReadinessProbeTimerRef.current = window.setInterval(probe, 250);
|
|
1192
1235
|
}, []);
|
|
1236
|
+
useEffect(
|
|
1237
|
+
() => () => {
|
|
1238
|
+
if (bridgeReadinessProbeTimerRef.current !== undefined) {
|
|
1239
|
+
window.clearInterval(bridgeReadinessProbeTimerRef.current);
|
|
1240
|
+
bridgeReadinessProbeTimerRef.current = undefined;
|
|
1241
|
+
}
|
|
1242
|
+
},
|
|
1243
|
+
[],
|
|
1244
|
+
);
|
|
1245
|
+
const postOneShotBridgeMessage = useCallback(
|
|
1246
|
+
(message: unknown) => {
|
|
1247
|
+
const iframe = iframeRef.current;
|
|
1248
|
+
const win = iframe?.contentWindow;
|
|
1249
|
+
// A one-shot prop can arrive in the same render that first creates the
|
|
1250
|
+
// iframe. Keep it queued even when the ref/contentWindow is not attached
|
|
1251
|
+
// yet; otherwise the effect records its request id as handled and the
|
|
1252
|
+
// command is lost permanently before the bridge can announce readiness.
|
|
1253
|
+
if (!win || !bridgeReadyRef.current) {
|
|
1254
|
+
pendingOneShotMessagesRef.current.push(message);
|
|
1255
|
+
// The readiness recovery in the message handler below is PASSIVE: it
|
|
1256
|
+
// waits for the frame to say something first. A live-edit screen keeps
|
|
1257
|
+
// its already-loaded iframe across a canvas remount, so a replacement
|
|
1258
|
+
// instance never sees `editor-chrome-ready`, and an idle frame says
|
|
1259
|
+
// nothing on its own — every inspector style commit then sat here
|
|
1260
|
+
// reporting success while the running app never changed, until some
|
|
1261
|
+
// unrelated hover/selection happened to talk and flushed the backlog.
|
|
1262
|
+
// Ask instead of waiting: `agent-native:text-edit-status` is the
|
|
1263
|
+
// cheapest bridge round trip (no DOM walk with an empty nodeId), its
|
|
1264
|
+
// reply is a trusted message from the current frame, and that reply is
|
|
1265
|
+
// what marks the bridge ready and drains this queue. A frame with no
|
|
1266
|
+
// bridge attached simply never answers, so the queue keeps its original
|
|
1267
|
+
// meaning.
|
|
1268
|
+
// ...and keep asking. A single probe is fire-and-forget: if it lands
|
|
1269
|
+
// while the frame is mid-navigation (or before its bridge listener is
|
|
1270
|
+
// attached) nothing answers, and because the frame is otherwise idle
|
|
1271
|
+
// nothing ever asks again — the queue strands and every queued command
|
|
1272
|
+
// keeps reporting success. Undo of a live style edit is the visible
|
|
1273
|
+
// case: the revert never reaches the running app. Retry on a bounded
|
|
1274
|
+
// schedule and stop as soon as the queue drains.
|
|
1275
|
+
if (win) probeBridgeReadinessUntilDrained();
|
|
1276
|
+
return true;
|
|
1277
|
+
}
|
|
1278
|
+
win.postMessage(message, "*");
|
|
1279
|
+
return true;
|
|
1280
|
+
},
|
|
1281
|
+
[probeBridgeReadinessUntilDrained],
|
|
1282
|
+
);
|
|
1193
1283
|
const [renderedContent, setRenderedContent] = useState(content);
|
|
1194
1284
|
// True while a drawing send is capturing/compositing/uploading the
|
|
1195
1285
|
// annotated screenshot (see design-canvas/annotation-snapshot.ts). Drives
|
|
@@ -1360,8 +1450,11 @@ export function DesignCanvas({
|
|
|
1360
1450
|
);
|
|
1361
1451
|
// Keep the installed gesture script identical between overview and focused
|
|
1362
1452
|
// mode. The live flags are posted below; baking `isEmbeddedFrame` into the
|
|
1363
|
-
// script changed the bridge key during
|
|
1453
|
+
// script changed the bridge key during responsive Interact and defeated the
|
|
1364
1454
|
// registration handoff cache, forcing an avoidable iframe navigation.
|
|
1455
|
+
// interactMode remains baked: un-baking its first-paint safety flag made the
|
|
1456
|
+
// responsive iframe render blank in live verification. The live message
|
|
1457
|
+
// below is additive; it does not replace the correct initial script.
|
|
1365
1458
|
const embeddedGestureBridgeForCurrentState = useMemo(
|
|
1366
1459
|
() =>
|
|
1367
1460
|
EMBEDDED_WHEEL_BRIDGE_SCRIPT.replace(
|
|
@@ -1475,10 +1568,11 @@ export function DesignCanvas({
|
|
|
1475
1568
|
editMode,
|
|
1476
1569
|
hasLiveEditorBridge: usesLiveEditEditorBridge,
|
|
1477
1570
|
});
|
|
1478
|
-
// Null only while an entitled viewer's keyed bridge is still registering
|
|
1479
|
-
//
|
|
1480
|
-
//
|
|
1481
|
-
//
|
|
1571
|
+
// Null only while an entitled viewer's keyed bridge is still registering.
|
|
1572
|
+
// During that interval the loading surface renders without an iframe; once
|
|
1573
|
+
// registration succeeds, the one real proxied document mounts directly.
|
|
1574
|
+
// A viewer with no previewToken has no bridge to wait for, so it loads the
|
|
1575
|
+
// dev server directly rather than degrading to a snapshot.
|
|
1482
1576
|
const externalPreviewUrl =
|
|
1483
1577
|
liveEditExternalPreviewUrl ??
|
|
1484
1578
|
(usesLiveEditInjectedBridge ? null : rawExternalPreviewUrl);
|
|
@@ -2099,14 +2193,10 @@ export function DesignCanvas({
|
|
|
2099
2193
|
// switching the active surface (board ↔ screen) or toggling Edit ⇄ Preview
|
|
2100
2194
|
// never rebuilds srcdoc / reloads every screen iframe.
|
|
2101
2195
|
const srcdoc = useMemo(() => {
|
|
2102
|
-
|
|
2103
|
-
//
|
|
2104
|
-
//
|
|
2105
|
-
|
|
2106
|
-
// directly at the authenticated proxied document.
|
|
2107
|
-
if (waitingForLiveEditBridge) {
|
|
2108
|
-
return '<!doctype html><html><head><meta charset="utf-8"></head><body></body></html>';
|
|
2109
|
-
}
|
|
2196
|
+
// A URL-backed screen is never an inline document, including while its
|
|
2197
|
+
// keyed bridge registration is pending. The loading surface waits without
|
|
2198
|
+
// mounting an iframe, then mounts the real `src` exactly once.
|
|
2199
|
+
if (rawExternalPreviewUrl) return undefined;
|
|
2110
2200
|
const editorChromeBridge = interactMode
|
|
2111
2201
|
? ""
|
|
2112
2202
|
: createEditorBridgeThemeScript(readEditorBridgeThemeVars()) +
|
|
@@ -2174,16 +2264,8 @@ export function DesignCanvas({
|
|
|
2174
2264
|
contentOffsetY: embeddedFrame?.contentOffsetY ?? 0,
|
|
2175
2265
|
});
|
|
2176
2266
|
let frameDocument: string;
|
|
2177
|
-
if (
|
|
2178
|
-
frameDocument = frameContent
|
|
2179
|
-
"</body>", // i18n-ignore generated iframe HTML injection
|
|
2180
|
-
bridgeToInject + "</body>", // i18n-ignore generated iframe HTML injection
|
|
2181
|
-
); // i18n-ignore generated iframe HTML injection
|
|
2182
|
-
} else if (frameContent.includes("</html>")) {
|
|
2183
|
-
frameDocument = frameContent.replace(
|
|
2184
|
-
"</html>", // i18n-ignore generated iframe HTML injection
|
|
2185
|
-
bridgeToInject + "</html>", // i18n-ignore generated iframe HTML injection
|
|
2186
|
-
); // i18n-ignore generated iframe HTML injection
|
|
2267
|
+
if (/<\/(?:body|html)\s*>/i.test(frameContent)) {
|
|
2268
|
+
frameDocument = injectDocumentMarkup(frameContent, bridgeToInject);
|
|
2187
2269
|
} else {
|
|
2188
2270
|
// No body/html tags — wrap it
|
|
2189
2271
|
const frameStyle = [
|
|
@@ -2215,14 +2297,13 @@ export function DesignCanvas({
|
|
|
2215
2297
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2216
2298
|
}, [
|
|
2217
2299
|
boardSurface,
|
|
2218
|
-
|
|
2300
|
+
rawExternalPreviewUrl,
|
|
2219
2301
|
interactMode,
|
|
2220
2302
|
isEmbeddedFrame,
|
|
2221
2303
|
embeddedFrameBackground,
|
|
2222
2304
|
embeddedGestureBridgeForCurrentState,
|
|
2223
2305
|
iframeRenderContent,
|
|
2224
2306
|
transparentBackground,
|
|
2225
|
-
waitingForLiveEditBridge,
|
|
2226
2307
|
]);
|
|
2227
2308
|
|
|
2228
2309
|
// PERF (soak measurement 2): contentHash walks the full srcdoc string
|
|
@@ -2248,13 +2329,15 @@ export function DesignCanvas({
|
|
|
2248
2329
|
previousIframeDocumentIdentityRef.current = iframeDocumentIdentity;
|
|
2249
2330
|
bridgeReadyRef.current = false;
|
|
2250
2331
|
}
|
|
2332
|
+
// No snapshot is ever painted over the live frame, not even for the few
|
|
2333
|
+
// frames of a document swap. Covering the real iframe with a frozen copy is
|
|
2334
|
+
// the same false-success shape as rendering the snapshot outright: when the
|
|
2335
|
+
// swap stalls, the canvas keeps showing a screen that looks correct and
|
|
2336
|
+
// responds to nothing. A brief flash is the honest signal.
|
|
2251
2337
|
const liveEditDocumentPending =
|
|
2252
2338
|
usesLiveEditEditorBridge &&
|
|
2253
2339
|
Boolean(externalPreviewUrl) &&
|
|
2254
2340
|
readyIframeDocumentIdentity !== iframeDocumentIdentity;
|
|
2255
|
-
const liveEditTransitionFallbackHtml = liveEditDocumentPending
|
|
2256
|
-
? activeExternalSnapshotHtml
|
|
2257
|
-
: undefined;
|
|
2258
2341
|
|
|
2259
2342
|
// Listen for messages from the iframe
|
|
2260
2343
|
useEffect(() => {
|
|
@@ -2356,6 +2439,20 @@ export function DesignCanvas({
|
|
|
2356
2439
|
}
|
|
2357
2440
|
return;
|
|
2358
2441
|
}
|
|
2442
|
+
// Any other trusted message from the CURRENT frame proves the chrome
|
|
2443
|
+
// bridge is live in the document that is in the iframe right now.
|
|
2444
|
+
// Readiness must follow the document, not the one-time handshake: a
|
|
2445
|
+
// live-edit screen keeps its already-loaded iframe across a canvas
|
|
2446
|
+
// remount, so a later instance never sees `editor-chrome-ready` and
|
|
2447
|
+
// `bridgeReadyRef` stays false forever. Every one-shot command then
|
|
2448
|
+
// lands in `pendingOneShotMessagesRef` and nothing ever flushes it —
|
|
2449
|
+
// the drop, the text edit, the delete all report success and do
|
|
2450
|
+
// nothing. Re-derive readiness here so the queue always drains.
|
|
2451
|
+
if (trustedCurrentFrame && !bridgeReadyRef.current) {
|
|
2452
|
+
bridgeReadyRef.current = true;
|
|
2453
|
+
setReadyIframeDocumentIdentity(iframeDocumentIdentity);
|
|
2454
|
+
flushPendingOneShotMessages();
|
|
2455
|
+
}
|
|
2359
2456
|
if (e.data.type === "agent-native:runtime-layer-snapshot") {
|
|
2360
2457
|
const payload = e.data.payload;
|
|
2361
2458
|
if (
|
|
@@ -2525,6 +2622,10 @@ export function DesignCanvas({
|
|
|
2525
2622
|
}
|
|
2526
2623
|
return;
|
|
2527
2624
|
}
|
|
2625
|
+
if (e.data.type === "runtime-structure-insert-rejected") {
|
|
2626
|
+
onRuntimeStructureInsertRejected?.(String(e.data.reason || "unknown"));
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2528
2629
|
if (e.data.type === "visual-structure-change") {
|
|
2529
2630
|
const selector = String(e.data.selector || "");
|
|
2530
2631
|
const anchorSelector = String(e.data.anchorSelector || "");
|
|
@@ -2600,6 +2701,10 @@ export function DesignCanvas({
|
|
|
2600
2701
|
anchorElementInfo: isElementInfoPayload(e.data.anchorPayload)
|
|
2601
2702
|
? e.data.anchorPayload
|
|
2602
2703
|
: undefined,
|
|
2704
|
+
insertedHtml:
|
|
2705
|
+
typeof e.data.insertedHtml === "string"
|
|
2706
|
+
? e.data.insertedHtml
|
|
2707
|
+
: undefined,
|
|
2603
2708
|
},
|
|
2604
2709
|
);
|
|
2605
2710
|
dndHostLog("persist:result", {
|
|
@@ -2933,6 +3038,7 @@ export function DesignCanvas({
|
|
|
2933
3038
|
onIframeContextMenu,
|
|
2934
3039
|
onEditorDragStateChange,
|
|
2935
3040
|
onVisualStructureChange,
|
|
3041
|
+
onRuntimeStructureInsertRejected,
|
|
2936
3042
|
onVisualDuplicateChange,
|
|
2937
3043
|
onZoomChange,
|
|
2938
3044
|
deviceFrame,
|
|
@@ -3274,15 +3380,33 @@ export function DesignCanvas({
|
|
|
3274
3380
|
]);
|
|
3275
3381
|
|
|
3276
3382
|
// Overview/focused placement is presentation state, not document identity.
|
|
3277
|
-
// Update gesture routing in place
|
|
3383
|
+
// Update gesture routing in place when entering responsive Interact.
|
|
3278
3384
|
// registered bridge key instead of rebuilding the injected script.
|
|
3385
|
+
//
|
|
3386
|
+
// readyIframeDocumentIdentity is a dep purely to re-fire this on every
|
|
3387
|
+
// (re)ready handshake: a document swap resets bridgeReadyRef and wipes
|
|
3388
|
+
// pendingOneShotMessagesRef (see the contentKey-change effect above), which
|
|
3389
|
+
// silently drops this message if it was still queued when the swap
|
|
3390
|
+
// happened. Its own value isn't read here — only bridgeReadyRef.current
|
|
3391
|
+
// (already true by the time the ready handler flips this state) matters,
|
|
3392
|
+
// so re-running always sends live instead of re-queuing into the
|
|
3393
|
+
// just-cleared queue.
|
|
3279
3394
|
useEffect(() => {
|
|
3280
3395
|
postOneShotBridgeMessage({
|
|
3281
3396
|
type: "embedded-canvas-gesture-mode",
|
|
3282
3397
|
wheelEnabled: isEmbeddedFrame,
|
|
3283
3398
|
spaceKeyForwardingEnabled: interactMode || readOnly,
|
|
3399
|
+
// Interact hands the app its own native interaction back; every other
|
|
3400
|
+
// mode keeps the editing shield armed.
|
|
3401
|
+
editingSafetyEnabled: !interactMode,
|
|
3284
3402
|
});
|
|
3285
|
-
}, [
|
|
3403
|
+
}, [
|
|
3404
|
+
interactMode,
|
|
3405
|
+
isEmbeddedFrame,
|
|
3406
|
+
postOneShotBridgeMessage,
|
|
3407
|
+
readOnly,
|
|
3408
|
+
readyIframeDocumentIdentity,
|
|
3409
|
+
]);
|
|
3286
3410
|
|
|
3287
3411
|
// The board iframe is a finite paint window over an infinite logical
|
|
3288
3412
|
// canvas. Re-centering that window must update its CSS/bridge coordinate
|
|
@@ -3478,8 +3602,8 @@ export function DesignCanvas({
|
|
|
3478
3602
|
options?: { selectorCandidates?: string[]; nodeId?: string | null },
|
|
3479
3603
|
) => {
|
|
3480
3604
|
const iframe = iframeRef.current;
|
|
3481
|
-
if (!iframe?.contentWindow) return;
|
|
3482
|
-
postOneShotBridgeMessage({
|
|
3605
|
+
if (!iframe?.contentWindow) return false;
|
|
3606
|
+
return postOneShotBridgeMessage({
|
|
3483
3607
|
type: "style-change",
|
|
3484
3608
|
selector,
|
|
3485
3609
|
property,
|
|
@@ -3490,6 +3614,19 @@ export function DesignCanvas({
|
|
|
3490
3614
|
},
|
|
3491
3615
|
[postOneShotBridgeMessage],
|
|
3492
3616
|
);
|
|
3617
|
+
const sendStyleChangeForScreen = useCallback(
|
|
3618
|
+
(
|
|
3619
|
+
targetScreenId: string,
|
|
3620
|
+
selector: string,
|
|
3621
|
+
property: string,
|
|
3622
|
+
value: string,
|
|
3623
|
+
options?: { selectorCandidates?: string[]; nodeId?: string | null },
|
|
3624
|
+
) => {
|
|
3625
|
+
if (!screenId || targetScreenId !== screenId) return false;
|
|
3626
|
+
return sendStyleChange(selector, property, value, options);
|
|
3627
|
+
},
|
|
3628
|
+
[screenId, sendStyleChange],
|
|
3629
|
+
);
|
|
3493
3630
|
|
|
3494
3631
|
const sendInteractionStatePreviewStyle = useCallback(
|
|
3495
3632
|
(args: {
|
|
@@ -3512,46 +3649,57 @@ export function DesignCanvas({
|
|
|
3512
3649
|
);
|
|
3513
3650
|
|
|
3514
3651
|
const lastStyleRevertRequestIdRef = useRef<number | null>(null);
|
|
3652
|
+
const replayStylePatches = useCallback(
|
|
3653
|
+
(patches: Array<StyleReplayPatch>) => {
|
|
3654
|
+
for (const patch of patches) {
|
|
3655
|
+
const target = runtimeStyleTarget(patch);
|
|
3656
|
+
if (target.selectorCandidates.length === 0) continue;
|
|
3657
|
+
if (patch.interactionState) {
|
|
3658
|
+
sendInteractionStatePreviewStyle({
|
|
3659
|
+
selector: target.selector,
|
|
3660
|
+
selectorCandidates: target.selectorCandidates,
|
|
3661
|
+
nodeId: target.nodeId,
|
|
3662
|
+
state: patch.interactionState,
|
|
3663
|
+
styles: patch.styles,
|
|
3664
|
+
});
|
|
3665
|
+
continue;
|
|
3666
|
+
}
|
|
3667
|
+
for (const [property, value] of Object.entries(patch.styles)) {
|
|
3668
|
+
postOneShotBridgeMessage({
|
|
3669
|
+
type: "style-change",
|
|
3670
|
+
selector: target.selector,
|
|
3671
|
+
property,
|
|
3672
|
+
value,
|
|
3673
|
+
selectorCandidates: target.selectorCandidates,
|
|
3674
|
+
nodeId: target.nodeId ?? "",
|
|
3675
|
+
});
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
},
|
|
3679
|
+
[postOneShotBridgeMessage, sendInteractionStatePreviewStyle],
|
|
3680
|
+
);
|
|
3515
3681
|
useEffect(() => {
|
|
3516
3682
|
if (!styleRevertRequest) return;
|
|
3517
3683
|
if (lastStyleRevertRequestIdRef.current === styleRevertRequest.requestId) {
|
|
3518
3684
|
return;
|
|
3519
3685
|
}
|
|
3520
3686
|
lastStyleRevertRequestIdRef.current = styleRevertRequest.requestId;
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
sendInteractionStatePreviewStyle({
|
|
3532
|
-
selector: patch.selector,
|
|
3533
|
-
selectorCandidates,
|
|
3534
|
-
nodeId: patch.sourceId,
|
|
3535
|
-
state: patch.interactionState,
|
|
3536
|
-
styles: patch.styles,
|
|
3537
|
-
});
|
|
3538
|
-
continue;
|
|
3539
|
-
}
|
|
3540
|
-
for (const [property, value] of Object.entries(patch.styles)) {
|
|
3541
|
-
postOneShotBridgeMessage({
|
|
3542
|
-
type: "style-change",
|
|
3543
|
-
selector: patch.selector,
|
|
3544
|
-
property,
|
|
3545
|
-
value,
|
|
3546
|
-
selectorCandidates,
|
|
3547
|
-
nodeId: patch.sourceId ?? "",
|
|
3548
|
-
});
|
|
3549
|
-
}
|
|
3550
|
-
}
|
|
3687
|
+
replayStylePatches(styleRevertRequest.patches);
|
|
3688
|
+
}, [replayStylePatches, styleRevertRequest]);
|
|
3689
|
+
|
|
3690
|
+
useEffect(() => {
|
|
3691
|
+
if (!screenId) return;
|
|
3692
|
+
replayStylePatches(
|
|
3693
|
+
(pendingStylePreviewPatches ?? []).filter(
|
|
3694
|
+
(patch) => patch.screenId === screenId,
|
|
3695
|
+
),
|
|
3696
|
+
);
|
|
3551
3697
|
}, [
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3698
|
+
contentKey,
|
|
3699
|
+
pendingStylePreviewPatches,
|
|
3700
|
+
readyIframeDocumentIdentity,
|
|
3701
|
+
replayStylePatches,
|
|
3702
|
+
screenId,
|
|
3555
3703
|
]);
|
|
3556
3704
|
|
|
3557
3705
|
const lastStyleBaselineResetRequestRef = useRef<number | null>(null);
|
|
@@ -3635,6 +3783,28 @@ export function DesignCanvas({
|
|
|
3635
3783
|
});
|
|
3636
3784
|
}, [postOneShotBridgeMessage, runtimeStructureMoveRequest]);
|
|
3637
3785
|
|
|
3786
|
+
const lastRuntimeStructureInsertRequestIdRef = useRef<number | null>(null);
|
|
3787
|
+
useEffect(() => {
|
|
3788
|
+
if (!runtimeStructureInsertRequest) return;
|
|
3789
|
+
if (
|
|
3790
|
+
lastRuntimeStructureInsertRequestIdRef.current ===
|
|
3791
|
+
runtimeStructureInsertRequest.requestId
|
|
3792
|
+
) {
|
|
3793
|
+
return;
|
|
3794
|
+
}
|
|
3795
|
+
lastRuntimeStructureInsertRequestIdRef.current =
|
|
3796
|
+
runtimeStructureInsertRequest.requestId;
|
|
3797
|
+
postOneShotBridgeMessage({
|
|
3798
|
+
type: "runtime-structure-insert",
|
|
3799
|
+
requestId: runtimeStructureInsertRequest.requestId,
|
|
3800
|
+
html: runtimeStructureInsertRequest.html,
|
|
3801
|
+
anchorSelector: runtimeStructureInsertRequest.anchor.selector,
|
|
3802
|
+
anchorSourceId: runtimeStructureInsertRequest.anchor.sourceId,
|
|
3803
|
+
anchorPendingNodeId: runtimeStructureInsertRequest.anchor.pendingNodeId,
|
|
3804
|
+
placement: runtimeStructureInsertRequest.placement,
|
|
3805
|
+
});
|
|
3806
|
+
}, [postOneShotBridgeMessage, runtimeStructureInsertRequest]);
|
|
3807
|
+
|
|
3638
3808
|
/**
|
|
3639
3809
|
* Send a motion-preview scrub tick to the iframe. `t` is the normalised
|
|
3640
3810
|
* playhead position in [0, 1]. Tracks must have been loaded first via the
|
|
@@ -3839,13 +4009,21 @@ export function DesignCanvas({
|
|
|
3839
4009
|
}, [replaceRuntimeContentInPlace, runtimeReplacementEnabled]);
|
|
3840
4010
|
|
|
3841
4011
|
const deleteRuntimeElement = useCallback(
|
|
3842
|
-
(
|
|
4012
|
+
(
|
|
4013
|
+
selector?: string | null,
|
|
4014
|
+
candidates?: string[],
|
|
4015
|
+
// Present when the host queued this deletion as a pending live edit; the
|
|
4016
|
+
// bridge keeps the detached node under this id so a later
|
|
4017
|
+
// visual-structure-ack with applied:false can put it back.
|
|
4018
|
+
requestId?: string,
|
|
4019
|
+
) => {
|
|
3843
4020
|
const iframe = iframeRef.current;
|
|
3844
4021
|
if (!iframe?.contentWindow) return false;
|
|
3845
4022
|
return postOneShotBridgeMessage({
|
|
3846
4023
|
type: "delete-element",
|
|
3847
4024
|
selector: selector ?? "",
|
|
3848
4025
|
selectorCandidates: candidates ?? [],
|
|
4026
|
+
requestId,
|
|
3849
4027
|
});
|
|
3850
4028
|
},
|
|
3851
4029
|
[postOneShotBridgeMessage],
|
|
@@ -3855,6 +4033,7 @@ export function DesignCanvas({
|
|
|
3855
4033
|
useEffect(() => {
|
|
3856
4034
|
if (!registerRuntimeBridge) return;
|
|
3857
4035
|
(window as any).__designCanvasSendStyle = sendStyleChange;
|
|
4036
|
+
(window as any).__designCanvasSendStyleForScreen = sendStyleChangeForScreen;
|
|
3858
4037
|
(window as any).__designCanvasSendInteractionStatePreviewStyle =
|
|
3859
4038
|
sendInteractionStatePreviewStyle;
|
|
3860
4039
|
(window as any).__designCanvasReplaceContent =
|
|
@@ -3875,6 +4054,12 @@ export function DesignCanvas({
|
|
|
3875
4054
|
if ((window as any).__designCanvasSendStyle === sendStyleChange) {
|
|
3876
4055
|
delete (window as any).__designCanvasSendStyle;
|
|
3877
4056
|
}
|
|
4057
|
+
if (
|
|
4058
|
+
(window as any).__designCanvasSendStyleForScreen ===
|
|
4059
|
+
sendStyleChangeForScreen
|
|
4060
|
+
) {
|
|
4061
|
+
delete (window as any).__designCanvasSendStyleForScreen;
|
|
4062
|
+
}
|
|
3878
4063
|
if (
|
|
3879
4064
|
(window as any).__designCanvasSendInteractionStatePreviewStyle ===
|
|
3880
4065
|
sendInteractionStatePreviewStyle
|
|
@@ -3921,6 +4106,7 @@ export function DesignCanvas({
|
|
|
3921
4106
|
}, [
|
|
3922
4107
|
deleteRuntimeElement,
|
|
3923
4108
|
registerRuntimeBridge,
|
|
4109
|
+
sendStyleChangeForScreen,
|
|
3924
4110
|
replacePreviewContentFromHost,
|
|
3925
4111
|
sendStyleChange,
|
|
3926
4112
|
sendInteractionStatePreviewStyle,
|
|
@@ -3959,6 +4145,12 @@ export function DesignCanvas({
|
|
|
3959
4145
|
previewWidthPx !== null && previewWidthPx !== undefined
|
|
3960
4146
|
? `${previewWidthPx}px`
|
|
3961
4147
|
: iframeWidth;
|
|
4148
|
+
const resolvedHeight =
|
|
4149
|
+
previewHeightPx !== null && previewHeightPx !== undefined
|
|
4150
|
+
? `${previewHeightPx}px`
|
|
4151
|
+
: deviceFrame === "none"
|
|
4152
|
+
? "100%"
|
|
4153
|
+
: (iframeHeight ?? undefined);
|
|
3962
4154
|
const focusScrollSurface = useCallback(() => {
|
|
3963
4155
|
const surface = scrollContainerRef.current;
|
|
3964
4156
|
if (!surface || document.activeElement === surface) return;
|
|
@@ -4147,9 +4339,7 @@ export function DesignCanvas({
|
|
|
4147
4339
|
? embeddedFrameFluid
|
|
4148
4340
|
? "100%"
|
|
4149
4341
|
: embeddedFrame.viewportHeight
|
|
4150
|
-
:
|
|
4151
|
-
? "100%"
|
|
4152
|
-
: (iframeHeight ?? undefined),
|
|
4342
|
+
: resolvedHeight,
|
|
4153
4343
|
// BP-DEEP item 2: when a breakpoint chip constrains the viewport
|
|
4154
4344
|
// (previewWidthPx) the wrapper is NARROWER than the canvas, so there
|
|
4155
4345
|
// is no horizontal overflow for the scroll-centering effect above to
|
|
@@ -4191,55 +4381,39 @@ export function DesignCanvas({
|
|
|
4191
4381
|
)}
|
|
4192
4382
|
/>
|
|
4193
4383
|
) : null}
|
|
4194
|
-
{
|
|
4384
|
+
{rawExternalPreviewUrl && !externalPreviewUrl ? null : (
|
|
4195
4385
|
<iframe
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4386
|
+
key={iframeDocumentIdentity}
|
|
4387
|
+
ref={iframeRef}
|
|
4388
|
+
src={externalPreviewUrl ?? undefined}
|
|
4389
|
+
srcDoc={externalPreviewUrl ? undefined : srcdoc}
|
|
4390
|
+
sandbox={getDesignCanvasIframeSandbox({
|
|
4391
|
+
externalPreview: Boolean(externalPreviewUrl),
|
|
4392
|
+
readOnly,
|
|
4393
|
+
})}
|
|
4394
|
+
data-design-preview-iframe
|
|
4395
|
+
{...{
|
|
4396
|
+
[SESSION_REPLAY_IFRAME_ATTRIBUTE]: !externalPreviewUrl
|
|
4397
|
+
? ""
|
|
4398
|
+
: undefined,
|
|
4399
|
+
}}
|
|
4400
|
+
data-screen-iframe-id={
|
|
4401
|
+
boardSurface ? undefined : (previewFrameId ?? screenId ?? undefined)
|
|
4402
|
+
}
|
|
4403
|
+
data-design-source-type={
|
|
4404
|
+
sourceType ??
|
|
4405
|
+
(externalPreviewUrl
|
|
4406
|
+
? "localhost" // inferred — content is a URL
|
|
4407
|
+
: "inline")
|
|
4408
|
+
}
|
|
4409
|
+
className="relative block h-full w-full border-0 bg-transparent"
|
|
4202
4410
|
style={{
|
|
4203
4411
|
background: iframeBackgroundColor,
|
|
4204
4412
|
backgroundColor: iframeBackgroundColor,
|
|
4205
4413
|
}}
|
|
4206
|
-
title=""
|
|
4414
|
+
title={t("designEditor.designPreview")}
|
|
4207
4415
|
/>
|
|
4208
|
-
)
|
|
4209
|
-
<iframe
|
|
4210
|
-
key={iframeDocumentIdentity}
|
|
4211
|
-
ref={iframeRef}
|
|
4212
|
-
src={externalPreviewUrl ?? undefined}
|
|
4213
|
-
srcDoc={externalPreviewUrl ? undefined : srcdoc}
|
|
4214
|
-
sandbox={getDesignCanvasIframeSandbox({
|
|
4215
|
-
externalPreview: Boolean(externalPreviewUrl),
|
|
4216
|
-
readOnly,
|
|
4217
|
-
})}
|
|
4218
|
-
data-design-preview-iframe
|
|
4219
|
-
{...{
|
|
4220
|
-
[SESSION_REPLAY_IFRAME_ATTRIBUTE]: !externalPreviewUrl
|
|
4221
|
-
? ""
|
|
4222
|
-
: undefined,
|
|
4223
|
-
}}
|
|
4224
|
-
data-screen-iframe-id={
|
|
4225
|
-
boardSurface ? undefined : (previewFrameId ?? screenId ?? undefined)
|
|
4226
|
-
}
|
|
4227
|
-
data-design-source-type={
|
|
4228
|
-
sourceType ??
|
|
4229
|
-
(externalPreviewUrl
|
|
4230
|
-
? "localhost" // inferred — content is a URL
|
|
4231
|
-
: "inline")
|
|
4232
|
-
}
|
|
4233
|
-
className={cn(
|
|
4234
|
-
"relative block h-full w-full border-0 bg-transparent",
|
|
4235
|
-
liveEditTransitionFallbackHtml && "pointer-events-none opacity-0",
|
|
4236
|
-
)}
|
|
4237
|
-
style={{
|
|
4238
|
-
background: iframeBackgroundColor,
|
|
4239
|
-
backgroundColor: iframeBackgroundColor,
|
|
4240
|
-
}}
|
|
4241
|
-
title={t("designEditor.designPreview")}
|
|
4242
|
-
/>
|
|
4416
|
+
)}
|
|
4243
4417
|
{runtimeVerificationUrl ? (
|
|
4244
4418
|
<iframe
|
|
4245
4419
|
key={`${runtimeVerificationUrl}::${runtimeVerificationRequest?.requestId ?? 0}`}
|
|
@@ -4335,7 +4509,7 @@ export function DesignCanvas({
|
|
|
4335
4509
|
) : null}
|
|
4336
4510
|
{waitingForEditableExternalSnapshot ||
|
|
4337
4511
|
waitingForLiveEditBridge ||
|
|
4338
|
-
|
|
4512
|
+
liveEditDocumentPending ? (
|
|
4339
4513
|
<div className="pointer-events-auto absolute inset-0 z-10 flex items-center justify-center bg-background/85 px-4 text-center text-sm text-muted-foreground">
|
|
4340
4514
|
{waitingForLiveEditBridge &&
|
|
4341
4515
|
bridgeRegistrationError?.bridgeKey === liveEditBridgeKey ? (
|