@agent-native/core 0.80.11 → 0.81.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.
Files changed (225) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +47 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/cli/design-connect.ts +419 -19
  5. package/corpus/core/src/client/ConnectBuilderCard.tsx +1 -0
  6. package/corpus/core/src/client/chat/index.ts +1 -0
  7. package/corpus/core/src/client/chat/run-recovery.tsx +9 -7
  8. package/corpus/core/src/client/chat-view-transition.ts +33 -2
  9. package/corpus/core/src/client/composer/PromptComposer.tsx +21 -2
  10. package/corpus/core/src/client/index.ts +1 -0
  11. package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -4
  12. package/corpus/core/src/client/sharing/ShareButton.tsx +3 -3
  13. package/corpus/core/src/client/use-agent-chat-home-handoff.ts +31 -3
  14. package/corpus/core/src/db/client.ts +29 -2
  15. package/corpus/core/src/provider-api/index.ts +29 -0
  16. package/corpus/core/src/server/core-routes-plugin.ts +58 -20
  17. package/corpus/core/src/styles/agent-native.css +54 -0
  18. package/corpus/core/src/usage/store.ts +2 -2
  19. package/corpus/templates/analytics/app/components/layout/Layout.tsx +118 -10
  20. package/corpus/templates/analytics/app/components/layout/layout-route-policy.ts +7 -0
  21. package/corpus/templates/analytics/app/global.css +8 -0
  22. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +7 -1
  23. package/corpus/templates/analytics/app/lib/chat-handoff.ts +34 -0
  24. package/corpus/templates/analytics/app/pages/Ask.tsx +9 -18
  25. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
  26. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +109 -21
  27. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -6
  28. package/corpus/templates/analytics/changelog/2026-06-30-ask-opens-a-fresh-chat-unless-you-were-just-chatting-and-das.md +6 -0
  29. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-email-reports-are-more-reliable-and-use-cleaner.md +6 -0
  30. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-toolbar-controls-use-a-quieter-share-button-and-ve.md +6 -0
  31. package/corpus/templates/analytics/changelog/2026-06-30-session-replay-rows-show-whole-minute-durations-in-the-playl.md +6 -0
  32. package/corpus/templates/analytics/changelog/2026-06-30-session-replays-now-render-captured-styling-and-keep-the-eve.md +6 -0
  33. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +16 -3
  34. package/corpus/templates/analytics/server/lib/dashboard-report.ts +31 -14
  35. package/corpus/templates/assets/actions/open-asset-picker.ts +9 -0
  36. package/corpus/templates/assets/app/global.css +15 -0
  37. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +4 -0
  38. package/corpus/templates/assets/app/routes/library.tsx +90 -16
  39. package/corpus/templates/assets/changelog/2026-06-30-the-assets-picker-now-supports-a-vertical-embedded-layout-fo.md +6 -0
  40. package/corpus/templates/clips/actions/finalize-recording.ts +1 -12
  41. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +10 -5
  42. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -8
  43. package/corpus/templates/clips/changelog/2026-06-30-extension-save-recovery-avoids-false-upload-failures.md +6 -0
  44. package/corpus/templates/clips/changelog/2026-06-30-longer-chrome-extension-recordings-now-keep-saving-reliably-.md +6 -0
  45. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  46. package/corpus/templates/clips/chrome-extension/src/background.ts +19 -10
  47. package/corpus/templates/clips/chrome-extension/src/content-script.ts +38 -12
  48. package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +224 -0
  49. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +119 -16
  50. package/corpus/templates/clips/chrome-extension/src/overlay.ts +16 -0
  51. package/corpus/templates/clips/server/lib/recording-upload-state.ts +48 -0
  52. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +9 -1
  53. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +63 -13
  54. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +74 -0
  55. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +32 -0
  56. package/corpus/templates/design/AGENTS.md +27 -0
  57. package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1 -1
  58. package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +5 -5
  59. package/corpus/templates/design/actions/apply-component-prop-edit.ts +63 -20
  60. package/corpus/templates/design/actions/apply-motion-edit.ts +67 -69
  61. package/corpus/templates/design/actions/apply-shader-fill.ts +148 -56
  62. package/corpus/templates/design/actions/capture-design-state.ts +27 -4
  63. package/corpus/templates/design/actions/connect-localhost.ts +59 -22
  64. package/corpus/templates/design/actions/export-zip.ts +23 -8
  65. package/corpus/templates/design/actions/generate-design.ts +53 -1
  66. package/corpus/templates/design/actions/get-component-details.ts +5 -19
  67. package/corpus/templates/design/actions/get-motion-timeline.ts +135 -10
  68. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +116 -0
  69. package/corpus/templates/design/actions/import-design-tokens.ts +521 -0
  70. package/corpus/templates/design/actions/index-design-tokens.ts +10 -1
  71. package/corpus/templates/design/actions/insert-design-native-asset.ts +268 -0
  72. package/corpus/templates/design/actions/insert-figma-library-asset.ts +233 -0
  73. package/corpus/templates/design/actions/list-design-extensions.ts +32 -10
  74. package/corpus/templates/design/actions/list-design-native-assets.ts +105 -0
  75. package/corpus/templates/design/actions/list-figma-library-assets.ts +292 -0
  76. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +238 -0
  77. package/corpus/templates/design/actions/navigate.ts +18 -3
  78. package/corpus/templates/design/actions/provider-api-catalog.ts +2 -2
  79. package/corpus/templates/design/actions/provider-api-docs.ts +1 -1
  80. package/corpus/templates/design/actions/provider-api-request.ts +3 -3
  81. package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +48 -0
  82. package/corpus/templates/design/actions/run-design-audit.ts +53 -4
  83. package/corpus/templates/design/actions/run-design-extension-action.ts +1 -1
  84. package/corpus/templates/design/actions/view-screen.ts +1 -1
  85. package/corpus/templates/design/actions/write-local-file.ts +213 -0
  86. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +230 -3308
  87. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +30 -20
  88. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +776 -287
  89. package/corpus/templates/design/app/components/design/EditPanel.tsx +212 -208
  90. package/corpus/templates/design/app/components/design/LayersPanel.tsx +14 -2
  91. package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +161 -0
  92. package/corpus/templates/design/app/components/design/MotionDock.tsx +235 -266
  93. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +490 -55
  94. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +43 -62
  95. package/corpus/templates/design/app/components/design/StatesPanel.tsx +34 -61
  96. package/corpus/templates/design/app/components/design/TokensPanel.tsx +251 -0
  97. package/corpus/templates/design/app/components/design/bridge/codegen.ts +125 -0
  98. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4037 -0
  99. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +62 -0
  100. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +272 -0
  101. package/corpus/templates/design/app/components/design/bridge/nav.bridge.ts +116 -0
  102. package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +24 -0
  103. package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +78 -0
  104. package/corpus/templates/design/app/components/design/bridge/tsconfig.json +17 -0
  105. package/corpus/templates/design/app/components/design/bridge/tweak.bridge.ts +28 -0
  106. package/corpus/templates/design/app/components/design/bridge/zoom.bridge.ts +43 -0
  107. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +45 -16
  108. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +88 -9
  109. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +94 -9
  110. package/corpus/templates/design/app/components/layout/Layout.tsx +19 -3
  111. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  112. package/corpus/templates/design/app/global.css +7 -0
  113. package/corpus/templates/design/app/hooks/use-navigation-state.ts +23 -0
  114. package/corpus/templates/design/app/i18n/zh-TW.ts +21 -0
  115. package/corpus/templates/design/app/i18n-data.ts +358 -0
  116. package/corpus/templates/design/app/lib/pending-generation.ts +1 -0
  117. package/corpus/templates/design/app/pages/DesignEditor.tsx +2402 -499
  118. package/corpus/templates/design/app/pages/Index.tsx +5 -1
  119. package/corpus/templates/design/changelog/2026-06-30-applying-the-one-click-fix-for-a-small-tap-target-accessibil.md +6 -0
  120. package/corpus/templates/design/changelog/2026-06-30-canvas-creation-screen-dragging-undo-redo-and-image-fill-edi.md +6 -0
  121. package/corpus/templates/design/changelog/2026-06-30-component-prop-edits-and-shader-fills-now-preserve-rapid-sam.md +6 -0
  122. package/corpus/templates/design/changelog/2026-06-30-design-can-browse-figma-library-components-and-insert-them-i.md +6 -0
  123. package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +6 -0
  124. package/corpus/templates/design/changelog/2026-06-30-design-now-has-native-components-embedded-media-and-figma-im.md +6 -0
  125. package/corpus/templates/design/changelog/2026-06-30-design-preview-now-includes-a-publish-app-waitlist-option-fr.md +6 -0
  126. package/corpus/templates/design/changelog/2026-06-30-design-s-left-rail-now-matches-the-sidebar-chrome-and-uses-t.md +6 -0
  127. package/corpus/templates/design/changelog/2026-06-30-design-s-tools-create-menu-now-stays-compact-instead-of-rend.md +6 -0
  128. package/corpus/templates/design/changelog/2026-06-30-design-starter-prompts-now-begin-generating-immediately-and-.md +6 -0
  129. package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +6 -0
  130. package/corpus/templates/design/changelog/2026-06-30-drawing-rectangles-on-the-all-screens-canvas-no-longer-flash.md +6 -0
  131. package/corpus/templates/design/changelog/2026-06-30-fixed-code-native-design-studio-edits-so-component-props-mot.md +6 -0
  132. package/corpus/templates/design/changelog/2026-06-30-fixed-visual-editing-hover-overlays-and-spacing-handles-so-s.md +6 -0
  133. package/corpus/templates/design/changelog/2026-06-30-motion-edits-now-save-automatically-without-a-separate-css-a.md +6 -0
  134. package/corpus/templates/design/changelog/2026-06-30-motion-timelines-now-reopen-as-editable-tracks-after-writing.md +6 -0
  135. package/corpus/templates/design/changelog/2026-06-30-new-design-prompts-with-uploaded-screenshots-work-reliably-o.md +6 -0
  136. package/corpus/templates/design/changelog/2026-06-30-screen-previews-in-all-screens-view-now-keep-rounded-outline.md +6 -0
  137. package/corpus/templates/design/changelog/2026-06-30-selection-outlines-now-sit-flush-on-rectangles-drawn-directl.md +6 -0
  138. package/corpus/templates/design/changelog/2026-06-30-share-options-use-a-tighter-design-editor-popover-with-compa.md +6 -0
  139. package/corpus/templates/design/changelog/2026-06-30-the-collapsed-motion-panel-now-stays-tucked-under-the-left-s.md +6 -0
  140. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-now-shows-states-and-review-in-a-tighte.md +6 -0
  141. package/corpus/templates/design/changelog/2026-06-30-the-sidebar-keeps-the-organization-picker-space-stable-while.md +6 -0
  142. package/corpus/templates/design/changelog/2026-06-30-tokens-can-now-be-imported-from-pasted-notes-code-files-fold.md +6 -0
  143. package/corpus/templates/design/e2e/helpers.ts +168 -65
  144. package/corpus/templates/design/package.json +3 -1
  145. package/corpus/templates/design/server/db/schema.ts +23 -0
  146. package/corpus/templates/design/server/handlers/uploads.ts +22 -1
  147. package/corpus/templates/design/server/lib/provider-api.ts +7 -4
  148. package/corpus/templates/design/server/lib/verify-write-grant.ts +108 -0
  149. package/corpus/templates/design/server/plugins/db.ts +39 -0
  150. package/corpus/templates/design/server/register-secrets.ts +38 -0
  151. package/corpus/templates/design/shared/board-file.ts +228 -0
  152. package/corpus/templates/design/shared/board-objects.ts +288 -0
  153. package/corpus/templates/design/shared/code-layer.ts +52 -0
  154. package/corpus/templates/design/shared/motion-compiler.ts +58 -7
  155. package/corpus/templates/design/shared/motion-timeline.ts +2 -2
  156. package/corpus/templates/design/tsconfig.json +2 -1
  157. package/corpus/templates/slides/AGENTS.md +9 -0
  158. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -0
  159. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +4 -24
  160. package/corpus/templates/slides/app/lib/export-pdf-client.ts +29 -20
  161. package/corpus/templates/slides/app/lib/export-pptx-client.ts +365 -0
  162. package/corpus/templates/slides/app/pages/DeckEditor.tsx +12 -9
  163. package/corpus/templates/slides/app/vite-env.d.ts +18 -0
  164. package/corpus/templates/slides/changelog/2026-06-30-powerpoint-downloads-now-preserve-the-rendered-slide-layout-.md +6 -0
  165. package/corpus/templates/slides/changelog/2026-06-30-unavailable-decks-open-in-a-cleaner-full-height-centered-sta.md +6 -0
  166. package/corpus/templates/slides/package.json +1 -0
  167. package/corpus/templates/slides/vite.config.ts +1 -0
  168. package/dist/cli/design-connect.d.ts +25 -0
  169. package/dist/cli/design-connect.d.ts.map +1 -1
  170. package/dist/cli/design-connect.js +357 -18
  171. package/dist/cli/design-connect.js.map +1 -1
  172. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  173. package/dist/client/ConnectBuilderCard.js +1 -0
  174. package/dist/client/ConnectBuilderCard.js.map +1 -1
  175. package/dist/client/chat/index.d.ts +1 -1
  176. package/dist/client/chat/index.d.ts.map +1 -1
  177. package/dist/client/chat/index.js +1 -1
  178. package/dist/client/chat/index.js.map +1 -1
  179. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  180. package/dist/client/chat/run-recovery.js +5 -5
  181. package/dist/client/chat/run-recovery.js.map +1 -1
  182. package/dist/client/chat-view-transition.d.ts +6 -0
  183. package/dist/client/chat-view-transition.d.ts.map +1 -1
  184. package/dist/client/chat-view-transition.js +23 -2
  185. package/dist/client/chat-view-transition.js.map +1 -1
  186. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  187. package/dist/client/composer/PromptComposer.js +3 -2
  188. package/dist/client/composer/PromptComposer.js.map +1 -1
  189. package/dist/client/index.d.ts +1 -1
  190. package/dist/client/index.d.ts.map +1 -1
  191. package/dist/client/index.js +1 -1
  192. package/dist/client/index.js.map +1 -1
  193. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  194. package/dist/client/org/OrgSwitcher.js +11 -4
  195. package/dist/client/org/OrgSwitcher.js.map +1 -1
  196. package/dist/client/sharing/ShareButton.js +3 -3
  197. package/dist/client/sharing/ShareButton.js.map +1 -1
  198. package/dist/client/use-agent-chat-home-handoff.d.ts +8 -2
  199. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
  200. package/dist/client/use-agent-chat-home-handoff.js +20 -6
  201. package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
  202. package/dist/collab/awareness.d.ts +2 -2
  203. package/dist/collab/awareness.d.ts.map +1 -1
  204. package/dist/collab/routes.d.ts +2 -2
  205. package/dist/db/client.d.ts +1 -0
  206. package/dist/db/client.d.ts.map +1 -1
  207. package/dist/db/client.js +28 -2
  208. package/dist/db/client.js.map +1 -1
  209. package/dist/notifications/routes.d.ts +3 -3
  210. package/dist/observability/routes.d.ts +2 -2
  211. package/dist/progress/routes.d.ts +1 -1
  212. package/dist/provider-api/index.d.ts +5 -4
  213. package/dist/provider-api/index.d.ts.map +1 -1
  214. package/dist/provider-api/index.js +28 -0
  215. package/dist/provider-api/index.js.map +1 -1
  216. package/dist/resources/handlers.d.ts +3 -3
  217. package/dist/server/core-routes-plugin.d.ts +25 -0
  218. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  219. package/dist/server/core-routes-plugin.js +43 -18
  220. package/dist/server/core-routes-plugin.js.map +1 -1
  221. package/dist/server/transcribe-voice.d.ts +1 -1
  222. package/dist/styles/agent-native.css +54 -0
  223. package/dist/usage/store.js +2 -2
  224. package/dist/usage/store.js.map +1 -1
  225. package/package.json +1 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Embedded overview bridge — injected into every canvas iframe.
3
+ *
4
+ * A screen preview is a real iframe, so normal wheel events never bubble to
5
+ * the overview canvas underneath. In embedded mode we forward a bounded wheel
6
+ * payload to the parent so the existing canvas wheel handler can pan/zoom
7
+ * exactly as if the pointer were over empty canvas.
8
+ *
9
+ * Runtime placeholder (replaced by DesignCanvas.tsx before injection):
10
+ * __EMBEDDED_WHEEL_FORWARDING_ENABLED__ — boolean literal "true"/"false"
11
+ *
12
+ * Protocol (iframe → parent, only when enabled):
13
+ *
14
+ * { type: 'embedded-canvas-wheel', deltaX, deltaY, deltaZ, deltaMode,
15
+ * clientX, clientY, ctrlKey, metaKey, shiftKey, altKey }
16
+ *
17
+ * Rules:
18
+ * • No import/require of any module (DOM globals only).
19
+ * • No references to outer/module scope (the code runs inside an iframe).
20
+ * • Wrap everything in a self-executing IIFE.
21
+ */
22
+ declare var __EMBEDDED_WHEEL_FORWARDING_ENABLED__: boolean;
23
+
24
+ (function () {
25
+ var enabled = __EMBEDDED_WHEEL_FORWARDING_ENABLED__;
26
+ if (!enabled) return;
27
+ function clamp(value: number, limit: number): number {
28
+ var number = Number(value) || 0;
29
+ if (number > limit) return limit;
30
+ if (number < -limit) return -limit;
31
+ return number;
32
+ }
33
+ function onWheel(e: WheelEvent): void {
34
+ e.preventDefault();
35
+ e.stopPropagation();
36
+ if (e.stopImmediatePropagation) e.stopImmediatePropagation();
37
+ try {
38
+ (window.parent as Window).postMessage(
39
+ {
40
+ type: "embedded-canvas-wheel",
41
+ deltaX: clamp(e.deltaX, 240),
42
+ deltaY: clamp(e.deltaY, 240),
43
+ deltaZ: clamp(e.deltaZ, 240),
44
+ deltaMode: e.deltaMode,
45
+ clientX: e.clientX,
46
+ clientY: e.clientY,
47
+ ctrlKey: !!e.ctrlKey,
48
+ metaKey: !!e.metaKey,
49
+ shiftKey: !!e.shiftKey,
50
+ altKey: !!e.altKey,
51
+ },
52
+ "*",
53
+ );
54
+ } catch (_err) {}
55
+ }
56
+ var wheelTarget: EventTarget =
57
+ document.documentElement || document.body || document;
58
+ wheelTarget.addEventListener("wheel", onWheel as EventListener, {
59
+ passive: false,
60
+ capture: true,
61
+ });
62
+ })();
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Lightweight hit-test bridge — injected into every inline canvas iframe so the
3
+ * parent editor can resolve drop-anchor positions via postMessage without a full
4
+ * editor-chrome bridge in non-edit views (e.g. multi-screen overview).
5
+ *
6
+ * Protocol (parent → iframe via postMessage):
7
+ * { type: 'agent-native:hit-test', correlationId: string, x: number, y: number }
8
+ * where x/y are in this iframe's viewport coordinate space.
9
+ *
10
+ * Reply (iframe → window.parent):
11
+ * { type: 'agent-native:hit-test-result', correlationId: string,
12
+ * anchorNodeId: string, placement: 'before'|'after'|'inside' }
13
+ *
14
+ * Reads DOM only — no mutations, no event interception. The container-drop and
15
+ * placement logic is intentionally kept in sync with the corresponding helpers
16
+ * inside editor-chrome.bridge.ts (search for "// keep in sync with
17
+ * hit-test.bridge.ts" comments there).
18
+ *
19
+ * Rules:
20
+ * • No import/require of any module (DOM globals only).
21
+ * • No references to outer/module scope (the code runs inside an iframe).
22
+ * • Wrap everything in a self-executing IIFE.
23
+ */
24
+ (function () {
25
+ // keep in sync with editor-chrome.bridge.ts container/leaf/text tag lists
26
+ var BRIDGE_CONTAINER_TAGS = [
27
+ "div",
28
+ "section",
29
+ "main",
30
+ "header",
31
+ "footer",
32
+ "nav",
33
+ "article",
34
+ "aside",
35
+ "form",
36
+ "ul",
37
+ "ol",
38
+ "figure",
39
+ "fieldset",
40
+ "details",
41
+ "dialog",
42
+ "blockquote",
43
+ "table",
44
+ "tbody",
45
+ "thead",
46
+ "tr",
47
+ ];
48
+ var BRIDGE_LEAF_TAGS = [
49
+ "img",
50
+ "video",
51
+ "picture",
52
+ "audio",
53
+ "canvas",
54
+ "svg",
55
+ "path",
56
+ "input",
57
+ "textarea",
58
+ "select",
59
+ "br",
60
+ "hr",
61
+ "iframe",
62
+ ];
63
+ var BRIDGE_TEXT_TAGS = [
64
+ "p",
65
+ "h1",
66
+ "h2",
67
+ "h3",
68
+ "h4",
69
+ "h5",
70
+ "h6",
71
+ "span",
72
+ "a",
73
+ "strong",
74
+ "em",
75
+ "label",
76
+ "li",
77
+ ];
78
+
79
+ function isOverlayElement(el: Element | null): boolean {
80
+ return Boolean(
81
+ el && el.closest && el.closest("[data-agent-native-edit-overlay]"),
82
+ );
83
+ }
84
+
85
+ function isLayerInteractionBlocked(el: Element | null): boolean {
86
+ if (!el) return false;
87
+ if (
88
+ el.closest &&
89
+ el.closest(
90
+ '[data-agent-native-locked="true"],[data-agent-native-hidden="true"]',
91
+ )
92
+ )
93
+ return true;
94
+ return false;
95
+ }
96
+
97
+ // keep in sync with editor-chrome.bridge.ts isContainerDropTarget
98
+ function isContainerDropTarget(el: Element | null): boolean {
99
+ if (!el || el === document.documentElement) return false;
100
+ if (isOverlayElement(el) || isLayerInteractionBlocked(el)) return false;
101
+ if (el === document.body) return true;
102
+ var tag = (el.tagName || "").toLowerCase();
103
+ if (
104
+ BRIDGE_LEAF_TAGS.indexOf(tag) !== -1 ||
105
+ BRIDGE_TEXT_TAGS.indexOf(tag) !== -1
106
+ )
107
+ return false;
108
+ var cs = window.getComputedStyle(el);
109
+ if (
110
+ cs.display === "flex" ||
111
+ cs.display === "inline-flex" ||
112
+ cs.display === "grid" ||
113
+ cs.display === "inline-grid"
114
+ )
115
+ return true;
116
+ return BRIDGE_CONTAINER_TAGS.indexOf(tag) !== -1;
117
+ }
118
+
119
+ // keep in sync with editor-chrome.bridge.ts elementFromEditorPoint
120
+ function elementFromEditorPoint(
121
+ clientX: number,
122
+ clientY: number,
123
+ ): Element | null {
124
+ var targets: Element[] = document.elementsFromPoint
125
+ ? document.elementsFromPoint(clientX, clientY)
126
+ : ([document.elementFromPoint(clientX, clientY)] as Element[]);
127
+ for (var i = 0; i < targets.length; i += 1) {
128
+ var target = targets[i];
129
+ if (!target || target.nodeType !== 1) continue;
130
+ // Skip injected bridge overlays so they don't shadow real content.
131
+ if (isOverlayElement(target)) continue;
132
+ if (isLayerInteractionBlocked(target)) return null;
133
+ return target;
134
+ }
135
+ return null;
136
+ }
137
+
138
+ // keep in sync with editor-chrome.bridge.ts parentFlowAxis
139
+ function parentFlowAxis(parent: Element): string {
140
+ var cs = window.getComputedStyle(parent);
141
+ if (cs.display === "flex" || cs.display === "inline-flex") {
142
+ var isRow = cs.flexDirection && cs.flexDirection.indexOf("row") === 0;
143
+ var wraps = cs.flexWrap === "wrap" || cs.flexWrap === "wrap-reverse";
144
+ if (isRow && !wraps) return "x";
145
+ return "y";
146
+ }
147
+ if (cs.display === "grid" || cs.display === "inline-grid") {
148
+ var cols = (cs.gridTemplateColumns || "")
149
+ .split(" ")
150
+ .filter(Boolean).length;
151
+ return cols > 1 ? "x" : "y";
152
+ }
153
+ return "y";
154
+ }
155
+
156
+ // keep in sync with editor-chrome.bridge.ts edgePlacementForRect
157
+ function edgePlacementForRect(
158
+ rect: DOMRect,
159
+ axis: string,
160
+ clientX: number,
161
+ clientY: number,
162
+ ): string | null {
163
+ var size = axis === "x" ? rect.width : rect.height;
164
+ if (!size) return null;
165
+ var offset = axis === "x" ? clientX - rect.left : clientY - rect.top;
166
+ if (offset < size * 0.22) return "before";
167
+ if (offset > size * 0.78) return "after";
168
+ return null;
169
+ }
170
+
171
+ function draggableElementChildren(parent: Element): Element[] {
172
+ return Array.prototype.slice.call(parent.children).filter(function (
173
+ child: Element,
174
+ ) {
175
+ return (
176
+ child.nodeType === 1 &&
177
+ !isOverlayElement(child) &&
178
+ !isLayerInteractionBlocked(child)
179
+ );
180
+ });
181
+ }
182
+
183
+ function getNodeId(el: Element | null): string {
184
+ if (!el) return "";
185
+ return (
186
+ el.getAttribute("data-agent-native-node-id") ||
187
+ el.getAttribute("data-code-layer-id") ||
188
+ el.getAttribute("data-layer-id") ||
189
+ el.getAttribute("data-builder-id") ||
190
+ el.id ||
191
+ ""
192
+ );
193
+ }
194
+
195
+ /**
196
+ * Resolve the deepest container element under (x, y) and a placement hint,
197
+ * mirroring reorderTargetForPoint from editor-chrome.bridge.ts but
198
+ * without a dragged element (we only need the anchor + placement).
199
+ *
200
+ * keep in sync with editor-chrome.bridge.ts reorderTargetForPoint
201
+ */
202
+ function resolveHitTarget(
203
+ clientX: number,
204
+ clientY: number,
205
+ ): { anchor: Element; placement: string } | null {
206
+ var hit = elementFromEditorPoint(clientX, clientY);
207
+ if (!hit || hit === document.documentElement) return null;
208
+
209
+ if (isContainerDropTarget(hit)) {
210
+ var containerRect = hit.getBoundingClientRect();
211
+ var edgeAxis = hit.parentElement
212
+ ? parentFlowAxis(hit.parentElement)
213
+ : parentFlowAxis(hit);
214
+ var edgePlacement = edgePlacementForRect(
215
+ containerRect,
216
+ edgeAxis,
217
+ clientX,
218
+ clientY,
219
+ );
220
+ if (!edgePlacement) {
221
+ return { anchor: hit, placement: "inside" };
222
+ }
223
+ return { anchor: hit, placement: edgePlacement };
224
+ }
225
+
226
+ // Non-container: use sibling before/after placement.
227
+ var hitParent = hit.parentElement;
228
+ if (hitParent) {
229
+ var hitAxis = parentFlowAxis(hitParent);
230
+ var hitRect = hit.getBoundingClientRect();
231
+ var hitCenter =
232
+ hitAxis === "x"
233
+ ? hitRect.left + hitRect.width / 2
234
+ : hitRect.top + hitRect.height / 2;
235
+ var hitPointer = hitAxis === "x" ? clientX : clientY;
236
+ return {
237
+ anchor: hit,
238
+ placement: hitPointer < hitCenter ? "before" : "after",
239
+ };
240
+ }
241
+
242
+ // Fallback: body-level, treat as inside.
243
+ if (hit === document.body || !hit.parentElement) {
244
+ return { anchor: document.body, placement: "inside" };
245
+ }
246
+
247
+ return null;
248
+ }
249
+
250
+ window.addEventListener("message", function (e: MessageEvent) {
251
+ if (e.source !== window.parent) return;
252
+ if (!e.data || e.data.type !== "agent-native:hit-test") return;
253
+ var correlationId: string = e.data.correlationId;
254
+ var x: number = Number(e.data.x);
255
+ var y: number = Number(e.data.y);
256
+ if (!correlationId) return;
257
+ var result = resolveHitTarget(x, y);
258
+ var anchorNodeId: string = result ? getNodeId(result.anchor) : "";
259
+ var placement: string = result ? result.placement : "inside";
260
+ try {
261
+ (window.parent as Window).postMessage(
262
+ {
263
+ type: "agent-native:hit-test-result",
264
+ correlationId: correlationId,
265
+ anchorNodeId: anchorNodeId,
266
+ placement: placement,
267
+ },
268
+ "*",
269
+ );
270
+ } catch (_err) {}
271
+ });
272
+ })();
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Navigation bridge — injected into every canvas iframe.
3
+ *
4
+ * ALWAYS injected. A prototype lives in a `srcdoc` iframe, so a plain
5
+ * `<a href="/pricing">` resolves the relative URL against the PARENT app
6
+ * document and navigates the iframe to the Design app itself ("Design not
7
+ * found"), nuking the prototype. We intercept link clicks + relative form
8
+ * submits and route them to the parent instead:
9
+ * - in-page anchors (`#...`) and `javascript:`/`@click` handlers: left alone
10
+ * - external `http(s)`/`//` links: opened in a new tab by the parent
11
+ * - internal/relative links (or an explicit `data-screen`): asked to switch
12
+ * to the matching screen in a multi-screen design; otherwise a no-op so the
13
+ * prototype never blows itself away.
14
+ *
15
+ * Protocol (iframe → parent):
16
+ *
17
+ * { type: 'prototype-navigate', href: string, screen: string }
18
+ * Sent when the user clicks an internal link or a `data-screen` element.
19
+ *
20
+ * Rules:
21
+ * • No import/require of any module (DOM globals only).
22
+ * • No references to outer/module scope (the code runs inside an iframe).
23
+ * • Wrap everything in a self-executing IIFE.
24
+ */
25
+ (function () {
26
+ function classify(
27
+ href: string,
28
+ ): { external: boolean; href: string; screen?: string } | null {
29
+ var h = (href || "").trim();
30
+ if (!h) return null;
31
+ var lower = h.toLowerCase();
32
+ if (lower.charAt(0) === "#") return null;
33
+ if (lower.indexOf("javascript:") === 0) return null;
34
+ if (lower.indexOf("mailto:") === 0 || lower.indexOf("tel:") === 0) {
35
+ return { external: true, href: h };
36
+ }
37
+ if (/^https?:\/\//i.test(h) || /^\/\//.test(h)) {
38
+ return { external: true, href: h };
39
+ }
40
+ var screen = h.replace(/^\.?\//, "").split(/[?#]/)[0];
41
+ return { external: false, href: h, screen: screen };
42
+ }
43
+ document.addEventListener(
44
+ "click",
45
+ function (e: MouseEvent) {
46
+ var t = e.target as Element | null;
47
+ if (!t || !t.closest) return;
48
+ var a = t.closest("a[href], [data-screen]") as HTMLElement | null;
49
+ if (!a) return;
50
+ var ds = a.getAttribute && a.getAttribute("data-screen");
51
+ // In-page anchors ('#...') and empty hrefs must be handled in-document.
52
+ // A srcdoc document resolves '#'/'' against the PARENT app URL, so the
53
+ // browser's default action would navigate the iframe to the app itself.
54
+ if (!ds) {
55
+ var rawHref = a.getAttribute("href");
56
+ if (rawHref != null) {
57
+ var hh = rawHref.trim();
58
+ if (hh === "" || hh.charAt(0) === "#") {
59
+ e.preventDefault();
60
+ var fid = hh.charAt(0) === "#" ? hh.slice(1) : "";
61
+ var tgt = fid ? document.getElementById(fid) : null;
62
+ if (tgt && tgt.scrollIntoView) {
63
+ tgt.scrollIntoView({ behavior: "smooth", block: "start" });
64
+ } else {
65
+ window.scrollTo({ top: 0, behavior: "smooth" });
66
+ }
67
+ return;
68
+ }
69
+ }
70
+ }
71
+ var info = ds
72
+ ? {
73
+ external: false,
74
+ href: ds,
75
+ screen: ds.replace(/^\.?\//, "").split(/[?#]/)[0],
76
+ }
77
+ : classify(a.getAttribute("href") || "");
78
+ if (!info) return;
79
+ if (info.external) {
80
+ // Open external links in a new tab from the iframe itself (the sandbox
81
+ // grants allow-popups), bound to this real user click. We deliberately
82
+ // do NOT round-trip through the parent: a parent window.open() driven
83
+ // by postMessage would let any script in here spawn popups without a
84
+ // gesture.
85
+ try {
86
+ a.setAttribute("target", "_blank");
87
+ a.setAttribute("rel", "noopener noreferrer");
88
+ } catch (_err) {}
89
+ return; // allow the native click to proceed
90
+ }
91
+ e.preventDefault();
92
+ try {
93
+ (window.parent as Window).postMessage(
94
+ {
95
+ type: "prototype-navigate",
96
+ href: info.href,
97
+ screen: info.screen || "",
98
+ },
99
+ "*",
100
+ );
101
+ } catch (_err) {}
102
+ },
103
+ true,
104
+ );
105
+ document.addEventListener(
106
+ "submit",
107
+ function (e: SubmitEvent) {
108
+ var f = e.target as HTMLFormElement | null;
109
+ if (!f || f.tagName !== "FORM") return;
110
+ var action = f.getAttribute("action") || "";
111
+ if (/^https?:\/\//i.test(action)) return;
112
+ e.preventDefault();
113
+ },
114
+ true,
115
+ );
116
+ })();
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Sample bridge — proves the compile-time pipeline.
3
+ *
4
+ * Rules that every *.bridge.ts MUST follow:
5
+ * • No import/require of any module (DOM globals only).
6
+ * • No references to outer/module scope (the code runs inside an iframe).
7
+ * • Wrap everything in a self-executing IIFE.
8
+ * • Type-only imports (erased by tsc) are permitted if needed for doc purposes,
9
+ * but in practice they are unnecessary since no app types are reachable here.
10
+ */
11
+ (function () {
12
+ window.addEventListener("message", function (e: MessageEvent) {
13
+ if (!e.data || e.data.type !== "agent-native:sample-ping") return;
14
+ var correlationId: string = e.data.correlationId ?? "";
15
+ try {
16
+ (window.parent as Window).postMessage(
17
+ { type: "agent-native:sample-pong", correlationId },
18
+ "*",
19
+ );
20
+ } catch (_err) {
21
+ // Cross-origin errors are silently swallowed.
22
+ }
23
+ });
24
+ })();
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Shader-fill preview bridge — injected into every canvas iframe.
3
+ *
4
+ * Allows the parent to apply a CSS gradient approximation of a shader fill to
5
+ * the currently-selected element WITHOUT persisting anything.
6
+ *
7
+ * Protocol (parent → iframe):
8
+ *
9
+ * { type: 'shader-fill-preview', selector, nodeId, css }
10
+ * Apply `css` as the `background` inline style on the first element that
11
+ * matches `selector` (preferred) or `[data-agent-native-node-id="nodeId"]`.
12
+ * When both are absent, targets `document.body`. Stores the previous
13
+ * background value so it can be restored on clear.
14
+ * Preview-only — never writes to DB, Yjs, or source files.
15
+ *
16
+ * { type: 'shader-fill-preview-clear' }
17
+ * Remove the applied background override and restore the previous value.
18
+ * Called when the user discards the preview or switches selections.
19
+ *
20
+ * Rules:
21
+ * • No import/require of any module (DOM globals only).
22
+ * • No references to outer/module scope (the code runs inside an iframe).
23
+ * • Wrap everything in a self-executing IIFE.
24
+ */
25
+ (function () {
26
+ // Track the element we patched and its original background so we can undo.
27
+ var patchedEl: HTMLElement | null = null;
28
+ var originalBackground = "";
29
+
30
+ function resolveTarget(selector: string, nodeId: string): HTMLElement | null {
31
+ if (selector) {
32
+ try {
33
+ var hit = document.querySelector(selector) as HTMLElement | null;
34
+ if (hit) return hit;
35
+ } catch (_err) {}
36
+ }
37
+ if (nodeId) {
38
+ var byId = document.querySelector(
39
+ '[data-agent-native-node-id="' + nodeId.replace(/"/g, '\\"') + '"]',
40
+ ) as HTMLElement | null;
41
+ if (byId) return byId;
42
+ }
43
+ return document.body;
44
+ }
45
+
46
+ function applyPreview(selector: string, nodeId: string, css: string): void {
47
+ // Clear any prior patch first so we don't stack patches.
48
+ clearPreview();
49
+ var el = resolveTarget(selector, nodeId);
50
+ if (!el) return;
51
+ originalBackground = el.style.background || "";
52
+ el.style.background = css || "";
53
+ patchedEl = el;
54
+ }
55
+
56
+ function clearPreview(): void {
57
+ if (!patchedEl) return;
58
+ patchedEl.style.background = originalBackground;
59
+ patchedEl = null;
60
+ originalBackground = "";
61
+ }
62
+
63
+ window.addEventListener("message", function (e: MessageEvent) {
64
+ if (e.source !== window.parent) return;
65
+ if (!e.data || typeof e.data.type !== "string") return;
66
+ if (e.data.type === "shader-fill-preview") {
67
+ var selector = typeof e.data.selector === "string" ? e.data.selector : "";
68
+ var nodeId = typeof e.data.nodeId === "string" ? e.data.nodeId : "";
69
+ var css = typeof e.data.css === "string" ? e.data.css : "";
70
+ applyPreview(selector, nodeId, css);
71
+ return;
72
+ }
73
+ if (e.data.type === "shader-fill-preview-clear") {
74
+ clearPreview();
75
+ return;
76
+ }
77
+ });
78
+ })();
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "compilerOptions": {
4
+ "target": "ES2020",
5
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "isolatedModules": true,
9
+ "strict": true,
10
+ "noEmit": true,
11
+ "skipLibCheck": false,
12
+ "types": [],
13
+ "paths": {}
14
+ },
15
+ "include": ["./*.bridge.ts"],
16
+ "exclude": []
17
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tweak bridge — injected into every canvas iframe.
3
+ *
4
+ * ALWAYS injected so the parent's postMessage (`tweak-values`) can update CSS
5
+ * custom properties on the iframe's :root regardless of which editor mode is
6
+ * active. Without this the tweak panel silently no-ops in Comment mode.
7
+ *
8
+ * Protocol (parent → iframe):
9
+ *
10
+ * { type: 'tweak-values', values: Record<string, string> }
11
+ * Apply each key/value pair as a CSS custom property on :root.
12
+ *
13
+ * Rules:
14
+ * • No import/require of any module (DOM globals only).
15
+ * • No references to outer/module scope (the code runs inside an iframe).
16
+ * • Wrap everything in a self-executing IIFE.
17
+ */
18
+ (function () {
19
+ window.addEventListener("message", function (e: MessageEvent) {
20
+ if (e.source !== window.parent) return;
21
+ if (!e.data || e.data.type !== "tweak-values") return;
22
+ var root = document.documentElement;
23
+ var vals: Record<string, string> = e.data.values || {};
24
+ Object.keys(vals).forEach(function (k: string) {
25
+ root.style.setProperty(k, vals[k]);
26
+ });
27
+ });
28
+ })();
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Pinch-zoom bridge — injected into every canvas iframe.
3
+ *
4
+ * Forwards trackpad pinch / Cmd-Ctrl+scroll wheel events from inside the
5
+ * iframe to the parent window. Wheel events don't naturally bubble out of an
6
+ * iframe, so without this the user can only pinch in the empty area around the
7
+ * canvas, not over the design itself.
8
+ *
9
+ * Protocol (iframe → parent):
10
+ *
11
+ * { type: 'pinch-zoom-wheel', deltaY, clientX, clientY }
12
+ *
13
+ * Rules:
14
+ * • No import/require of any module (DOM globals only).
15
+ * • No references to outer/module scope (the code runs inside an iframe).
16
+ * • Wrap everything in a self-executing IIFE.
17
+ */
18
+ (function () {
19
+ // Attach to documentElement (not window/document) so { passive: false }
20
+ // is honored consistently and the browser doesn't natively pinch-zoom the
21
+ // iframe's own document alongside the parent's zoom.
22
+ var target: EventTarget =
23
+ document.documentElement || document.body || document;
24
+ function onWheel(e: WheelEvent): void {
25
+ if (!(e.ctrlKey || e.metaKey)) return;
26
+ e.preventDefault();
27
+ try {
28
+ (window.parent as Window).postMessage(
29
+ {
30
+ type: "pinch-zoom-wheel",
31
+ deltaY: e.deltaY,
32
+ clientX: e.clientX,
33
+ clientY: e.clientY,
34
+ },
35
+ "*",
36
+ );
37
+ } catch (_err) {}
38
+ }
39
+ target.addEventListener("wheel", onWheel as EventListener, {
40
+ passive: false,
41
+ capture: true,
42
+ });
43
+ })();