@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
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
utilityStem,
|
|
16
16
|
} from "@shared/responsive-classes";
|
|
17
17
|
import {
|
|
18
|
+
type ElementProvenanceUnavailableReason,
|
|
18
19
|
normalizeDesignSourceType,
|
|
19
20
|
type DesignSourceType,
|
|
20
21
|
} from "@shared/source-mode";
|
|
@@ -23,6 +24,7 @@ import type { ElementInfo } from "@/components/design/types";
|
|
|
23
24
|
|
|
24
25
|
import {
|
|
25
26
|
buildReactSemanticHandoff,
|
|
27
|
+
buildRuntimeReactLayerStateHandoff,
|
|
26
28
|
redactReactSourceAnchor,
|
|
27
29
|
type ReactSourceAnchor,
|
|
28
30
|
type ReactSourceScope,
|
|
@@ -35,6 +37,19 @@ export interface PendingVisualStyleEdit {
|
|
|
35
37
|
screenName: string;
|
|
36
38
|
selector: string;
|
|
37
39
|
sourceId?: string | null;
|
|
40
|
+
/**
|
|
41
|
+
* The selector/node id the canvas bridge reported, kept when the host
|
|
42
|
+
* canonicalized the selection onto its source projection
|
|
43
|
+
* (canonicalElementInfoForCodeLayerNode). A localhost screen runs two
|
|
44
|
+
* disjoint node-id namespaces: the injected bridge stamps `runtime-…` ids on
|
|
45
|
+
* the live document, while the host stamps `an-…` ids on the source html it
|
|
46
|
+
* fetched separately. Only this pair addresses the running app, so every
|
|
47
|
+
* replay into the live frame must prefer it. Absent for inline/snapshot
|
|
48
|
+
* screens, where the bridge reuses the ids already in the document and the
|
|
49
|
+
* two pairs are the same value.
|
|
50
|
+
*/
|
|
51
|
+
runtimeSelector?: string | null;
|
|
52
|
+
runtimeSourceId?: string | null;
|
|
38
53
|
sourceAnchor?: ReactSourceAnchor;
|
|
39
54
|
tagName?: string | null;
|
|
40
55
|
classes: string[];
|
|
@@ -72,7 +87,7 @@ export interface PendingVisualStyleEdit {
|
|
|
72
87
|
};
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
function
|
|
90
|
+
function pendingLiveEditSubjectKey(edit: PendingLiveNonStyleEdit): string {
|
|
76
91
|
return `${edit.screenId}:${edit.sourceId?.trim() || edit.selector.trim()}`;
|
|
77
92
|
}
|
|
78
93
|
|
|
@@ -82,14 +97,56 @@ export function mergePendingLiveNonStyleEdits(
|
|
|
82
97
|
const merged: PendingLiveNonStyleEdit[] = [];
|
|
83
98
|
for (const edit of edits) {
|
|
84
99
|
if (edit.kind === "structure") {
|
|
100
|
+
// Deleting a node this session INSERTED nets to zero in source: the
|
|
101
|
+
// markup was never written there. Queuing both would hand the coding
|
|
102
|
+
// agent markup to add plus a node to delete, and an apply that runs the
|
|
103
|
+
// insert can resurrect exactly what the user deleted. Both entries stay
|
|
104
|
+
// on the undo stack, so undoing the delete re-queues the insertion.
|
|
105
|
+
const supersededInsertIndex = edit.removed
|
|
106
|
+
? merged.findIndex(
|
|
107
|
+
(candidate) =>
|
|
108
|
+
candidate.kind === "structure" &&
|
|
109
|
+
Boolean(candidate.insertedHtml) &&
|
|
110
|
+
pendingLiveEditSubjectKey(candidate) ===
|
|
111
|
+
pendingLiveEditSubjectKey(edit),
|
|
112
|
+
)
|
|
113
|
+
: -1;
|
|
114
|
+
if (supersededInsertIndex !== -1) {
|
|
115
|
+
merged.splice(supersededInsertIndex, 1);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
85
118
|
merged.push(edit);
|
|
86
119
|
continue;
|
|
87
120
|
}
|
|
88
|
-
|
|
121
|
+
if (edit.kind === "layer-state") {
|
|
122
|
+
const nextKey = `${pendingLiveEditSubjectKey(edit)}:${edit.state}`;
|
|
123
|
+
const index = merged.findIndex(
|
|
124
|
+
(candidate) =>
|
|
125
|
+
candidate.kind === "layer-state" &&
|
|
126
|
+
`${pendingLiveEditSubjectKey(candidate)}:${candidate.state}` ===
|
|
127
|
+
nextKey,
|
|
128
|
+
);
|
|
129
|
+
if (index === -1) {
|
|
130
|
+
merged.push(edit);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const previous = merged[index] as PendingLiveLayerStateEdit;
|
|
134
|
+
if (previous.originalEnabled === edit.enabled) {
|
|
135
|
+
merged.splice(index, 1);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
merged[index] = {
|
|
139
|
+
...previous,
|
|
140
|
+
...edit,
|
|
141
|
+
originalEnabled: previous.originalEnabled,
|
|
142
|
+
};
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const nextKey = pendingLiveEditSubjectKey(edit);
|
|
89
146
|
const index = merged.findIndex(
|
|
90
147
|
(candidate) =>
|
|
91
148
|
candidate.kind === "text" &&
|
|
92
|
-
|
|
149
|
+
pendingLiveEditSubjectKey(candidate) === nextKey,
|
|
93
150
|
);
|
|
94
151
|
if (index === -1) {
|
|
95
152
|
merged.push(edit);
|
|
@@ -113,7 +170,7 @@ export function pendingLiveTextUndoRevertValue(
|
|
|
113
170
|
const currentForTarget = currentEdits.find(
|
|
114
171
|
(edit): edit is PendingLiveTextEdit =>
|
|
115
172
|
edit.kind === "text" &&
|
|
116
|
-
|
|
173
|
+
pendingLiveEditSubjectKey(edit) === pendingLiveEditSubjectKey(nextEdit),
|
|
117
174
|
);
|
|
118
175
|
return currentForTarget
|
|
119
176
|
? { value: currentForTarget.value, html: currentForTarget.html }
|
|
@@ -137,6 +194,46 @@ export interface PendingLiveTextEdit {
|
|
|
137
194
|
updatedAt: number;
|
|
138
195
|
}
|
|
139
196
|
|
|
197
|
+
export interface PendingLiveLayerStateEdit {
|
|
198
|
+
kind: "layer-state";
|
|
199
|
+
screenId: string;
|
|
200
|
+
filename: string;
|
|
201
|
+
screenName: string;
|
|
202
|
+
layerId: string;
|
|
203
|
+
selector: string;
|
|
204
|
+
sourceId?: string | null;
|
|
205
|
+
sourceAnchor?: ReactSourceAnchor;
|
|
206
|
+
tagName?: string | null;
|
|
207
|
+
classes: string[];
|
|
208
|
+
state: "hidden" | "locked";
|
|
209
|
+
enabled: boolean;
|
|
210
|
+
originalEnabled: boolean;
|
|
211
|
+
updatedAt: number;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function pendingLiveLayerStateUndoRevertValue(
|
|
215
|
+
currentEdits: readonly PendingLiveNonStyleEdit[],
|
|
216
|
+
nextEdit: PendingLiveLayerStateEdit,
|
|
217
|
+
): boolean {
|
|
218
|
+
const currentForTarget = currentEdits.find(
|
|
219
|
+
(edit): edit is PendingLiveLayerStateEdit =>
|
|
220
|
+
edit.kind === "layer-state" &&
|
|
221
|
+
edit.state === nextEdit.state &&
|
|
222
|
+
pendingLiveEditSubjectKey(edit) === pendingLiveEditSubjectKey(nextEdit),
|
|
223
|
+
);
|
|
224
|
+
return currentForTarget?.enabled ?? nextEdit.originalEnabled;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function shouldRedoPendingLiveNonStyleBeforeStyle(
|
|
228
|
+
styleEntry: { edit: { updatedAt: number } } | undefined,
|
|
229
|
+
nonStyleEntry: { edit: { updatedAt: number } } | undefined,
|
|
230
|
+
): boolean {
|
|
231
|
+
return Boolean(
|
|
232
|
+
nonStyleEntry &&
|
|
233
|
+
(!styleEntry || nonStyleEntry.edit.updatedAt < styleEntry.edit.updatedAt),
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
140
237
|
export interface PendingLiveStructureEdit {
|
|
141
238
|
kind: "structure";
|
|
142
239
|
screenId: string;
|
|
@@ -148,6 +245,13 @@ export interface PendingLiveStructureEdit {
|
|
|
148
245
|
anchorSelector: string;
|
|
149
246
|
anchorSourceId?: string | null;
|
|
150
247
|
anchorSourceAnchor?: ReactSourceAnchor;
|
|
248
|
+
/**
|
|
249
|
+
* Project-relative route module reported by the localhost manifest. A
|
|
250
|
+
* top-level canvas insert targets the live document body, which intentionally
|
|
251
|
+
* has no framework element provenance; this keeps Apply bounded to the route
|
|
252
|
+
* source without inventing a fake body line/column.
|
|
253
|
+
*/
|
|
254
|
+
routeSourceFile?: string;
|
|
151
255
|
placement: "before" | "after" | "inside";
|
|
152
256
|
/** Runtime layout semantics captured at drop time. These are required for
|
|
153
257
|
* the coding agent to distinguish a flow/auto-layout insertion from an
|
|
@@ -156,6 +260,20 @@ export interface PendingLiveStructureEdit {
|
|
|
156
260
|
forceFlowPositionOverride?: boolean;
|
|
157
261
|
sourceRect?: { x: number; y: number; width: number; height: number };
|
|
158
262
|
anchorRect?: { x: number; y: number; width: number; height: number };
|
|
263
|
+
/**
|
|
264
|
+
* Markup this edit ADDED to the running app. Present only for a drop whose
|
|
265
|
+
* subject had no counterpart in the screen's source, so the coding agent
|
|
266
|
+
* must insert this markup rather than relocate an existing element.
|
|
267
|
+
*/
|
|
268
|
+
insertedHtml?: string;
|
|
269
|
+
/**
|
|
270
|
+
* This edit DELETED the subject from the running app. A removal has no
|
|
271
|
+
* anchor — `anchorSelector`/`placement` carry no meaning for it — so every
|
|
272
|
+
* consumer that pairs a subject with a target (the semantic handoff, the
|
|
273
|
+
* source-path collection before apply, runtime verification) must branch on
|
|
274
|
+
* this instead of reading anchor fields that were never captured.
|
|
275
|
+
*/
|
|
276
|
+
removed?: true;
|
|
159
277
|
requestId?: string;
|
|
160
278
|
updatedAt: number;
|
|
161
279
|
}
|
|
@@ -258,6 +376,18 @@ function sourcePathRelativeToRoot(args: {
|
|
|
258
376
|
return normalizeResolvablePath(relative)?.value;
|
|
259
377
|
}
|
|
260
378
|
|
|
379
|
+
export function projectRelativeSourcePath(args: {
|
|
380
|
+
sourceFile?: string;
|
|
381
|
+
rootPath?: string;
|
|
382
|
+
}): string | undefined {
|
|
383
|
+
const sourceFile = args.sourceFile?.trim();
|
|
384
|
+
if (!sourceFile) return undefined;
|
|
385
|
+
return sourcePathRelativeToRoot({
|
|
386
|
+
sourceFile,
|
|
387
|
+
rootPath: args.rootPath,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
261
391
|
export function reactSourceAnchorForPendingEdit(args: {
|
|
262
392
|
info?: Pick<ElementInfo, "provenance" | "sourceId" | "selector"> | null;
|
|
263
393
|
id?: string;
|
|
@@ -278,6 +408,13 @@ export function reactSourceAnchorForPendingEdit(args: {
|
|
|
278
408
|
sourceFile,
|
|
279
409
|
rootPath: args.rootPath,
|
|
280
410
|
});
|
|
411
|
+
const ownerSourceFile = provenance.ownerSourceFile?.trim();
|
|
412
|
+
const ownerRelPath = ownerSourceFile
|
|
413
|
+
? sourcePathRelativeToRoot({
|
|
414
|
+
sourceFile: ownerSourceFile,
|
|
415
|
+
rootPath: args.rootPath,
|
|
416
|
+
})
|
|
417
|
+
: undefined;
|
|
281
418
|
return {
|
|
282
419
|
id:
|
|
283
420
|
args.id?.trim() ||
|
|
@@ -291,7 +428,26 @@ export function reactSourceAnchorForPendingEdit(args: {
|
|
|
291
428
|
...(relPath ? { relPath } : {}),
|
|
292
429
|
line: provenance.line,
|
|
293
430
|
column: provenance.column,
|
|
431
|
+
// Which tier produced line/column, so no consumer can read a React 19
|
|
432
|
+
// owner-stack (transformed) position as the authored JSX line.
|
|
433
|
+
...(provenance.method ? { method: provenance.method } : {}),
|
|
294
434
|
component: provenance.component,
|
|
435
|
+
// The nearest component's INSTANTIATION site — the `.map()` call site for a
|
|
436
|
+
// mapped instance. Dropping it here is what left the handoff unable to say
|
|
437
|
+
// where a mapped sibling actually comes from.
|
|
438
|
+
...(ownerSourceFile ? { ownerSourceFile } : {}),
|
|
439
|
+
...(ownerRelPath ? { ownerRelPath } : {}),
|
|
440
|
+
...(provenance.ownerLine ? { ownerLine: provenance.ownerLine } : {}),
|
|
441
|
+
...(provenance.ownerColumn ? { ownerColumn: provenance.ownerColumn } : {}),
|
|
442
|
+
...(provenance.ownerComponentName
|
|
443
|
+
? { ownerComponent: provenance.ownerComponentName }
|
|
444
|
+
: {}),
|
|
445
|
+
// The owner's own tier: a data-attribute element can still owe its owner
|
|
446
|
+
// line to a transformed owner stack.
|
|
447
|
+
...(provenance.ownerMethod ? { ownerMethod: provenance.ownerMethod } : {}),
|
|
448
|
+
// Every `.map()` sibling shares one call site, so runtimeMultiplicity alone
|
|
449
|
+
// cannot say WHICH instance was selected; the React key can.
|
|
450
|
+
...(provenance.ownerKey ? { ownerKey: provenance.ownerKey } : {}),
|
|
295
451
|
runtimeMultiplicity,
|
|
296
452
|
...(args.reason?.trim() ? { reason: args.reason.trim() } : {}),
|
|
297
453
|
scope:
|
|
@@ -299,8 +455,26 @@ export function reactSourceAnchorForPendingEdit(args: {
|
|
|
299
455
|
};
|
|
300
456
|
}
|
|
301
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Why an anchor could not be built: a runtime that reports it exposes no
|
|
460
|
+
* source locations at all is a permanent answer, not a slow one. Returns
|
|
461
|
+
* undefined when nothing has reported a reason yet — that case is still
|
|
462
|
+
* "loading", and callers must not present it as unsupported.
|
|
463
|
+
*/
|
|
464
|
+
export function reactSourceAnchorUnavailableReason(
|
|
465
|
+
infos: ReadonlyArray<Pick<ElementInfo, "provenance"> | null | undefined>,
|
|
466
|
+
): ElementProvenanceUnavailableReason | undefined {
|
|
467
|
+
for (const info of infos) {
|
|
468
|
+
const provenance = info?.provenance;
|
|
469
|
+
if (provenance?.sourceFile) continue;
|
|
470
|
+
if (provenance?.unavailableReason) return provenance.unavailableReason;
|
|
471
|
+
}
|
|
472
|
+
return undefined;
|
|
473
|
+
}
|
|
474
|
+
|
|
302
475
|
export type PendingLiveNonStyleEdit =
|
|
303
476
|
| PendingLiveTextEdit
|
|
477
|
+
| PendingLiveLayerStateEdit
|
|
304
478
|
| PendingLiveStructureEdit;
|
|
305
479
|
export type PendingVisualStyleUndoEntry = {
|
|
306
480
|
edit: PendingVisualStyleEdit;
|
|
@@ -316,10 +490,59 @@ export type PendingLiveStructureUndoEntry = {
|
|
|
316
490
|
kind: "structure";
|
|
317
491
|
edit: PendingLiveStructureEdit;
|
|
318
492
|
};
|
|
493
|
+
export type PendingLiveLayerStateUndoEntry = {
|
|
494
|
+
kind: "layer-state";
|
|
495
|
+
edit: PendingLiveLayerStateEdit;
|
|
496
|
+
revertEnabled: boolean;
|
|
497
|
+
};
|
|
319
498
|
export type PendingLiveNonStyleUndoEntry =
|
|
320
499
|
| PendingLiveTextUndoEntry
|
|
500
|
+
| PendingLiveLayerStateUndoEntry
|
|
321
501
|
| PendingLiveStructureUndoEntry;
|
|
322
502
|
|
|
503
|
+
/**
|
|
504
|
+
* Project-relative source files that must be read before this edit can be
|
|
505
|
+
* handed off. A removal has no anchor, and an INSERT has no subject — its
|
|
506
|
+
* markup exists in no source file yet — so demanding both paths rejected every
|
|
507
|
+
* insert as "anchors still loading". `null` means a path this edit does need
|
|
508
|
+
* has not resolved yet, which is the only honest "not ready" answer.
|
|
509
|
+
*/
|
|
510
|
+
export function pendingStructureEditSourcePaths(
|
|
511
|
+
edit: PendingLiveStructureEdit,
|
|
512
|
+
): string[] | null {
|
|
513
|
+
const required = [
|
|
514
|
+
...(edit.insertedHtml ? [] : [edit.sourceAnchor?.relPath]),
|
|
515
|
+
...(edit.removed
|
|
516
|
+
? []
|
|
517
|
+
: [
|
|
518
|
+
edit.anchorSourceAnchor?.relPath ??
|
|
519
|
+
(edit.insertedHtml ? edit.routeSourceFile : undefined),
|
|
520
|
+
]),
|
|
521
|
+
];
|
|
522
|
+
if (required.some((path) => !path)) return null;
|
|
523
|
+
return required as string[];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export type PendingStructureRedoCommand =
|
|
527
|
+
| { kind: "delete" }
|
|
528
|
+
| { kind: "insert"; html: string }
|
|
529
|
+
| { kind: "move" };
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Which runtime command replays this edit. Undoing an insert REMOVED the node,
|
|
533
|
+
* so replaying it as a move would address an element that is no longer in the
|
|
534
|
+
* document and the bridge would return silently — a redo that reports success
|
|
535
|
+
* and does nothing.
|
|
536
|
+
*/
|
|
537
|
+
export function pendingStructureRedoCommand(
|
|
538
|
+
edit: PendingLiveStructureEdit,
|
|
539
|
+
): PendingStructureRedoCommand {
|
|
540
|
+
if (edit.removed) return { kind: "delete" };
|
|
541
|
+
return edit.insertedHtml
|
|
542
|
+
? { kind: "insert", html: edit.insertedHtml }
|
|
543
|
+
: { kind: "move" };
|
|
544
|
+
}
|
|
545
|
+
|
|
323
546
|
export function pendingLiveStructureEditsMatch(
|
|
324
547
|
left: PendingLiveStructureEdit,
|
|
325
548
|
right: PendingLiveStructureEdit,
|
|
@@ -331,6 +554,7 @@ export function pendingLiveStructureEditsMatch(
|
|
|
331
554
|
left.anchorSelector === right.anchorSelector &&
|
|
332
555
|
(left.anchorSourceId ?? "") === (right.anchorSourceId ?? "") &&
|
|
333
556
|
left.placement === right.placement &&
|
|
557
|
+
Boolean(left.removed) === Boolean(right.removed) &&
|
|
334
558
|
left.dropMode === right.dropMode &&
|
|
335
559
|
Boolean(left.forceFlowPositionOverride) ===
|
|
336
560
|
Boolean(right.forceFlowPositionOverride)
|
|
@@ -427,20 +651,27 @@ export function originalStylesForPendingVisualEdit(
|
|
|
427
651
|
);
|
|
428
652
|
}
|
|
429
653
|
|
|
654
|
+
export type PendingVisualStyleRevertPatch = PendingVisualStyleRuntimePatch & {
|
|
655
|
+
interactionState?: InteractionState;
|
|
656
|
+
};
|
|
657
|
+
|
|
430
658
|
export function buildPendingVisualStyleRevertPatches(
|
|
431
659
|
edits: readonly PendingVisualStyleEdit[],
|
|
432
|
-
):
|
|
433
|
-
screenId: string;
|
|
434
|
-
selector: string;
|
|
435
|
-
sourceId?: string | null;
|
|
436
|
-
styles: Record<string, string>;
|
|
437
|
-
interactionState?: InteractionState;
|
|
438
|
-
}> {
|
|
660
|
+
): PendingVisualStyleRevertPatch[] {
|
|
439
661
|
return edits
|
|
440
662
|
.map((edit) => ({
|
|
441
663
|
screenId: edit.screenId,
|
|
442
664
|
selector: edit.selector,
|
|
443
665
|
sourceId: edit.sourceId,
|
|
666
|
+
// Carried, not resolved: consumers replay into the live frame (prefer the
|
|
667
|
+
// runtime pair) and into the source projection (prefer the canonical
|
|
668
|
+
// one), so the patch has to keep both.
|
|
669
|
+
...(edit.runtimeSelector
|
|
670
|
+
? { runtimeSelector: edit.runtimeSelector }
|
|
671
|
+
: {}),
|
|
672
|
+
...(edit.runtimeSourceId
|
|
673
|
+
? { runtimeSourceId: edit.runtimeSourceId }
|
|
674
|
+
: {}),
|
|
444
675
|
styles: edit.originalStyles,
|
|
445
676
|
...(edit.interactionState
|
|
446
677
|
? { interactionState: edit.interactionState }
|
|
@@ -449,13 +680,101 @@ export function buildPendingVisualStyleRevertPatches(
|
|
|
449
680
|
.filter((patch) => Object.keys(patch.styles).length > 0);
|
|
450
681
|
}
|
|
451
682
|
|
|
452
|
-
export
|
|
683
|
+
export type PendingVisualStyleRuntimePatch = {
|
|
684
|
+
screenId: string;
|
|
685
|
+
selector: string;
|
|
686
|
+
sourceId?: string | null;
|
|
687
|
+
runtimeSelector?: string | null;
|
|
688
|
+
runtimeSourceId?: string | null;
|
|
689
|
+
styles: Record<string, string>;
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
function nodeIdSelector(nodeId: string): string {
|
|
693
|
+
return `[data-agent-native-node-id="${nodeId
|
|
694
|
+
.replace(/\\/g, "\\\\")
|
|
695
|
+
.replace(/"/g, '\\"')}"]`;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* How a pending edit addresses the RUNNING document. The runtime pair wins
|
|
700
|
+
* because a localhost screen's canonical selector/sourceId name nodes in the
|
|
701
|
+
* host's source projection, which the live frame has never seen. Candidates
|
|
702
|
+
* stay a runtime-first superset so nothing that used to resolve stops
|
|
703
|
+
* resolving, and an inline screen — which records no runtime pair — produces
|
|
704
|
+
* byte-identical output to the canonical-only list.
|
|
705
|
+
*/
|
|
706
|
+
export function runtimeStyleTarget(target: {
|
|
707
|
+
selector: string;
|
|
708
|
+
sourceId?: string | null;
|
|
709
|
+
runtimeSelector?: string | null;
|
|
710
|
+
runtimeSourceId?: string | null;
|
|
711
|
+
}): { selector: string; nodeId: string | null; selectorCandidates: string[] } {
|
|
712
|
+
const selector = target.runtimeSelector?.trim() || target.selector;
|
|
713
|
+
const nodeId = target.runtimeSourceId?.trim() || target.sourceId || null;
|
|
714
|
+
return {
|
|
715
|
+
selector,
|
|
716
|
+
nodeId,
|
|
717
|
+
selectorCandidates: [
|
|
718
|
+
...new Set(
|
|
719
|
+
[
|
|
720
|
+
selector,
|
|
721
|
+
target.selector,
|
|
722
|
+
nodeId ? nodeIdSelector(nodeId) : "",
|
|
723
|
+
target.sourceId ? nodeIdSelector(target.sourceId) : "",
|
|
724
|
+
].filter(Boolean),
|
|
725
|
+
),
|
|
726
|
+
],
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
export type SendPendingVisualStyleRuntimeProperty = (
|
|
731
|
+
screenId: string,
|
|
732
|
+
selector: string,
|
|
733
|
+
property: string,
|
|
734
|
+
value: string,
|
|
735
|
+
options: {
|
|
736
|
+
selectorCandidates: string[];
|
|
737
|
+
nodeId?: string | null;
|
|
738
|
+
},
|
|
739
|
+
) => boolean;
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Forward, undo, and redo all use this exact per-property runtime channel.
|
|
743
|
+
* The screen id is part of the command boundary so a retained/remounted
|
|
744
|
+
* overview iframe cannot accidentally receive history intended for another
|
|
745
|
+
* screen.
|
|
746
|
+
*/
|
|
747
|
+
export function replayPendingVisualStyleRuntimePatch(
|
|
748
|
+
patch: PendingVisualStyleRuntimePatch,
|
|
749
|
+
sendProperty: SendPendingVisualStyleRuntimeProperty,
|
|
750
|
+
): boolean {
|
|
751
|
+
const entries = Object.entries(patch.styles);
|
|
752
|
+
if (entries.length === 0) return false;
|
|
753
|
+
const target = runtimeStyleTarget(patch);
|
|
754
|
+
// No candidate at all is not "apply it to the obvious element": the bridge
|
|
755
|
+
// falls back to its own current selection when the candidate list is empty,
|
|
756
|
+
// so an unaddressable revert would silently restyle whatever happens to be
|
|
757
|
+
// selected. Report failure and let the caller surface it.
|
|
758
|
+
if (target.selectorCandidates.length === 0) return false;
|
|
759
|
+
return entries.every(([property, value]) =>
|
|
760
|
+
sendProperty(patch.screenId, target.selector, property, value, {
|
|
761
|
+
selectorCandidates: target.selectorCandidates,
|
|
762
|
+
nodeId: target.nodeId,
|
|
763
|
+
}),
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Badge number on the Apply bar: how many user-meaningful updates Apply would
|
|
769
|
+
* hand to the agent. A style edit is already coalesced by screen, target, and
|
|
770
|
+
* interaction state, so counting its individual CSS declarations inflates one
|
|
771
|
+
* inspector gesture into several apparent updates.
|
|
772
|
+
*/
|
|
773
|
+
export function getPendingVisualEditCount(
|
|
453
774
|
edits: readonly PendingVisualStyleEdit[],
|
|
775
|
+
liveEdits: readonly PendingLiveNonStyleEdit[] = [],
|
|
454
776
|
): number {
|
|
455
|
-
return edits.
|
|
456
|
-
(count, edit) => count + Object.keys(edit.styles).length,
|
|
457
|
-
0,
|
|
458
|
-
);
|
|
777
|
+
return edits.length + liveEdits.length;
|
|
459
778
|
}
|
|
460
779
|
|
|
461
780
|
export function shouldBlockPendingVisualStyleNavigation(args: {
|
|
@@ -469,6 +788,22 @@ export function shouldBlockPendingVisualStyleNavigation(args: {
|
|
|
469
788
|
);
|
|
470
789
|
}
|
|
471
790
|
|
|
791
|
+
/**
|
|
792
|
+
* Inserted markup is the only unbounded field in the pending-edit payload, and
|
|
793
|
+
* that payload is JSON.stringified straight into an agent prompt. Truncation is
|
|
794
|
+
* reported so the agent never mistakes a cut-off tree for the whole node.
|
|
795
|
+
*/
|
|
796
|
+
const MAX_INSERTED_HTML_LENGTH = 4_000;
|
|
797
|
+
|
|
798
|
+
function boundedInsertedHtml(html: string): {
|
|
799
|
+
value: string;
|
|
800
|
+
truncated: boolean;
|
|
801
|
+
} {
|
|
802
|
+
return html.length > MAX_INSERTED_HTML_LENGTH
|
|
803
|
+
? { value: html.slice(0, MAX_INSERTED_HTML_LENGTH), truncated: true }
|
|
804
|
+
: { value: html, truncated: false };
|
|
805
|
+
}
|
|
806
|
+
|
|
472
807
|
export function formatPendingVisualStylePrompt(args: {
|
|
473
808
|
designId?: string | null;
|
|
474
809
|
designTitle?: string | null;
|
|
@@ -528,34 +863,59 @@ export function formatPendingVisualStylePrompt(args: {
|
|
|
528
863
|
html: edit.html,
|
|
529
864
|
};
|
|
530
865
|
}
|
|
866
|
+
if (edit.kind === "layer-state") {
|
|
867
|
+
const semanticHandoff = edit.sourceAnchor
|
|
868
|
+
? buildRuntimeReactLayerStateHandoff({
|
|
869
|
+
subjectAnchor: edit.sourceAnchor,
|
|
870
|
+
screenId: edit.screenId,
|
|
871
|
+
state: edit.state,
|
|
872
|
+
enabled: edit.enabled,
|
|
873
|
+
})
|
|
874
|
+
: null;
|
|
875
|
+
return {
|
|
876
|
+
kind: edit.kind,
|
|
877
|
+
screenId: edit.screenId,
|
|
878
|
+
filename: edit.filename,
|
|
879
|
+
screenName: edit.screenName,
|
|
880
|
+
selector: edit.selector,
|
|
881
|
+
sourceId: edit.sourceId ?? null,
|
|
882
|
+
sourceAnchor: redactReactSourceAnchor(edit.sourceAnchor),
|
|
883
|
+
tagName: edit.tagName ?? null,
|
|
884
|
+
classes: edit.classes,
|
|
885
|
+
state: edit.state,
|
|
886
|
+
enabled: edit.enabled,
|
|
887
|
+
attributeName: `data-agent-native-${edit.state}`,
|
|
888
|
+
...(semanticHandoff?.ok
|
|
889
|
+
? { semanticHandoff: semanticHandoff.handoff }
|
|
890
|
+
: {}),
|
|
891
|
+
};
|
|
892
|
+
}
|
|
531
893
|
const subjectAnchor = edit.sourceAnchor
|
|
532
894
|
? { ...edit.sourceAnchor, id: "subject" }
|
|
533
895
|
: undefined;
|
|
534
896
|
const targetAnchor = edit.anchorSourceAnchor
|
|
535
897
|
? { ...edit.anchorSourceAnchor, id: "target" }
|
|
536
898
|
: undefined;
|
|
537
|
-
|
|
538
|
-
|
|
899
|
+
// An insert's subject is markup that does not exist in the program yet, so
|
|
900
|
+
// it has no source anchor and cannot be described as a move. Telling the
|
|
901
|
+
// agent to relocate an element the file has never contained is worse than
|
|
902
|
+
// reporting nothing.
|
|
903
|
+
const insertedHtml = edit.insertedHtml
|
|
904
|
+
? boundedInsertedHtml(edit.insertedHtml)
|
|
905
|
+
: undefined;
|
|
906
|
+
const semanticHandoff = edit.removed
|
|
907
|
+
? subjectAnchor
|
|
539
908
|
? buildReactSemanticHandoff({
|
|
540
|
-
operation:
|
|
541
|
-
desiredChange:
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
? `The drop is a flow/auto-layout insertion${edit.forceFlowPositionOverride ? "; remove authored absolute positioning so the moved element participates in the target container's layout" : "; preserve normal flow participation"}.`
|
|
545
|
-
: edit.dropMode === "absolute-container"
|
|
546
|
-
? "The target is an absolute-positioning container; preserve absolute positioning and rebase the moved element's visual offset from sourceRect into the target anchorRect coordinate space."
|
|
547
|
-
: "Preserve the runtime layout behavior observed in the preview.",
|
|
548
|
-
].join(" "),
|
|
549
|
-
sourceAnchors: [subjectAnchor, targetAnchor],
|
|
909
|
+
operation: "remove",
|
|
910
|
+
desiredChange:
|
|
911
|
+
"Delete the selected runtime element from the source that renders it. The live preview already shows it gone; remove its markup (and anything that exists only to render it) without disturbing sibling layout or behavior.",
|
|
912
|
+
sourceAnchors: [subjectAnchor],
|
|
550
913
|
runtimeRelationship: {
|
|
551
|
-
kind:
|
|
914
|
+
kind: "remove",
|
|
552
915
|
subjectAnchorIds: ["subject"],
|
|
553
|
-
targetAnchorId: "target",
|
|
554
916
|
screenId: edit.screenId,
|
|
555
|
-
description:
|
|
917
|
+
description: `remove ${edit.selector}`,
|
|
556
918
|
},
|
|
557
|
-
// The packet intentionally starts without a hash: its execution
|
|
558
|
-
// contract requires read-local-file before every write.
|
|
559
919
|
versionHashes: [],
|
|
560
920
|
})
|
|
561
921
|
: {
|
|
@@ -563,9 +923,71 @@ export function formatPendingVisualStylePrompt(args: {
|
|
|
563
923
|
rejection: {
|
|
564
924
|
code: "missing-source-provenance" as const,
|
|
565
925
|
reason:
|
|
566
|
-
"
|
|
926
|
+
"The removed element's source anchor was not available for this runtime deletion.",
|
|
567
927
|
},
|
|
568
|
-
}
|
|
928
|
+
}
|
|
929
|
+
: insertedHtml
|
|
930
|
+
? targetAnchor
|
|
931
|
+
? buildReactSemanticHandoff({
|
|
932
|
+
operation: "insert",
|
|
933
|
+
desiredChange: [
|
|
934
|
+
`Add the new markup in insertedHtml ${edit.placement} the target runtime element.`,
|
|
935
|
+
insertedHtml.truncated
|
|
936
|
+
? "The markup below was truncated for prompt size; read the running preview or ask before writing it verbatim."
|
|
937
|
+
: "The markup is already positioned for the drop point.",
|
|
938
|
+
edit.dropMode === "absolute-container"
|
|
939
|
+
? "The target is an absolute-positioning container; keep the inline left/top offsets."
|
|
940
|
+
: "This is a flow/auto-layout insertion; the markup carries no absolute positioning.",
|
|
941
|
+
].join(" "),
|
|
942
|
+
sourceAnchors: [targetAnchor],
|
|
943
|
+
runtimeRelationship: {
|
|
944
|
+
kind: edit.placement,
|
|
945
|
+
subjectAnchorIds: [],
|
|
946
|
+
targetAnchorId: "target",
|
|
947
|
+
screenId: edit.screenId,
|
|
948
|
+
description: `insert ${edit.selector} ${edit.placement} ${edit.anchorSelector}`,
|
|
949
|
+
},
|
|
950
|
+
versionHashes: [],
|
|
951
|
+
})
|
|
952
|
+
: {
|
|
953
|
+
ok: false as const,
|
|
954
|
+
rejection: {
|
|
955
|
+
code: "missing-source-provenance" as const,
|
|
956
|
+
reason:
|
|
957
|
+
"The insertion target's source anchor was not available for this runtime insert.",
|
|
958
|
+
},
|
|
959
|
+
}
|
|
960
|
+
: subjectAnchor && targetAnchor
|
|
961
|
+
? buildReactSemanticHandoff({
|
|
962
|
+
operation: edit.placement === "inside" ? "reparent" : "move",
|
|
963
|
+
desiredChange: [
|
|
964
|
+
`Move the selected runtime element ${edit.placement} the target runtime element.`,
|
|
965
|
+
edit.dropMode === "flow-insert"
|
|
966
|
+
? `The drop is a flow/auto-layout insertion${edit.forceFlowPositionOverride ? "; remove authored absolute positioning so the moved element participates in the target container's layout" : "; preserve normal flow participation"}.`
|
|
967
|
+
: edit.dropMode === "absolute-container"
|
|
968
|
+
? "The target is an absolute-positioning container; preserve absolute positioning and rebase the moved element's visual offset from sourceRect into the target anchorRect coordinate space."
|
|
969
|
+
: "Preserve the runtime layout behavior observed in the preview.",
|
|
970
|
+
].join(" "),
|
|
971
|
+
sourceAnchors: [subjectAnchor, targetAnchor],
|
|
972
|
+
runtimeRelationship: {
|
|
973
|
+
kind: edit.placement,
|
|
974
|
+
subjectAnchorIds: ["subject"],
|
|
975
|
+
targetAnchorId: "target",
|
|
976
|
+
screenId: edit.screenId,
|
|
977
|
+
description: `${edit.selector} ${edit.placement} ${edit.anchorSelector}`,
|
|
978
|
+
},
|
|
979
|
+
// The packet intentionally starts without a hash: its execution
|
|
980
|
+
// contract requires read-local-file before every write.
|
|
981
|
+
versionHashes: [],
|
|
982
|
+
})
|
|
983
|
+
: {
|
|
984
|
+
ok: false as const,
|
|
985
|
+
rejection: {
|
|
986
|
+
code: "missing-source-provenance" as const,
|
|
987
|
+
reason:
|
|
988
|
+
"Exact subject and target source anchors were not both available for this React structure edit.",
|
|
989
|
+
},
|
|
990
|
+
};
|
|
569
991
|
return {
|
|
570
992
|
kind: edit.kind,
|
|
571
993
|
screenId: edit.screenId,
|
|
@@ -574,16 +996,33 @@ export function formatPendingVisualStylePrompt(args: {
|
|
|
574
996
|
selector: edit.selector,
|
|
575
997
|
sourceId: edit.sourceId ?? null,
|
|
576
998
|
sourceAnchor: redactReactSourceAnchor(edit.sourceAnchor),
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
999
|
+
// A removal has no anchor; emitting empty anchor fields alongside a
|
|
1000
|
+
// meaningless placement reads as a half-captured move.
|
|
1001
|
+
...(edit.removed
|
|
1002
|
+
? { removed: true as const }
|
|
1003
|
+
: {
|
|
1004
|
+
anchorSelector: edit.anchorSelector,
|
|
1005
|
+
anchorSourceId: edit.anchorSourceId ?? null,
|
|
1006
|
+
anchorSourceAnchor: redactReactSourceAnchor(
|
|
1007
|
+
edit.anchorSourceAnchor,
|
|
1008
|
+
),
|
|
1009
|
+
placement: edit.placement,
|
|
1010
|
+
}),
|
|
581
1011
|
...(edit.dropMode ? { dropMode: edit.dropMode } : {}),
|
|
1012
|
+
...(edit.routeSourceFile
|
|
1013
|
+
? { routeSourceFile: edit.routeSourceFile }
|
|
1014
|
+
: {}),
|
|
582
1015
|
...(edit.forceFlowPositionOverride
|
|
583
1016
|
? { forceFlowPositionOverride: true }
|
|
584
1017
|
: {}),
|
|
585
1018
|
...(edit.sourceRect ? { sourceRect: edit.sourceRect } : {}),
|
|
586
1019
|
...(edit.anchorRect ? { anchorRect: edit.anchorRect } : {}),
|
|
1020
|
+
...(insertedHtml
|
|
1021
|
+
? {
|
|
1022
|
+
insertedHtml: insertedHtml.value,
|
|
1023
|
+
...(insertedHtml.truncated ? { insertedHtmlTruncated: true } : {}),
|
|
1024
|
+
}
|
|
1025
|
+
: {}),
|
|
587
1026
|
...(semanticHandoff.ok
|
|
588
1027
|
? { semanticHandoff: semanticHandoff.handoff }
|
|
589
1028
|
: { semanticHandoffFailure: semanticHandoff.rejection }),
|
|
@@ -600,7 +1039,7 @@ export function formatPendingVisualStylePrompt(args: {
|
|
|
600
1039
|
? `Active localhost connection id: "${args.localhostConnectionId}".`
|
|
601
1040
|
: "",
|
|
602
1041
|
"",
|
|
603
|
-
"Use the Design source tools to make the source match the current live canvas preview. Read each target screen, resolve source ids/selectors through the code-layer projection, then apply the style, text, and structure changes with focused source edits. Preserve layout, behavior, and unrelated styling.",
|
|
1042
|
+
"Use the Design source tools to make the source match the current live canvas preview. Read each target screen, resolve source ids/selectors through the code-layer projection, then apply the style, text, layer-state, and structure changes with focused source edits. Preserve layout, behavior, and unrelated styling.",
|
|
604
1043
|
hasReactSourceAnchors
|
|
605
1044
|
? "React sourceAnchor fields are source provenance; runtime source ids and selectors are correlation hints only. For a single-instance leaf text, literal className/class, or flat literal style-object edit, call apply-visual-edit with source.kind=local-file plus designId, connectionId, the verified project-relative path, and target.sourceAnchor. First omit persist and inspect proposedDiff; then retry with persist=true only when the diff matches the preview. That write still requires human localhost consent and exact version-hash concurrency. Verify every file, line, column, component, and surrounding control flow before editing. Never use a generic AST reparent, group, wrapper, breakpoint, dynamic expression, repeated render, or shared component transform through this path. For semantic structure edits, follow the embedded semanticHandoff packet and use this exact guarded sequence: read-local-file, capture its versionHash, obtain human write consent, write-local-file with expectedVersionHash and requireExpectedVersionHash: true, then keep the preview pending until HMR proves the intended runtime relationship. On a version conflict, re-read and re-plan; never overwrite blindly."
|
|
606
1045
|
: "",
|
|
@@ -610,13 +1049,29 @@ export function formatPendingVisualStylePrompt(args: {
|
|
|
610
1049
|
hasBreakpointScopedEdits
|
|
611
1050
|
? "Edits that carry a `breakpoint` field were made while a narrower breakpoint frame was active: apply them as width-scoped overrides (apply-visual-edit with `activeFrameWidthPx` set to breakpoint.activeWidthPx), NOT as base writes — base values must keep rendering at wider viewports. When breakpoint.editScope is `only`, confine the override to breakpoint.activeWidthPx through breakpoint.upperBoundPx; otherwise use the normal desktop-down cascade."
|
|
612
1051
|
: "",
|
|
1052
|
+
(args.liveEdits ?? []).some(
|
|
1053
|
+
(edit) => edit.kind === "structure" && edit.removed,
|
|
1054
|
+
)
|
|
1055
|
+
? "Structure edits carrying `removed: true` are DELETIONS, not moves: the element is already gone from the live preview and must be deleted from the source that renders it. Do not re-create it, and do not read its absent anchor as a half-captured move."
|
|
1056
|
+
: "",
|
|
1057
|
+
(args.liveEdits ?? []).some(
|
|
1058
|
+
(edit) =>
|
|
1059
|
+
edit.kind === "structure" &&
|
|
1060
|
+
Boolean(edit.insertedHtml) &&
|
|
1061
|
+
Boolean(edit.routeSourceFile) &&
|
|
1062
|
+
!edit.anchorSourceAnchor,
|
|
1063
|
+
)
|
|
1064
|
+
? "A live insert with `routeSourceFile` but no `anchorSourceAnchor` was drawn directly on the screen frame, so its runtime target is the document body rather than a framework-owned element. Treat `routeSourceFile` as the bounded source target, inspect that route's root markup/component, and add `insertedHtml` as a top-level positioned child that matches the live preview. Do not fabricate a body source line or write outside that file unless the route delegates its root markup and you can verify the exact delegated source."
|
|
1065
|
+
: "",
|
|
613
1066
|
args.edits.some((edit) => edit.interactionState)
|
|
614
1067
|
? "Edits that carry an `interactionState` field are pseudo-class overrides, not base styles. Apply each property only to that exact state (`hover`, `focus`, `focus-visible`, `active`, or `disabled`) while preserving the element's default styling and its other states."
|
|
615
1068
|
: "",
|
|
616
1069
|
"",
|
|
617
1070
|
"Pending style edits:",
|
|
618
1071
|
JSON.stringify(editPayload, null, 2),
|
|
619
|
-
liveEditPayload.length > 0
|
|
1072
|
+
liveEditPayload.length > 0
|
|
1073
|
+
? "Pending text/layer-state/structure edits:"
|
|
1074
|
+
: "",
|
|
620
1075
|
liveEditPayload.length > 0 ? JSON.stringify(liveEditPayload, null, 2) : "",
|
|
621
1076
|
]
|
|
622
1077
|
.filter((line) => line !== "")
|