@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
@@ -249,6 +249,7 @@ export default function Index() {
249
249
  prompt: string,
250
250
  files: UploadedFile[],
251
251
  options: PromptComposerSubmitOptions,
252
+ pendingOptions?: { skipQuestions?: boolean },
252
253
  ) => {
253
254
  // Derive a short title from the prompt — first line, ~40 chars max,
254
255
  // word-boundary truncated. The full prompt still drives generation;
@@ -266,6 +267,7 @@ export default function Index() {
266
267
  files,
267
268
  title,
268
269
  designSystemId,
270
+ skipQuestions: pendingOptions?.skipQuestions,
269
271
  ...options,
270
272
  });
271
273
 
@@ -425,7 +427,9 @@ export default function Index() {
425
427
  ) : designs.length === 0 ? (
426
428
  <EmptyState
427
429
  onCreateDesign={openNewDesign}
428
- onStarterPrompt={(prompt) => handleSubmitPrompt(prompt, [], {})}
430
+ onStarterPrompt={(prompt) =>
431
+ handleSubmitPrompt(prompt, [], {}, { skipQuestions: true })
432
+ }
429
433
  />
430
434
  ) : (
431
435
  <>
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Applying the one-click fix for a small tap-target accessibility finding now clears it on re-audit instead of having it reappear
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Canvas creation, screen dragging, undo/redo, and image fill edits are more reliable in the visual editor.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Component prop edits and shader fills now preserve rapid same-tab Design Studio changes.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design can browse Figma library components and insert them into the active screen with source provenance.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design now has a Figma-style left rail for File, Agent, Assets, Tools, and Tokens.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design now has native components, embedded media, and Figma imports as separate asset tabs.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design preview now includes a publish app waitlist option from the play menu.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design's left rail now matches the sidebar chrome and uses tighter labels.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design's Tools create menu now stays compact instead of rendering the full chat setup flow.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design starter prompts now begin generating immediately and avoid stalled native tool calls.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design tools now use a quieter Figma-style list layout.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Drawing rectangles on the all screens canvas no longer flashes a default-size preview and selects the new rectangle.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Fixed Code-Native Design Studio edits so component props, motion CSS, shader fills, audits, and exports persist cleanly.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Fixed visual editing hover overlays and spacing handles so selection stays steady.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Motion edits now save automatically without a separate CSS apply button.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Motion timelines now reopen as editable tracks after writing keyframes to CSS.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ New design prompts with uploaded screenshots work reliably on hosted deployments.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Screen previews in all-screens view now keep rounded outlines visible at the corners.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Selection outlines now sit flush on rectangles drawn directly on the all screens canvas.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Share options use a tighter Design editor popover with compact tabs and controls.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The Motion timeline now opens from a quiet footer row in the Layers panel.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The Design inspector now shows States and Review in a tighter, less noisy sidebar layout.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ The sidebar keeps the organization picker space stable while account details load.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Tokens can now be imported from pasted notes, code files, folders, or the current design instead of entering each one by hand.
@@ -1,7 +1,14 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
 
4
- import { expect, type Page, type FrameLocator } from "@playwright/test";
4
+ import {
5
+ expect,
6
+ type Page,
7
+ type FrameLocator,
8
+ type Locator,
9
+ } from "@playwright/test";
10
+
11
+ import { FIXTURE_HTML, SEED_TITLE } from "./global-setup";
5
12
 
6
13
  /**
7
14
  * Helpers for driving the Design visual editor in real Chrome.
@@ -25,15 +32,122 @@ export async function readSeedDesignId(): Promise<string> {
25
32
  return designId;
26
33
  }
27
34
 
35
+ function e2eBaseUrl(page: Page): string {
36
+ const currentUrl = page.url();
37
+ if (currentUrl && currentUrl !== "about:blank") {
38
+ return new URL(currentUrl).origin;
39
+ }
40
+ return (
41
+ process.env.E2E_BASE_URL ??
42
+ `http://127.0.0.1:${process.env.E2E_PORT ?? "9333"}`
43
+ );
44
+ }
45
+
46
+ async function postAction(
47
+ page: Page,
48
+ name: string,
49
+ input: Record<string, unknown>,
50
+ ): Promise<any> {
51
+ const res = await page.request.post(
52
+ `${e2eBaseUrl(page)}/_agent-native/actions/${name}`,
53
+ {
54
+ data: input,
55
+ headers: { "Content-Type": "application/json" },
56
+ },
57
+ );
58
+ if (!res.ok()) {
59
+ throw new Error(
60
+ `action ${name} failed: ${res.status()} ${await res.text()}`,
61
+ );
62
+ }
63
+ return res.json();
64
+ }
65
+
66
+ export async function createFixtureDesign(
67
+ page: Page,
68
+ title = SEED_TITLE,
69
+ ): Promise<string> {
70
+ const created = await postAction(page, "create-design", {
71
+ title,
72
+ projectType: "prototype",
73
+ });
74
+ const designId: string | undefined =
75
+ created?.id ?? created?.data?.id ?? created?.design?.id;
76
+ if (!designId) {
77
+ throw new Error(
78
+ `create-design did not return an id: ${JSON.stringify(created)}`,
79
+ );
80
+ }
81
+ await postAction(page, "create-file", {
82
+ designId,
83
+ filename: "index.html",
84
+ content: FIXTURE_HTML,
85
+ fileType: "html",
86
+ });
87
+ return designId;
88
+ }
89
+
28
90
  const DESIGN_PREVIEW_IFRAME_SELECTOR = "iframe[data-design-preview-iframe]";
91
+ const E2E_BASE_URL = process.env.E2E_BASE_URL;
92
+ const E2E_BASE_PATH = (() => {
93
+ if (!E2E_BASE_URL) return "";
94
+ try {
95
+ return new URL(E2E_BASE_URL).pathname.replace(/\/$/, "");
96
+ } catch {
97
+ return "";
98
+ }
99
+ })();
100
+
101
+ export function appPath(path: string): string {
102
+ const route = new URL(path, "http://agent-native.local");
103
+ if (E2E_BASE_URL && E2E_BASE_PATH) {
104
+ const url = new URL(E2E_BASE_URL);
105
+ // dev-lazy strips the app mount (/design) before handing the request to the
106
+ // app, so the editor's own /design/:id route intentionally becomes
107
+ // /design/design/:id when E2E_BASE_URL points at the gateway mount.
108
+ url.pathname = `${E2E_BASE_PATH}${route.pathname}`;
109
+ url.search = route.search;
110
+ url.hash = route.hash;
111
+ return url.toString();
112
+ }
113
+ return `${route.pathname}${route.search}${route.hash}`;
114
+ }
29
115
 
30
116
  export function designFrame(page: Page): FrameLocator {
31
- return page.locator(DESIGN_PREVIEW_IFRAME_SELECTOR).first().contentFrame();
117
+ return page.locator(DESIGN_PREVIEW_IFRAME_SELECTOR).last().contentFrame();
118
+ }
119
+
120
+ async function selectableNodeByText(
121
+ page: Page,
122
+ text: string,
123
+ ): Promise<Locator> {
124
+ const candidates = designFrame(page).locator("[data-agent-native-node-id]", {
125
+ hasText: text,
126
+ });
127
+ const fallback = designFrame(page).getByText(text, { exact: false }).first();
128
+ const count = await candidates.count();
129
+ if (count === 0) return fallback;
130
+
131
+ let bestIndex = 0;
132
+ let bestArea = Number.POSITIVE_INFINITY;
133
+ for (let index = 0; index < count; index += 1) {
134
+ const candidate = candidates.nth(index);
135
+ const box = await candidate.boundingBox().catch(() => null);
136
+ if (!box || box.width <= 0 || box.height <= 0) continue;
137
+ const area = box.width * box.height;
138
+ if (area < bestArea) {
139
+ bestIndex = index;
140
+ bestArea = area;
141
+ }
142
+ }
143
+ return candidates.nth(bestIndex);
32
144
  }
33
145
 
34
146
  /** Open the editor for a design and wait for the toolbar + iframe to be ready. */
35
147
  export async function gotoEditor(page: Page, designId: string): Promise<void> {
36
- await page.goto(`/design/${designId}`, { waitUntil: "domcontentloaded" });
148
+ await page.goto(appPath(`/design/${designId}`), {
149
+ waitUntil: "domcontentloaded",
150
+ });
37
151
  await expect(
38
152
  page.getByRole("button", { name: "Move", exact: true }),
39
153
  ).toBeVisible({ timeout: 30_000 });
@@ -44,9 +158,16 @@ async function waitForDesignBridgeReady(page: Page): Promise<void> {
44
158
  await expect(
45
159
  page.locator(DESIGN_PREVIEW_IFRAME_SELECTOR).first(),
46
160
  ).toBeVisible();
47
- await expect(
48
- designFrame(page).locator('[data-agent-native-edit-overlay="shield"]'),
49
- ).toBeVisible({ timeout: 10_000 });
161
+ const overviewChromeVisible = await page
162
+ .getByRole("button", { name: "Full view", exact: true })
163
+ .first()
164
+ .isVisible()
165
+ .catch(() => false);
166
+ if (!overviewChromeVisible) {
167
+ await expect(
168
+ designFrame(page).locator('[data-agent-native-edit-overlay="shield"]'),
169
+ ).toBeVisible({ timeout: 10_000 });
170
+ }
50
171
  // Wait for the iframe bridge to stamp at least one selectable node.
51
172
  await expect
52
173
  .poll(
@@ -57,6 +178,25 @@ async function waitForDesignBridgeReady(page: Page): Promise<void> {
57
178
  { timeout: 20_000 },
58
179
  )
59
180
  .toBeGreaterThan(0);
181
+ if (overviewChromeVisible) {
182
+ await expect(page.locator("[data-screen-shell]").first()).toBeVisible({
183
+ timeout: 10_000,
184
+ });
185
+ await expect
186
+ .poll(
187
+ async () => {
188
+ const box = await page
189
+ .locator("[data-screen-shell]")
190
+ .first()
191
+ .locator("[data-screen-card]")
192
+ .boundingBox();
193
+ return box && box.width > 0 && box.height > 0;
194
+ },
195
+ { timeout: 10_000 },
196
+ )
197
+ .toBeTruthy();
198
+ await page.waitForTimeout(750);
199
+ }
60
200
  }
61
201
 
62
202
  export async function enterDirectMode(page: Page): Promise<void> {
@@ -76,7 +216,7 @@ export async function enterDirectMode(page: Page): Promise<void> {
76
216
  (
77
217
  await page
78
218
  .locator(DESIGN_PREVIEW_IFRAME_SELECTOR)
79
- .first()
219
+ .last()
80
220
  .boundingBox()
81
221
  )?.width ?? 0,
82
222
  { timeout: 10_000 },
@@ -135,7 +275,7 @@ export async function selectByText(page: Page, text: string): Promise<any> {
135
275
  await enterDirectMode(page);
136
276
  await installBridge(page);
137
277
  await page.evaluate(() => ((window as any).__bridge = []));
138
- const target = designFrame(page).getByText(text, { exact: false }).first();
278
+ const target = await selectableNodeByText(page, text);
139
279
  await target.waitFor({ state: "visible", timeout: 8_000 });
140
280
  const box = await target.boundingBox();
141
281
  if (!box) throw new Error(`no bounding box for "${text}"`);
@@ -157,60 +297,25 @@ async function dispatchShieldClickByText(
157
297
  page: Page,
158
298
  text: string,
159
299
  ): Promise<void> {
300
+ const target = await selectableNodeByText(page, text);
301
+ await target.waitFor({ state: "visible", timeout: 8_000 });
302
+ const rect = await target.boundingBox();
303
+ if (!rect) throw new Error(`unable to dispatch selection for "${text}"`);
304
+ const frameRect = await page
305
+ .locator(DESIGN_PREVIEW_IFRAME_SELECTOR)
306
+ .last()
307
+ .boundingBox();
308
+ if (!frameRect) throw new Error("unable to locate design iframe");
160
309
  await designFrame(page)
161
- .locator("body")
162
- .evaluate((_, targetText) => {
163
- const normalizeText = (element: HTMLElement) =>
164
- (element.textContent ?? "").replace(/\s+/g, " ").trim();
165
- const isVisible = (element: HTMLElement) => {
166
- const rect = element.getBoundingClientRect();
167
- const styles = window.getComputedStyle(element);
168
- return (
169
- rect.width > 0 &&
170
- rect.height > 0 &&
171
- styles.display !== "none" &&
172
- styles.visibility !== "hidden"
173
- );
174
- };
175
- const shield = document.querySelector<HTMLElement>(
176
- '[data-agent-native-edit-overlay="shield"]',
177
- );
178
- const leafCandidates = Array.from(
179
- document.querySelectorAll<HTMLElement>(
180
- "h1, h2, h3, h4, h5, h6, p, button, a, label, span, input, textarea",
181
- ),
182
- ).filter(isVisible);
183
- const nodeCandidates = Array.from(
184
- document.querySelectorAll<HTMLElement>("[data-agent-native-node-id]"),
185
- ).filter(isVisible);
186
- const target =
187
- nodeCandidates.find(
188
- (element) => normalizeText(element) === targetText,
189
- ) ??
190
- leafCandidates.find(
191
- (element) => normalizeText(element) === targetText,
192
- ) ??
193
- nodeCandidates.find((element) =>
194
- normalizeText(element).includes(targetText),
195
- ) ??
196
- leafCandidates.find((element) =>
197
- normalizeText(element).includes(targetText),
198
- );
199
- if (!shield || !target) {
200
- throw new Error(`unable to dispatch selection for "${targetText}"`);
201
- }
202
- const rect = target.getBoundingClientRect();
203
- shield.dispatchEvent(
204
- new MouseEvent("click", {
205
- bubbles: true,
206
- cancelable: true,
207
- view: window,
208
- clientX: rect.left + rect.width / 2,
209
- clientY: rect.top + rect.height / 2,
210
- detail: 1,
211
- }),
212
- );
213
- }, text);
310
+ .locator('[data-agent-native-edit-overlay="shield"]')
311
+ .first()
312
+ .dispatchEvent("click", {
313
+ bubbles: true,
314
+ cancelable: true,
315
+ clientX: rect.x - frameRect.x + rect.width / 2,
316
+ clientY: rect.y - frameRect.y + rect.height / 2,
317
+ detail: 1,
318
+ });
214
319
  }
215
320
 
216
321
  /** Number of inputs in the right-hand inspector (proxy for "inspector populated"). */
@@ -231,10 +336,8 @@ export async function dragCanvasByText(
231
336
  ): Promise<string[]> {
232
337
  await selectByText(page, text);
233
338
  await page.evaluate(() => ((window as any).__bridge = []));
234
- const box = await designFrame(page)
235
- .getByText(text, { exact: false })
236
- .first()
237
- .boundingBox();
339
+ const target = await selectableNodeByText(page, text);
340
+ const box = await target.boundingBox();
238
341
  if (!box) throw new Error(`no bounding box for "${text}"`);
239
342
  const cx = box.x + box.width / 2;
240
343
  const cy = box.y + box.height / 2;
@@ -8,7 +8,8 @@
8
8
  "build": "agent-native build",
9
9
  "start": "agent-native start",
10
10
  "test": "vitest --run",
11
- "typecheck": "agent-native typecheck",
11
+ "typecheck": "agent-native typecheck && pnpm exec tsc --noEmit -p app/components/design/bridge/tsconfig.json",
12
+ "codegen:bridge": "tsx app/components/design/bridge/codegen.ts",
12
13
  "action": "agent-native action",
13
14
  "script": "agent-native script",
14
15
  "e2e": "playwright test",
@@ -78,6 +79,7 @@
78
79
  "clsx": "^2.1.1",
79
80
  "cmdk": "^1.1.1",
80
81
  "embla-carousel-react": "^8.6.0",
82
+ "esbuild": "^0.27.7",
81
83
  "input-otp": "^1.4.2",
82
84
  "next-themes": "^0.4.6",
83
85
  "oxfmt": "catalog:",
@@ -75,6 +75,7 @@ export const designLocalhostConnections = table(
75
75
  .notNull()
76
76
  .default("connected"),
77
77
  lastSeenAt: text("last_seen_at"),
78
+ bridgeToken: text("bridge_token"),
78
79
  ownerEmail: text("owner_email").notNull(),
79
80
  orgId: text("org_id"),
80
81
  createdAt: text("created_at").default(now()),
@@ -178,6 +179,28 @@ export const designState = table("design_state", {
178
179
  ...ownableColumns(),
179
180
  });
180
181
 
182
+ /**
183
+ * Localhost write-consent grants minted when the user explicitly allows file
184
+ * writes for a specific design + connection pair. Expire after 8 hours.
185
+ * Only HTML/CSS files may be written (enforced at the action layer).
186
+ */
187
+ export const designLocalhostWriteGrants = table(
188
+ "design_localhost_write_grants",
189
+ {
190
+ id: text("id").primaryKey(),
191
+ designId: text("design_id").notNull(),
192
+ connectionId: text("connection_id").notNull(),
193
+ /** Filesystem root that was visible when the grant was created. */
194
+ rootPath: text("root_path").notNull(),
195
+ /** Short-lived token passed in the X-Bridge-Token header. */
196
+ bridgeToken: text("bridge_token").notNull(),
197
+ /** ISO timestamp after which the grant is considered expired (8 hours). */
198
+ grantedUntil: text("granted_until").notNull(),
199
+ createdAt: text("created_at").default(now()),
200
+ ...ownableColumns(),
201
+ },
202
+ );
203
+
181
204
  /**
182
205
  * Cached accessibility audit + visual diff results for a design.
183
206
  * Keyed by design + optional base/compare design_versions pair + source ref.
@@ -1,5 +1,6 @@
1
1
  import crypto from "crypto";
2
2
  import fs from "fs";
3
+ import os from "os";
3
4
  import path from "path";
4
5
 
5
6
  import { getSession } from "@agent-native/core/server";
@@ -11,7 +12,27 @@ import {
11
12
  } from "h3";
12
13
  import { nanoid } from "nanoid";
13
14
 
14
- const UPLOADS_ROOT = path.join(process.cwd(), "data", "uploads");
15
+ function isServerlessRuntime(env: NodeJS.ProcessEnv = process.env): boolean {
16
+ return Boolean(
17
+ env.NETLIFY ||
18
+ env.VERCEL ||
19
+ env.AWS_LAMBDA_FUNCTION_NAME ||
20
+ env.LAMBDA_TASK_ROOT ||
21
+ env.CF_PAGES,
22
+ );
23
+ }
24
+
25
+ export function uploadsRootForRuntime(
26
+ cwd = process.cwd(),
27
+ env: NodeJS.ProcessEnv = process.env,
28
+ ): string {
29
+ const baseDir = isServerlessRuntime(env)
30
+ ? path.join(os.tmpdir(), "agent-native-design")
31
+ : cwd;
32
+ return path.join(baseDir, "data", "uploads");
33
+ }
34
+
35
+ const UPLOADS_ROOT = uploadsRootForRuntime();
15
36
  const MAX_EXTRACTED_TEXT_CHARS = 8_000;
16
37
  const TEXT_EXTENSIONS = new Set([
17
38
  ".html",
@@ -19,18 +19,21 @@ export type { ProviderApiMethod, ProviderApiRequestArgs };
19
19
  const resolveDesignCredential: ProviderApiCredentialResolver = async (
20
20
  options,
21
21
  ) => {
22
- if (options.provider !== "github" || options.key !== "GITHUB_TOKEN") {
22
+ const supported =
23
+ (options.provider === "github" && options.key === "GITHUB_TOKEN") ||
24
+ (options.provider === "figma" && options.key === "FIGMA_ACCESS_TOKEN");
25
+ if (!supported) {
23
26
  return null;
24
27
  }
25
28
 
26
- const value = await resolveSecret("GITHUB_TOKEN");
29
+ const value = await resolveSecret(options.key);
27
30
  if (!value) return null;
28
31
 
29
32
  return {
30
- key: "GITHUB_TOKEN",
33
+ key: options.key,
31
34
  value,
32
35
  source: `${DESIGN_APP_ID}_secret`,
33
- provider: "github",
36
+ provider: options.provider,
34
37
  scope: "request",
35
38
  };
36
39
  };