@agent-native/core 0.163.4 → 0.164.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/app/components/agents/FeatureFlagsFleetPanel.tsx +78 -19
  3. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +29 -0
  4. package/corpus/templates/analytics/app/lib/use-auto-focus-select.ts +4 -4
  5. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -0
  6. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +6 -0
  7. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -2
  8. package/corpus/templates/analytics/app/routes/_index.tsx +3 -2
  9. package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +7 -2
  10. package/corpus/templates/analytics/app/routes/dashboard.tsx +3 -2
  11. package/corpus/templates/analytics/app/routes/overview.tsx +3 -2
  12. package/corpus/templates/analytics/app/routes/traffic.tsx +3 -2
  13. package/corpus/templates/analytics/changelog/2026-08-18-verify-cross-app-feature-flag-changes.md +6 -0
  14. package/corpus/templates/analytics/netlify.toml +2 -0
  15. package/corpus/templates/analytics/server/lib/workspace-feature-flags.ts +196 -48
  16. package/corpus/templates/analytics/server/plugins/feature-flags.ts +5 -0
  17. package/corpus/templates/analytics/shared/feature-flags.ts +10 -0
  18. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +5 -1
  19. package/corpus/templates/assets/app/routes/brand-kits._index.tsx +4 -1
  20. package/corpus/templates/assets/app/routes/libraries.tsx +4 -1
  21. package/corpus/templates/assets/app/routes/picker.tsx +4 -1
  22. package/corpus/templates/assets/netlify.toml +2 -0
  23. package/corpus/templates/brain/netlify.toml +2 -0
  24. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +2 -1
  25. package/corpus/templates/calendar/changelog/2026-08-19-calendar-page-loads-stay-fast-after-idle-periods.md +6 -0
  26. package/corpus/templates/calendar/netlify.toml +2 -0
  27. package/corpus/templates/chat/netlify.toml +2 -0
  28. package/corpus/templates/clips/app/components/player/player-controls.tsx +3 -3
  29. package/corpus/templates/clips/app/components/player/reaction-emojis.ts +12 -0
  30. package/corpus/templates/clips/app/components/player/reactions-tray.tsx +90 -9
  31. package/corpus/templates/clips/app/components/player/scrubber.tsx +43 -10
  32. package/corpus/templates/clips/app/components/player/video-player.tsx +105 -15
  33. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -2
  34. package/corpus/templates/clips/app/routes/_app.wispr.tsx +2 -1
  35. package/corpus/templates/clips/app/routes/_index.tsx +7 -3
  36. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +13 -8
  37. package/corpus/templates/clips/app/routes/share.$shareId.tsx +15 -8
  38. package/corpus/templates/clips/netlify.toml +2 -0
  39. package/corpus/templates/clips/server/routes/[...page].head.ts +5 -0
  40. package/corpus/templates/content/netlify.toml +2 -0
  41. package/corpus/templates/design/.agents/skills/design-editor-architecture/SKILL.md +103 -0
  42. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +2 -1
  43. package/corpus/templates/design/AGENTS.md +3 -1
  44. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +3 -2
  45. package/corpus/templates/design/app/components/design/editor/AgentNativeMenuMark.tsx +25 -0
  46. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +411 -0
  47. package/corpus/templates/design/app/components/design/editor/DesignCollaborators.tsx +153 -0
  48. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +231 -0
  49. package/corpus/templates/design/app/components/design/editor/MakeRealDialog.tsx +223 -0
  50. package/corpus/templates/design/app/components/design/editor/PendingScreenDeletionDialog.tsx +58 -0
  51. package/corpus/templates/design/app/components/design/editor/PendingVisualStyleWarningDialog.tsx +56 -0
  52. package/corpus/templates/design/app/components/design/editor/ReadOnlyEditorPanel.tsx +23 -0
  53. package/corpus/templates/design/app/components/design/editor/SaveTemplateDialog.tsx +161 -0
  54. package/corpus/templates/design/app/components/design/editor/toolbar-controls.tsx +185 -0
  55. package/corpus/templates/design/app/pages/DesignEditor.tsx +20913 -0
  56. package/corpus/templates/design/app/pages/design-editor/command-types.ts +120 -0
  57. package/corpus/templates/design/app/pages/design-editor/commands/README.md +193 -0
  58. package/corpus/templates/design/app/pages/design-editor/commands/add-auto-layout.ts +416 -0
  59. package/corpus/templates/design/app/pages/design-editor/commands/add-screen.ts +112 -0
  60. package/corpus/templates/design/app/pages/design-editor/commands/align-selection.ts +183 -0
  61. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +243 -0
  62. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +236 -0
  63. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +304 -0
  64. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +376 -0
  65. package/corpus/templates/design/app/pages/design-editor/commands/apply-to-source.ts +132 -0
  66. package/corpus/templates/design/app/pages/design-editor/commands/can-move-layer.ts +117 -0
  67. package/corpus/templates/design/app/pages/design-editor/commands/change-selected-z-index.ts +212 -0
  68. package/corpus/templates/design/app/pages/design-editor/commands/commit-relative-style-delta-to-selected-layers.ts +176 -0
  69. package/corpus/templates/design/app/pages/design-editor/commands/commit-styles-to-selected-layers.ts +175 -0
  70. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +710 -0
  71. package/corpus/templates/design/app/pages/design-editor/commands/confirm-make-real.ts +99 -0
  72. package/corpus/templates/design/app/pages/design-editor/commands/copy-as-figma-svg.ts +95 -0
  73. package/corpus/templates/design/app/pages/design-editor/commands/copy-selection.ts +156 -0
  74. package/corpus/templates/design/app/pages/design-editor/commands/create-primitive.ts +291 -0
  75. package/corpus/templates/design/app/pages/design-editor/commands/create-screen-frame.ts +131 -0
  76. package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-element-drop.ts +577 -0
  77. package/corpus/templates/design/app/pages/design-editor/commands/delete-files.ts +364 -0
  78. package/corpus/templates/design/app/pages/design-editor/commands/delete-selection.ts +521 -0
  79. package/corpus/templates/design/app/pages/design-editor/commands/detach-instance-menu-action.ts +88 -0
  80. package/corpus/templates/design/app/pages/design-editor/commands/distribute-selection.ts +114 -0
  81. package/corpus/templates/design/app/pages/design-editor/commands/download-all-screens-pdf.ts +116 -0
  82. package/corpus/templates/design/app/pages/design-editor/commands/download-pdf.ts +103 -0
  83. package/corpus/templates/design/app/pages/design-editor/commands/download-svg.ts +159 -0
  84. package/corpus/templates/design/app/pages/design-editor/commands/duplicate-screen.ts +201 -0
  85. package/corpus/templates/design/app/pages/design-editor/commands/duplicate-selection.ts +279 -0
  86. package/corpus/templates/design/app/pages/design-editor/commands/editor-paste.ts +81 -0
  87. package/corpus/templates/design/app/pages/design-editor/commands/enter-hotkey.ts +155 -0
  88. package/corpus/templates/design/app/pages/design-editor/commands/enter-single-screen.ts +168 -0
  89. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +212 -0
  90. package/corpus/templates/design/app/pages/design-editor/commands/frame-selection.ts +119 -0
  91. package/corpus/templates/design/app/pages/design-editor/commands/geometry-commit.ts +169 -0
  92. package/corpus/templates/design/app/pages/design-editor/commands/get-selected-layer-snapshots.ts +177 -0
  93. package/corpus/templates/design/app/pages/design-editor/commands/group-selection.ts +127 -0
  94. package/corpus/templates/design/app/pages/design-editor/commands/iframe-context-menu.ts +121 -0
  95. package/corpus/templates/design/app/pages/design-editor/commands/import-figma-clipboard-into-design.ts +119 -0
  96. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +163 -0
  97. package/corpus/templates/design/app/pages/design-editor/commands/layer-move-to-screen.ts +331 -0
  98. package/corpus/templates/design/app/pages/design-editor/commands/layer-move.ts +517 -0
  99. package/corpus/templates/design/app/pages/design-editor/commands/layer-rename.ts +247 -0
  100. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +161 -0
  101. package/corpus/templates/design/app/pages/design-editor/commands/mode-change.ts +122 -0
  102. package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +213 -0
  103. package/corpus/templates/design/app/pages/design-editor/commands/overview-primitive-reparent.ts +318 -0
  104. package/corpus/templates/design/app/pages/design-editor/commands/paste-copied-screens.ts +114 -0
  105. package/corpus/templates/design/app/pages/design-editor/commands/paste-over-selection.ts +70 -0
  106. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +436 -0
  107. package/corpus/templates/design/app/pages/design-editor/commands/paste-to-replace.ts +135 -0
  108. package/corpus/templates/design/app/pages/design-editor/commands/pasted-image-files.ts +209 -0
  109. package/corpus/templates/design/app/pages/design-editor/commands/persist-frame-geometry-save.ts +113 -0
  110. package/corpus/templates/design/app/pages/design-editor/commands/persist-tweak-save.ts +160 -0
  111. package/corpus/templates/design/app/pages/design-editor/commands/primitive-created.ts +168 -0
  112. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-live-layer-state-edit.ts +149 -0
  113. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-live-structure-edit.ts +200 -0
  114. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-live-text-edit.ts +152 -0
  115. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-visual-style-edit.ts +247 -0
  116. package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +1086 -0
  117. package/corpus/templates/design/app/pages/design-editor/commands/render-png-blob.ts +200 -0
  118. package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +207 -0
  119. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +262 -0
  120. package/corpus/templates/design/app/pages/design-editor/commands/screen-text-content-change.ts +216 -0
  121. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +108 -0
  122. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-structure-change.ts +280 -0
  123. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +151 -0
  124. package/corpus/templates/design/app/pages/design-editor/commands/send-overview-annotations.ts +88 -0
  125. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +122 -0
  126. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +143 -0
  127. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +115 -0
  128. package/corpus/templates/design/app/pages/design-editor/commands/start-retry-generation.ts +152 -0
  129. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +99 -0
  130. package/corpus/templates/design/app/pages/design-editor/commands/style-change.ts +152 -0
  131. package/corpus/templates/design/app/pages/design-editor/commands/styles-change.ts +155 -0
  132. package/corpus/templates/design/app/pages/design-editor/commands/suggest-auto-layout.ts +125 -0
  133. package/corpus/templates/design/app/pages/design-editor/commands/text-content-change.ts +201 -0
  134. package/corpus/templates/design/app/pages/design-editor/commands/tidy-up.ts +123 -0
  135. package/corpus/templates/design/app/pages/design-editor/commands/toggle-layer-hidden.ts +167 -0
  136. package/corpus/templates/design/app/pages/design-editor/commands/toggle-layer-locked.ts +175 -0
  137. package/corpus/templates/design/app/pages/design-editor/commands/toggle-motion-keyframe.ts +99 -0
  138. package/corpus/templates/design/app/pages/design-editor/commands/tweak-prompt-submit.ts +84 -0
  139. package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +906 -0
  140. package/corpus/templates/design/app/pages/design-editor/commands/ungroup-selection.ts +170 -0
  141. package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +119 -0
  142. package/corpus/templates/design/app/pages/design-editor/commands/visual-structure-change.ts +274 -0
  143. package/corpus/templates/design/app/pages/design-editor/commands/write-frame-geometry-snapshot.ts +99 -0
  144. package/corpus/templates/design/app/pages/design-editor/derive/design-breakpoints.ts +56 -0
  145. package/corpus/templates/design/app/pages/design-editor/derive/overview-screens.ts +146 -0
  146. package/corpus/templates/design/app/pages/design-editor/domains/use-tweaks.ts +326 -0
  147. package/corpus/templates/design/app/pages/design-editor/editor-constants.ts +54 -0
  148. package/corpus/templates/design/app/pages/design-editor/editor-helpers.ts +183 -0
  149. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +270 -0
  150. package/corpus/templates/design/app/pages/design-editor/effects/mirror-selection-to-agent-chat.ts +134 -0
  151. package/corpus/templates/design/app/pages/design-editor/effects/motion-autosave.ts +335 -0
  152. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +183 -0
  153. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +252 -0
  154. package/corpus/templates/design/app/pages/design-editor/effects/resume-pending-generation.ts +178 -0
  155. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +157 -0
  156. package/corpus/templates/design/app/pages/design-editor/preview-html.ts +19 -0
  157. package/corpus/templates/design/app/routes/examples.tsx +2 -1
  158. package/corpus/templates/design/netlify.toml +2 -0
  159. package/corpus/templates/design/shared/board-file.ts +2 -1
  160. package/corpus/templates/dispatch/netlify.toml +2 -0
  161. package/corpus/templates/forms/app/routes/_index.tsx +3 -2
  162. package/corpus/templates/forms/netlify.toml +2 -0
  163. package/corpus/templates/mail/app/routes/_index.tsx +3 -2
  164. package/corpus/templates/mail/netlify.toml +2 -0
  165. package/corpus/templates/plan/netlify.toml +2 -0
  166. package/corpus/templates/slides/netlify.toml +2 -0
  167. package/corpus/templates/tasks/app/routes/_index.tsx +2 -1
  168. package/dist/agent/engine/builder-engine.d.ts +6 -4
  169. package/dist/agent/engine/builder-engine.js +91 -26
  170. package/dist/agent/engine/registry.js +16 -0
  171. package/dist/cli/code-agent-agent-tools.d.ts +2 -0
  172. package/dist/cli/code-agent-agent-tools.js +188 -0
  173. package/dist/cli/code-agent-collaboration.d.ts +34 -0
  174. package/dist/cli/code-agent-collaboration.js +104 -0
  175. package/dist/cli/code-agent-executor.js +6 -0
  176. package/dist/cli/code-agent-schedules.d.ts +54 -0
  177. package/dist/cli/code-agent-schedules.js +198 -0
  178. package/dist/client/AgentPanel.js +1 -1
  179. package/dist/client/ConnectBuilderCard.js +5 -2
  180. package/dist/client/EnvironmentBadge.js +6 -5
  181. package/dist/client/chat/run-recovery.js +3 -2
  182. package/dist/client/chat/tool-call-display.js +2 -3
  183. package/dist/client/components/CodeRequiredDialog.js +4 -2
  184. package/dist/client/i18n.js +5 -4
  185. package/dist/client/settings/SettingsPanel.js +1 -1
  186. package/dist/client/settings/VoiceTranscriptionSection.js +1 -1
  187. package/dist/client/settings/useBuilderStatus.d.ts +6 -1
  188. package/dist/client/settings/useBuilderStatus.js +22 -33
  189. package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
  190. package/dist/code-agents/index.d.ts +2 -0
  191. package/dist/code-agents/index.js +2 -0
  192. package/dist/collab/awareness.d.ts +2 -2
  193. package/dist/collab/routes.d.ts +1 -1
  194. package/dist/deploy/build.js +10 -4
  195. package/dist/localization/shared.d.ts +2 -0
  196. package/dist/localization/shared.js +5 -0
  197. package/dist/mcp-client/oauth-client.d.ts +1 -0
  198. package/dist/mcp-client/oauth-client.js +50 -1
  199. package/dist/notifications/routes.d.ts +3 -3
  200. package/dist/observability/routes.d.ts +1 -1
  201. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  202. package/dist/server/auth-marketing-locales.d.ts +7 -0
  203. package/dist/server/auth-marketing-locales.js +1322 -0
  204. package/dist/server/auth-marketing.d.ts +1 -0
  205. package/dist/server/auth-marketing.js +35 -6
  206. package/dist/server/auth.js +4 -17
  207. package/dist/server/builder-browser.d.ts +22 -0
  208. package/dist/server/builder-browser.js +77 -1
  209. package/dist/server/builder-oauth.d.ts +50 -0
  210. package/dist/server/builder-oauth.js +263 -0
  211. package/dist/server/core-routes-plugin.d.ts +11 -0
  212. package/dist/server/core-routes-plugin.js +291 -415
  213. package/dist/server/credential-provider.d.ts +1 -1
  214. package/dist/server/credential-provider.js +1 -1
  215. package/dist/server/csrf.js +2 -2
  216. package/dist/server/onboarding-html.js +52 -120
  217. package/dist/server/ssr-handler.js +13 -4
  218. package/dist/settings/store.d.ts +9 -0
  219. package/dist/settings/store.js +19 -0
  220. package/dist/shared/cache-control.d.ts +22 -0
  221. package/dist/shared/cache-control.js +25 -0
  222. package/dist/shared/index.d.ts +1 -0
  223. package/dist/shared/index.js +1 -0
  224. package/dist/templates/chat/netlify.toml +2 -0
  225. package/docs/content/deployment.mdx +2 -0
  226. package/docs/content/multi-app-workspace.mdx +1 -1
  227. package/package.json +2 -2
  228. package/src/templates/chat/netlify.toml +2 -0
@@ -0,0 +1,331 @@
1
+ import type { CodeLayerNode, CodeLayerTreeNode } from "@shared/code-layer";
2
+ import {
3
+ applyVisualEdit,
4
+ buildCodeLayerProjection,
5
+ buildCodeLayerTree,
6
+ moveNodeBetweenDocuments,
7
+ } from "@shared/code-layer";
8
+ import type { Dispatch, RefObject, SetStateAction } from "react";
9
+ import { toast } from "sonner";
10
+
11
+ import type { LayersPanelMoveIntent } from "@/components/design/LayersPanel";
12
+ import type {
13
+ ElementInfo,
14
+ RuntimeStructureInsertRequest,
15
+ } from "@/components/design/types";
16
+ import type { ClipboardContentMutationPublication } from "@/lib/clipboard-content-lineage";
17
+ import type { EffectiveCodeLayerState } from "@/pages/design-editor/code-layer-state";
18
+ import {
19
+ codeLayerPatchMessage,
20
+ elementInfoFromCodeLayerNode,
21
+ findMovedCodeLayerNodeInProjection,
22
+ } from "@/pages/design-editor/code-layer-state";
23
+ import {
24
+ getLayerMoveSourceContent,
25
+ isStandaloneHttpUrl,
26
+ } from "@/pages/design-editor/editor-state";
27
+ import type {
28
+ ContentHistoryChange,
29
+ ContentHistoryEntry,
30
+ } from "@/pages/design-editor/history";
31
+ import { prepareLiveScreenLayerDrop } from "@/pages/design-editor/live-screen-layer-drop";
32
+ import type { DesignFile } from "@/pages/design-editor/types";
33
+
34
+ export interface LayerMoveToScreenArgs {
35
+ activeFile: DesignFile;
36
+ applyFileContentUpdate: (
37
+ fileId: string,
38
+ nextContent: string,
39
+ options?: {
40
+ refreshPreview?: boolean;
41
+ skipPreview?: boolean;
42
+ forcePreviewFullDocument?: boolean;
43
+ persist?: boolean;
44
+ recordHistory?: boolean;
45
+ updatedAt?: string;
46
+ clipboardMutation?: ClipboardContentMutationPublication;
47
+ },
48
+ ) => void;
49
+ boardFileId: string | undefined;
50
+ codeLayerOwnerByNodeId: Map<
51
+ string,
52
+ {
53
+ fileId: string;
54
+ node: CodeLayerNode;
55
+ tree: CodeLayerTreeNode[];
56
+ runtimeOnly: boolean;
57
+ }
58
+ >;
59
+ effectiveCodeLayerState: EffectiveCodeLayerState;
60
+ files: DesignFile[];
61
+ getFreshActiveContent: () => string;
62
+ recordContentHistoryEntry: (entry: ContentHistoryEntry) => void;
63
+ recordLocalContentHistoryEntry: (change: ContentHistoryChange) => void;
64
+ runtimeStructureInsertRevisionRef: RefObject<number>;
65
+ setExpandedLayerIds: Dispatch<SetStateAction<string[]>>;
66
+ setRuntimeStructureInsertRequest: Dispatch<
67
+ SetStateAction<
68
+ (RuntimeStructureInsertRequest & { screenId: string }) | null
69
+ >
70
+ >;
71
+ setSelectedElement: Dispatch<SetStateAction<ElementInfo | null>>;
72
+ setSelectedLayerIdsState: Dispatch<SetStateAction<string[]>>;
73
+ t: (key: string, options?: Record<string, unknown>) => string;
74
+ viewModeRef: RefObject<"single" | "overview">;
75
+ }
76
+
77
+ export function runLayerMoveToScreen(
78
+ {
79
+ activeFile,
80
+ applyFileContentUpdate,
81
+ boardFileId,
82
+ codeLayerOwnerByNodeId,
83
+ effectiveCodeLayerState,
84
+ files,
85
+ getFreshActiveContent,
86
+ recordContentHistoryEntry,
87
+ recordLocalContentHistoryEntry,
88
+ runtimeStructureInsertRevisionRef,
89
+ setExpandedLayerIds,
90
+ setRuntimeStructureInsertRequest,
91
+ setSelectedElement,
92
+ setSelectedLayerIdsState,
93
+ t,
94
+ viewModeRef,
95
+ }: LayerMoveToScreenArgs,
96
+ intent: LayersPanelMoveIntent,
97
+ targetFileId: string,
98
+ ) {
99
+ const freshActiveContent = getFreshActiveContent();
100
+ const destFile = files.find((file) => file.id === targetFileId);
101
+ const destContent =
102
+ targetFileId === activeFile?.id
103
+ ? freshActiveContent
104
+ : (destFile?.content ?? "");
105
+ if (!destContent) return;
106
+
107
+ if (isStandaloneHttpUrl(destContent)) {
108
+ // A localhost screen row represents the live iframe's body, while its
109
+ // stored content remains the route URL. Layers-panel drops from the
110
+ // board therefore use the same runtime insert lifecycle as canvas
111
+ // drops: serialize the complete subtree, insert optimistically in the
112
+ // iframe, and let the bridge echo create the pending source handoff.
113
+ // Keep the board copy until Apply for the same undo/data-loss reason
114
+ // documented in handleCrossScreenElementDrop.
115
+ if (intent.draggedIds.length !== 1) {
116
+ toast.error(t("designEditor.toasts.layerMoveFailed"), {
117
+ duration: 4000,
118
+ });
119
+ return;
120
+ }
121
+ const draggedId = intent.draggedIds[0]!;
122
+ const draggedOwner = codeLayerOwnerByNodeId.get(draggedId);
123
+ if (
124
+ !draggedOwner ||
125
+ effectiveCodeLayerState.lockedIds.has(draggedId) ||
126
+ !boardFileId ||
127
+ draggedOwner.fileId !== boardFileId
128
+ ) {
129
+ toast.error(t("designEditor.toasts.layerMoveFailed"), {
130
+ duration: 4000,
131
+ });
132
+ return;
133
+ }
134
+ const sourceFile = files.find((file) => file.id === draggedOwner.fileId);
135
+ const sourceContent = getLayerMoveSourceContent({
136
+ sourceFileId: draggedOwner.fileId,
137
+ activeFileId: activeFile?.id,
138
+ activeContent: freshActiveContent,
139
+ sourceFileContent: sourceFile?.content,
140
+ sourceContentMap: new Map(),
141
+ });
142
+ const nodeId =
143
+ draggedOwner.node.dataAttributes["data-agent-native-node-id"] ??
144
+ draggedId;
145
+ const prepared = prepareLiveScreenLayerDrop({
146
+ sourceContent,
147
+ destinationContent: destContent,
148
+ nodeId,
149
+ });
150
+ if (prepared.status !== "applied") {
151
+ toast.error(t("designEditor.toasts.layerMoveFailed"), {
152
+ duration: 4000,
153
+ });
154
+ return;
155
+ }
156
+ runtimeStructureInsertRevisionRef.current += 1;
157
+ setRuntimeStructureInsertRequest({
158
+ requestId: runtimeStructureInsertRevisionRef.current,
159
+ screenId: targetFileId,
160
+ html: prepared.html,
161
+ anchor: { selector: "body" },
162
+ placement: "inside",
163
+ });
164
+ return;
165
+ }
166
+
167
+ let nextDestContent = destContent;
168
+ const sourceContentMap = new Map<string, string>();
169
+ const sourceOriginalContentMap = new Map<string, string>();
170
+ const movedNodeSnapshots = new Map<string, CodeLayerNode>();
171
+ const movedNodeIdByDraggedId = new Map<string, string>();
172
+ let moved = false;
173
+
174
+ for (const draggedId of intent.draggedIds) {
175
+ const draggedOwner = codeLayerOwnerByNodeId.get(draggedId);
176
+ if (!draggedOwner || effectiveCodeLayerState.lockedIds.has(draggedId)) {
177
+ continue;
178
+ }
179
+ movedNodeSnapshots.set(draggedId, draggedOwner.node);
180
+ const nodeAttrId =
181
+ draggedOwner.node.dataAttributes["data-agent-native-node-id"] ??
182
+ draggedId;
183
+
184
+ if (draggedOwner.fileId === targetFileId) {
185
+ // Already in this screen — move to the end of <body> (topmost
186
+ // paint / top of the panel's top-level list) via moveNode with no
187
+ // anchor needed: reuse moveNodeBetweenDocuments's own-document
188
+ // append behavior by routing it through itself (source === dest)
189
+ // isn't safe (it would duplicate the node), so instead resolve the
190
+ // body element directly via applyVisualEdit's moveNode against the
191
+ // document's own root container element by falling back to the
192
+ // existing tree ordering: append after the current last top-level
193
+ // sibling in this screen. When there's no other top-level sibling
194
+ // to anchor on, the node is already effectively at the root and
195
+ // there's nothing to do.
196
+ const tree = buildCodeLayerTree(
197
+ buildCodeLayerProjection(nextDestContent),
198
+ );
199
+ const lastRootId = tree[tree.length - 1]?.id;
200
+ if (!lastRootId || lastRootId === draggedId) continue;
201
+ const patch = applyVisualEdit(nextDestContent, {
202
+ kind: "moveNode",
203
+ target: { nodeId: draggedId },
204
+ anchor: { nodeId: lastRootId },
205
+ placement: "after",
206
+ });
207
+ if (patch.result.status !== "applied") {
208
+ toast.error(
209
+ codeLayerPatchMessage(
210
+ patch.result.message,
211
+ t("designEditor.toasts.layerMoveFailed"),
212
+ ),
213
+ { duration: 4000 },
214
+ );
215
+ continue;
216
+ }
217
+ nextDestContent = patch.content;
218
+ moved = true;
219
+ continue;
220
+ }
221
+
222
+ // Cross-file: append into the target screen's body (no anchor ==
223
+ // moveNodeBetweenDocuments's own default append-to-body behavior).
224
+ const sourceFileId = draggedOwner.fileId;
225
+ const srcFile = files.find((f) => f.id === sourceFileId);
226
+ if (!srcFile) continue;
227
+ const currentSourceContent = getLayerMoveSourceContent({
228
+ sourceFileId,
229
+ activeFileId: activeFile?.id,
230
+ activeContent: freshActiveContent,
231
+ sourceFileContent: srcFile.content,
232
+ sourceContentMap,
233
+ });
234
+ if (!sourceOriginalContentMap.has(sourceFileId)) {
235
+ sourceOriginalContentMap.set(sourceFileId, currentSourceContent);
236
+ }
237
+ const result = moveNodeBetweenDocuments(
238
+ currentSourceContent,
239
+ nextDestContent,
240
+ { nodeId: nodeAttrId, placement: "inside" },
241
+ );
242
+ if (result.status !== "applied") {
243
+ toast.error(
244
+ codeLayerPatchMessage(
245
+ result.message,
246
+ t("designEditor.toasts.layerMoveFailed"),
247
+ ),
248
+ { duration: 4000 },
249
+ );
250
+ continue;
251
+ }
252
+ sourceContentMap.set(sourceFileId, result.sourceHtml);
253
+ nextDestContent = result.destHtml;
254
+ movedNodeIdByDraggedId.set(draggedId, result.movedNodeId ?? nodeAttrId);
255
+ moved = true;
256
+ }
257
+
258
+ if (!moved) return;
259
+
260
+ const finalDestProjection = buildCodeLayerProjection(nextDestContent);
261
+ const movedNodesAfterMove = intent.draggedIds
262
+ .map((draggedId) => {
263
+ const node = movedNodeSnapshots.get(draggedId);
264
+ return node
265
+ ? findMovedCodeLayerNodeInProjection(
266
+ finalDestProjection,
267
+ node,
268
+ movedNodeIdByDraggedId.get(draggedId),
269
+ )
270
+ : null;
271
+ })
272
+ .filter((node): node is CodeLayerNode => Boolean(node));
273
+
274
+ if (movedNodesAfterMove.length > 0) {
275
+ setSelectedLayerIdsState(movedNodesAfterMove.map((node) => node.id));
276
+ const lastMovedNode = movedNodesAfterMove[movedNodesAfterMove.length - 1];
277
+ if (lastMovedNode && targetFileId === activeFile?.id) {
278
+ setSelectedElement(elementInfoFromCodeLayerNode(lastMovedNode));
279
+ }
280
+ setExpandedLayerIds((current) => {
281
+ const next = new Set(current);
282
+ next.add(targetFileId);
283
+ return next.size === current.length ? current : Array.from(next);
284
+ });
285
+ }
286
+
287
+ const hasCrossFileMoves = sourceContentMap.size > 0;
288
+ if (hasCrossFileMoves) {
289
+ const crossFileChanges = [
290
+ ...Array.from(sourceContentMap.entries()).map(
291
+ ([sourceFileId, newSourceContent]) => ({
292
+ fileId: sourceFileId,
293
+ before:
294
+ sourceOriginalContentMap.get(sourceFileId) ??
295
+ files.find((file) => file.id === sourceFileId)?.content ??
296
+ "",
297
+ after: newSourceContent,
298
+ }),
299
+ ),
300
+ ...(nextDestContent !== destContent
301
+ ? [
302
+ {
303
+ fileId: targetFileId,
304
+ before: destContent,
305
+ after: nextDestContent,
306
+ },
307
+ ]
308
+ : []),
309
+ ];
310
+ if (viewModeRef.current === "overview") {
311
+ recordContentHistoryEntry({ changes: crossFileChanges });
312
+ } else {
313
+ crossFileChanges.forEach((change) =>
314
+ recordLocalContentHistoryEntry(change),
315
+ );
316
+ }
317
+ }
318
+
319
+ for (const [sourceFileId, newSourceContent] of sourceContentMap) {
320
+ applyFileContentUpdate(sourceFileId, newSourceContent, {
321
+ recordHistory: !hasCrossFileMoves,
322
+ refreshPreview: false,
323
+ });
324
+ }
325
+ if (nextDestContent !== destContent) {
326
+ applyFileContentUpdate(targetFileId, nextDestContent, {
327
+ recordHistory: !hasCrossFileMoves,
328
+ refreshPreview: false,
329
+ });
330
+ }
331
+ }