@agent-native/core 0.90.1 → 0.90.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (714) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +26 -0
  3. package/corpus/core/docs/content/agent-native-toolkit.mdx +87 -80
  4. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  5. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  6. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  7. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  8. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  9. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  10. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  11. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  12. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  13. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  14. package/corpus/core/docs/content/toolkit-agent-ux.mdx +43 -0
  15. package/corpus/core/docs/content/toolkit-app-adapters.mdx +9 -0
  16. package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +12 -0
  17. package/corpus/core/docs/content/toolkit-collaboration.mdx +74 -0
  18. package/corpus/core/docs/content/toolkit-command-navigation.mdx +106 -0
  19. package/corpus/core/docs/content/toolkit-comments-review.mdx +98 -0
  20. package/corpus/core/docs/content/toolkit-history.mdx +95 -0
  21. package/corpus/core/docs/content/toolkit-observability.mdx +41 -0
  22. package/corpus/core/docs/content/toolkit-org-team.mdx +80 -0
  23. package/corpus/core/docs/content/toolkit-resources.mdx +57 -0
  24. package/corpus/core/docs/content/toolkit-settings.mdx +65 -0
  25. package/corpus/core/docs/content/toolkit-setup-connections.mdx +109 -0
  26. package/corpus/core/docs/content/toolkit-sharing-ui.mdx +18 -6
  27. package/corpus/core/docs/content/toolkit-sharing.mdx +81 -0
  28. package/corpus/core/docs/content/toolkit-shell-hooks.mdx +9 -0
  29. package/corpus/core/docs/content/toolkit-ui.mdx +9 -0
  30. package/corpus/core/package.json +35 -1
  31. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +19 -1
  32. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -1
  33. package/corpus/core/src/agent/engine/registry.ts +23 -16
  34. package/corpus/core/src/agent/production-agent.ts +37 -6
  35. package/corpus/core/src/client/AgentPanel.tsx +1 -1
  36. package/corpus/core/src/client/command-navigation/index.ts +15 -0
  37. package/corpus/core/src/client/comments-review/index.ts +1 -0
  38. package/corpus/core/src/client/history/VersionHistoryPanel.tsx +145 -0
  39. package/corpus/core/src/client/history/index.ts +18 -0
  40. package/corpus/core/src/client/history/use-history.ts +86 -0
  41. package/corpus/core/src/client/index.ts +76 -9
  42. package/corpus/core/src/client/org/OrgSwitcher.tsx +6 -6
  43. package/corpus/core/src/client/org/RequireActiveOrg.tsx +2 -2
  44. package/corpus/core/src/client/org/TeamPage.tsx +3 -3
  45. package/corpus/core/src/client/org/hooks.ts +32 -0
  46. package/corpus/core/src/client/org/index.ts +30 -1
  47. package/corpus/core/src/client/org-team/index.ts +1 -0
  48. package/corpus/core/src/client/review/ReviewStatusBadge.tsx +39 -0
  49. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +278 -0
  50. package/corpus/core/src/client/review/index.ts +25 -0
  51. package/corpus/core/src/client/review/use-review.ts +114 -0
  52. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +11 -6
  53. package/corpus/core/src/client/settings/index.ts +11 -1
  54. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +94 -0
  55. package/corpus/core/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  56. package/corpus/core/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  57. package/corpus/core/src/client/setup-connections/index.ts +46 -0
  58. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -14
  59. package/corpus/core/src/client/sharing/ShareDialog.tsx +3 -3
  60. package/corpus/core/src/client/use-action.ts +39 -2
  61. package/corpus/core/src/client/use-db-sync.ts +44 -18
  62. package/corpus/core/src/command-navigation/actions.ts +100 -0
  63. package/corpus/core/src/command-navigation/index.ts +12 -0
  64. package/corpus/core/src/comments-review/index.ts +1 -0
  65. package/corpus/core/src/db/create-get-db.ts +32 -2
  66. package/corpus/core/src/file-upload/builder.ts +24 -3
  67. package/corpus/core/src/file-upload/types.ts +3 -1
  68. package/corpus/core/src/history/actions/create-resource-version.ts +89 -0
  69. package/corpus/core/src/history/actions/get-resource-version.ts +60 -0
  70. package/corpus/core/src/history/actions/list-resource-history.ts +53 -0
  71. package/corpus/core/src/history/actions/list-resource-versions.ts +43 -0
  72. package/corpus/core/src/history/actions/restore-resource-version.ts +96 -0
  73. package/corpus/core/src/history/index.ts +27 -0
  74. package/corpus/core/src/history/registry.ts +99 -0
  75. package/corpus/core/src/history/store.ts +348 -0
  76. package/corpus/core/src/history/types.ts +69 -0
  77. package/corpus/core/src/index.ts +10 -0
  78. package/corpus/core/src/navigation/index.ts +170 -0
  79. package/corpus/core/src/org/index.ts +8 -0
  80. package/corpus/core/src/org/permissions.ts +30 -0
  81. package/corpus/core/src/org-team/index.ts +1 -0
  82. package/corpus/core/src/private-blob/registry.ts +1 -0
  83. package/corpus/core/src/review/actions/consume-review-feedback.ts +38 -0
  84. package/corpus/core/src/review/actions/create-review-comment.ts +107 -0
  85. package/corpus/core/src/review/actions/delete-review-comment.ts +55 -0
  86. package/corpus/core/src/review/actions/get-review-feedback.ts +54 -0
  87. package/corpus/core/src/review/actions/list-review-comments.ts +53 -0
  88. package/corpus/core/src/review/actions/reply-review-comment.ts +107 -0
  89. package/corpus/core/src/review/actions/resolve-review-thread.ts +60 -0
  90. package/corpus/core/src/review/actions/set-review-status.ts +58 -0
  91. package/corpus/core/src/review/index.ts +36 -0
  92. package/corpus/core/src/review/mentions.ts +44 -0
  93. package/corpus/core/src/review/registry.ts +99 -0
  94. package/corpus/core/src/review/store.ts +687 -0
  95. package/corpus/core/src/review/types.ts +97 -0
  96. package/corpus/core/src/server/action-discovery.ts +54 -0
  97. package/corpus/core/src/server/agent-engine-api-key-route.ts +5 -0
  98. package/corpus/core/src/server/credential-provider.ts +108 -0
  99. package/corpus/core/src/server/framework-request-handler.ts +52 -4
  100. package/corpus/core/src/setup-connections/index.ts +89 -0
  101. package/corpus/core/src/setup-connections/onboarding.ts +47 -0
  102. package/corpus/core/src/transcription/builder-transcription.ts +9 -2
  103. package/corpus/core/src/vite/action-types-plugin.ts +52 -0
  104. package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -1
  105. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -2
  106. package/corpus/templates/analytics/app/global.css +22 -10
  107. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -1
  108. package/corpus/templates/analytics/app/i18n-data.ts +81 -13
  109. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
  110. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +2 -2
  111. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +528 -108
  112. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +466 -183
  113. package/corpus/templates/analytics/changelog/2026-07-07-session-replays-load-sooner-show-clearer-activity-timelines-.md +6 -0
  114. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +5 -0
  115. package/corpus/templates/assets/.agents/skills/logo-composite/SKILL.md +34 -6
  116. package/corpus/templates/assets/AGENTS.md +23 -4
  117. package/corpus/templates/assets/actions/_generation-preset-settings.ts +48 -0
  118. package/corpus/templates/assets/actions/_helpers.ts +8 -1
  119. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +64 -0
  120. package/corpus/templates/assets/actions/create-generation-preset.ts +11 -3
  121. package/corpus/templates/assets/actions/generate-image-batch.ts +7 -2
  122. package/corpus/templates/assets/actions/generate-image.ts +342 -25
  123. package/corpus/templates/assets/actions/get-library.ts +4 -3
  124. package/corpus/templates/assets/actions/navigate.ts +2 -1
  125. package/corpus/templates/assets/actions/refresh-generation-run.ts +5 -1
  126. package/corpus/templates/assets/actions/update-asset.ts +1 -0
  127. package/corpus/templates/assets/actions/update-generation-preset.ts +8 -1
  128. package/corpus/templates/assets/actions/view-screen.ts +8 -1
  129. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +9 -1
  130. package/corpus/templates/assets/app/hooks/use-image-model-menu.ts +1 -0
  131. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +11 -0
  132. package/corpus/templates/assets/app/i18n/zh-TW.ts +64 -0
  133. package/corpus/templates/assets/app/i18n-data.ts +650 -0
  134. package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -1
  135. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +44 -33
  136. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1474 -0
  137. package/corpus/templates/assets/app/routes/library.tsx +43 -1
  138. package/corpus/templates/assets/server/lib/generation.ts +366 -44
  139. package/corpus/templates/assets/server/lib/image-processing.ts +252 -0
  140. package/corpus/templates/assets/server/lib/preset-skeleton.ts +137 -0
  141. package/corpus/templates/assets/shared/api.ts +47 -0
  142. package/corpus/templates/brain/app/routes/settings.tsx +2 -2
  143. package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +32 -6
  144. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +120 -40
  145. package/corpus/templates/calendar/app/hooks/use-people.ts +55 -0
  146. package/corpus/templates/calendar/changelog/2026-07-07-guest-suggestions-now-find-coworkers-from-your-google-worksp.md +6 -0
  147. package/corpus/templates/calendar/changelog/2026-07-07-zoom-stays-selected-after-connecting-it-from-a-draft-event.md +6 -0
  148. package/corpus/templates/clips/actions/create-recording.ts +5 -1
  149. package/corpus/templates/clips/actions/finalize-recording.ts +140 -1
  150. package/corpus/templates/clips/actions/import-loom-recording.ts +1 -0
  151. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -0
  152. package/corpus/templates/clips/actions/request-transcript.ts +31 -0
  153. package/corpus/templates/clips/actions/set-thumbnail.ts +2 -0
  154. package/corpus/templates/clips/app/components/library/library-layout.tsx +7 -2
  155. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  156. package/corpus/templates/clips/app/components/library/sort-menu.tsx +1 -1
  157. package/corpus/templates/clips/app/components/player/scrubber-position.ts +9 -0
  158. package/corpus/templates/clips/app/components/player/scrubber.tsx +5 -2
  159. package/corpus/templates/clips/app/components/player/share-dialog.tsx +69 -41
  160. package/corpus/templates/clips/app/components/player/video-player.tsx +38 -1
  161. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +114 -33
  162. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -3
  163. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +9 -19
  164. package/corpus/templates/clips/app/routes/_app.library._index.tsx +27 -1
  165. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -3
  166. package/corpus/templates/clips/app/routes/record.tsx +178 -80
  167. package/corpus/templates/clips/changelog/2026-07-02-recordings-now-wait-for-storage-media-to-serve-before-finishing.md +6 -0
  168. package/corpus/templates/clips/changelog/2026-07-07-a-pending-app-update-no-longer-blocks-screen-recording-updat.md +6 -0
  169. package/corpus/templates/clips/changelog/2026-07-07-chrome-extension-recordings-keep-audio-after-refreshing-tab.md +6 -0
  170. package/corpus/templates/clips/changelog/2026-07-07-clip-playback-progress-now-starts-and-finishes-at-the-right-times.md +6 -0
  171. package/corpus/templates/clips/changelog/2026-07-07-sharing-public-clips-now-stays-focused-on-the-normal-link-wi.md +6 -0
  172. package/corpus/templates/clips/chrome-extension/src/background.ts +18 -0
  173. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +23 -8
  174. package/corpus/templates/clips/desktop/src/app.tsx +40 -3
  175. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +19 -7
  176. package/corpus/templates/clips/desktop/src/lib/permissions.ts +2 -0
  177. package/corpus/templates/clips/desktop/src/lib/updater.ts +25 -2
  178. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +7 -0
  179. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +1 -0
  180. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +23 -6
  181. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +28 -3
  182. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +13 -6
  183. package/corpus/templates/clips/shared/finalize-recovery.ts +35 -3
  184. package/corpus/templates/content/AGENTS.md +52 -52
  185. package/corpus/templates/content/actions/_builder-cms-read-client.ts +188 -8
  186. package/corpus/templates/content/actions/_builder-docs-client.ts +41 -3
  187. package/corpus/templates/content/actions/_database-source-utils.ts +998 -160
  188. package/corpus/templates/content/actions/_database-utils.ts +44 -4
  189. package/corpus/templates/content/actions/_notion-action-utils.ts +6 -2
  190. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -1
  191. package/corpus/templates/content/actions/attach-content-database-source.ts +85 -12
  192. package/corpus/templates/content/actions/change-content-database-source-role.ts +9 -1
  193. package/corpus/templates/content/actions/delete-content-database.ts +1 -0
  194. package/corpus/templates/content/actions/delete-document.ts +337 -52
  195. package/corpus/templates/content/actions/get-document.ts +11 -2
  196. package/corpus/templates/content/actions/list-content-databases.ts +57 -9
  197. package/corpus/templates/content/actions/prepare-builder-source-review.ts +23 -6
  198. package/corpus/templates/content/actions/refresh-content-database-source.ts +26 -3
  199. package/corpus/templates/content/actions/restore-content-database.ts +1 -0
  200. package/corpus/templates/content/actions/update-document.ts +43 -0
  201. package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +21 -0
  202. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +0 -1
  203. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +70 -28
  204. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +69 -17
  205. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +4 -4
  206. package/corpus/templates/content/app/components/editor/body-hydration.ts +112 -0
  207. package/corpus/templates/content/app/components/editor/builder-body-hydration-pump.ts +52 -0
  208. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +9076 -2876
  209. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +41 -1
  210. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +36 -11
  211. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +21 -1
  212. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +11 -1
  213. package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +11 -8
  214. package/corpus/templates/content/app/global.css +41 -0
  215. package/corpus/templates/content/app/hooks/use-content-database.ts +346 -42
  216. package/corpus/templates/content/app/hooks/use-db-sync.ts +9 -0
  217. package/corpus/templates/content/app/hooks/use-documents.ts +47 -0
  218. package/corpus/templates/content/app/hooks/use-notion.ts +12 -10
  219. package/corpus/templates/content/app/i18n/zh-TW.ts +35 -0
  220. package/corpus/templates/content/app/i18n-data.ts +355 -0
  221. package/corpus/templates/content/app/root.tsx +22 -0
  222. package/corpus/templates/content/changelog/2026-07-01-builder-database-sources-keep-loading-rows-in-the-background.md +6 -0
  223. package/corpus/templates/content/changelog/2026-07-01-builder-source-attach-starts-with-usable-rows.md +6 -0
  224. package/corpus/templates/content/changelog/2026-07-01-builder-source-attachment-now-stays-connected-after-large.md +6 -0
  225. package/corpus/templates/content/changelog/2026-07-01-builder-source-refreshes-now-show-progress-for-large-docs-blog.md +6 -0
  226. package/corpus/templates/content/changelog/2026-07-01-database-pages-now-delete-to-trash-without-route-errors.md +6 -0
  227. package/corpus/templates/content/changelog/2026-07-02-builder-source-refreshes-recover-from-stalled-background-row.md +6 -0
  228. package/corpus/templates/content/changelog/2026-07-02-builder-sourced-rows-open-with-sync-protection.md +6 -0
  229. package/corpus/templates/content/changelog/2026-07-02-database-rows-and-pages-open-faster-from-recently-loaded-dat.md +6 -0
  230. package/corpus/templates/content/changelog/2026-07-02-preview-panels-close-reliably-narrow-sidebar-row-actions-sta.md +6 -0
  231. package/corpus/templates/content/changelog/2026-07-06-builder-sync-progress-no-longer-shows-continue.md +6 -0
  232. package/corpus/templates/content/changelog/2026-07-07-permanently-deleting-trashed-databases-now-finishes-reliably.md +6 -0
  233. package/corpus/templates/content/shared/api.ts +13 -0
  234. package/corpus/templates/content/shared/builder-mdx.ts +16 -3
  235. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +23 -13
  236. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +98 -0
  237. package/corpus/templates/design/.agents/skills/shader-fills/SKILL.md +162 -0
  238. package/corpus/templates/design/AGENTS.md +9 -2
  239. package/corpus/templates/design/actions/add-breakpoint.ts +6 -3
  240. package/corpus/templates/design/actions/apply-a11y-fix.ts +57 -37
  241. package/corpus/templates/design/actions/apply-component-prop-edit.ts +41 -20
  242. package/corpus/templates/design/actions/apply-motion-edit.ts +251 -38
  243. package/corpus/templates/design/actions/apply-shader-fill.ts +90 -66
  244. package/corpus/templates/design/actions/apply-visual-edit.ts +282 -55
  245. package/corpus/templates/design/actions/create-component.ts +29 -60
  246. package/corpus/templates/design/actions/create-file.ts +9 -2
  247. package/corpus/templates/design/actions/duplicate-design.ts +31 -2
  248. package/corpus/templates/design/actions/edit-design.ts +36 -38
  249. package/corpus/templates/design/actions/generate-design-title.ts +87 -0
  250. package/corpus/templates/design/actions/generate-design.ts +53 -18
  251. package/corpus/templates/design/actions/generate-screens.ts +108 -4
  252. package/corpus/templates/design/actions/get-motion-timeline.ts +35 -7
  253. package/corpus/templates/design/actions/insert-asset.ts +34 -29
  254. package/corpus/templates/design/actions/insert-design-native-asset.ts +129 -32
  255. package/corpus/templates/design/actions/insert-figma-library-asset.ts +35 -30
  256. package/corpus/templates/design/actions/present-design-variants.ts +7 -2
  257. package/corpus/templates/design/actions/remove-motion-timeline.ts +31 -36
  258. package/corpus/templates/design/actions/update-file.ts +190 -75
  259. package/corpus/templates/design/app/components/design/BreakpointBar.tsx +403 -0
  260. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +469 -222
  261. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +708 -53
  262. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +83 -3
  263. package/corpus/templates/design/app/components/design/EditPanel.tsx +1091 -6948
  264. package/corpus/templates/design/app/components/design/LayersPanel.tsx +419 -85
  265. package/corpus/templates/design/app/components/design/MotionDock.tsx +1124 -103
  266. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2610 -1398
  267. package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +22 -0
  268. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2182 -235
  269. package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +187 -11
  270. package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +376 -1
  271. package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +746 -0
  272. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +17 -0
  273. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +1 -1
  274. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +1 -3
  275. package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +1 -1
  276. package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +518 -0
  277. package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +562 -0
  278. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +763 -0
  279. package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +94 -0
  280. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +780 -0
  281. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +446 -0
  282. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +79 -0
  283. package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +315 -0
  284. package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +344 -0
  285. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +594 -0
  286. package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +119 -0
  287. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +248 -0
  288. package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +45 -0
  289. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +693 -0
  290. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +724 -0
  291. package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +207 -0
  292. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +628 -0
  293. package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +91 -0
  294. package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +649 -0
  295. package/corpus/templates/design/app/components/design/edit-panel/style-change-types.ts +118 -0
  296. package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +88 -0
  297. package/corpus/templates/design/app/components/design/edit-panel/transform-helpers.ts +100 -0
  298. package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +117 -0
  299. package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +501 -0
  300. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +91 -40
  301. package/corpus/templates/design/app/components/design/inspector/BreakpointOverrideIndicator.tsx +82 -0
  302. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +189 -87
  303. package/corpus/templates/design/app/components/design/inspector/GlslShaderPanel.tsx +1097 -0
  304. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +44 -0
  305. package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +258 -0
  306. package/corpus/templates/design/app/components/design/inspector/MotionKeyframeDiamond.tsx +144 -0
  307. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +99 -9
  308. package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +116 -0
  309. package/corpus/templates/design/app/components/design/inspector/index.ts +26 -0
  310. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +29 -0
  311. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +171 -0
  312. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +220 -0
  313. package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +35 -0
  314. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +134 -0
  315. package/corpus/templates/design/app/components/design/multi-screen/culling.ts +185 -0
  316. package/corpus/templates/design/app/components/design/multi-screen/gradient-overlay-geometry.ts +120 -0
  317. package/corpus/templates/design/app/components/design/multi-screen/types.ts +892 -0
  318. package/corpus/templates/design/app/components/design/multi-screen/vector-edit-geometry.ts +21 -0
  319. package/corpus/templates/design/app/components/design/types.ts +15 -0
  320. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +109 -5
  321. package/corpus/templates/design/app/global.css +8 -8
  322. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +259 -2
  323. package/corpus/templates/design/app/i18n/zh-TW.ts +163 -9
  324. package/corpus/templates/design/app/i18n-breakpoints.ts +205 -0
  325. package/corpus/templates/design/app/i18n-data.ts +1664 -152
  326. package/corpus/templates/design/app/i18n-motion.ts +563 -0
  327. package/corpus/templates/design/app/lib/design-import.ts +73 -0
  328. package/corpus/templates/design/app/pages/Index.tsx +41 -22
  329. package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +1 -1
  330. package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +1 -1
  331. package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +1 -1
  332. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +1 -1
  333. package/corpus/templates/design/changelog/2026-07-03-canvas-interactions-now-match-figma-rotation-aware-resizing-.md +1 -1
  334. package/corpus/templates/design/changelog/2026-07-03-layers-panel-matches-figma-top-layer-on-top-drag-with-auto-s.md +1 -1
  335. package/corpus/templates/design/changelog/2026-07-05-designs-get-ai-generated-names-from-your-prompt.md +6 -0
  336. package/corpus/templates/design/changelog/2026-07-05-local-code-screens-keep-their-connection-when-duplicated-and.md +6 -0
  337. package/corpus/templates/design/changelog/2026-07-05-press-a-to-draw-screens-on-the-canvas-inside-a-screen-it-dr.md +6 -0
  338. package/corpus/templates/design/changelog/2026-07-06-3d-rotation-and-perspective-controls-on-every-element.md +6 -0
  339. package/corpus/templates/design/changelog/2026-07-06-ai-generated-and-duplicated-screens-now-get-their-editor-sel.md +6 -0
  340. package/corpus/templates/design/changelog/2026-07-06-applying-shaders-and-fills-in-quick-succession-can-no-longer.md +6 -0
  341. package/corpus/templates/design/changelog/2026-07-06-breakpoint-frames-in-the-overview-now-support-click-to-selec.md +6 -0
  342. package/corpus/templates/design/changelog/2026-07-06-breakpoint-segments-in-the-inspector-now-show-a-device-icon-.md +6 -0
  343. package/corpus/templates/design/changelog/2026-07-06-breakpoint-targeting-now-lives-in-one-compact-control-in-the.md +6 -0
  344. package/corpus/templates/design/changelog/2026-07-06-canvas-edits-can-no-longer-be-overwritten-by-stale-collabora.md +6 -0
  345. package/corpus/templates/design/changelog/2026-07-06-canvas-edits-inside-screens-save-reliably-again.md +6 -0
  346. package/corpus/templates/design/changelog/2026-07-06-cleaner-inspector-removed-the-ask-ai-box-from-the-design-tab.md +6 -0
  347. package/corpus/templates/design/changelog/2026-07-06-clicking-empty-canvas-space-now-deselects-an-element-inside-.md +6 -0
  348. package/corpus/templates/design/changelog/2026-07-06-dragging-an-element-onto-a-rectangle-now-nests-it-inside-wit.md +6 -0
  349. package/corpus/templates/design/changelog/2026-07-06-dragging-screens-and-objects-on-the-canvas-is-now-much-smoot.md +6 -0
  350. package/corpus/templates/design/changelog/2026-07-06-drawing-a-shape-or-text-on-the-canvas-no-longer-flashes-away.md +6 -0
  351. package/corpus/templates/design/changelog/2026-07-06-dropping-an-element-between-two-others-inside-a-screen-now-s.md +6 -0
  352. package/corpus/templates/design/changelog/2026-07-06-duplicating-a-screen-now-places-the-copy-exactly-where-you-d.md +6 -0
  353. package/corpus/templates/design/changelog/2026-07-06-edit-gradients-directly-on-elements-inside-screens-scale-str.md +6 -0
  354. package/corpus/templates/design/changelog/2026-07-06-edits-from-collaborators-and-the-agent-now-update-the-canvas.md +6 -0
  355. package/corpus/templates/design/changelog/2026-07-06-fixed-a-bug-where-most-style-position-and-text-edits-briefly.md +6 -0
  356. package/corpus/templates/design/changelog/2026-07-06-fixed-a-confusing-raw-error-message-when-a-file-upload-fails.md +6 -0
  357. package/corpus/templates/design/changelog/2026-07-06-fixed-a-rare-case-where-an-edit-could-be-silently-overwritte.md +6 -0
  358. package/corpus/templates/design/changelog/2026-07-06-fixed-inserted-assets-sometimes-disappearing-reappearing-or-.md +6 -0
  359. package/corpus/templates/design/changelog/2026-07-06-fixed-inspector-value-scrubbing-producing-erratic-numbers-an.md +6 -0
  360. package/corpus/templates/design/changelog/2026-07-06-fixed-padding-gap-and-min-max-size-scrubbing-not-updating-th.md +6 -0
  361. package/corpus/templates/design/changelog/2026-07-06-fixed-text-stroke-color-turning-black-and-glyphs-disappearin.md +6 -0
  362. package/corpus/templates/design/changelog/2026-07-06-fixed-the-collapsed-effects-and-stroke-inspector-sections-sh.md +6 -0
  363. package/corpus/templates/design/changelog/2026-07-06-fixed-the-new-design-dialog-closing-unexpectedly-when-using-.md +6 -0
  364. package/corpus/templates/design/changelog/2026-07-06-fixed-the-typography-section-missing-when-selecting-text-nes.md +6 -0
  365. package/corpus/templates/design/changelog/2026-07-06-full-view-no-longer-flashes-back-to-the-overview-on-entry-no.md +6 -0
  366. package/corpus/templates/design/changelog/2026-07-06-keyframe-animation-timeline-per-property-keyframes-easing-cu.md +6 -0
  367. package/corpus/templates/design/changelog/2026-07-06-moving-restyling-and-scrubbing-values-on-elements-in-ai-gene.md +6 -0
  368. package/corpus/templates/design/changelog/2026-07-06-padding-and-corner-radius-value-scrubbing-now-snaps-to-whole.md +6 -0
  369. package/corpus/templates/design/changelog/2026-07-06-padding-handles-now-only-resize-on-the-handle-line-itself-sh.md +6 -0
  370. package/corpus/templates/design/changelog/2026-07-06-preview-and-edit-hover-focus-and-pressed-states-with-real-cs.md +6 -0
  371. package/corpus/templates/design/changelog/2026-07-06-promoting-an-element-to-a-component-now-works-correctly-for-.md +6 -0
  372. package/corpus/templates/design/changelog/2026-07-06-reduced-url-history-churn-and-selection-overlay-flicker-whil.md +6 -0
  373. package/corpus/templates/design/changelog/2026-07-06-removed-the-decorative-dot-before-screen-names-in-the-overvi.md +6 -0
  374. package/corpus/templates/design/changelog/2026-07-06-responsive-breakpoints-edit-at-any-width-with-cascading-over.md +6 -0
  375. package/corpus/templates/design/changelog/2026-07-06-screen-labels-no-longer-turn-blue-when-you-hover-inside-the-.md +6 -0
  376. package/corpus/templates/design/changelog/2026-07-06-scrolling-a-screen-with-an-element-selected-stays-smooth-on-.md +6 -0
  377. package/corpus/templates/design/changelog/2026-07-06-selecting-multiple-elements-and-dragging-now-moves-the-whole.md +6 -0
  378. package/corpus/templates/design/changelog/2026-07-06-selection-borders-handles-and-value-readouts-now-stay-the-sa.md +6 -0
  379. package/corpus/templates/design/changelog/2026-07-06-selection-handles-and-editing-chrome-now-stay-a-constant-siz.md +6 -0
  380. package/corpus/templates/design/changelog/2026-07-06-shader-fills-and-effects-ai-authored-or-preset-glsl-shaders-.md +6 -0
  381. package/corpus/templates/design/changelog/2026-07-06-text-drawn-on-the-canvas-now-defaults-to-white-and-inter-in-.md +6 -0
  382. package/corpus/templates/design/changelog/2026-07-06-text-dropped-into-a-shape-now-stays-readable-instead-of-disa.md +6 -0
  383. package/corpus/templates/design/changelog/2026-07-06-the-add-tweak-controls-prompt-no-longer-jumps-to-the-corner-.md +6 -0
  384. package/corpus/templates/design/changelog/2026-07-06-the-padding-value-readout-now-stays-visible-while-you-hover-.md +6 -0
  385. package/corpus/templates/design/changelog/2026-07-06-the-selected-element-attachment-now-clears-from-the-chat-com.md +6 -0
  386. package/corpus/templates/design/changelog/2026-07-06-the-zoom-menu-is-more-compact-with-tight-rows-and-right-alig.md +6 -0
  387. package/corpus/templates/design/changelog/2026-07-06-undo-and-redo-no-longer-flash-the-screen-changes-now-apply-i.md +6 -0
  388. package/corpus/templates/design/changelog/2026-07-06-zoom-presets-like-zoom-to-50-now-stay-on-the-focused-screen-.md +6 -0
  389. package/corpus/templates/design/server/lib/import-design-files.ts +11 -2
  390. package/corpus/templates/design/server/source-workspace.ts +139 -59
  391. package/corpus/templates/design/shared/board-file.ts +11 -2
  392. package/corpus/templates/design/shared/breakpoint-media.ts +543 -0
  393. package/corpus/templates/design/shared/canvas-math.ts +354 -35
  394. package/corpus/templates/design/shared/code-layer.ts +277 -8
  395. package/corpus/templates/design/shared/design-state.ts +11 -4
  396. package/corpus/templates/design/shared/interaction-states.ts +548 -0
  397. package/corpus/templates/design/shared/motion-compiler.ts +186 -23
  398. package/corpus/templates/design/shared/motion-easing.ts +294 -0
  399. package/corpus/templates/design/shared/motion-timeline.ts +400 -34
  400. package/corpus/templates/design/shared/prompt-title.ts +95 -0
  401. package/corpus/templates/design/shared/responsive-classes.ts +448 -10
  402. package/corpus/templates/design/shared/screen-annotation.ts +46 -0
  403. package/corpus/templates/design/shared/shader-fills.ts +1009 -0
  404. package/corpus/templates/design/shared/shader-presets.ts +852 -4
  405. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +15 -2
  406. package/corpus/templates/slides/app/components/editor/ImportButton.tsx +10 -1
  407. package/corpus/templates/slides/app/lib/upload-response.ts +71 -0
  408. package/corpus/templates/slides/app/pages/DeckEditor.tsx +2 -2
  409. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  410. package/dist/agent/engine/ai-sdk-engine.js +15 -1
  411. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  412. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  413. package/dist/agent/engine/anthropic-engine.js +20 -1
  414. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  415. package/dist/agent/engine/registry.d.ts.map +1 -1
  416. package/dist/agent/engine/registry.js +22 -14
  417. package/dist/agent/engine/registry.js.map +1 -1
  418. package/dist/agent/production-agent.d.ts.map +1 -1
  419. package/dist/agent/production-agent.js +27 -7
  420. package/dist/agent/production-agent.js.map +1 -1
  421. package/dist/client/AgentPanel.js +1 -1
  422. package/dist/client/AgentPanel.js.map +1 -1
  423. package/dist/client/command-navigation/index.d.ts +4 -0
  424. package/dist/client/command-navigation/index.d.ts.map +1 -0
  425. package/dist/client/command-navigation/index.js +4 -0
  426. package/dist/client/command-navigation/index.js.map +1 -0
  427. package/dist/client/comments-review/index.d.ts +2 -0
  428. package/dist/client/comments-review/index.d.ts.map +1 -0
  429. package/dist/client/comments-review/index.js +2 -0
  430. package/dist/client/comments-review/index.js.map +1 -0
  431. package/dist/client/history/VersionHistoryPanel.d.ts +18 -0
  432. package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -0
  433. package/dist/client/history/VersionHistoryPanel.js +24 -0
  434. package/dist/client/history/VersionHistoryPanel.js.map +1 -0
  435. package/dist/client/history/index.d.ts +3 -0
  436. package/dist/client/history/index.d.ts.map +1 -0
  437. package/dist/client/history/index.js +3 -0
  438. package/dist/client/history/index.js.map +1 -0
  439. package/dist/client/history/use-history.d.ts +46 -0
  440. package/dist/client/history/use-history.d.ts.map +1 -0
  441. package/dist/client/history/use-history.js +18 -0
  442. package/dist/client/history/use-history.js.map +1 -0
  443. package/dist/client/index.d.ts +6 -4
  444. package/dist/client/index.d.ts.map +1 -1
  445. package/dist/client/index.js +6 -4
  446. package/dist/client/index.js.map +1 -1
  447. package/dist/client/org/OrgSwitcher.js +5 -5
  448. package/dist/client/org/OrgSwitcher.js.map +1 -1
  449. package/dist/client/org/RequireActiveOrg.js +2 -2
  450. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  451. package/dist/client/org/TeamPage.js +3 -3
  452. package/dist/client/org/TeamPage.js.map +1 -1
  453. package/dist/client/org/hooks.d.ts +12 -1
  454. package/dist/client/org/hooks.d.ts.map +1 -1
  455. package/dist/client/org/hooks.js +15 -0
  456. package/dist/client/org/hooks.js.map +1 -1
  457. package/dist/client/org/index.d.ts +4 -2
  458. package/dist/client/org/index.d.ts.map +1 -1
  459. package/dist/client/org/index.js +3 -1
  460. package/dist/client/org/index.js.map +1 -1
  461. package/dist/client/org-team/index.d.ts +2 -0
  462. package/dist/client/org-team/index.d.ts.map +1 -0
  463. package/dist/client/org-team/index.js +2 -0
  464. package/dist/client/org-team/index.js.map +1 -0
  465. package/dist/client/review/ReviewStatusBadge.d.ts +7 -0
  466. package/dist/client/review/ReviewStatusBadge.d.ts.map +1 -0
  467. package/dist/client/review/ReviewStatusBadge.js +19 -0
  468. package/dist/client/review/ReviewStatusBadge.js.map +1 -0
  469. package/dist/client/review/ReviewThreadPanel.d.ts +20 -0
  470. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -0
  471. package/dist/client/review/ReviewThreadPanel.js +84 -0
  472. package/dist/client/review/ReviewThreadPanel.js.map +1 -0
  473. package/dist/client/review/index.d.ts +4 -0
  474. package/dist/client/review/index.d.ts.map +1 -0
  475. package/dist/client/review/index.js +4 -0
  476. package/dist/client/review/index.js.map +1 -0
  477. package/dist/client/review/use-review.d.ts +68 -0
  478. package/dist/client/review/use-review.d.ts.map +1 -0
  479. package/dist/client/review/use-review.js +22 -0
  480. package/dist/client/review/use-review.js.map +1 -0
  481. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  482. package/dist/client/rich-markdown-editor/useCollabReconcile.js +11 -6
  483. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  484. package/dist/client/settings/index.d.ts +1 -1
  485. package/dist/client/settings/index.d.ts.map +1 -1
  486. package/dist/client/settings/index.js +1 -1
  487. package/dist/client/settings/index.js.map +1 -1
  488. package/dist/client/setup-connections/BuilderConnectCard.d.ts +9 -0
  489. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -0
  490. package/dist/client/setup-connections/BuilderConnectCard.js +25 -0
  491. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -0
  492. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts +8 -0
  493. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts.map +1 -0
  494. package/dist/client/setup-connections/ProviderReadinessBadge.js +32 -0
  495. package/dist/client/setup-connections/ProviderReadinessBadge.js.map +1 -0
  496. package/dist/client/setup-connections/SetupConnectionsPage.d.ts +17 -0
  497. package/dist/client/setup-connections/SetupConnectionsPage.d.ts.map +1 -0
  498. package/dist/client/setup-connections/SetupConnectionsPage.js +10 -0
  499. package/dist/client/setup-connections/SetupConnectionsPage.js.map +1 -0
  500. package/dist/client/setup-connections/index.d.ts +7 -0
  501. package/dist/client/setup-connections/index.d.ts.map +1 -0
  502. package/dist/client/setup-connections/index.js +7 -0
  503. package/dist/client/setup-connections/index.js.map +1 -0
  504. package/dist/client/sharing/ShareButton.d.ts +4 -4
  505. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  506. package/dist/client/sharing/ShareButton.js +13 -7
  507. package/dist/client/sharing/ShareButton.js.map +1 -1
  508. package/dist/client/sharing/ShareDialog.js +3 -3
  509. package/dist/client/sharing/ShareDialog.js.map +1 -1
  510. package/dist/client/use-action.d.ts +3 -0
  511. package/dist/client/use-action.d.ts.map +1 -1
  512. package/dist/client/use-action.js +34 -3
  513. package/dist/client/use-action.js.map +1 -1
  514. package/dist/client/use-db-sync.d.ts +4 -0
  515. package/dist/client/use-db-sync.d.ts.map +1 -1
  516. package/dist/client/use-db-sync.js +37 -18
  517. package/dist/client/use-db-sync.js.map +1 -1
  518. package/dist/collab/routes.d.ts +1 -1
  519. package/dist/command-navigation/actions.d.ts +25 -0
  520. package/dist/command-navigation/actions.d.ts.map +1 -0
  521. package/dist/command-navigation/actions.js +64 -0
  522. package/dist/command-navigation/actions.js.map +1 -0
  523. package/dist/command-navigation/index.d.ts +4 -0
  524. package/dist/command-navigation/index.d.ts.map +1 -0
  525. package/dist/command-navigation/index.js +4 -0
  526. package/dist/command-navigation/index.js.map +1 -0
  527. package/dist/comments-review/index.d.ts +2 -0
  528. package/dist/comments-review/index.d.ts.map +1 -0
  529. package/dist/comments-review/index.js +2 -0
  530. package/dist/comments-review/index.js.map +1 -0
  531. package/dist/db/create-get-db.d.ts +25 -0
  532. package/dist/db/create-get-db.d.ts.map +1 -1
  533. package/dist/db/create-get-db.js +25 -2
  534. package/dist/db/create-get-db.js.map +1 -1
  535. package/dist/file-upload/builder.d.ts.map +1 -1
  536. package/dist/file-upload/builder.js +18 -2
  537. package/dist/file-upload/builder.js.map +1 -1
  538. package/dist/file-upload/types.d.ts +3 -0
  539. package/dist/file-upload/types.d.ts.map +1 -1
  540. package/dist/file-upload/types.js.map +1 -1
  541. package/dist/history/actions/create-resource-version.d.ts +10 -0
  542. package/dist/history/actions/create-resource-version.d.ts.map +1 -0
  543. package/dist/history/actions/create-resource-version.js +65 -0
  544. package/dist/history/actions/create-resource-version.js.map +1 -0
  545. package/dist/history/actions/get-resource-version.d.ts +10 -0
  546. package/dist/history/actions/get-resource-version.d.ts.map +1 -0
  547. package/dist/history/actions/get-resource-version.js +38 -0
  548. package/dist/history/actions/get-resource-version.js.map +1 -0
  549. package/dist/history/actions/list-resource-history.d.ts +10 -0
  550. package/dist/history/actions/list-resource-history.d.ts.map +1 -0
  551. package/dist/history/actions/list-resource-history.js +45 -0
  552. package/dist/history/actions/list-resource-history.js.map +1 -0
  553. package/dist/history/actions/list-resource-versions.d.ts +10 -0
  554. package/dist/history/actions/list-resource-versions.d.ts.map +1 -0
  555. package/dist/history/actions/list-resource-versions.js +35 -0
  556. package/dist/history/actions/list-resource-versions.js.map +1 -0
  557. package/dist/history/actions/restore-resource-version.d.ts +11 -0
  558. package/dist/history/actions/restore-resource-version.d.ts.map +1 -0
  559. package/dist/history/actions/restore-resource-version.js +59 -0
  560. package/dist/history/actions/restore-resource-version.js.map +1 -0
  561. package/dist/history/index.d.ts +4 -0
  562. package/dist/history/index.d.ts.map +1 -0
  563. package/dist/history/index.js +3 -0
  564. package/dist/history/index.js.map +1 -0
  565. package/dist/history/registry.d.ts +10 -0
  566. package/dist/history/registry.d.ts.map +1 -0
  567. package/dist/history/registry.js +61 -0
  568. package/dist/history/registry.js.map +1 -0
  569. package/dist/history/store.d.ts +34 -0
  570. package/dist/history/store.d.ts.map +1 -0
  571. package/dist/history/store.js +265 -0
  572. package/dist/history/store.js.map +1 -0
  573. package/dist/history/types.d.ts +55 -0
  574. package/dist/history/types.d.ts.map +1 -0
  575. package/dist/history/types.js +2 -0
  576. package/dist/history/types.js.map +1 -0
  577. package/dist/index.d.ts +6 -0
  578. package/dist/index.d.ts.map +1 -1
  579. package/dist/index.js +6 -0
  580. package/dist/index.js.map +1 -1
  581. package/dist/navigation/index.d.ts +53 -0
  582. package/dist/navigation/index.d.ts.map +1 -0
  583. package/dist/navigation/index.js +105 -0
  584. package/dist/navigation/index.js.map +1 -0
  585. package/dist/observability/routes.d.ts +3 -3
  586. package/dist/org/index.d.ts +1 -0
  587. package/dist/org/index.d.ts.map +1 -1
  588. package/dist/org/index.js +1 -0
  589. package/dist/org/index.js.map +1 -1
  590. package/dist/org/permissions.d.ts +7 -0
  591. package/dist/org/permissions.d.ts.map +1 -0
  592. package/dist/org/permissions.js +21 -0
  593. package/dist/org/permissions.js.map +1 -0
  594. package/dist/org-team/index.d.ts +2 -0
  595. package/dist/org-team/index.d.ts.map +1 -0
  596. package/dist/org-team/index.js +2 -0
  597. package/dist/org-team/index.js.map +1 -0
  598. package/dist/private-blob/registry.d.ts.map +1 -1
  599. package/dist/private-blob/registry.js +1 -0
  600. package/dist/private-blob/registry.js.map +1 -1
  601. package/dist/resources/handlers.d.ts +2 -2
  602. package/dist/review/actions/consume-review-feedback.d.ts +9 -0
  603. package/dist/review/actions/consume-review-feedback.d.ts.map +1 -0
  604. package/dist/review/actions/consume-review-feedback.js +29 -0
  605. package/dist/review/actions/consume-review-feedback.js.map +1 -0
  606. package/dist/review/actions/create-review-comment.d.ts +18 -0
  607. package/dist/review/actions/create-review-comment.d.ts.map +1 -0
  608. package/dist/review/actions/create-review-comment.js +81 -0
  609. package/dist/review/actions/create-review-comment.js.map +1 -0
  610. package/dist/review/actions/delete-review-comment.d.ts +10 -0
  611. package/dist/review/actions/delete-review-comment.d.ts.map +1 -0
  612. package/dist/review/actions/delete-review-comment.js +45 -0
  613. package/dist/review/actions/delete-review-comment.js.map +1 -0
  614. package/dist/review/actions/get-review-feedback.d.ts +10 -0
  615. package/dist/review/actions/get-review-feedback.d.ts.map +1 -0
  616. package/dist/review/actions/get-review-feedback.js +45 -0
  617. package/dist/review/actions/get-review-feedback.js.map +1 -0
  618. package/dist/review/actions/list-review-comments.d.ts +13 -0
  619. package/dist/review/actions/list-review-comments.d.ts.map +1 -0
  620. package/dist/review/actions/list-review-comments.js +44 -0
  621. package/dist/review/actions/list-review-comments.js.map +1 -0
  622. package/dist/review/actions/reply-review-comment.d.ts +16 -0
  623. package/dist/review/actions/reply-review-comment.d.ts.map +1 -0
  624. package/dist/review/actions/reply-review-comment.js +84 -0
  625. package/dist/review/actions/reply-review-comment.js.map +1 -0
  626. package/dist/review/actions/resolve-review-thread.d.ts +11 -0
  627. package/dist/review/actions/resolve-review-thread.d.ts.map +1 -0
  628. package/dist/review/actions/resolve-review-thread.js +46 -0
  629. package/dist/review/actions/resolve-review-thread.js.map +1 -0
  630. package/dist/review/actions/set-review-status.d.ts +9 -0
  631. package/dist/review/actions/set-review-status.d.ts.map +1 -0
  632. package/dist/review/actions/set-review-status.js +43 -0
  633. package/dist/review/actions/set-review-status.js.map +1 -0
  634. package/dist/review/index.d.ts +5 -0
  635. package/dist/review/index.d.ts.map +1 -0
  636. package/dist/review/index.js +4 -0
  637. package/dist/review/index.js.map +1 -0
  638. package/dist/review/mentions.d.ts +4 -0
  639. package/dist/review/mentions.d.ts.map +1 -0
  640. package/dist/review/mentions.js +39 -0
  641. package/dist/review/mentions.js.map +1 -0
  642. package/dist/review/registry.d.ts +10 -0
  643. package/dist/review/registry.d.ts.map +1 -0
  644. package/dist/review/registry.js +61 -0
  645. package/dist/review/registry.js.map +1 -0
  646. package/dist/review/store.d.ts +63 -0
  647. package/dist/review/store.d.ts.map +1 -0
  648. package/dist/review/store.js +558 -0
  649. package/dist/review/store.js.map +1 -0
  650. package/dist/review/types.d.ts +77 -0
  651. package/dist/review/types.d.ts.map +1 -0
  652. package/dist/review/types.js +2 -0
  653. package/dist/review/types.js.map +1 -0
  654. package/dist/secrets/routes.d.ts +9 -9
  655. package/dist/server/action-discovery.d.ts.map +1 -1
  656. package/dist/server/action-discovery.js +54 -0
  657. package/dist/server/action-discovery.js.map +1 -1
  658. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  659. package/dist/server/agent-engine-api-key-route.d.ts.map +1 -1
  660. package/dist/server/agent-engine-api-key-route.js +5 -0
  661. package/dist/server/agent-engine-api-key-route.js.map +1 -1
  662. package/dist/server/credential-provider.d.ts +26 -0
  663. package/dist/server/credential-provider.d.ts.map +1 -1
  664. package/dist/server/credential-provider.js +82 -0
  665. package/dist/server/credential-provider.js.map +1 -1
  666. package/dist/server/framework-request-handler.d.ts.map +1 -1
  667. package/dist/server/framework-request-handler.js +37 -1
  668. package/dist/server/framework-request-handler.js.map +1 -1
  669. package/dist/setup-connections/index.d.ts +6 -0
  670. package/dist/setup-connections/index.d.ts.map +1 -0
  671. package/dist/setup-connections/index.js +6 -0
  672. package/dist/setup-connections/index.js.map +1 -0
  673. package/dist/setup-connections/onboarding.d.ts +14 -0
  674. package/dist/setup-connections/onboarding.d.ts.map +1 -0
  675. package/dist/setup-connections/onboarding.js +23 -0
  676. package/dist/setup-connections/onboarding.js.map +1 -0
  677. package/dist/transcription/builder-transcription.d.ts +1 -0
  678. package/dist/transcription/builder-transcription.d.ts.map +1 -1
  679. package/dist/transcription/builder-transcription.js +5 -2
  680. package/dist/transcription/builder-transcription.js.map +1 -1
  681. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  682. package/dist/vite/action-types-plugin.js +52 -0
  683. package/dist/vite/action-types-plugin.js.map +1 -1
  684. package/docs/content/agent-native-toolkit.mdx +87 -80
  685. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  686. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  687. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  688. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  689. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  690. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  691. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  692. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  693. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  694. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  695. package/docs/content/toolkit-agent-ux.mdx +43 -0
  696. package/docs/content/toolkit-app-adapters.mdx +9 -0
  697. package/docs/content/toolkit-collaboration-ui.mdx +12 -0
  698. package/docs/content/toolkit-collaboration.mdx +74 -0
  699. package/docs/content/toolkit-command-navigation.mdx +106 -0
  700. package/docs/content/toolkit-comments-review.mdx +98 -0
  701. package/docs/content/toolkit-history.mdx +95 -0
  702. package/docs/content/toolkit-observability.mdx +41 -0
  703. package/docs/content/toolkit-org-team.mdx +80 -0
  704. package/docs/content/toolkit-resources.mdx +57 -0
  705. package/docs/content/toolkit-settings.mdx +65 -0
  706. package/docs/content/toolkit-setup-connections.mdx +109 -0
  707. package/docs/content/toolkit-sharing-ui.mdx +18 -6
  708. package/docs/content/toolkit-sharing.mdx +81 -0
  709. package/docs/content/toolkit-shell-hooks.mdx +9 -0
  710. package/docs/content/toolkit-ui.mdx +9 -0
  711. package/package.json +36 -2
  712. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +0 -153
  713. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +0 -133
  714. package/corpus/templates/design/app/pages/DesignEditor.tsx +0 -22924
@@ -75,6 +75,30 @@ function normalizedBuilderBodyProse(content: string | null | undefined) {
75
75
  .trim();
76
76
  }
77
77
 
78
+ export function isEffectivelyEmptyDocumentContent(
79
+ content: string | null | undefined,
80
+ ) {
81
+ const normalized = (content ?? "").trim();
82
+ return normalized === "" || normalized === "<empty-block/>";
83
+ }
84
+
85
+ export function shouldRejectStaleEmptyBodySave(args: {
86
+ incomingContent: string | null | undefined;
87
+ currentContent: string | null | undefined;
88
+ loadedUpdatedAt: string | null | undefined;
89
+ currentUpdatedAt: string | null | undefined;
90
+ loadedContentWasEmpty?: boolean | null | undefined;
91
+ }) {
92
+ if (!args.loadedUpdatedAt || !args.currentUpdatedAt) return false;
93
+ if (!isEffectivelyEmptyDocumentContent(args.incomingContent)) return false;
94
+ if (isEffectivelyEmptyDocumentContent(args.currentContent)) return false;
95
+ if (args.loadedContentWasEmpty === true) return true;
96
+ return (
97
+ new Date(args.currentUpdatedAt).getTime() >
98
+ new Date(args.loadedUpdatedAt).getTime()
99
+ );
100
+ }
101
+
78
102
  /**
79
103
  * Best-effort quote of the first changed span between two document bodies, used
80
104
  * as the `{ kind: "text", quote }` descriptor so the recent-edit highlight lands
@@ -133,6 +157,14 @@ export default defineAction({
133
157
  .boolean()
134
158
  .optional()
135
159
  .describe("Favorite status (true/false)"),
160
+ loadedUpdatedAt: z
161
+ .string()
162
+ .optional()
163
+ .describe("Document updatedAt value the client loaded before editing"),
164
+ loadedContentWasEmpty: z
165
+ .boolean()
166
+ .optional()
167
+ .describe("Whether the client-loaded content snapshot was empty"),
136
168
  // Optional optimistic-concurrency guard for content saves: the
137
169
  // `updatedAt` of the document snapshot the caller last loaded/reconciled.
138
170
  // When provided alongside `content`, the write is a compare-and-swap on
@@ -229,6 +261,17 @@ export default defineAction({
229
261
  content = existing.content;
230
262
  }
231
263
  }
264
+ if (
265
+ shouldRejectStaleEmptyBodySave({
266
+ incomingContent: content,
267
+ currentContent: existing.content,
268
+ loadedUpdatedAt: args.loadedUpdatedAt,
269
+ currentUpdatedAt: existing.updatedAt,
270
+ loadedContentWasEmpty: args.loadedContentWasEmpty,
271
+ })
272
+ ) {
273
+ content = existing.content;
274
+ }
232
275
  }
233
276
 
234
277
  // Detect actual changes — a no-op call (e.g. the editor echoing back the
@@ -0,0 +1,21 @@
1
+ import { IconLoader2 } from "@tabler/icons-react";
2
+
3
+ export function BuilderBodySyncingNotice({
4
+ title,
5
+ description,
6
+ }: {
7
+ title: string;
8
+ description: string;
9
+ }) {
10
+ return (
11
+ <div className="rounded-lg border border-dashed border-border bg-muted/35 px-4 py-5 text-sm">
12
+ <div className="flex items-center gap-2 font-medium text-foreground">
13
+ <IconLoader2 className="size-4 animate-spin text-muted-foreground" />
14
+ {title}
15
+ </div>
16
+ <p className="mt-2 max-w-2xl leading-6 text-muted-foreground">
17
+ {description}
18
+ </p>
19
+ </div>
20
+ );
21
+ }
@@ -18,7 +18,6 @@ export function DocumentDatabase({ document, canEdit }: DocumentDatabaseProps) {
18
18
  databaseId={databaseId}
19
19
  databaseDocumentId={document.id}
20
20
  canEdit={canEdit}
21
- documentOverride={document}
22
21
  />
23
22
  );
24
23
  }
@@ -11,7 +11,7 @@ import {
11
11
  type CollabUser,
12
12
  } from "@agent-native/core/client";
13
13
  import type { Document, DocumentSyncStatus } from "@shared/api";
14
- import { IconArrowLeft, IconDatabase } from "@tabler/icons-react";
14
+ import { IconArrowLeft, IconDatabase, IconLoader2 } from "@tabler/icons-react";
15
15
  import { IconLock } from "@tabler/icons-react";
16
16
  import { useQueryClient } from "@tanstack/react-query";
17
17
  import {
@@ -54,6 +54,11 @@ import {
54
54
  } from "@/lib/local-content-source-files";
55
55
  import { cn } from "@/lib/utils";
56
56
 
57
+ import {
58
+ documentBodyHydrationIsPending,
59
+ isEffectivelyEmptyDocumentContent,
60
+ } from "./body-hydration";
61
+ import { BuilderBodySyncingNotice } from "./BuilderBodySyncingNotice";
57
62
  import type { CommentTextAnchor } from "./comment-anchors";
58
63
  import { CommentsSidebar } from "./CommentsSidebar";
59
64
  import { DocumentBlockFields } from "./DocumentBlockFields";
@@ -309,7 +314,6 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
309
314
  );
310
315
  const canEdit = document.canEdit ?? true;
311
316
  const canEditRef = useRef(canEdit);
312
- canEditRef.current = canEdit;
313
317
  // The block render context (asset/upload resolvers, inline markdown reader,
314
318
  // panel popover) is stable for the editor's lifetime. Created once here and
315
319
  // provided alongside the content block registry so every registry block in the
@@ -468,6 +472,10 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
468
472
  requestSource: TAB_ID,
469
473
  user: currentUser,
470
474
  });
475
+ const bodyHydrationPending = documentBodyHydrationIsPending(document);
476
+ const editorCanEdit =
477
+ canEdit && !bodyHydrationPending && (isLocalFileDocument || !collabLoading);
478
+ canEditRef.current = editorCanEdit;
471
479
 
472
480
  // Initialize from fetched document, reset on document switch
473
481
  useEffect(() => {
@@ -601,7 +609,14 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
601
609
  const serverContent = document.content;
602
610
  const lastSaved = lastSavedContentRef.current;
603
611
  if (serverContent === lastSaved.content) return;
604
- const adopt = localContent === lastSaved.content || contentExternalIsNewer;
612
+ const staleEmptyLocalOverFreshServer =
613
+ isEffectivelyEmptyDocumentContent(lastSaved.content) &&
614
+ isEffectivelyEmptyDocumentContent(localContent) &&
615
+ !isEffectivelyEmptyDocumentContent(serverContent);
616
+ const adopt =
617
+ localContent === lastSaved.content ||
618
+ contentExternalIsNewer ||
619
+ staleEmptyLocalOverFreshServer;
605
620
  if (adopt) {
606
621
  if (saveTimeoutRef.current) {
607
622
  clearTimeout(saveTimeoutRef.current);
@@ -701,6 +716,13 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
701
716
  : undefined;
702
717
  return await updateDocument.mutateAsync({
703
718
  id: documentId,
719
+ loadedUpdatedAt: documentUpdatedAtRef.current ?? undefined,
720
+ loadedContentWasEmpty:
721
+ updates.content !== undefined
722
+ ? isEffectivelyEmptyDocumentContent(
723
+ lastSavedContentRef.current.content,
724
+ )
725
+ : undefined,
704
726
  ...updates,
705
727
  ...(baseUpdatedAt !== undefined ? { baseUpdatedAt } : {}),
706
728
  });
@@ -997,7 +1019,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
997
1019
  // key we force an immediate (non-debounced) save of the current editor
998
1020
  // state, then delete the key so `pull-document` knows the flush landed.
999
1021
  useEffect(() => {
1000
- if (!canEdit || isLocalFileDocument) return;
1022
+ if (!editorCanEdit || isLocalFileDocument) return;
1001
1023
  let active = true;
1002
1024
  const flushKey = `flush-request-${documentId}`;
1003
1025
  const flushPath = agentNativePath(
@@ -1060,29 +1082,29 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1060
1082
  active = false;
1061
1083
  clearTimeout(timer);
1062
1084
  };
1063
- }, [canEdit, documentId, isLocalFileDocument, persistDocumentUpdates]);
1085
+ }, [documentId, editorCanEdit, isLocalFileDocument, persistDocumentUpdates]);
1064
1086
 
1065
1087
  const handleTitleChange = useCallback(
1066
1088
  (newTitle: string) => {
1067
- if (!canEdit) return;
1089
+ if (!editorCanEdit) return;
1068
1090
  setLocalTitle(newTitle);
1069
1091
  debouncedSave(newTitle, localContentRef.current);
1070
1092
  },
1071
- [canEdit, debouncedSave],
1093
+ [debouncedSave, editorCanEdit],
1072
1094
  );
1073
1095
 
1074
1096
  const handleContentChange = useCallback(
1075
1097
  (newContent: string) => {
1076
- if (!canEdit) return;
1098
+ if (!editorCanEdit) return;
1077
1099
  setLocalContent(newContent);
1078
1100
  debouncedSave(localTitleRef.current, newContent);
1079
1101
  },
1080
- [canEdit, debouncedSave],
1102
+ [debouncedSave, editorCanEdit],
1081
1103
  );
1082
1104
 
1083
1105
  const handleContentSaveNow = useCallback(
1084
1106
  async (newContent: string) => {
1085
- if (!canEdit) return false;
1107
+ if (!editorCanEdit) return false;
1086
1108
  if (saveTimeoutRef.current) {
1087
1109
  clearTimeout(saveTimeoutRef.current);
1088
1110
  saveTimeoutRef.current = null;
@@ -1096,7 +1118,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1096
1118
  );
1097
1119
  return result.contentPersisted;
1098
1120
  },
1099
- [canEdit, saveDocumentImmediately],
1121
+ [editorCanEdit, saveDocumentImmediately],
1100
1122
  );
1101
1123
 
1102
1124
  // Comments state — pending comment from text selection
@@ -1114,11 +1136,12 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1114
1136
  );
1115
1137
  const hasComments =
1116
1138
  !isLocalFileDocument &&
1117
- canEdit &&
1139
+ editorCanEdit &&
1118
1140
  ((threads?.length ?? 0) > 0 || !!pendingComment);
1119
1141
  const hasCommentRailSpace = useMinViewportWidth(1024);
1120
1142
  const showDesktopComments = hasComments && hasCommentRailSpace;
1121
- const showCommentsSheet = hasComments && canEdit && !showDesktopComments;
1143
+ const showCommentsSheet =
1144
+ hasComments && editorCanEdit && !showDesktopComments;
1122
1145
 
1123
1146
  const handleComment = useCallback(
1124
1147
  (
@@ -1175,7 +1198,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1175
1198
 
1176
1199
  const handleTitlePaste = useCallback(
1177
1200
  (event: ClipboardEvent<HTMLTextAreaElement>) => {
1178
- if (!canEdit) return;
1201
+ if (!editorCanEdit) return;
1179
1202
 
1180
1203
  const pastedText = event.clipboardData.getData("text/plain");
1181
1204
  if (!pastedText) return;
@@ -1196,12 +1219,12 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1196
1219
  titleInputRef.current?.setSelectionRange(nextCaret, nextCaret);
1197
1220
  });
1198
1221
  },
1199
- [canEdit, handleTitleChange, localTitle],
1222
+ [editorCanEdit, handleTitleChange, localTitle],
1200
1223
  );
1201
1224
 
1202
1225
  // Auto-focus title on new empty documents once collab finishes loading
1203
1226
  useEffect(() => {
1204
- if (canEdit && !collabLoading && shouldFocusTitleRef.current) {
1227
+ if (editorCanEdit && shouldFocusTitleRef.current) {
1205
1228
  shouldFocusTitleRef.current = false;
1206
1229
  requestAnimationFrame(() => titleInputRef.current?.focus());
1207
1230
  }
@@ -1212,10 +1235,6 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1212
1235
  [document, documents],
1213
1236
  );
1214
1237
 
1215
- if (!isLocalFileDocument && collabLoading) {
1216
- return <DocumentEditorSkeleton />;
1217
- }
1218
-
1219
1238
  const sidebar = (
1220
1239
  <CommentsSidebar
1221
1240
  documentId={documentId}
@@ -1315,7 +1334,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1315
1334
  />
1316
1335
  {document.icon || !isDatabasePage ? (
1317
1336
  <div className="mb-1">
1318
- {canEdit ? (
1337
+ {editorCanEdit ? (
1319
1338
  <EmojiPicker
1320
1339
  icon={document.icon}
1321
1340
  defaultIcon={defaultIcon}
@@ -1376,6 +1395,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1376
1395
  titleFocusedRef.current = false;
1377
1396
  }}
1378
1397
  onKeyDown={(e) => {
1398
+ if (!editorCanEdit) return;
1379
1399
  if (e.key === "Enter") {
1380
1400
  e.preventDefault();
1381
1401
  const pm = window.document.querySelector(
@@ -1386,7 +1406,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1386
1406
  }}
1387
1407
  aria-label={t("editor.documentTitle")}
1388
1408
  placeholder={t("editor.title")}
1389
- readOnly={!canEdit}
1409
+ readOnly={!editorCanEdit}
1390
1410
  style={{ fieldSizing: "content" } as any}
1391
1411
  className={cn(
1392
1412
  "block w-full resize-none overflow-hidden break-words border-none bg-transparent p-0 font-bold leading-tight text-foreground outline-none placeholder:text-muted-foreground/40",
@@ -1396,7 +1416,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1396
1416
  {document.databaseMembership && !isLocalFileDocument ? (
1397
1417
  <DocumentProperties
1398
1418
  documentId={documentId}
1399
- canEdit={canEdit}
1419
+ canEdit={editorCanEdit}
1400
1420
  />
1401
1421
  ) : null}
1402
1422
  </div>
@@ -1418,6 +1438,17 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1418
1438
  }}
1419
1439
  >
1420
1440
  {(() => {
1441
+ if (bodyHydrationPending) {
1442
+ return (
1443
+ <BuilderBodySyncingNotice
1444
+ title={t("editor.builderBodySyncing")}
1445
+ description={t(
1446
+ "editor.builderBodySyncingDescription",
1447
+ )}
1448
+ />
1449
+ );
1450
+ }
1451
+
1421
1452
  // The primary "Content" Blocks field IS the document body,
1422
1453
  // with the full collaborative editor. It renders chromeless
1423
1454
  // when it's the only Blocks field, or inside a
@@ -1425,7 +1456,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1425
1456
  // fields.
1426
1457
  const primaryEditor = (
1427
1458
  <VisualEditor
1428
- key={documentId}
1459
+ key={`${documentId}:${editorCanEdit && !isLocalFileDocument ? "live" : "snapshot"}`}
1429
1460
  documentId={documentId}
1430
1461
  content={
1431
1462
  isLocalFileDocument ? localContent : document.content
@@ -1445,13 +1476,13 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1445
1476
  collabSynced={collabEnabled ? collabSynced : true}
1446
1477
  awareness={collabEnabled ? awareness : null}
1447
1478
  user={currentUser}
1448
- editable={canEdit}
1479
+ editable={editorCanEdit}
1449
1480
  localFileMode={isLocalFileDocument}
1450
1481
  localFilePath={
1451
1482
  isLocalFileDocument ? document.source?.path : null
1452
1483
  }
1453
1484
  onComment={
1454
- canEdit && !isLocalFileDocument
1485
+ editorCanEdit && !isLocalFileDocument
1455
1486
  ? handleComment
1456
1487
  : undefined
1457
1488
  }
@@ -1459,7 +1490,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1459
1490
  activeThreadId={activeThreadId}
1460
1491
  pendingHighlight={pendingComment?.range ?? null}
1461
1492
  onActivateThread={
1462
- canEdit && !isLocalFileDocument
1493
+ editorCanEdit && !isLocalFileDocument
1463
1494
  ? setSelectedThreadId
1464
1495
  : undefined
1465
1496
  }
@@ -1476,7 +1507,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1476
1507
  return (
1477
1508
  <DocumentBlockFields
1478
1509
  documentId={documentId}
1479
- canEdit={canEdit}
1510
+ canEdit={editorCanEdit}
1480
1511
  primaryEditor={primaryEditor}
1481
1512
  />
1482
1513
  );
@@ -1484,6 +1515,17 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1484
1515
 
1485
1516
  return primaryEditor;
1486
1517
  })()}
1518
+ {!bodyHydrationPending &&
1519
+ !isLocalFileDocument &&
1520
+ collabLoading ? (
1521
+ <div
1522
+ className="mt-4 inline-flex items-center gap-2 rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground"
1523
+ role="status"
1524
+ >
1525
+ <IconLoader2 className="size-3.5 animate-spin" />
1526
+ {t("editor.collabConnectingReadOnly")}
1527
+ </div>
1528
+ ) : null}
1487
1529
  </div>
1488
1530
  </div>
1489
1531
 
@@ -2621,6 +2621,17 @@ export function AddProperty({
2621
2621
  }))
2622
2622
  .filter((group) => group.fields.length > 0);
2623
2623
  const addPropertySearchInputRef = useRef<HTMLInputElement>(null);
2624
+ const [pendingPropertyType, setPendingPropertyType] =
2625
+ useState<DocumentPropertyType | null>(null);
2626
+ const [pendingSourceFieldId, setPendingSourceFieldId] = useState<
2627
+ string | null
2628
+ >(null);
2629
+ const [addPropertyError, setAddPropertyError] = useState<string | null>(null);
2630
+ const isAddingProperty =
2631
+ configure.isPending ||
2632
+ addSourceFieldProperty.isPending ||
2633
+ pendingPropertyType !== null ||
2634
+ pendingSourceFieldId !== null;
2624
2635
 
2625
2636
  useEffect(() => {
2626
2637
  if (!open) return;
@@ -2632,27 +2643,49 @@ export function AddProperty({
2632
2643
  }, [open]);
2633
2644
 
2634
2645
  function closeAddPropertyPicker() {
2646
+ if (isAddingProperty) return;
2635
2647
  setTypeQuery("");
2648
+ setAddPropertyError(null);
2636
2649
  setOpen(false);
2637
2650
  }
2638
2651
 
2639
2652
  async function add(type: DocumentPropertyType) {
2640
2653
  const label = t(`editor.propertyTypes.${type}`);
2641
- await configure.mutateAsync({
2642
- documentId,
2643
- name: label,
2644
- type,
2645
- options: defaultPropertyOptions(type),
2646
- });
2647
- closeAddPropertyPicker();
2654
+ setPendingPropertyType(type);
2655
+ setPendingSourceFieldId(null);
2656
+ setAddPropertyError(null);
2657
+ try {
2658
+ await configure.mutateAsync({
2659
+ documentId,
2660
+ name: label,
2661
+ type,
2662
+ options: defaultPropertyOptions(type),
2663
+ });
2664
+ setTypeQuery("");
2665
+ setOpen(false);
2666
+ } catch (error) {
2667
+ setAddPropertyError(error instanceof Error ? error.message : "");
2668
+ } finally {
2669
+ setPendingPropertyType(null);
2670
+ }
2648
2671
  }
2649
2672
 
2650
2673
  async function addFromSourceField(sourceFieldId: string) {
2651
- await addSourceFieldProperty.mutateAsync({
2652
- documentId,
2653
- sourceFieldId,
2654
- });
2655
- closeAddPropertyPicker();
2674
+ setPendingSourceFieldId(sourceFieldId);
2675
+ setPendingPropertyType(null);
2676
+ setAddPropertyError(null);
2677
+ try {
2678
+ await addSourceFieldProperty.mutateAsync({
2679
+ documentId,
2680
+ sourceFieldId,
2681
+ });
2682
+ setTypeQuery("");
2683
+ setOpen(false);
2684
+ } catch (error) {
2685
+ setAddPropertyError(error instanceof Error ? error.message : "");
2686
+ } finally {
2687
+ setPendingSourceFieldId(null);
2688
+ }
2656
2689
  }
2657
2690
 
2658
2691
  return (
@@ -2661,7 +2694,7 @@ export function AddProperty({
2661
2694
  onOpenChange={(nextOpen) => {
2662
2695
  if (nextOpen) {
2663
2696
  setOpen(true);
2664
- } else {
2697
+ } else if (!isAddingProperty) {
2665
2698
  closeAddPropertyPicker();
2666
2699
  }
2667
2700
  }}
@@ -2729,11 +2762,16 @@ export function AddProperty({
2729
2762
  aria-label={t("editor.properties.sourceField", {
2730
2763
  name: field.sourceFieldLabel,
2731
2764
  })}
2732
- disabled={addSourceFieldProperty.isPending}
2765
+ disabled={isAddingProperty}
2766
+ aria-busy={pendingSourceFieldId === field.id}
2733
2767
  className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent disabled:opacity-50"
2734
2768
  onClick={() => void addFromSourceField(field.id)}
2735
2769
  >
2736
- <IconLink className="size-4 shrink-0 text-muted-foreground" />
2770
+ {pendingSourceFieldId === field.id ? (
2771
+ <Spinner className="size-4 shrink-0 text-muted-foreground" />
2772
+ ) : (
2773
+ <IconLink className="size-4 shrink-0 text-muted-foreground" />
2774
+ )}
2737
2775
  <span className="min-w-0 flex-1 truncate">
2738
2776
  {field.sourceFieldLabel}
2739
2777
  </span>
@@ -2761,10 +2799,15 @@ export function AddProperty({
2761
2799
  type: t(`editor.propertyTypes.${type}`),
2762
2800
  })}
2763
2801
  className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent"
2764
- disabled={configure.isPending}
2802
+ disabled={isAddingProperty}
2803
+ aria-busy={pendingPropertyType === type}
2765
2804
  onClick={() => void add(type)}
2766
2805
  >
2767
- <Icon className="size-4 text-muted-foreground" />
2806
+ {pendingPropertyType === type ? (
2807
+ <Spinner className="size-4 text-muted-foreground" />
2808
+ ) : (
2809
+ <Icon className="size-4 text-muted-foreground" />
2810
+ )}
2768
2811
  <span className="flex-1">
2769
2812
  {t(`editor.propertyTypes.${type}`)}
2770
2813
  </span>
@@ -2776,6 +2819,15 @@ export function AddProperty({
2776
2819
  </button>
2777
2820
  );
2778
2821
  })}
2822
+ {addPropertyError !== null ? (
2823
+ <div
2824
+ role="alert"
2825
+ className="px-2 py-1.5 text-xs text-destructive"
2826
+ >
2827
+ {t("editor.properties.addPropertyFailed")}
2828
+ {addPropertyError ? ` ${addPropertyError}` : null}
2829
+ </div>
2830
+ ) : null}
2779
2831
  </div>
2780
2832
  </div>
2781
2833
  </PopoverContent>
@@ -326,7 +326,7 @@ const JoinFirstBodyBlockToTitle = Extension.create<{
326
326
 
327
327
  const text = firstBlock.textContent.trim();
328
328
  if (!text) {
329
- queueMicrotask(() => this.options.onJoinTitle?.(""));
329
+ setTimeout(() => this.options.onJoinTitle?.(""), 0);
330
330
  return true;
331
331
  }
332
332
 
@@ -336,7 +336,7 @@ const JoinFirstBodyBlockToTitle = Extension.create<{
336
336
  ? state.tr.replaceWith(0, firstBlock.nodeSize, paragraph.create())
337
337
  : state.tr.delete(0, firstBlock.nodeSize);
338
338
  view.dispatch(tr.scrollIntoView());
339
- queueMicrotask(() => this.options.onJoinTitle?.(text));
339
+ setTimeout(() => this.options.onJoinTitle?.(text), 0);
340
340
  return true;
341
341
  };
342
342
 
@@ -1731,7 +1731,7 @@ export function VisualEditor({
1731
1731
  // clobber DB content with an empty string). `registerEmitted` records
1732
1732
  // this as the last-emitted value and returns false to skip the save.
1733
1733
  if (!guards.registerEmitted(normalized)) return true;
1734
- queueMicrotask(() => onChangeRef.current(normalized));
1734
+ setTimeout(() => onChangeRef.current(normalized), 0);
1735
1735
  return true;
1736
1736
  } catch (err: any) {
1737
1737
  toast.error(
@@ -2172,7 +2172,7 @@ export function VisualEditor({
2172
2172
  ) as HTMLElement | null;
2173
2173
  if (!el) return;
2174
2174
  const id = el.getAttribute("data-comment-thread");
2175
- if (id) onActivateThread(id);
2175
+ if (id) setTimeout(() => onActivateThread(id), 0);
2176
2176
  };
2177
2177
  dom.addEventListener("click", handleClick);
2178
2178
  return () => dom.removeEventListener("click", handleClick);
@@ -0,0 +1,112 @@
1
+ import type {
2
+ ContentDatabaseBodyHydration,
3
+ ContentDatabaseBodyHydrationSummary,
4
+ ContentDatabaseItem,
5
+ Document,
6
+ } from "@shared/api";
7
+
8
+ export function builderBodyHydrationIsPending(
9
+ hydration: ContentDatabaseBodyHydration | null | undefined,
10
+ ) {
11
+ return (
12
+ !!hydration &&
13
+ (hydration.status === "pending" || hydration.status === "hydrating")
14
+ );
15
+ }
16
+
17
+ export function builderBodyHydrationIsTerminalError(
18
+ hydration: ContentDatabaseBodyHydration | null | undefined,
19
+ ) {
20
+ return hydration?.status === "error";
21
+ }
22
+
23
+ export function builderBodyHydrationDisplayHydratedCount(args: {
24
+ summary: ContentDatabaseBodyHydrationSummary;
25
+ highWaterCount?: number | null;
26
+ }) {
27
+ const total = Math.max(0, args.summary.total);
28
+ const unresolved = Math.max(
29
+ 0,
30
+ args.summary.pending + args.summary.hydrating + args.summary.error,
31
+ );
32
+ const maxResolved = Math.max(0, total - unresolved);
33
+ return Math.min(
34
+ Math.max(args.summary.hydrated, args.highWaterCount ?? 0),
35
+ unresolved > 0 ? maxResolved : total,
36
+ );
37
+ }
38
+
39
+ export function databaseItemBodyHydrationIsPending(
40
+ item: Pick<ContentDatabaseItem, "bodyHydration" | "document">,
41
+ ) {
42
+ if (
43
+ item.document.databaseMembership?.sourceId &&
44
+ !item.bodyHydration &&
45
+ !item.document.databaseMembership.bodyHydration
46
+ ) {
47
+ return true;
48
+ }
49
+ return builderBodyHydrationIsPending(
50
+ item.bodyHydration ?? item.document.databaseMembership?.bodyHydration,
51
+ );
52
+ }
53
+
54
+ export function documentBodyHydrationIsPending(
55
+ document: Pick<Document, "databaseMembership">,
56
+ ) {
57
+ return builderBodyHydrationIsPending(
58
+ document.databaseMembership?.bodyHydration,
59
+ );
60
+ }
61
+
62
+ export function previewBodyHydrationIsPending(args: {
63
+ item: Pick<ContentDatabaseItem, "bodyHydration" | "document">;
64
+ document: Pick<Document, "databaseMembership"> | null | undefined;
65
+ }) {
66
+ const membership =
67
+ args.document?.databaseMembership ?? args.item.document.databaseMembership;
68
+ if (
69
+ membership?.sourceId &&
70
+ !args.document &&
71
+ !args.item.bodyHydration &&
72
+ !args.item.document.databaseMembership?.bodyHydration
73
+ ) {
74
+ return true;
75
+ }
76
+ return (
77
+ databaseItemBodyHydrationIsPending(args.item) ||
78
+ (args.document ? documentBodyHydrationIsPending(args.document) : false)
79
+ );
80
+ }
81
+
82
+ export function previewBodyHydrationIsTerminalError(args: {
83
+ item: Pick<ContentDatabaseItem, "bodyHydration" | "document">;
84
+ document: Pick<Document, "databaseMembership"> | null | undefined;
85
+ }) {
86
+ return (
87
+ builderBodyHydrationIsTerminalError(
88
+ args.document?.databaseMembership?.bodyHydration,
89
+ ) ||
90
+ builderBodyHydrationIsTerminalError(
91
+ args.item.bodyHydration ??
92
+ args.item.document.databaseMembership?.bodyHydration,
93
+ )
94
+ );
95
+ }
96
+
97
+ export function isEffectivelyEmptyDocumentContent(
98
+ content: string | null | undefined,
99
+ ) {
100
+ const normalized = (content ?? "").trim();
101
+ return normalized === "" || normalized === "<empty-block/>";
102
+ }
103
+
104
+ export function shouldIgnorePreviewEmptyNormalization(args: {
105
+ currentContent: string | null | undefined;
106
+ nextContent: string | null | undefined;
107
+ }) {
108
+ return (
109
+ isEffectivelyEmptyDocumentContent(args.currentContent) &&
110
+ isEffectivelyEmptyDocumentContent(args.nextContent)
111
+ );
112
+ }