@agent-native/core 0.169.1 → 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 (459) 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/query-agent-native-analytics.ts +1 -1
  6. package/corpus/templates/analytics/app/i18n-data.ts +28 -0
  7. package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
  8. package/corpus/templates/analytics/app/routes/$.tsx +10 -0
  9. package/corpus/templates/analytics/app/routes.ts +3 -1
  10. package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
  11. package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
  12. package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
  13. package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
  14. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
  15. package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
  16. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
  17. package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
  18. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
  20. package/corpus/templates/analytics/server/lib/slack.ts +4 -2
  21. package/corpus/templates/analytics/vitest.config.ts +6 -1
  22. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
  23. package/corpus/templates/assets/app/routes/library.tsx +5 -3
  24. package/corpus/templates/assets/app/routes.ts +3 -1
  25. package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
  26. package/corpus/templates/assets/vitest.config.ts +6 -1
  27. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
  28. package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
  29. package/corpus/templates/brain/app/routes/sources.tsx +8 -3
  30. package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
  31. package/corpus/templates/brain/vitest.config.ts +1 -0
  32. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
  33. package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
  34. package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
  35. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
  36. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
  37. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
  38. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
  39. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
  40. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
  41. package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
  42. package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
  43. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
  44. package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
  45. package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
  46. package/corpus/templates/calendar/app/routes.ts +3 -1
  47. package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
  48. package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
  49. package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
  50. package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
  51. package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
  52. package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
  53. package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
  54. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
  55. package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
  56. package/corpus/templates/calendar/server/onboarding.ts +85 -0
  57. package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
  58. package/corpus/templates/calendar/shared/api.ts +9 -1
  59. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  60. package/corpus/templates/chat/app/routes.ts +3 -1
  61. package/corpus/templates/chat/vitest.config.ts +8 -0
  62. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
  63. package/corpus/templates/clips/actions/get-meeting.ts +9 -4
  64. package/corpus/templates/clips/actions/list-recordings.ts +16 -3
  65. package/corpus/templates/clips/actions/search-meetings.ts +1 -0
  66. package/corpus/templates/clips/actions/view-screen.ts +8 -1
  67. package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
  68. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
  69. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
  70. package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
  71. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
  72. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
  73. package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
  74. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
  75. package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
  76. package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
  77. package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
  78. package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
  80. package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
  81. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
  82. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
  83. package/corpus/templates/clips/desktop/src/app.tsx +53 -24
  84. package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
  85. package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
  86. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
  87. package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
  88. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
  89. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
  90. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
  91. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
  92. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
  93. package/corpus/templates/clips/server/lib/emails.ts +17 -33
  94. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
  95. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
  96. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
  97. package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
  98. package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
  99. package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
  100. package/corpus/templates/content/app/i18n-data.ts +25 -0
  101. package/corpus/templates/content/app/routes.ts +3 -1
  102. package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
  103. package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
  104. package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
  105. package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
  106. package/corpus/templates/content/vitest.config.ts +7 -1
  107. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
  108. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
  109. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1383 -88
  110. package/corpus/templates/design/actions/generate-design.ts +98 -47
  111. package/corpus/templates/design/actions/get-design-system.ts +6 -1
  112. package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
  113. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
  114. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
  115. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
  116. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
  117. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
  118. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -1
  119. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
  120. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
  121. package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
  122. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
  123. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -4
  124. package/corpus/templates/design/app/i18n-data.ts +1 -0
  125. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
  126. package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
  127. package/corpus/templates/design/app/pages/DesignEditor.tsx +77 -35
  128. package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
  129. package/corpus/templates/design/app/pages/Index.tsx +2 -0
  130. package/corpus/templates/design/app/pages/Templates.tsx +0 -10
  131. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
  132. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
  133. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
  134. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
  135. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
  136. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
  137. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
  138. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
  139. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
  140. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
  141. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
  142. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
  143. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
  144. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
  145. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
  146. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
  147. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
  148. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
  149. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
  150. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
  151. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
  152. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
  153. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
  154. package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
  155. package/corpus/templates/design/app/routes.ts +3 -1
  156. package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
  157. package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
  158. package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
  159. package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
  160. package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
  161. package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
  162. package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
  163. package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
  164. package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
  165. package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
  166. package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
  167. package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
  168. package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
  169. package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
  170. package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
  171. package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
  172. package/corpus/templates/design/package.json +2 -0
  173. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
  174. package/corpus/templates/design/shared/canvas-math.ts +612 -206
  175. package/corpus/templates/design/shared/pen-path.ts +37 -0
  176. package/corpus/templates/design/vitest.config.ts +7 -1
  177. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
  178. package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
  179. package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
  180. package/corpus/templates/dispatch/app/routes.ts +3 -1
  181. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
  182. package/corpus/templates/factory/.env.example +2 -7
  183. package/corpus/templates/factory/AGENTS.md +3 -0
  184. package/corpus/templates/factory/README.md +5 -3
  185. package/corpus/templates/factory/actions/create-factory.ts +16 -3
  186. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
  187. package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
  188. package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
  189. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  190. package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
  191. package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
  192. package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
  193. package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
  194. package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
  195. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
  196. package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
  197. package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
  198. package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
  199. package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
  200. package/corpus/templates/factory/app/routes/factory.tsx +84 -11
  201. package/corpus/templates/factory/app/routes.ts +3 -1
  202. package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
  203. package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
  204. package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
  205. package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
  206. package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
  207. package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
  208. package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
  209. package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
  210. package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
  211. package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
  212. package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
  213. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
  214. package/corpus/templates/factory/vitest.config.ts +17 -2
  215. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
  216. package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
  217. package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  218. package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
  219. package/corpus/templates/forms/vitest.config.ts +1 -0
  220. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
  221. package/corpus/templates/macros/app/routes.ts +3 -1
  222. package/corpus/templates/macros/vitest.config.ts +6 -1
  223. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
  224. package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
  225. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
  226. package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
  227. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
  228. package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
  229. package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
  230. package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
  231. package/corpus/templates/mail/app/routes/$.tsx +9 -0
  232. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
  233. package/corpus/templates/mail/app/routes/$view.tsx +47 -1
  234. package/corpus/templates/mail/app/routes.ts +3 -1
  235. package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
  236. package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
  237. package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
  238. package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
  239. package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
  240. package/corpus/templates/mail/server/onboarding.ts +66 -18
  241. package/corpus/templates/mail/vitest.config.ts +6 -1
  242. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
  243. package/corpus/templates/plan/app/routes/settings.tsx +4 -1
  244. package/corpus/templates/plan/app/routes.ts +3 -1
  245. package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  246. package/corpus/templates/plan/netlify.toml +1 -1
  247. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
  248. package/corpus/templates/slides/actions/patch-deck.ts +79 -10
  249. package/corpus/templates/slides/actions/update-slide.ts +11 -1
  250. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
  251. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
  252. package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
  253. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
  254. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
  255. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
  256. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
  257. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
  258. package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
  259. package/corpus/templates/slides/app/routes.ts +3 -1
  260. package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
  261. package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
  262. package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
  263. package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
  264. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
  265. package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
  266. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
  267. package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
  268. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
  269. package/corpus/templates/slides/tsconfig.json +5 -0
  270. package/corpus/templates/slides/vitest.config.ts +6 -1
  271. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
  272. package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
  273. package/corpus/templates/tasks/app/routes.ts +3 -1
  274. package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  275. package/corpus/templates/tasks/vitest.config.ts +7 -1
  276. package/dist/action.d.ts +91 -0
  277. package/dist/action.js +50 -0
  278. package/dist/agent/abort-reasons.d.ts +38 -0
  279. package/dist/agent/abort-reasons.js +49 -0
  280. package/dist/agent/engine/ai-sdk-engine.js +8 -5
  281. package/dist/agent/engine/anthropic-engine.js +7 -5
  282. package/dist/agent/engine/first-event-timeout.d.ts +42 -17
  283. package/dist/agent/engine/first-event-timeout.js +67 -25
  284. package/dist/agent/production-agent.d.ts +23 -0
  285. package/dist/agent/production-agent.js +107 -102
  286. package/dist/agent/run-loop-with-resume.d.ts +2 -28
  287. package/dist/agent/run-loop-with-resume.js +25 -40
  288. package/dist/agent/run-manager.js +5 -4
  289. package/dist/agent/run-store.d.ts +55 -0
  290. package/dist/agent/run-store.js +124 -1
  291. package/dist/agent/tool-search.js +2 -1
  292. package/dist/agent/types.d.ts +9 -4
  293. package/dist/app-config/configuration-error.d.ts +11 -0
  294. package/dist/app-config/configuration-error.js +14 -0
  295. package/dist/app-config/index.d.ts +1 -0
  296. package/dist/app-config/index.js +1 -0
  297. package/dist/app-config/integrations.d.ts +1 -0
  298. package/dist/app-config/integrations.js +10 -0
  299. package/dist/app-config/plugins.d.ts +34 -0
  300. package/dist/app-config/plugins.js +39 -0
  301. package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
  302. package/dist/app-config/run-lifecycle-invariants.js +18 -25
  303. package/dist/app-config/schema.d.ts +16 -0
  304. package/dist/app-config/schema.js +2 -0
  305. package/dist/chat-threads/schema-migrations.js +20 -0
  306. package/dist/chat-threads/store.js +21 -4
  307. package/dist/cli/native-dependencies.d.ts +4 -0
  308. package/dist/cli/native-dependencies.js +15 -0
  309. package/dist/client/EnvironmentBadge.d.ts +1 -1
  310. package/dist/client/EnvironmentBadge.js +40 -5
  311. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  312. package/dist/client/MultiTabAssistantChat.js +35 -14
  313. package/dist/client/agent-chat/index.d.ts +1 -1
  314. package/dist/client/agent-chat/index.js +1 -1
  315. package/dist/client/agent-page/use-jobs.d.ts +2 -1
  316. package/dist/client/agent-page/use-jobs.js +3 -5
  317. package/dist/client/agent-sidebar-state.js +3 -1
  318. package/dist/client/blocks/library/code-tabs.js +5 -0
  319. package/dist/client/blocks/library/code.js +1 -0
  320. package/dist/client/chat-first/apps-rail.js +2 -2
  321. package/dist/client/chat-model-groups.d.ts +12 -0
  322. package/dist/client/chat-model-groups.js +3 -2
  323. package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
  324. package/dist/client/integrations/GoogleProductLogo.js +45 -0
  325. package/dist/client/integrations/index.d.ts +2 -0
  326. package/dist/client/integrations/index.js +2 -0
  327. package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
  328. package/dist/client/integrations/workspace-provider-oauth.js +13 -0
  329. package/dist/client/resources/mcp-integration-catalog.js +0 -29
  330. package/dist/client/settings/SettingsTabsPage.js +10 -6
  331. package/dist/client/sharing/ShareButton.js +11 -2
  332. package/dist/client/use-chat-models.d.ts +6 -0
  333. package/dist/client/use-chat-models.js +10 -0
  334. package/dist/client/use-db-sync.js +27 -9
  335. package/dist/connections/catalog.d.ts +111 -9
  336. package/dist/connections/catalog.js +86 -30
  337. package/dist/db/create-get-db.js +18 -0
  338. package/dist/db/ddl-guard.d.ts +0 -4
  339. package/dist/db/ddl-guard.js +46 -0
  340. package/dist/deploy/build.d.ts +19 -0
  341. package/dist/deploy/build.js +190 -16
  342. package/dist/deploy/function-bundle.d.ts +45 -0
  343. package/dist/deploy/function-bundle.js +337 -0
  344. package/dist/deploy/workspace-deploy.js +19 -1
  345. package/dist/eject/workspace-connections.js +4 -0
  346. package/dist/email-catalog/registry.d.ts +4 -0
  347. package/dist/email-catalog/registry.js +79 -14
  348. package/dist/extensions/content-patch.js +14 -2
  349. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  350. package/dist/integrations/plugin.d.ts +10 -0
  351. package/dist/integrations/plugin.js +40 -6
  352. package/dist/jobs/actions/run-automation-now.d.ts +2 -1
  353. package/dist/jobs/actions/run-automation-now.js +11 -5
  354. package/dist/jobs/frontmatter.js +53 -2
  355. package/dist/jobs/run-now.d.ts +11 -1
  356. package/dist/jobs/run-now.js +42 -7
  357. package/dist/jobs/scheduler.d.ts +1 -0
  358. package/dist/jobs/scheduler.js +2 -1
  359. package/dist/localization/core-messages/ar-SA.js +3 -0
  360. package/dist/localization/core-messages/de-DE.js +3 -0
  361. package/dist/localization/core-messages/en-US.d.ts +3 -0
  362. package/dist/localization/core-messages/en-US.js +3 -0
  363. package/dist/localization/core-messages/es-ES.js +3 -0
  364. package/dist/localization/core-messages/fr-FR.js +3 -0
  365. package/dist/localization/core-messages/hi-IN.js +3 -0
  366. package/dist/localization/core-messages/ja-JP.js +3 -0
  367. package/dist/localization/core-messages/ko-KR.js +3 -0
  368. package/dist/localization/core-messages/pt-BR.js +3 -0
  369. package/dist/localization/core-messages/zh-CN.js +3 -0
  370. package/dist/localization/core-messages/zh-TW.js +3 -0
  371. package/dist/localization/core-messages.d.ts +3 -0
  372. package/dist/localization/default-messages.d.ts +2 -5
  373. package/dist/localization/default-messages.js +2 -5
  374. package/dist/mcp/build-server.d.ts +9 -0
  375. package/dist/mcp/build-server.js +37 -8
  376. package/dist/mcp-client/oauth-client.d.ts +7 -0
  377. package/dist/mcp-client/oauth-client.js +12 -1
  378. package/dist/oauth-tokens/index.d.ts +1 -1
  379. package/dist/oauth-tokens/index.js +1 -1
  380. package/dist/oauth-tokens/lifecycle.d.ts +11 -0
  381. package/dist/oauth-tokens/lifecycle.js +17 -0
  382. package/dist/oauth-tokens/store.js +7 -0
  383. package/dist/observability/posthog-ai.d.ts +15 -1
  384. package/dist/observability/posthog-ai.js +24 -12
  385. package/dist/observability/routes.d.ts +3 -3
  386. package/dist/observability/traces.js +158 -28
  387. package/dist/onboarding/app-profile.js +2 -2
  388. package/dist/onboarding/plugin.js +10 -2
  389. package/dist/onboarding/types.d.ts +2 -0
  390. package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
  391. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  392. package/dist/provider-api/index.js +2 -0
  393. package/dist/resources/store.js +13 -4
  394. package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
  395. package/dist/secrets/register-framework-secrets.js +1 -1
  396. package/dist/server/action-discovery.js +5 -0
  397. package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
  398. package/dist/server/agent-chat/action-filters-a2a.js +48 -9
  399. package/dist/server/agent-chat-plugin.js +36 -9
  400. package/dist/server/agent-discovery.js +43 -20
  401. package/dist/server/auth.js +18 -16
  402. package/dist/server/beta-opt-out-html.js +45 -4
  403. package/dist/server/better-auth-instance.d.ts +2 -1
  404. package/dist/server/better-auth-instance.js +23 -7
  405. package/dist/server/builder-design-systems.d.ts +4 -1
  406. package/dist/server/builder-design-systems.js +87 -6
  407. package/dist/server/builder-oauth.d.ts +1 -7
  408. package/dist/server/builder-oauth.js +80 -163
  409. package/dist/server/core-routes-plugin.d.ts +29 -0
  410. package/dist/server/core-routes-plugin.js +100 -20
  411. package/dist/server/default-plugins.d.ts +18 -0
  412. package/dist/server/default-plugins.js +22 -0
  413. package/dist/server/edge.d.ts +1 -0
  414. package/dist/server/edge.js +1 -0
  415. package/dist/server/framework-request-handler.js +31 -3
  416. package/dist/server/google-oauth.d.ts +3 -0
  417. package/dist/server/google-oauth.js +3 -0
  418. package/dist/server/index.d.ts +4 -4
  419. package/dist/server/index.js +3 -3
  420. package/dist/server/onboarding-html.js +37 -3
  421. package/dist/server/realtime-token.d.ts +1 -1
  422. package/dist/server/transcribe-voice.d.ts +1 -1
  423. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  424. package/dist/server/workspace-provider-oauth.js +72 -20
  425. package/dist/shared/agent-sidebar-url.d.ts +1 -0
  426. package/dist/shared/agent-sidebar-url.js +1 -0
  427. package/dist/shared/environment-lanes.d.ts +2 -0
  428. package/dist/shared/environment-lanes.js +3 -1
  429. package/dist/shared/index.d.ts +3 -1
  430. package/dist/shared/index.js +3 -1
  431. package/dist/shared/surface-visibility.d.ts +31 -0
  432. package/dist/shared/surface-visibility.js +57 -0
  433. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  434. package/dist/templates/chat/app/routes.ts +3 -1
  435. package/dist/templates/chat/vitest.config.ts +8 -0
  436. package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  437. package/dist/templates/default/app/routes.ts +3 -1
  438. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  439. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  440. package/dist/tracking/registry.d.ts +11 -0
  441. package/dist/tracking/registry.js +5 -2
  442. package/dist/triggers/actions.js +10 -3
  443. package/dist/usage/store.js +23 -3
  444. package/dist/user-profile/actions/get-auth-methods.js +18 -5
  445. package/dist/vite/client.js +24 -5
  446. package/docs/content/actions-access-control.mdx +43 -4
  447. package/docs/content/actions-defining.mdx +16 -0
  448. package/docs/content/template-clips-capture-everywhere.mdx +29 -30
  449. package/docs/content/template-clips-developers.mdx +4 -4
  450. package/docs/content/template-clips.mdx +3 -1
  451. package/package.json +2 -2
  452. package/src/eject/workspace-connections.ts +4 -0
  453. package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  454. package/src/templates/chat/app/routes.ts +3 -1
  455. package/src/templates/chat/vitest.config.ts +8 -0
  456. package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  457. package/src/templates/default/app/routes.ts +3 -1
  458. package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  459. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
@@ -16,6 +16,7 @@ import { canonicalizeNfm, docToNfm, nfmToDoc } from "@shared/nfm";
16
16
  import {
17
17
  serializeRegistryBlockToMdx,
18
18
  parseRegistryBlockData,
19
+ type ParsedRegistryBlock,
19
20
  } from "@shared/nfm-registry";
20
21
  import { IconMusic, IconPhoto, IconVideo } from "@tabler/icons-react";
21
22
  import {
@@ -1741,6 +1742,7 @@ export function createVisualEditorExtensions({
1741
1742
  */
1742
1743
  interface RegistryBlockStoreEntry {
1743
1744
  type: string;
1745
+ rawSource: string;
1744
1746
  base?: {
1745
1747
  title?: string;
1746
1748
  summary?: string;
@@ -1748,6 +1750,42 @@ interface RegistryBlockStoreEntry {
1748
1750
  };
1749
1751
  data: unknown;
1750
1752
  edited: boolean;
1753
+ loadError?: {
1754
+ reason: string;
1755
+ };
1756
+ }
1757
+
1758
+ export async function hydrateRegistryBlockRaw(
1759
+ rawSource: string,
1760
+ ): Promise<
1761
+ | { status: "loaded"; block: ParsedRegistryBlock }
1762
+ | { status: "error"; message: string; rawSource: string }
1763
+ > {
1764
+ try {
1765
+ const block = await parseRegistryBlockData(rawSource);
1766
+ if (!block) {
1767
+ return {
1768
+ status: "error",
1769
+ message: "unreadable",
1770
+ rawSource,
1771
+ };
1772
+ }
1773
+ return { status: "loaded", block };
1774
+ } catch (error) {
1775
+ return {
1776
+ status: "error",
1777
+ message: error instanceof Error ? error.message : "unreadable",
1778
+ rawSource,
1779
+ };
1780
+ }
1781
+ }
1782
+
1783
+ export function isRegistryBlockHydrationCurrent(
1784
+ expectedRaw: string,
1785
+ pendingRaw: string | undefined,
1786
+ liveRaw: string,
1787
+ ): boolean {
1788
+ return pendingRaw === expectedRaw && liveRaw === expectedRaw;
1751
1789
  }
1752
1790
 
1753
1791
  function serializeRegistryBlockRaw(
@@ -1803,8 +1841,9 @@ function isNotionIncompatibleBlockType(blockType: string): boolean {
1803
1841
  * serializes identically to before.
1804
1842
  */
1805
1843
  function useRegistryBlockStore(editor: CoreEditor | null) {
1844
+ const t = useT();
1806
1845
  const cacheRef = useRef<Map<string, RegistryBlockStoreEntry>>(new Map());
1807
- const pendingRef = useRef<Set<string>>(new Set());
1846
+ const pendingRef = useRef<Map<string, string>>(new Map());
1808
1847
  // Bumping this state forces the NodeViews to re-read the cache once async
1809
1848
  // hydration (or an edit) lands. The `version` is surfaced to the side-map
1810
1849
  // value so the context reference changes on each bump — otherwise the Tiptap
@@ -1845,25 +1884,66 @@ function useRegistryBlockStore(editor: CoreEditor | null) {
1845
1884
  typeof node.attrs.title === "string" ? node.attrs.title : undefined;
1846
1885
  const summary =
1847
1886
  typeof node.attrs.summary === "string" ? node.attrs.summary : undefined;
1887
+ const raw = typeof node.attrs.__raw === "string" ? node.attrs.__raw : "";
1848
1888
 
1849
1889
  const cached = cacheRef.current.get(blockId);
1850
- if (cached) {
1851
- return { id: blockId, title, summary, data: cached.data };
1890
+ if (cached?.rawSource === raw) {
1891
+ return {
1892
+ id: blockId,
1893
+ title,
1894
+ summary,
1895
+ data: cached.data,
1896
+ loadError: cached.loadError
1897
+ ? {
1898
+ message: t("editor.registryBlockLoadError", {
1899
+ type:
1900
+ typeof node.attrs.blockType === "string"
1901
+ ? node.attrs.blockType
1902
+ : "registry",
1903
+ message:
1904
+ cached.loadError.reason === "unreadable"
1905
+ ? t("editor.registryBlockUnreadable")
1906
+ : cached.loadError.reason,
1907
+ }),
1908
+ rawSource: cached.rawSource,
1909
+ }
1910
+ : undefined,
1911
+ };
1852
1912
  }
1913
+ if (cached) cacheRef.current.delete(blockId);
1853
1914
 
1854
1915
  // Not hydrated yet: kick off a one-shot async parse of the verbatim MDX.
1855
- const raw = typeof node.attrs.__raw === "string" ? node.attrs.__raw : "";
1856
- if (raw && !pendingRef.current.has(blockId)) {
1857
- pendingRef.current.add(blockId);
1858
- void parseRegistryBlockData(raw)
1859
- .then((parsed) => {
1860
- if (parsed) {
1916
+ if (pendingRef.current.get(blockId) !== raw) {
1917
+ pendingRef.current.set(blockId, raw);
1918
+ void hydrateRegistryBlockRaw(raw)
1919
+ .then((result) => {
1920
+ const live = findNode(blockId);
1921
+ const liveRaw =
1922
+ live && typeof live.node.attrs.__raw === "string"
1923
+ ? live.node.attrs.__raw
1924
+ : "";
1925
+ if (
1926
+ !isRegistryBlockHydrationCurrent(
1927
+ raw,
1928
+ pendingRef.current.get(blockId),
1929
+ liveRaw,
1930
+ )
1931
+ ) {
1932
+ if (pendingRef.current.get(blockId) === raw) {
1933
+ pendingRef.current.delete(blockId);
1934
+ bump();
1935
+ }
1936
+ return;
1937
+ }
1938
+ if (result.status === "loaded") {
1939
+ const parsed = result.block;
1861
1940
  const existing = cacheRef.current.get(blockId);
1862
1941
  // A concurrent edit may have populated the cache first — don't
1863
1942
  // clobber it with the stale parse.
1864
1943
  if (!existing) {
1865
1944
  cacheRef.current.set(blockId, {
1866
1945
  type: parsed.type,
1946
+ rawSource: raw,
1867
1947
  base: parsed.base,
1868
1948
  data: parsed.data,
1869
1949
  edited: false,
@@ -1902,6 +1982,8 @@ function useRegistryBlockStore(editor: CoreEditor | null) {
1902
1982
  },
1903
1983
  );
1904
1984
  editor.view.dispatch(tr);
1985
+ const entry = cacheRef.current.get(blockId);
1986
+ if (entry) entry.rawSource = refreshedRaw;
1905
1987
  } catch {
1906
1988
  /* Keep the parsed cache; leave raw untouched if invalid. */
1907
1989
  }
@@ -1909,18 +1991,31 @@ function useRegistryBlockStore(editor: CoreEditor | null) {
1909
1991
  }
1910
1992
  bump();
1911
1993
  }
1994
+ } else if (!cacheRef.current.has(blockId)) {
1995
+ cacheRef.current.set(blockId, {
1996
+ type:
1997
+ typeof node.attrs.blockType === "string"
1998
+ ? node.attrs.blockType
1999
+ : "",
2000
+ rawSource: result.rawSource,
2001
+ data: undefined,
2002
+ edited: false,
2003
+ loadError: {
2004
+ reason: result.message,
2005
+ },
2006
+ });
2007
+ bump();
1912
2008
  }
1913
2009
  })
1914
- .catch(() => {
1915
- /* Leave uncached; the NodeView keeps showing its placeholder. */
1916
- })
1917
2010
  .finally(() => {
1918
- pendingRef.current.delete(blockId);
2011
+ if (pendingRef.current.get(blockId) === raw) {
2012
+ pendingRef.current.delete(blockId);
2013
+ }
1919
2014
  });
1920
2015
  }
1921
2016
  return undefined;
1922
2017
  },
1923
- [editor, findNode, bump],
2018
+ [editor, findNode, bump, t],
1924
2019
  );
1925
2020
 
1926
2021
  const onBlockDataChange = useCallback(
@@ -1939,6 +2034,7 @@ function useRegistryBlockStore(editor: CoreEditor | null) {
1939
2034
  cacheRef.current.set(blockId, {
1940
2035
  type,
1941
2036
  base,
2037
+ rawSource: typeof node.attrs.__raw === "string" ? node.attrs.__raw : "",
1942
2038
  data: nextData,
1943
2039
  edited: true,
1944
2040
  });
@@ -1954,6 +2050,8 @@ function useRegistryBlockStore(editor: CoreEditor | null) {
1954
2050
  bump();
1955
2051
  return;
1956
2052
  }
2053
+ const updated = cacheRef.current.get(blockId);
2054
+ if (updated) updated.rawSource = raw;
1957
2055
 
1958
2056
  const tr = editor.state.tr.setNodeMarkup(pos, undefined, {
1959
2057
  ...node.attrs,
@@ -2009,6 +2107,33 @@ export function VisualEditor({
2009
2107
  onSaveContentRef.current = onSaveContent;
2010
2108
  const onHistoryStateChangeRef = useRef(onHistoryStateChange);
2011
2109
  onHistoryStateChangeRef.current = onHistoryStateChange;
2110
+ const historyStateNotificationRef = useRef<VisualEditorHistoryState | null>(
2111
+ null,
2112
+ );
2113
+ const historyStateNotificationQueuedRef = useRef(false);
2114
+ const editorMountedRef = useRef(false);
2115
+ const notifyHistoryStateChange = useCallback(
2116
+ (state: VisualEditorHistoryState) => {
2117
+ historyStateNotificationRef.current = state;
2118
+ if (historyStateNotificationQueuedRef.current) return;
2119
+ historyStateNotificationQueuedRef.current = true;
2120
+ queueMicrotask(() => {
2121
+ historyStateNotificationQueuedRef.current = false;
2122
+ const next = historyStateNotificationRef.current;
2123
+ historyStateNotificationRef.current = null;
2124
+ if (!editorMountedRef.current || !next) return;
2125
+ onHistoryStateChangeRef.current?.(next);
2126
+ });
2127
+ },
2128
+ [],
2129
+ );
2130
+ useEffect(() => {
2131
+ editorMountedRef.current = true;
2132
+ return () => {
2133
+ editorMountedRef.current = false;
2134
+ historyStateNotificationRef.current = null;
2135
+ };
2136
+ }, []);
2012
2137
  const notionPageLinksRef = useRef(notionPageLinks);
2013
2138
  notionPageLinksRef.current = notionPageLinks;
2014
2139
  const onMediaSourceCommittedRef = useRef<
@@ -2334,7 +2459,7 @@ export function VisualEditor({
2334
2459
  },
2335
2460
  editable,
2336
2461
  onTransaction: ({ editor }) => {
2337
- onHistoryStateChangeRef.current?.({
2462
+ notifyHistoryStateChange({
2338
2463
  canUndo: editor.can().undo(),
2339
2464
  canRedo: editor.can().redo(),
2340
2465
  });
@@ -65,6 +65,7 @@ import {
65
65
  DropdownMenuRadioItem,
66
66
  DropdownMenuTrigger,
67
67
  } from "@/components/ui/dropdown-menu";
68
+ import { afterBodyPointerUnlock } from "@/components/ui/pointer-lock";
68
69
  import { ScrollArea } from "@/components/ui/scroll-area";
69
70
  import { Skeleton } from "@/components/ui/skeleton";
70
71
  import {
@@ -212,17 +213,6 @@ const TRASH_COLLAPSED_DEFAULT_MIGRATION_KEY =
212
213
  "content-sidebar-trash-collapsed-default-v2";
213
214
  const CONTENT_SIDEBAR_STATE_VERSION = 1 as const;
214
215
 
215
- function afterBodyPointerUnlock(callback: () => void) {
216
- const run = () => {
217
- if (document.body.style.pointerEvents === "none") {
218
- window.requestAnimationFrame(run);
219
- return;
220
- }
221
- callback();
222
- };
223
- window.requestAnimationFrame(run);
224
- }
225
-
226
216
  interface ContentSidebarStateSnapshot {
227
217
  version: typeof CONTENT_SIDEBAR_STATE_VERSION;
228
218
  expandedWorkspaceIds: string[];
@@ -376,7 +366,12 @@ function useDeferredFilesDatabaseId(
376
366
  return () => window.clearTimeout(timeout);
377
367
  }, [databaseId, deferUntilDocumentId, expanded]);
378
368
 
379
- return expanded && ready ? databaseId : null;
369
+ // `databaseId` stays stable across the defer window so the query key never
370
+ // changes; only `enabled` pauses the fetch. Swapping `databaseId` itself to
371
+ // null here would move the tree to a disabled, never-fetched query key and
372
+ // drop the rows already on screen for the whole deferred window instead of
373
+ // just holding off the refetch.
374
+ return { databaseId: expanded ? databaseId : null, enabled: ready };
380
375
  }
381
376
 
382
377
  function WorkspaceSidebarItem({
@@ -472,12 +467,15 @@ function WorkspaceSidebarItem({
472
467
  removeActivation();
473
468
  };
474
469
  }, []);
475
- const activeFilesDatabaseId = useDeferredFilesDatabaseId(
470
+ const deferredFilesDatabase = useDeferredFilesDatabaseId(
476
471
  space.filesDatabaseId,
477
472
  expanded,
478
473
  deferInitialReadUntilDocumentId,
479
474
  );
480
- const filesDatabase = useContentDatabaseById(activeFilesDatabaseId);
475
+ const filesDatabase = useContentDatabaseById(
476
+ deferredFilesDatabase.databaseId,
477
+ { enabled: deferredFilesDatabase.enabled },
478
+ );
481
479
  const filesDatabaseData = isContentDatabaseUnavailable(filesDatabase.data)
482
480
  ? undefined
483
481
  : filesDatabase.data;
@@ -0,0 +1 @@
1
+ export * from "@agent-native/toolkit/ui/pointer-lock";
@@ -693,12 +693,28 @@ export function useContentDatabase(
693
693
  };
694
694
  }
695
695
 
696
- export function useContentDatabaseById(databaseId: string | null) {
696
+ // `enabled` pauses fetching without touching the query key: a caller that
697
+ // wants to briefly hold off refetching (e.g. to avoid competing with a
698
+ // higher-priority read) can pass `databaseId` unchanged and flip `enabled` to
699
+ // false instead of nulling `databaseId` out. Nulling it changes the query key
700
+ // to its disabled `undefined`-params form, which has no cached data of its
701
+ // own and drops the rows already on screen for as long as it stays disabled.
702
+ export function isContentDatabaseByIdQueryEnabled(
703
+ databaseId: string | null,
704
+ options?: { enabled?: boolean },
705
+ ): boolean {
706
+ return !!databaseId && options?.enabled !== false;
707
+ }
708
+
709
+ export function useContentDatabaseById(
710
+ databaseId: string | null,
711
+ options?: { enabled?: boolean },
712
+ ) {
697
713
  return useActionQuery<ContentDatabaseResponse>(
698
714
  "get-content-database",
699
715
  databaseId ? { databaseId } : undefined,
700
716
  {
701
- enabled: !!databaseId,
717
+ enabled: isContentDatabaseByIdQueryEnabled(databaseId, options),
702
718
  retry: false,
703
719
  placeholderData: (previous, previousQuery) =>
704
720
  preserveScopedDatabasePlaceholder(previous, previousQuery, {
@@ -1,6 +1,14 @@
1
- import { useState, useCallback, useEffect, useRef } from "react";
1
+ import {
2
+ useCallback,
3
+ useEffect,
4
+ useLayoutEffect,
5
+ useRef,
6
+ useState,
7
+ } from "react";
2
8
 
3
9
  const LOCAL_STORAGE_CHANGE_EVENT = "content-local-storage-change";
10
+ const useIsomorphicLayoutEffect =
11
+ typeof window === "undefined" ? useEffect : useLayoutEffect;
4
12
 
5
13
  function readStorage<T>(key: string, defaultValue: T): T {
6
14
  if (typeof window === "undefined") return defaultValue;
@@ -19,25 +27,33 @@ export function useLocalStorage<T>(
19
27
  ): [T, (val: T | ((prev: T) => T)) => void] {
20
28
  const prevKeyRef = useRef(key);
21
29
  const [value, setValue] = useState<T>(() => readStorage(key, defaultValue));
30
+ const valueRef = useRef(value);
31
+ const keyChanged = prevKeyRef.current !== key;
32
+ const visibleValue = keyChanged ? readStorage(key, defaultValue) : value;
22
33
 
23
- // Synchronously update value when key changes (no stale render)
24
- if (prevKeyRef.current !== key) {
25
- prevKeyRef.current = key;
26
- const fresh = readStorage(key, defaultValue);
27
- setValue(fresh);
28
- }
34
+ useIsomorphicLayoutEffect(() => {
35
+ if (prevKeyRef.current !== key) {
36
+ prevKeyRef.current = key;
37
+ valueRef.current = visibleValue;
38
+ setValue(visibleValue);
39
+ }
40
+ }, [key, visibleValue]);
29
41
 
30
42
  useEffect(() => {
31
43
  function handleStorage(event: StorageEvent) {
32
44
  if (event.key === key) {
33
- setValue(readStorage(key, defaultValue));
45
+ const next = readStorage(key, defaultValue);
46
+ valueRef.current = next;
47
+ setValue(next);
34
48
  }
35
49
  }
36
50
 
37
51
  function handleLocalStorageChange(event: Event) {
38
52
  const detail = (event as CustomEvent<{ key?: string; value?: T }>).detail;
39
53
  if (detail?.key === key) {
40
- setValue(detail.value as T);
54
+ const next = detail.value as T;
55
+ valueRef.current = next;
56
+ setValue(next);
41
57
  }
42
58
  }
43
59
 
@@ -58,21 +74,21 @@ export function useLocalStorage<T>(
58
74
 
59
75
  const set = useCallback(
60
76
  (val: T | ((prev: T) => T)) => {
61
- setValue((prev) => {
62
- const next = val instanceof Function ? val(prev) : val;
63
- try {
64
- window.localStorage.setItem(key, JSON.stringify(next));
65
- window.dispatchEvent(
66
- new CustomEvent(LOCAL_STORAGE_CHANGE_EVENT, {
67
- detail: { key, value: next },
68
- }),
69
- );
70
- } catch {}
71
- return next;
72
- });
77
+ const next = val instanceof Function ? val(valueRef.current) : val;
78
+ valueRef.current = next;
79
+ setValue(next);
80
+ try {
81
+ window.localStorage.setItem(key, JSON.stringify(next));
82
+ window.dispatchEvent(
83
+ new CustomEvent(LOCAL_STORAGE_CHANGE_EVENT, {
84
+ detail: { key, value: next },
85
+ }),
86
+ );
87
+ // coercion-ok: local persistence is optional; the in-memory value remains available.
88
+ } catch {}
73
89
  },
74
90
  [key],
75
91
  );
76
92
 
77
- return [value, set];
93
+ return [visibleValue, set];
78
94
  }
@@ -3167,6 +3167,8 @@ const enUS = {
3167
3167
  searchLanguages: "Search languages...",
3168
3168
  noBlocksFields: "No Blocks fields. Add one from the property menu.",
3169
3169
  noDocumentSelected: "No document selected",
3170
+ registryBlockLoadError: "Could not load {{type}} block: {{message}}",
3171
+ registryBlockUnreadable: "Persisted block source is unreadable.",
3170
3172
  blocksFieldRevisionConflict:
3171
3173
  "This Blocks field changed elsewhere. Your edit wasn't saved; the latest version is now shown.",
3172
3174
  couldNotReadLocalSourceFile: "Could not read local source file",
@@ -5762,6 +5764,8 @@ const editorMessagesByLocale = {
5762
5764
  red: "红色",
5763
5765
  },
5764
5766
  noDocumentSelected: "未选择文档",
5767
+ registryBlockLoadError: "无法加载 {{type}} 块:{{message}}",
5768
+ registryBlockUnreadable: "无法读取已保存的块源内容。",
5765
5769
  blocksFieldRevisionConflict:
5766
5770
  "此 Blocks 字段已在其他位置更改。你的编辑未保存;现已显示最新版本。",
5767
5771
  collabConnectingReadOnly: "正在连接实时编辑器。显示只读快照。",
@@ -6127,6 +6131,8 @@ const editorMessagesByLocale = {
6127
6131
  red: "Rojo",
6128
6132
  },
6129
6133
  noDocumentSelected: "Ningún documento seleccionado",
6134
+ registryBlockLoadError: "No se pudo cargar el bloque {{type}}: {{message}}",
6135
+ registryBlockUnreadable: "No se puede leer el origen guardado del bloque.",
6130
6136
  blocksFieldRevisionConflict:
6131
6137
  "Este campo de bloques cambió en otro lugar. Tu edición no se guardó; ahora se muestra la versión más reciente.",
6132
6138
  collabConnectingReadOnly:
@@ -6505,6 +6511,9 @@ const editorMessagesByLocale = {
6505
6511
  red: "Rouge",
6506
6512
  },
6507
6513
  noDocumentSelected: "Aucun document sélectionné",
6514
+ registryBlockLoadError:
6515
+ "Impossible de charger le bloc {{type}} : {{message}}",
6516
+ registryBlockUnreadable: "La source enregistrée du bloc est illisible.",
6508
6517
  blocksFieldRevisionConflict:
6509
6518
  "Ce champ de blocs a été modifié ailleurs. Votre modification n’a pas été enregistrée ; la dernière version est maintenant affichée.",
6510
6519
  collabConnectingReadOnly:
@@ -6888,6 +6897,10 @@ const editorMessagesByLocale = {
6888
6897
  red: "Rot",
6889
6898
  },
6890
6899
  noDocumentSelected: "Kein Dokument ausgewählt",
6900
+ registryBlockLoadError:
6901
+ "Der Block {{type}} konnte nicht geladen werden: {{message}}",
6902
+ registryBlockUnreadable:
6903
+ "Die gespeicherte Blockquelle kann nicht gelesen werden.",
6891
6904
  blocksFieldRevisionConflict:
6892
6905
  "Dieses Blocks-Feld wurde an anderer Stelle geändert. Deine Bearbeitung wurde nicht gespeichert; jetzt wird die neueste Version angezeigt.",
6893
6906
  collabConnectingReadOnly:
@@ -7274,6 +7287,9 @@ const editorMessagesByLocale = {
7274
7287
  red: "赤",
7275
7288
  },
7276
7289
  noDocumentSelected: "ドキュメントが選択されていません",
7290
+ registryBlockLoadError:
7291
+ "{{type}} ブロックを読み込めませんでした: {{message}}",
7292
+ registryBlockUnreadable: "保存されたブロックソースを読み取れません。",
7277
7293
  blocksFieldRevisionConflict:
7278
7294
  "このブロックフィールドは別の場所で変更されました。編集内容は保存されず、最新バージョンが表示されています。",
7279
7295
  collabConnectingReadOnly:
@@ -7649,6 +7665,8 @@ const editorMessagesByLocale = {
7649
7665
  red: "빨간색",
7650
7666
  },
7651
7667
  noDocumentSelected: "선택한 문서가 없습니다.",
7668
+ registryBlockLoadError: "{{type}} 블록을 불러올 수 없습니다: {{message}}",
7669
+ registryBlockUnreadable: "저장된 블록 소스를 읽을 수 없습니다.",
7652
7670
  blocksFieldRevisionConflict:
7653
7671
  "이 블록 필드가 다른 곳에서 변경되었습니다. 편집 내용은 저장되지 않았으며 최신 버전이 표시됩니다.",
7654
7672
  collabConnectingReadOnly:
@@ -8023,6 +8041,9 @@ const editorMessagesByLocale = {
8023
8041
  red: "Vermelho",
8024
8042
  },
8025
8043
  noDocumentSelected: "Nenhum documento selecionado",
8044
+ registryBlockLoadError:
8045
+ "Não foi possível carregar o bloco {{type}}: {{message}}",
8046
+ registryBlockUnreadable: "Não foi possível ler a origem salva do bloco.",
8026
8047
  blocksFieldRevisionConflict:
8027
8048
  "Este campo de blocos foi alterado em outro lugar. Sua edição não foi salva; a versão mais recente agora está sendo exibida.",
8028
8049
  collabConnectingReadOnly:
@@ -8403,6 +8424,8 @@ const editorMessagesByLocale = {
8403
8424
  red: "लाल",
8404
8425
  },
8405
8426
  noDocumentSelected: "कोई दस्तावेज़ चयनित नहीं",
8427
+ registryBlockLoadError: "{{type}} ब्लॉक लोड नहीं किया जा सका: {{message}}",
8428
+ registryBlockUnreadable: "सहेजा गया ब्लॉक स्रोत पढ़ा नहीं जा सकता।",
8406
8429
  blocksFieldRevisionConflict:
8407
8430
  "यह ब्लॉक फ़ील्ड कहीं और बदल गया है। आपका संपादन सहेजा नहीं गया; अब नवीनतम संस्करण दिखाया जा रहा है।",
8408
8431
  collabConnectingReadOnly:
@@ -8773,6 +8796,8 @@ const editorMessagesByLocale = {
8773
8796
  red: "أحمر",
8774
8797
  },
8775
8798
  noDocumentSelected: "لم يتم تحديد أي مستند",
8799
+ registryBlockLoadError: "تعذر تحميل كتلة {{type}}: {{message}}",
8800
+ registryBlockUnreadable: "تعذرت قراءة مصدر الكتلة المحفوظ.",
8776
8801
  blocksFieldRevisionConflict:
8777
8802
  "تم تغيير حقل الكتل هذا في مكان آخر. لم يتم حفظ تعديلك؛ ويظهر الآن أحدث إصدار.",
8778
8803
  collabConnectingReadOnly:
@@ -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: fixed
3
+ date: 2026-08-22
4
+ ---
5
+
6
+ Code and code-tabs blocks inserted from the slash menu no longer get stuck on "Loading…"
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-22
4
+ ---
5
+
6
+ The sidebar page tree no longer flashes empty for a moment after creating a new page