@agent-native/core 0.169.0 → 0.170.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 (496) hide show
  1. package/agent-native.eject.json +4 -1
  2. package/bin/agent-native.js +23 -5
  3. package/corpus/README.md +1 -1
  4. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
  5. package/corpus/templates/analytics/actions/bigquery-table-info.ts +3 -2
  6. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  7. package/corpus/templates/analytics/actions/search-bigquery-schema.ts +130 -4
  8. package/corpus/templates/analytics/agent-native.config.ts +1 -0
  9. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +36 -23
  10. package/corpus/templates/analytics/app/i18n-data.ts +28 -0
  11. package/corpus/templates/analytics/app/lib/dashboard-visibility.ts +41 -0
  12. package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
  13. package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +34 -9
  14. package/corpus/templates/analytics/app/routes/$.tsx +10 -0
  15. package/corpus/templates/analytics/app/routes.ts +3 -1
  16. package/corpus/templates/analytics/changelog/2026-08-21-dashboard-filters-keep-other-users-dashboards-out-of-mine.md +6 -0
  17. package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
  18. package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
  19. package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
  20. package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
  21. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
  22. package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
  23. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
  24. package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
  25. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
  26. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
  27. package/corpus/templates/analytics/server/lib/real-data-actions.ts +14 -3
  28. package/corpus/templates/analytics/server/lib/slack.ts +4 -2
  29. package/corpus/templates/analytics/server/plugins/agent-chat.ts +33 -3
  30. package/corpus/templates/analytics/vitest.config.ts +6 -1
  31. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
  32. package/corpus/templates/assets/app/routes/library.tsx +5 -3
  33. package/corpus/templates/assets/app/routes.ts +3 -1
  34. package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
  35. package/corpus/templates/assets/vitest.config.ts +6 -1
  36. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
  37. package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
  38. package/corpus/templates/brain/app/routes/sources.tsx +8 -3
  39. package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
  40. package/corpus/templates/brain/server/lib/brain.ts +27 -2
  41. package/corpus/templates/brain/vitest.config.ts +1 -0
  42. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
  43. package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
  44. package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
  45. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
  46. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
  47. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
  48. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
  49. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
  50. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
  51. package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
  52. package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
  53. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
  54. package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
  55. package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
  56. package/corpus/templates/calendar/app/routes.ts +3 -1
  57. package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
  58. package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
  59. package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
  60. package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
  61. package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
  62. package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
  63. package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
  64. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
  65. package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
  66. package/corpus/templates/calendar/server/onboarding.ts +85 -0
  67. package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
  68. package/corpus/templates/calendar/shared/api.ts +9 -1
  69. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  70. package/corpus/templates/chat/app/routes.ts +3 -1
  71. package/corpus/templates/chat/vitest.config.ts +8 -0
  72. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
  73. package/corpus/templates/clips/actions/get-meeting.ts +9 -4
  74. package/corpus/templates/clips/actions/list-recordings.ts +16 -3
  75. package/corpus/templates/clips/actions/search-meetings.ts +1 -0
  76. package/corpus/templates/clips/actions/stop-meeting-recording.ts +87 -6
  77. package/corpus/templates/clips/actions/view-screen.ts +8 -1
  78. package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -1
  79. package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
  80. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
  81. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
  82. package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
  83. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
  84. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
  85. package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
  86. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
  87. package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
  88. package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
  89. package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
  90. package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
  91. package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
  92. package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
  93. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
  94. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
  95. package/corpus/templates/clips/desktop/src/app.tsx +53 -24
  96. package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
  97. package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
  98. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
  99. package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
  100. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
  101. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
  102. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
  103. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
  104. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
  105. package/corpus/templates/clips/server/lib/emails.ts +17 -33
  106. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
  107. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
  108. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
  109. package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
  110. package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
  111. package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
  112. package/corpus/templates/content/app/i18n-data.ts +25 -0
  113. package/corpus/templates/content/app/routes.ts +3 -1
  114. package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
  115. package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
  116. package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
  117. package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
  118. package/corpus/templates/content/vitest.config.ts +7 -1
  119. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
  120. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
  121. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1386 -92
  122. package/corpus/templates/design/actions/generate-design.ts +98 -47
  123. package/corpus/templates/design/actions/get-design-system.ts +6 -1
  124. package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
  125. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
  126. package/corpus/templates/design/app/components/design/EditPanel.tsx +15 -47
  127. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
  128. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2060 -144
  129. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
  130. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
  131. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -8
  132. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
  133. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
  134. package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
  135. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
  136. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +13 -8
  137. package/corpus/templates/design/app/i18n-data.ts +11 -10
  138. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
  139. package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
  140. package/corpus/templates/design/app/pages/DesignEditor.tsx +99 -57
  141. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +39 -8
  142. package/corpus/templates/design/app/pages/DesignSystems.tsx +137 -43
  143. package/corpus/templates/design/app/pages/Index.tsx +3 -1
  144. package/corpus/templates/design/app/pages/Templates.tsx +0 -10
  145. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
  146. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
  147. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
  148. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
  149. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
  150. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
  151. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
  152. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
  153. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
  154. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
  155. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
  156. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
  157. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
  158. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
  159. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
  160. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
  161. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
  162. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
  163. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
  164. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
  165. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
  166. package/corpus/templates/design/app/pages/design-editor/preview-navigation.ts +25 -0
  167. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
  168. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
  169. package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
  170. package/corpus/templates/design/app/routes.ts +3 -1
  171. package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
  172. package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
  173. package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
  174. package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
  175. package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
  176. package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
  177. package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
  178. package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
  179. package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
  180. package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
  181. package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
  182. package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
  183. package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
  184. package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
  185. package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
  186. package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
  187. package/corpus/templates/design/package.json +2 -0
  188. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
  189. package/corpus/templates/design/shared/canvas-math.ts +612 -206
  190. package/corpus/templates/design/shared/pen-path.ts +37 -0
  191. package/corpus/templates/design/vitest.config.ts +7 -1
  192. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
  193. package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
  194. package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
  195. package/corpus/templates/dispatch/app/routes.ts +3 -1
  196. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
  197. package/corpus/templates/factory/.env.example +2 -7
  198. package/corpus/templates/factory/AGENTS.md +3 -0
  199. package/corpus/templates/factory/README.md +5 -3
  200. package/corpus/templates/factory/actions/create-factory.ts +16 -3
  201. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
  202. package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
  203. package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
  204. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  205. package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
  206. package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
  207. package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
  208. package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
  209. package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
  210. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
  211. package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
  212. package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
  213. package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
  214. package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
  215. package/corpus/templates/factory/app/routes/factory.tsx +84 -11
  216. package/corpus/templates/factory/app/routes.ts +3 -1
  217. package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
  218. package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
  219. package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
  220. package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
  221. package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
  222. package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
  223. package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
  224. package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
  225. package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
  226. package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
  227. package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
  228. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
  229. package/corpus/templates/factory/vitest.config.ts +17 -2
  230. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
  231. package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
  232. package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  233. package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
  234. package/corpus/templates/forms/vitest.config.ts +1 -0
  235. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
  236. package/corpus/templates/macros/app/routes.ts +3 -1
  237. package/corpus/templates/macros/vitest.config.ts +6 -1
  238. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
  239. package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
  240. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
  241. package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
  242. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
  243. package/corpus/templates/mail/app/hooks/use-emails.ts +13 -3
  244. package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
  245. package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
  246. package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
  247. package/corpus/templates/mail/app/routes/$.tsx +9 -0
  248. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
  249. package/corpus/templates/mail/app/routes/$view.tsx +47 -1
  250. package/corpus/templates/mail/app/routes.ts +3 -1
  251. package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
  252. package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
  253. package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
  254. package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
  255. package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
  256. package/corpus/templates/mail/server/onboarding.ts +66 -18
  257. package/corpus/templates/mail/vitest.config.ts +6 -1
  258. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
  259. package/corpus/templates/plan/app/routes/settings.tsx +4 -1
  260. package/corpus/templates/plan/app/routes.ts +3 -1
  261. package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  262. package/corpus/templates/plan/netlify.toml +1 -1
  263. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
  264. package/corpus/templates/slides/actions/patch-deck.ts +79 -10
  265. package/corpus/templates/slides/actions/update-slide.ts +11 -1
  266. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
  267. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
  268. package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
  269. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
  270. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
  271. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
  272. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
  273. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
  274. package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
  275. package/corpus/templates/slides/app/routes.ts +3 -1
  276. package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
  277. package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
  278. package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
  279. package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
  280. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
  281. package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
  282. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
  283. package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
  284. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
  285. package/corpus/templates/slides/tsconfig.json +5 -0
  286. package/corpus/templates/slides/vitest.config.ts +6 -1
  287. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
  288. package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
  289. package/corpus/templates/tasks/app/routes.ts +3 -1
  290. package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  291. package/corpus/templates/tasks/vitest.config.ts +7 -1
  292. package/dist/action.d.ts +91 -0
  293. package/dist/action.js +50 -0
  294. package/dist/agent/abort-reasons.d.ts +38 -0
  295. package/dist/agent/abort-reasons.js +49 -0
  296. package/dist/agent/engine/ai-sdk-engine.js +8 -5
  297. package/dist/agent/engine/anthropic-engine.js +7 -5
  298. package/dist/agent/engine/credential-errors.d.ts +1 -1
  299. package/dist/agent/engine/credential-errors.js +2 -2
  300. package/dist/agent/engine/first-event-timeout.d.ts +42 -17
  301. package/dist/agent/engine/first-event-timeout.js +67 -25
  302. package/dist/agent/production-agent.d.ts +23 -0
  303. package/dist/agent/production-agent.js +107 -102
  304. package/dist/agent/run-loop-with-resume.d.ts +2 -28
  305. package/dist/agent/run-loop-with-resume.js +25 -40
  306. package/dist/agent/run-manager.js +5 -4
  307. package/dist/agent/run-store.d.ts +55 -0
  308. package/dist/agent/run-store.js +124 -1
  309. package/dist/agent/tool-search.js +2 -1
  310. package/dist/agent/types.d.ts +9 -4
  311. package/dist/app-config/configuration-error.d.ts +11 -0
  312. package/dist/app-config/configuration-error.js +14 -0
  313. package/dist/app-config/index.d.ts +1 -0
  314. package/dist/app-config/index.js +1 -0
  315. package/dist/app-config/integrations.d.ts +1 -0
  316. package/dist/app-config/integrations.js +10 -0
  317. package/dist/app-config/plugins.d.ts +34 -0
  318. package/dist/app-config/plugins.js +39 -0
  319. package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
  320. package/dist/app-config/run-lifecycle-invariants.js +18 -25
  321. package/dist/app-config/schema.d.ts +16 -0
  322. package/dist/app-config/schema.js +2 -0
  323. package/dist/chat-threads/schema-migrations.js +20 -0
  324. package/dist/chat-threads/store.js +21 -4
  325. package/dist/cli/native-dependencies.d.ts +4 -0
  326. package/dist/cli/native-dependencies.js +15 -0
  327. package/dist/client/AssistantChat.js +47 -15
  328. package/dist/client/ConnectBuilderCard.d.ts +3 -1
  329. package/dist/client/ConnectBuilderCard.js +6 -3
  330. package/dist/client/EnvironmentBadge.d.ts +1 -1
  331. package/dist/client/EnvironmentBadge.js +40 -5
  332. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  333. package/dist/client/MultiTabAssistantChat.js +35 -14
  334. package/dist/client/agent-chat/index.d.ts +1 -1
  335. package/dist/client/agent-chat/index.js +1 -1
  336. package/dist/client/agent-page/use-jobs.d.ts +2 -1
  337. package/dist/client/agent-page/use-jobs.js +3 -5
  338. package/dist/client/agent-sidebar-state.js +3 -1
  339. package/dist/client/blocks/library/code-tabs.js +5 -0
  340. package/dist/client/blocks/library/code.js +1 -0
  341. package/dist/client/chat/message-components.d.ts +7 -0
  342. package/dist/client/chat/message-components.js +1 -1
  343. package/dist/client/chat/run-recovery.js +5 -2
  344. package/dist/client/chat/tool-call-display.js +9 -3
  345. package/dist/client/chat-first/apps-rail.js +2 -2
  346. package/dist/client/chat-model-groups.d.ts +12 -0
  347. package/dist/client/chat-model-groups.js +3 -2
  348. package/dist/client/error-format.js +12 -0
  349. package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
  350. package/dist/client/integrations/GoogleProductLogo.js +45 -0
  351. package/dist/client/integrations/index.d.ts +2 -0
  352. package/dist/client/integrations/index.js +2 -0
  353. package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
  354. package/dist/client/integrations/workspace-provider-oauth.js +13 -0
  355. package/dist/client/navigation/index.d.ts +1 -0
  356. package/dist/client/navigation/index.js +1 -0
  357. package/dist/client/resources/mcp-integration-catalog.js +0 -29
  358. package/dist/client/route-state.js +6 -0
  359. package/dist/client/settings/SettingsTabsPage.js +10 -6
  360. package/dist/client/sharing/ShareButton.js +11 -2
  361. package/dist/client/use-chat-models.d.ts +6 -0
  362. package/dist/client/use-chat-models.js +10 -0
  363. package/dist/client/use-db-sync.js +27 -9
  364. package/dist/client/workspace-app-navigation.d.ts +10 -0
  365. package/dist/client/workspace-app-navigation.js +38 -0
  366. package/dist/collab/struct-routes.d.ts +1 -1
  367. package/dist/connections/catalog.d.ts +111 -9
  368. package/dist/connections/catalog.js +86 -30
  369. package/dist/db/create-get-db.js +18 -0
  370. package/dist/db/ddl-guard.d.ts +0 -4
  371. package/dist/db/ddl-guard.js +46 -0
  372. package/dist/deploy/build.d.ts +32 -0
  373. package/dist/deploy/build.js +241 -16
  374. package/dist/deploy/function-bundle.d.ts +45 -0
  375. package/dist/deploy/function-bundle.js +337 -0
  376. package/dist/deploy/workspace-deploy.js +19 -1
  377. package/dist/eject/workspace-connections.js +4 -0
  378. package/dist/email-catalog/registry.d.ts +4 -0
  379. package/dist/email-catalog/registry.js +79 -14
  380. package/dist/extensions/content-patch.js +14 -2
  381. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  382. package/dist/integrations/plugin.d.ts +10 -0
  383. package/dist/integrations/plugin.js +40 -6
  384. package/dist/jobs/actions/run-automation-now.d.ts +2 -1
  385. package/dist/jobs/actions/run-automation-now.js +11 -5
  386. package/dist/jobs/frontmatter.js +53 -2
  387. package/dist/jobs/run-now.d.ts +11 -1
  388. package/dist/jobs/run-now.js +42 -7
  389. package/dist/jobs/scheduler.d.ts +1 -0
  390. package/dist/jobs/scheduler.js +2 -1
  391. package/dist/localization/core-messages/ar-SA.js +4 -1
  392. package/dist/localization/core-messages/de-DE.js +4 -1
  393. package/dist/localization/core-messages/en-US.d.ts +4 -1
  394. package/dist/localization/core-messages/en-US.js +4 -1
  395. package/dist/localization/core-messages/es-ES.js +4 -1
  396. package/dist/localization/core-messages/fr-FR.js +4 -1
  397. package/dist/localization/core-messages/hi-IN.js +4 -1
  398. package/dist/localization/core-messages/ja-JP.js +4 -1
  399. package/dist/localization/core-messages/ko-KR.js +4 -1
  400. package/dist/localization/core-messages/pt-BR.js +4 -1
  401. package/dist/localization/core-messages/zh-CN.js +4 -1
  402. package/dist/localization/core-messages/zh-TW.js +4 -1
  403. package/dist/localization/core-messages.d.ts +4 -1
  404. package/dist/localization/default-messages.d.ts +2 -5
  405. package/dist/localization/default-messages.js +2 -5
  406. package/dist/mcp/build-server.d.ts +9 -0
  407. package/dist/mcp/build-server.js +37 -8
  408. package/dist/mcp-client/oauth-client.d.ts +7 -0
  409. package/dist/mcp-client/oauth-client.js +12 -1
  410. package/dist/notifications/routes.d.ts +1 -1
  411. package/dist/oauth-tokens/index.d.ts +1 -1
  412. package/dist/oauth-tokens/index.js +1 -1
  413. package/dist/oauth-tokens/lifecycle.d.ts +11 -0
  414. package/dist/oauth-tokens/lifecycle.js +17 -0
  415. package/dist/oauth-tokens/store.js +7 -0
  416. package/dist/observability/posthog-ai.d.ts +15 -1
  417. package/dist/observability/posthog-ai.js +24 -12
  418. package/dist/observability/traces.js +158 -28
  419. package/dist/onboarding/app-profile.js +2 -2
  420. package/dist/onboarding/plugin.js +10 -2
  421. package/dist/onboarding/types.d.ts +2 -0
  422. package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
  423. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  424. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  425. package/dist/provider-api/index.js +2 -0
  426. package/dist/resources/handlers.d.ts +1 -1
  427. package/dist/resources/store.js +13 -4
  428. package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
  429. package/dist/scripts/db/check-scoping.js +9 -6
  430. package/dist/secrets/register-framework-secrets.js +1 -1
  431. package/dist/secrets/routes.d.ts +6 -6
  432. package/dist/server/action-discovery.js +5 -0
  433. package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
  434. package/dist/server/agent-chat/action-filters-a2a.js +48 -9
  435. package/dist/server/agent-chat-plugin.js +36 -9
  436. package/dist/server/agent-discovery.js +43 -20
  437. package/dist/server/auth.js +18 -16
  438. package/dist/server/beta-opt-out-html.js +45 -4
  439. package/dist/server/better-auth-instance.d.ts +2 -1
  440. package/dist/server/better-auth-instance.js +23 -7
  441. package/dist/server/builder-browser.d.ts +4 -0
  442. package/dist/server/builder-browser.js +23 -1
  443. package/dist/server/builder-design-systems.d.ts +4 -1
  444. package/dist/server/builder-design-systems.js +87 -6
  445. package/dist/server/builder-oauth.d.ts +1 -7
  446. package/dist/server/builder-oauth.js +80 -163
  447. package/dist/server/core-routes-plugin.d.ts +29 -0
  448. package/dist/server/core-routes-plugin.js +113 -21
  449. package/dist/server/default-plugins.d.ts +18 -0
  450. package/dist/server/default-plugins.js +22 -0
  451. package/dist/server/edge.d.ts +1 -0
  452. package/dist/server/edge.js +1 -0
  453. package/dist/server/framework-request-handler.js +31 -3
  454. package/dist/server/google-oauth.d.ts +3 -0
  455. package/dist/server/google-oauth.js +3 -0
  456. package/dist/server/index.d.ts +4 -4
  457. package/dist/server/index.js +3 -3
  458. package/dist/server/onboarding-html.js +37 -3
  459. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  460. package/dist/server/workspace-provider-oauth.js +72 -20
  461. package/dist/shared/agent-sidebar-url.d.ts +1 -0
  462. package/dist/shared/agent-sidebar-url.js +1 -0
  463. package/dist/shared/environment-lanes.d.ts +2 -0
  464. package/dist/shared/environment-lanes.js +3 -1
  465. package/dist/shared/index.d.ts +3 -1
  466. package/dist/shared/index.js +3 -1
  467. package/dist/shared/surface-visibility.d.ts +31 -0
  468. package/dist/shared/surface-visibility.js +57 -0
  469. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  470. package/dist/templates/chat/app/routes.ts +3 -1
  471. package/dist/templates/chat/vitest.config.ts +8 -0
  472. package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  473. package/dist/templates/default/app/routes.ts +3 -1
  474. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  475. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  476. package/dist/tracking/registry.d.ts +11 -0
  477. package/dist/tracking/registry.js +5 -2
  478. package/dist/triggers/actions.js +10 -3
  479. package/dist/usage/store.js +23 -3
  480. package/dist/user-profile/actions/get-auth-methods.js +18 -5
  481. package/dist/vite/client.js +24 -5
  482. package/docs/content/actions-access-control.mdx +43 -4
  483. package/docs/content/actions-defining.mdx +16 -0
  484. package/docs/content/template-clips-capture-everywhere.mdx +29 -30
  485. package/docs/content/template-clips-developers.mdx +4 -4
  486. package/docs/content/template-clips.mdx +3 -1
  487. package/package.json +3 -3
  488. package/src/eject/workspace-connections.ts +4 -0
  489. package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  490. package/src/templates/chat/app/routes.ts +3 -1
  491. package/src/templates/chat/vitest.config.ts +8 -0
  492. package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  493. package/src/templates/default/app/routes.ts +3 -1
  494. package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  495. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  496. /package/corpus/templates/dispatch/app/routes/{apps.$appId.tsx → apps.$appId.$.tsx} +0 -0
@@ -9,6 +9,7 @@ import {
9
9
  getOverviewScreenIdsFromLayerSelection,
10
10
  getSidebarCodeLayerSelectionState,
11
11
  } from "@/pages/design-editor/selection-state";
12
+ import { resolveToolAfterSelection } from "@/pages/design-editor/tool-state";
12
13
  import type {
13
14
  DesignFile,
14
15
  DesignTool,
@@ -130,13 +131,13 @@ export function runLayerSelectionChange(
130
131
  if (layerCanvasBlocked) {
131
132
  setSelectedElement(null);
132
133
  focusDesignInspectorForSelection();
133
- setActiveTool("move");
134
+ setActiveTool(resolveToolAfterSelection);
134
135
  setMode("edit");
135
136
  return;
136
137
  }
137
138
  setSelectedElement(elementInfoFromCodeLayerNode(codeLayerOwner.node));
138
139
  focusDesignInspectorForSelection();
139
- setActiveTool("move");
140
+ setActiveTool(resolveToolAfterSelection);
140
141
  setMode("edit");
141
142
  return;
142
143
  }
@@ -153,7 +154,7 @@ export function runLayerSelectionChange(
153
154
  ? nextLayerIds
154
155
  : [fileId],
155
156
  );
156
- setActiveTool("move");
157
+ setActiveTool(resolveToolAfterSelection);
157
158
  setMode("edit");
158
159
  viewModeRef.current = "overview";
159
160
  setViewMode("overview");
@@ -20,6 +20,7 @@ import {
20
20
  isScreenRootElementInfo,
21
21
  shouldIgnoreOverviewLayerCreationEcho,
22
22
  } from "@/pages/design-editor/selection-state";
23
+ import { resolveToolAfterSelection } from "@/pages/design-editor/tool-state";
23
24
  import type { DesignTool, EditorMode } from "@/pages/design-editor/types";
24
25
 
25
26
  export interface ScreenElementSelectArgs {
@@ -234,8 +235,17 @@ export function runScreenElementSelect(
234
235
  }
235
236
  return dedupeStringIds([...current, node.id]);
236
237
  });
238
+ } else if (node) {
239
+ // An intent-less select is the bridge re-anchoring after a content
240
+ // replace, not a user picking one object, so it must not collapse a live
241
+ // multi-selection down to the member it re-found.
242
+ setSelectedLayerIdsState((current) =>
243
+ !intent && current.length > 1 && current.includes(node.id)
244
+ ? current
245
+ : [node.id],
246
+ );
237
247
  } else {
238
- setSelectedLayerIdsState(node ? [node.id] : []);
248
+ setSelectedLayerIdsState([]);
239
249
  }
240
250
  if (viewModeRef.current === "overview") {
241
251
  setOverviewSelectedScreenIds([]);
@@ -256,7 +266,7 @@ export function runScreenElementSelect(
256
266
  handleBreakpointBarSelect(undefined);
257
267
  }
258
268
  }
259
- setActiveTool("move");
269
+ setActiveTool(resolveToolAfterSelection);
260
270
  setMode("edit");
261
271
  focusDesignInspectorForSelection();
262
272
  }
@@ -39,7 +39,10 @@ export interface ScreenVisualStyleChangeArgs {
39
39
  selector: string,
40
40
  styles: Record<string, string>,
41
41
  elementInfo?: ElementInfo,
42
- metadata?: { originalStyles?: Record<string, string> },
42
+ metadata?: {
43
+ originalStyles?: Record<string, string>;
44
+ preserveSelection?: boolean;
45
+ },
43
46
  ) => void;
44
47
  overviewScreens: OverviewScreen[];
45
48
  recordPendingVisualStyleEdit: (
@@ -49,6 +52,7 @@ export interface ScreenVisualStyleChangeArgs {
49
52
  elementInfo?: ElementInfo,
50
53
  metadata?: {
51
54
  originalStyles?: Record<string, string>;
55
+ preserveSelection?: boolean;
52
56
  interactionState?: InteractionState;
53
57
  },
54
58
  ) => void;
@@ -75,7 +79,10 @@ export function runScreenVisualStyleChange(
75
79
  selector: string,
76
80
  styles: Record<string, string>,
77
81
  elementInfo?: ElementInfo,
78
- metadata?: { originalStyles?: Record<string, string> },
82
+ metadata?: {
83
+ originalStyles?: Record<string, string>;
84
+ preserveSelection?: boolean;
85
+ },
79
86
  ) {
80
87
  if (screenId === activeFile?.id) {
81
88
  handleVisualStyleChange(selector, styles, elementInfo, metadata);
@@ -29,7 +29,7 @@ export interface SendRuntimeLayerMoveSemanticHandoffArgs {
29
29
  localhostConnectionRootPathByIdRef: RefObject<Map<string, string>>;
30
30
  overviewScreens: OverviewScreen[];
31
31
  runtimeLayerSnapshotsById: Record<string, RuntimeLayerSnapshot>;
32
- setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel>>;
32
+ setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel | null>>;
33
33
  t: (key: string, options?: Record<string, unknown>) => string;
34
34
  }
35
35
 
@@ -29,7 +29,7 @@ export interface SendRuntimeLayerSemanticHandoffArgs {
29
29
  localhostConnectionRootPathByIdRef: RefObject<Map<string, string>>;
30
30
  overviewScreens: OverviewScreen[];
31
31
  runtimeLayerSnapshotsById: Record<string, RuntimeLayerSnapshot>;
32
- setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel>>;
32
+ setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel | null>>;
33
33
  t: (key: string, options?: Record<string, unknown>) => string;
34
34
  }
35
35
 
@@ -32,7 +32,7 @@ export interface SendRuntimeLayerStateSemanticHandoffArgs {
32
32
  localhostConnectionRootPathByIdRef: RefObject<Map<string, string>>;
33
33
  overviewScreens: OverviewScreen[];
34
34
  runtimeLayerSnapshotsById: Record<string, RuntimeLayerSnapshot>;
35
- setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel>>;
35
+ setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel | null>>;
36
36
  t: (key: string, options?: Record<string, unknown>) => string;
37
37
  }
38
38
 
@@ -8,7 +8,7 @@ import type {
8
8
  import type { DesignLeftPanel } from "@/pages/design-editor/types";
9
9
 
10
10
  export interface StartSidebarResizeArgs {
11
- activeLeftPanel: DesignLeftPanel;
11
+ activeLeftPanel: DesignLeftPanel | null;
12
12
  leftSidebarContentRef: RefObject<HTMLDivElement | null>;
13
13
  leftSidebarWidth: number;
14
14
  rightSidebarContentRef: RefObject<HTMLDivElement | null>;
@@ -1,5 +1,7 @@
1
1
  import { isStandaloneHttpUrl } from "@shared/html-content";
2
2
 
3
+ import { trace } from "@/components/design/design-trace";
4
+
3
5
  import { normalizeDesignLeftPanel } from "./tool-state";
4
6
  import {
5
7
  type DesignFile,
@@ -24,10 +26,18 @@ export type PreviewContentReplaceResult =
24
26
  | "skipped-caller-owns-preview"
25
27
  | "unavailable";
26
28
 
29
+ /**
30
+ * True when the in-place bridge patch could not run and the caller must fall
31
+ * back to rebuilding srcdoc — a real iframe reload that re-executes the editor
32
+ * bridge, Tailwind and Alpine. Traced because it is the one escalation a user
33
+ * perceives as "the frame refreshed", and it is otherwise invisible.
34
+ */
27
35
  export function previewContentReplaceNeedsRenderFallback(
28
36
  result: PreviewContentReplaceResult,
29
37
  ): boolean {
30
- return result === "unavailable";
38
+ if (result !== "unavailable") return false;
39
+ trace("persist", "preview-bridge-unavailable-reload");
40
+ return true;
31
41
  }
32
42
 
33
43
  /**
@@ -3,6 +3,7 @@ import { sourceContentHash } from "@shared/source-workspace";
3
3
  import type { Dispatch, RefObject, SetStateAction } from "react";
4
4
  import * as Y from "yjs";
5
5
 
6
+ import { writeCollabText } from "@/pages/design-editor/collab-sync";
6
7
  import {
7
8
  TAB_ID,
8
9
  shouldAdoptExternalReconcileContent,
@@ -103,16 +104,13 @@ export function runAdoptDbFileContent({
103
104
  if (isLeadClient && ydoc) {
104
105
  const ytext = ydoc.getText("content");
105
106
  if (ytext.toString() !== dbContent) {
106
- // Untracked full rewrite (agent edit / external DB content
107
- // replacing a live doc that diverged) — clear the undo stack so a
108
- // stale tracked delta can't be replayed against content it no
109
- // longer matches (see U1: this is the primary corruption path —
110
- // agent edits, motion autosave, and id-stamping all land here).
107
+ // Untracked write (agent edit / external DB content replacing a
108
+ // live doc that diverged) — clear the undo stack so a stale
109
+ // tracked delta can't be replayed against content it no longer
110
+ // matches (see U1: this is the primary corruption path — agent
111
+ // edits, motion autosave, and id-stamping all land here).
111
112
  undoManagerRef.current?.clear(true, false);
112
- ydoc.transact(() => {
113
- ytext.delete(0, ytext.length);
114
- ytext.insert(0, dbContent);
115
- }, TAB_ID);
113
+ writeCollabText(ydoc, ytext, dbContent, TAB_ID);
116
114
  }
117
115
  }
118
116
  return;
@@ -182,12 +180,9 @@ export function runAdoptDbFileContent({
182
180
  if (isLeadClient && ydoc) {
183
181
  const ytext = ydoc.getText("content");
184
182
  if (ytext.toString() !== expectedContent) {
185
- // Untracked full rewrite — see U1 note above.
183
+ // Untracked write — see U1 note above.
186
184
  undoManagerRef.current?.clear(true, false);
187
- ydoc.transact(() => {
188
- ytext.delete(0, ytext.length);
189
- ytext.insert(0, expectedContent);
190
- }, TAB_ID);
185
+ writeCollabText(ydoc, ytext, expectedContent, TAB_ID);
191
186
  }
192
187
  }
193
188
  }, 1200);
@@ -258,13 +253,10 @@ export function runAdoptDbFileContent({
258
253
  if (isLeadClient && ydoc) {
259
254
  const ytext = ydoc.getText("content");
260
255
  if (ytext.toString() !== dbContent) {
261
- // Untracked full rewrite — see U1 note above. The view-appropriate
256
+ // Untracked write — see U1 note above. The view-appropriate
262
257
  // checkpoint recorded above (U21) is what Cmd+Z now falls back to.
263
258
  undoManagerRef.current?.clear(true, false);
264
- ydoc.transact(() => {
265
- ytext.delete(0, ytext.length);
266
- ytext.insert(0, dbContent);
267
- }, TAB_ID);
259
+ writeCollabText(ydoc, ytext, dbContent, TAB_ID);
268
260
  }
269
261
  }
270
262
  }
@@ -3,7 +3,10 @@ import * as Y from "yjs";
3
3
 
4
4
  import type { ElementInfo } from "@/components/design/types";
5
5
  import { refreshElementInfoFromContent } from "@/pages/design-editor/code-layer-state";
6
- import { shouldApplyRemotePreviewContent } from "@/pages/design-editor/collab-sync";
6
+ import {
7
+ shouldApplyRemotePreviewContent,
8
+ writeCollabText,
9
+ } from "@/pages/design-editor/collab-sync";
7
10
  import {
8
11
  LOCAL_EDIT_ORIGIN,
9
12
  TAB_ID,
@@ -120,12 +123,9 @@ export function runObserveCollabText({
120
123
  ) {
121
124
  setContentRenderRevision((revision) => revision + 1);
122
125
  }
123
- // Untracked full rewrite — see clear() note in the seed effect above.
126
+ // Untracked write — see clear() note in the seed effect above.
124
127
  undoManagerRef.current?.clear(true, false);
125
- ydoc.transact(() => {
126
- ytext.delete(0, ytext.length);
127
- ytext.insert(0, pendingLocalContent);
128
- }, TAB_ID);
128
+ writeCollabText(ydoc, ytext, pendingLocalContent, TAB_ID);
129
129
  return;
130
130
  }
131
131
  setCollabContent(next);
@@ -20,7 +20,7 @@ export interface PublishAgentSelectionContextArgs {
20
20
  activeCodeFile: CodeWorkbenchActiveFile | null;
21
21
  activeFile: DesignFile;
22
22
  activeInspectorTab: InspectorTab;
23
- activeLeftPanel: DesignLeftPanel;
23
+ activeLeftPanel: DesignLeftPanel | null;
24
24
  activeTool: DesignTool;
25
25
  design: DesignData | null;
26
26
  designDataJson: Record<string, unknown>;
@@ -1,7 +1,10 @@
1
1
  import type { Dispatch, RefObject, SetStateAction } from "react";
2
2
  import * as Y from "yjs";
3
3
 
4
- import { shouldRebaseCollabDocFromStoredContent } from "@/pages/design-editor/collab-sync";
4
+ import {
5
+ shouldRebaseCollabDocFromStoredContent,
6
+ writeCollabText,
7
+ } from "@/pages/design-editor/collab-sync";
5
8
  import { TAB_ID } from "@/pages/design-editor/editor-session";
6
9
  import type { PreviewContentReplaceResult } from "@/pages/design-editor/editor-state";
7
10
  import { previewContentReplaceNeedsRenderFallback } from "@/pages/design-editor/editor-state";
@@ -69,16 +72,13 @@ export function runSeedCollabContent({
69
72
  ) {
70
73
  setContentRenderRevision((revision) => revision + 1);
71
74
  }
72
- // Full delete+insert with an untracked origin: the UndoManager only
73
- // tracks LOCAL_EDIT_ORIGIN, so this rewrite is invisible to it. Clear
74
- // the undo stack so a subsequent Cmd+Z can't replay a tracked delta
75
- // from before this rewrite against content it no longer matches
76
- // (see the DE:5135-style mitigation below for the same hazard).
75
+ // Untracked origin: the UndoManager only tracks LOCAL_EDIT_ORIGIN, so
76
+ // this write is invisible to it. Clear the undo stack so a subsequent
77
+ // Cmd+Z can't replay a tracked delta from before it against content it
78
+ // no longer matches (see the DE:5135-style mitigation below for the
79
+ // same hazard).
77
80
  undoManagerRef.current?.clear(true, false);
78
- ydoc.transact(() => {
79
- ytext.delete(0, ytext.length);
80
- ytext.insert(0, pendingLocalContent);
81
- }, TAB_ID);
81
+ writeCollabText(ydoc, ytext, pendingLocalContent, TAB_ID);
82
82
  return;
83
83
  }
84
84
  if (text.length > 0) {
@@ -115,12 +115,9 @@ export function runSeedCollabContent({
115
115
  ) {
116
116
  setContentRenderRevision((revision) => revision + 1);
117
117
  }
118
- // Untracked full rewrite — see clear() note above.
118
+ // Untracked write — see clear() note above.
119
119
  undoManagerRef.current?.clear(true, false);
120
- ydoc.transact(() => {
121
- ytext.delete(0, ytext.length);
122
- ytext.insert(0, storedContent);
123
- }, TAB_ID);
120
+ writeCollabText(ydoc, ytext, storedContent, TAB_ID);
124
121
  return;
125
122
  }
126
123
  // Y.Doc snapshots are a render seed, not the SQL source of truth; the
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Opens a preview from a user gesture without losing it to popup blocking.
3
+ * The blank window must be created before assigning the real URL; otherwise
4
+ * browsers can treat the delayed navigation as an unsolicited popup.
5
+ */
6
+ export function openPreviewUrl(
7
+ url: string,
8
+ openWindow: (url: string, target: string) => Window | null,
9
+ navigateSameTab: (url: string) => void,
10
+ ): "popup" | "same-tab" {
11
+ const popup = openWindow("", "_blank");
12
+ if (!popup) {
13
+ navigateSameTab(url);
14
+ return "same-tab";
15
+ }
16
+
17
+ try {
18
+ popup.opener = null;
19
+ popup.location.href = url;
20
+ return "popup";
21
+ } catch {
22
+ navigateSameTab(url);
23
+ return "same-tab";
24
+ }
25
+ }
@@ -401,15 +401,8 @@ export function shouldEscapeToOverview(args: {
401
401
  * node already carries `tag`/`layerNameSource` without needing a separate
402
402
  * lookup map.
403
403
  *
404
- * Both the Escape pop-one-level walk (`resolveEscapePopSelectionAction`) and
405
- * the shared Shift+Enter / "\\" select-parent walk (`handleSelectParentLayer`
406
- * in DesignEditor.tsx) must treat a parent that resolves to a document-shell
407
- * node as NO parent at all — otherwise popping from a top-level layer selects
408
- * the raw `<body>`/`<html>` DOM nodes instead of stopping at the screen/frame
409
- * level (or fully deselecting), which produces a permanently broken 0x0
410
- * inspector with no way back to a deselected state.
411
- *
412
- * Exported for unit testing.
404
+ * Select-parent must treat a document-shell parent as NO parent, or walking up
405
+ * from a top-level layer selects raw `<body>` and strands the inspector at 0x0.
413
406
  */
414
407
  export function isDocumentShellCodeLayerNode(node: {
415
408
  tag: string;
@@ -422,14 +415,9 @@ export function isDocumentShellCodeLayerNode(node: {
422
415
  }
423
416
 
424
417
  /**
425
- * True only when `parentNode` exists AND is not a document-shell node — see
426
- * `isDocumentShellCodeLayerNode`. Callers walking the flat code-layer
427
- * ownership map (Escape pop-one-level, Shift+Enter select-parent) must use
428
- * this instead of a bare `Boolean(parentNode)` truthiness check, or a
429
- * top-level layer's collapsed `<body>`/`<html>` ancestor gets treated as a
430
- * selectable parent layer.
431
- *
432
- * Exported for unit testing.
418
+ * Callers walking the flat code-layer ownership map must use this instead of a
419
+ * bare `Boolean(parentNode)` check, or a top-level layer's collapsed
420
+ * `<body>`/`<html>` ancestor gets treated as a selectable parent layer.
433
421
  */
434
422
  export function hasSelectableCodeLayerParent(args: {
435
423
  parentNode: { tag: string; layerNameSource: string } | null | undefined;
@@ -439,48 +427,6 @@ export function hasSelectableCodeLayerParent(args: {
439
427
  );
440
428
  }
441
429
 
442
- export type EscapePopSelectionAction =
443
- | { kind: "pop-to-parent-layer" }
444
- | { kind: "pop-to-screen-frame" }
445
- | { kind: "deselect" };
446
-
447
- /**
448
- * Figma parity — Escape on a plain canvas selection pops one level at a
449
- * time (child layer -> parent layer -> containing screen/frame -> fully
450
- * deselected) instead of deselecting everything on the first press.
451
- *
452
- * - A selected layer that has a code-layer parent (`hasLayerParent`) pops to
453
- * that parent, reusing the same ancestor-walk `handleSelectParentLayer`
454
- * (Shift+Enter / "\\") already uses via `codeLayerOwnerByNodeIdRef`.
455
- * - A selected TOP-level layer (no code-layer parent) in overview mode pops
456
- * to selecting its containing screen/frame — the same selection kind
457
- * (`overviewSelectedScreenIds`) clicking a frame directly in overview
458
- * already produces.
459
- * - Anything else — nothing selected, or a top-level layer in single-screen
460
- * mode where there's no separate "frame" to pop to (the screen already
461
- * fills the view, so top-level already reads as "the frame boundary") —
462
- * falls straight through to a full deselect, matching the previous
463
- * unconditional Escape behavior.
464
- *
465
- * Callers must have already handled every higher-priority Escape consumer
466
- * (an in-progress marquee/drag, an active breakpoint edit target,
467
- * `shouldEscapeToOverview`'s zoom-out-to-overview case) before calling this
468
- * — it only decides the remaining plain-canvas-selection case.
469
- *
470
- * Exported for unit testing.
471
- */
472
- export function resolveEscapePopSelectionAction(args: {
473
- hasSelectedLayer: boolean;
474
- hasLayerParent: boolean;
475
- viewMode: "single" | "overview";
476
- }): EscapePopSelectionAction {
477
- if (args.hasSelectedLayer) {
478
- if (args.hasLayerParent) return { kind: "pop-to-parent-layer" };
479
- if (args.viewMode === "overview") return { kind: "pop-to-screen-frame" };
480
- }
481
- return { kind: "deselect" };
482
- }
483
-
484
430
  /**
485
431
  * B5-1: an empty-canvas click (a marquee/hit-test that resolved to zero
486
432
  * elements) must deselect ANY current selection kind — a selected
@@ -79,6 +79,14 @@ export function normalizeDesignMode(value: unknown): EditorMode | null {
79
79
  : null;
80
80
  }
81
81
 
82
+ /**
83
+ * Scale is a mode, not a one-shot: Figma keeps K armed across selection
84
+ * changes, while every gesture-scoped tool falls back to move.
85
+ */
86
+ export function resolveToolAfterSelection(current: DesignTool): DesignTool {
87
+ return current === "scale" ? "scale" : "move";
88
+ }
89
+
82
90
  export function isSingleScreenAnnotationTool(tool: DesignTool): boolean {
83
91
  return tool === "draw" || tool === "comment";
84
92
  }
@@ -36,9 +36,9 @@ export type DesignLeftPanel =
36
36
  /**
37
37
  * Keep the still-evolving Design editor side panels out of the default
38
38
  * surface until their Figma parity work is ready. Flip this switch to expose
39
- * Assets, Tools, Tokens, and Code together while iterating on them. The E2E
40
- * harness sets the Vite flag so those existing advanced-surface tests keep
41
- * exercising the gated panels.
39
+ * Assets, Tools, Tokens, Code, and Motion together while iterating on them.
40
+ * The E2E harness sets the Vite flag so those existing advanced-surface tests
41
+ * keep exercising the gated panels.
42
42
  */
43
43
  const designSecondaryLeftPanelsSetting =
44
44
  typeof import.meta !== "undefined"
@@ -1,4 +1,6 @@
1
1
  import { type RouteConfig } from "@react-router/dev/routes";
2
2
  import { flatRoutes } from "@react-router/fs-routes";
3
3
 
4
- export default flatRoutes() satisfies RouteConfig;
4
+ export default flatRoutes({
5
+ ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
6
+ }) satisfies RouteConfig;
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-20
4
+ ---
5
+
6
+ Deleting or editing an element patches the canvas in place instead of rebuilding the frame, so scroll position, focus and running component state survive the edit.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Completed Builder design-system imports now update the local Design system with indexed tokens instead of leaving placeholder values.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Draw mode now needs Shift+Y, so a single stray keystroke can no longer switch the editor into annotate mode.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Press I anywhere on the canvas to sample a color with the eyedropper and apply it to the selection.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Dragging a screen or an element now lights up every edge and centre it lines up with, snaps spacing to gaps that already exist, and shows its pixel size and constraint lines.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Moving or scaling several objects at once keeps them all selected, so you can keep adjusting instead of falling back to one object.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Inspector number fields keep focus after Enter, so the next keystroke edits the field instead of triggering a canvas shortcut.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Pen: holding Alt on a new anchor now keeps the incoming handle where it was and stays broken after you release Alt.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Finishing a pen path on the canvas board creates one vector instead of two, and leaves the Pen tool armed for the next path.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Scale now applies to a multi-selection: drag a corner of the group box and every selected object scales together.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Scale resizes the text inside an object along with its box and stroke, matching Figma.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Selecting another object keeps the Scale tool armed instead of dropping you back to Move.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ The shape tool now stays on the shape you picked — drawing an ellipse no longer resets the toolbar button to Rectangle.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-21
4
+ ---
5
+
6
+ Pen paths, lines, arrows, polygons and stars drawn inside a frame now land where you drew them instead of jumping by the frame's position.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-22
4
+ ---
5
+
6
+ Generating or updating several screens in one request no longer loses an already-saved screen's layout and styling when another screen in the same request hits a save conflict — the saved screen keeps its placement, and the conflicting screen is reported so you can retry just that one.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-22
4
+ ---
5
+
6
+ The rename design and search text fields on the Designs home page now have accessible names, so screen readers announce them instead of leaving them unlabeled.
@@ -29,6 +29,7 @@
29
29
  "@tailwindcss/browser": "^4.3.3",
30
30
  "acorn": "^8.18.0",
31
31
  "alpinejs": "^3.15.12",
32
+ "diff-match-patch": "^1.0.5",
32
33
  "drizzle-orm": "^0.45.2",
33
34
  "entities": "8.0.0",
34
35
  "fzstd": "^0.1.1",
@@ -81,6 +82,7 @@
81
82
  "@tailwindcss/typography": "^0.5.20",
82
83
  "@tailwindcss/vite": "catalog:",
83
84
  "@tanstack/react-query": "^5.99.2",
85
+ "@types/diff-match-patch": "^1.0.36",
84
86
  "@types/node": "^24.2.1",
85
87
  "@types/react": "catalog:",
86
88
  "@types/react-dom": "catalog:",