@agent-native/core 0.80.4 → 0.80.5

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 (292) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -2
  3. package/corpus/core/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
  4. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -1
  5. package/corpus/core/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
  6. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -1
  7. package/corpus/core/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
  8. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -1
  9. package/corpus/core/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
  10. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -1
  11. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -1
  12. package/corpus/core/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
  13. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -1
  14. package/corpus/core/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
  15. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -1
  16. package/corpus/core/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
  17. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -1
  18. package/corpus/core/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
  19. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -1
  20. package/corpus/core/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
  21. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -1
  22. package/corpus/core/docs/content/real-time-collaboration.mdx +2 -2
  23. package/corpus/core/docs/content/template-design.mdx +1 -1
  24. package/corpus/core/package.json +3 -7
  25. package/corpus/core/src/action.ts +21 -0
  26. package/corpus/core/src/agent/durable-background.ts +32 -11
  27. package/corpus/core/src/agent/production-agent.ts +11 -1
  28. package/corpus/core/src/agent/run-loop-with-resume.ts +3 -1
  29. package/corpus/core/src/brand-kit/fig/index.ts +17 -37
  30. package/corpus/core/src/cli/index.ts +1 -1
  31. package/corpus/core/src/cli/mcp-config-writers.ts +187 -51
  32. package/corpus/core/src/cli/skills.ts +18 -3
  33. package/corpus/core/src/client/AssistantChat.tsx +11 -1
  34. package/corpus/core/src/client/agent-chat.ts +12 -1
  35. package/corpus/core/src/client/composer/PromptComposer.tsx +100 -41
  36. package/corpus/core/src/client/org/OrgSwitcher.tsx +1 -1
  37. package/corpus/core/src/client/sharing/ShareButton.tsx +3 -27
  38. package/corpus/core/src/collab/presence.ts +1 -1
  39. package/corpus/core/src/mcp/connect-route.ts +34 -5
  40. package/corpus/core/src/server/action-discovery.ts +4 -0
  41. package/corpus/core/src/server/agent-chat-plugin.ts +20 -0
  42. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -0
  43. package/corpus/templates/analytics/actions/update-dashboard.ts +8 -0
  44. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
  45. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +117 -33
  46. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +4 -0
  47. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +7 -0
  48. package/corpus/templates/analytics/changelog/2026-06-27-dashboards-can-now-nest-under-a-parent-in-the-sidebar-via-a-.md +6 -0
  49. package/corpus/templates/analytics/changelog/2026-06-29-analytics-pages-now-sit-closer-under-the-header-with-tighter.md +6 -0
  50. package/corpus/templates/assets/actions/generate-image-batch.ts +3 -0
  51. package/corpus/templates/assets/actions/generate-image.ts +3 -0
  52. package/corpus/templates/assets/changelog/2026-06-29-longer-agent-generation-window.md +6 -0
  53. package/corpus/templates/assets/netlify.toml +3 -3
  54. package/corpus/templates/assets/server/plugins/agent-chat.ts +4 -1
  55. package/corpus/templates/clips/app/components/capture-install-options.tsx +7 -8
  56. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +1 -1
  57. package/corpus/templates/content/AGENTS.md +12 -0
  58. package/corpus/templates/content/app/blocks/BuilderDocsBlocks.tsx +10 -0
  59. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +1 -0
  60. package/corpus/templates/content/app/components/editor/ContentReferencePreview.tsx +185 -0
  61. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -0
  62. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +19 -0
  63. package/corpus/templates/content/app/components/editor/extensions/ContentReferenceNode.tsx +82 -0
  64. package/corpus/templates/content/app/global.css +9 -0
  65. package/corpus/templates/content/app/i18n/zh-TW.ts +12 -0
  66. package/corpus/templates/content/app/i18n-data.ts +140 -0
  67. package/corpus/templates/content/changelog/2026-06-29-reusable-mdx-references-now-preview-linked-local-documents-i.md +6 -0
  68. package/corpus/templates/content/shared/builder-docs-blocks.ts +8 -0
  69. package/corpus/templates/content/shared/builder-mdx.ts +141 -4
  70. package/corpus/templates/content/shared/nfm.ts +62 -0
  71. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +10 -11
  72. package/corpus/templates/design/AGENTS.md +5 -0
  73. package/corpus/templates/design/_gitignore +7 -0
  74. package/corpus/templates/design/actions/apply-visual-edit.ts +22 -12
  75. package/corpus/templates/design/actions/create-design-system.ts +15 -4
  76. package/corpus/templates/design/actions/create-file.ts +20 -1
  77. package/corpus/templates/design/actions/delete-design-system.ts +2 -2
  78. package/corpus/templates/design/actions/duplicate-design.ts +35 -9
  79. package/corpus/templates/design/actions/generate-design.ts +146 -69
  80. package/corpus/templates/design/actions/generate-screens.ts +51 -19
  81. package/corpus/templates/design/actions/get-design-snapshot.ts +5 -1
  82. package/corpus/templates/design/actions/get-design.ts +2 -0
  83. package/corpus/templates/design/actions/import-design-project.ts +28 -9
  84. package/corpus/templates/design/actions/import-document.ts +22 -8
  85. package/corpus/templates/design/actions/index-design-system-with-builder.ts +6 -153
  86. package/corpus/templates/design/actions/navigate.ts +105 -54
  87. package/corpus/templates/design/actions/set-default-design-system.ts +17 -3
  88. package/corpus/templates/design/actions/show-design-questions.ts +2 -0
  89. package/corpus/templates/design/actions/update-design.ts +2 -1
  90. package/corpus/templates/design/actions/view-screen.ts +12 -6
  91. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +4 -4
  92. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +159 -41
  93. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +8 -4
  94. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +37 -42
  95. package/corpus/templates/design/app/components/design/EditPanel.tsx +336 -183
  96. package/corpus/templates/design/app/components/design/LayersPanel.tsx +153 -34
  97. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +135 -33
  98. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +6 -0
  99. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
  100. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +4 -10
  101. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +84 -43
  102. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +4 -4
  103. package/corpus/templates/design/app/components/design/inspector/{FigmaColorPicker.tsx → DesignColorPicker.tsx} +89 -62
  104. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +14 -26
  105. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +40 -12
  106. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +13 -4
  107. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +13 -13
  108. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -9
  109. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +13 -4
  110. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +6 -6
  111. package/corpus/templates/design/app/components/design/inspector/{figma-icons.tsx → design-icons.tsx} +2 -2
  112. package/corpus/templates/design/app/components/design/inspector/index.ts +12 -12
  113. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +5 -2
  114. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -3
  115. package/corpus/templates/design/app/components/layout/Layout.tsx +5 -2
  116. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  117. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +167 -91
  118. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +16 -3
  119. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +15 -0
  120. package/corpus/templates/design/app/global.css +4 -0
  121. package/corpus/templates/design/app/hooks/use-design-system.ts +4 -1
  122. package/corpus/templates/design/app/hooks/use-navigation-state.ts +38 -3
  123. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +9 -2
  124. package/corpus/templates/design/app/i18n/zh-TW.ts +22 -0
  125. package/corpus/templates/design/app/i18n-data.ts +527 -0
  126. package/corpus/templates/design/app/lib/design-systems.ts +6 -4
  127. package/corpus/templates/design/app/lib/design-templates.ts +15 -3
  128. package/corpus/templates/design/app/pages/DesignEditor.tsx +641 -158
  129. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +42 -34
  130. package/corpus/templates/design/app/pages/VisualEdit.tsx +100 -0
  131. package/corpus/templates/design/app/root.tsx +42 -9
  132. package/corpus/templates/design/app/routes/visual-edit.tsx +7 -0
  133. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +1 -1
  134. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +1 -1
  135. package/corpus/templates/design/changelog/2026-06-28-visual-code-design-mode.md +6 -0
  136. package/corpus/templates/design/changelog/2026-06-29-design-generation-prompts-now-show-connect-ai-before-sending.md +6 -0
  137. package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +1 -1
  138. package/corpus/templates/design/changelog/2026-06-29-fixed-design-editor-exports-and-gradient-edits-so-multi-scre.md +6 -0
  139. package/corpus/templates/design/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
  140. package/corpus/templates/design/changelog/2026-06-29-png-export-handles-modern-css-color-functions-more-reliably.md +6 -0
  141. package/corpus/templates/design/changelog/2026-06-29-png-export-now-ignores-duplicate-clicks-while-a-download-is-.md +6 -0
  142. package/corpus/templates/design/changelog/2026-06-29-public-visual-edit-and-shared-design-links-now-invite-visito.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-29-visual-edit-actions-now-reject-missing-design-targets-before.md +6 -0
  144. package/corpus/templates/design/e2e/README.md +71 -0
  145. package/corpus/templates/design/e2e/global-setup.ts +157 -0
  146. package/corpus/templates/design/e2e/helpers.ts +148 -0
  147. package/corpus/templates/design/netlify.toml +3 -4
  148. package/corpus/templates/design/package.json +5 -1
  149. package/corpus/templates/design/playwright.config.ts +51 -0
  150. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +121 -0
  151. package/corpus/templates/design/server/handlers/uploads.ts +89 -38
  152. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +181 -0
  153. package/corpus/templates/design/server/lib/coding-handoff.ts +33 -4
  154. package/corpus/templates/design/server/lib/design-export.ts +35 -8
  155. package/corpus/templates/design/server/plugins/agent-chat.ts +4 -0
  156. package/corpus/templates/design/server/plugins/auth.ts +10 -1
  157. package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +1 -0
  158. package/corpus/templates/design/shared/api.ts +2 -0
  159. package/corpus/templates/design/shared/apply-edits.ts +12 -8
  160. package/corpus/templates/design/shared/canvas-math.ts +19 -1
  161. package/corpus/templates/design/shared/code-layer.ts +87 -28
  162. package/corpus/templates/design/shared/generation-session.ts +1 -0
  163. package/corpus/templates/design/shared/resolve-tweaks.ts +4 -3
  164. package/corpus/templates/design/shared/shader-presets.ts +10 -0
  165. package/corpus/templates/design/shared/source-mode.ts +9 -0
  166. package/corpus/templates/design/vitest.config.ts +2 -1
  167. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
  168. package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +1 -1
  169. package/corpus/templates/plan/AGENTS.md +1 -1
  170. package/corpus/templates/plan/actions/create-plan-design.ts +1 -1
  171. package/corpus/templates/plan/actions/validate-local-plan-source.ts +2 -10
  172. package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -0
  173. package/corpus/templates/plan/docs/commenting-ux-plan.md +2 -2
  174. package/corpus/templates/plan/server/plan-content.ts +1 -1
  175. package/corpus/templates/plan/server/ui-plan-html.ts +2 -2
  176. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +6 -153
  177. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +53 -38
  178. package/corpus/templates/slides/app/components/design-system/{fig-import-response.ts → builder-index-response.ts} +9 -6
  179. package/corpus/templates/slides/app/components/visual-editor/MultiSelectChip.tsx +1 -1
  180. package/corpus/templates/slides/changelog/2026-06-29-design-system-setup-now-indexes-uploaded-design-files-throug.md +6 -0
  181. package/corpus/templates/slides/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
  182. package/corpus/templates/slides/netlify.toml +3 -6
  183. package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +116 -0
  184. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +179 -0
  185. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -1
  186. package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +1 -0
  187. package/dist/action.d.ts +15 -0
  188. package/dist/action.d.ts.map +1 -1
  189. package/dist/action.js +6 -0
  190. package/dist/action.js.map +1 -1
  191. package/dist/agent/durable-background.d.ts +9 -7
  192. package/dist/agent/durable-background.d.ts.map +1 -1
  193. package/dist/agent/durable-background.js +27 -11
  194. package/dist/agent/durable-background.js.map +1 -1
  195. package/dist/agent/production-agent.d.ts +7 -0
  196. package/dist/agent/production-agent.d.ts.map +1 -1
  197. package/dist/agent/production-agent.js +4 -1
  198. package/dist/agent/production-agent.js.map +1 -1
  199. package/dist/agent/run-loop-with-resume.d.ts +2 -1
  200. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  201. package/dist/agent/run-loop-with-resume.js +2 -2
  202. package/dist/agent/run-loop-with-resume.js.map +1 -1
  203. package/dist/brand-kit/fig/index.d.ts +4 -4
  204. package/dist/brand-kit/fig/index.d.ts.map +1 -1
  205. package/dist/brand-kit/fig/index.js +14 -27
  206. package/dist/brand-kit/fig/index.js.map +1 -1
  207. package/dist/cli/index.js +1 -1
  208. package/dist/cli/index.js.map +1 -1
  209. package/dist/cli/mcp-config-writers.d.ts +15 -7
  210. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  211. package/dist/cli/mcp-config-writers.js +198 -45
  212. package/dist/cli/mcp-config-writers.js.map +1 -1
  213. package/dist/cli/skills.d.ts +1 -1
  214. package/dist/cli/skills.d.ts.map +1 -1
  215. package/dist/cli/skills.js +18 -3
  216. package/dist/cli/skills.js.map +1 -1
  217. package/dist/client/AssistantChat.d.ts.map +1 -1
  218. package/dist/client/AssistantChat.js +11 -1
  219. package/dist/client/AssistantChat.js.map +1 -1
  220. package/dist/client/agent-chat.d.ts.map +1 -1
  221. package/dist/client/agent-chat.js +15 -2
  222. package/dist/client/agent-chat.js.map +1 -1
  223. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  224. package/dist/client/composer/PromptComposer.js +35 -1
  225. package/dist/client/composer/PromptComposer.js.map +1 -1
  226. package/dist/client/org/OrgSwitcher.js +1 -1
  227. package/dist/client/org/OrgSwitcher.js.map +1 -1
  228. package/dist/client/sharing/ShareButton.d.ts +1 -1
  229. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  230. package/dist/client/sharing/ShareButton.js +2 -15
  231. package/dist/client/sharing/ShareButton.js.map +1 -1
  232. package/dist/collab/presence.d.ts +1 -1
  233. package/dist/collab/presence.js +1 -1
  234. package/dist/collab/presence.js.map +1 -1
  235. package/dist/collab/routes.d.ts +1 -1
  236. package/dist/mcp/connect-route.d.ts.map +1 -1
  237. package/dist/mcp/connect-route.js +34 -5
  238. package/dist/mcp/connect-route.js.map +1 -1
  239. package/dist/notifications/routes.d.ts +3 -3
  240. package/dist/observability/routes.d.ts +3 -3
  241. package/dist/resources/handlers.d.ts +1 -1
  242. package/dist/server/action-discovery.d.ts.map +1 -1
  243. package/dist/server/action-discovery.js +5 -0
  244. package/dist/server/action-discovery.js.map +1 -1
  245. package/dist/server/agent-chat-plugin.d.ts +6 -0
  246. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  247. package/dist/server/agent-chat-plugin.js +12 -3
  248. package/dist/server/agent-chat-plugin.js.map +1 -1
  249. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  250. package/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
  251. package/docs/content/locales/ar-SA/template-design.mdx +1 -1
  252. package/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
  253. package/docs/content/locales/de-DE/template-design.mdx +1 -1
  254. package/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
  255. package/docs/content/locales/es-ES/template-design.mdx +1 -1
  256. package/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
  257. package/docs/content/locales/fr-FR/template-design.mdx +1 -1
  258. package/docs/content/locales/hi-IN/template-design.mdx +1 -1
  259. package/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
  260. package/docs/content/locales/ja-JP/template-design.mdx +1 -1
  261. package/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
  262. package/docs/content/locales/ko-KR/template-design.mdx +1 -1
  263. package/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
  264. package/docs/content/locales/pt-BR/template-design.mdx +1 -1
  265. package/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
  266. package/docs/content/locales/zh-CN/template-design.mdx +1 -1
  267. package/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
  268. package/docs/content/locales/zh-TW/template-design.mdx +1 -1
  269. package/docs/content/real-time-collaboration.mdx +2 -2
  270. package/docs/content/template-design.mdx +1 -1
  271. package/package.json +3 -7
  272. package/corpus/core/src/brand-kit/fig/decode.ts +0 -410
  273. package/corpus/core/src/brand-kit/fig/extract-design-system.ts +0 -947
  274. package/corpus/core/src/brand-kit/fig/fig-to-html.ts +0 -1906
  275. package/corpus/templates/design/actions/import-figma.ts +0 -55
  276. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +0 -6
  277. package/corpus/templates/design/server/handlers/import-figma-system.ts +0 -86
  278. package/corpus/templates/design/server/routes/api/import-figma-system.post.ts +0 -1
  279. package/corpus/templates/slides/server/handlers/import-figma-system.ts +0 -101
  280. package/corpus/templates/slides/server/routes/api/import-figma-system.post.ts +0 -1
  281. package/dist/brand-kit/fig/decode.d.ts +0 -33
  282. package/dist/brand-kit/fig/decode.d.ts.map +0 -1
  283. package/dist/brand-kit/fig/decode.js +0 -358
  284. package/dist/brand-kit/fig/decode.js.map +0 -1
  285. package/dist/brand-kit/fig/extract-design-system.d.ts +0 -44
  286. package/dist/brand-kit/fig/extract-design-system.d.ts.map +0 -1
  287. package/dist/brand-kit/fig/extract-design-system.js +0 -752
  288. package/dist/brand-kit/fig/extract-design-system.js.map +0 -1
  289. package/dist/brand-kit/fig/fig-to-html.d.ts +0 -246
  290. package/dist/brand-kit/fig/fig-to-html.d.ts.map +0 -1
  291. package/dist/brand-kit/fig/fig-to-html.js +0 -1506
  292. package/dist/brand-kit/fig/fig-to-html.js.map +0 -1
@@ -195,6 +195,18 @@ Content has two file workflows:
195
195
  `select` fields; selecting the component in the editor shows a corner edit
196
196
  button that rewrites the MDX props. JSX expression props are preserved in
197
197
  source but shown as an unsupported preview.
198
+ - **Reusable MDX references:** local-file MDX can embed another local document
199
+ with `<ContentReference sourcePath="./shared/example.mdx" />`. The editor
200
+ resolves `sourcePath` relative to the current file, previews the referenced
201
+ MDX read-only in place, and preserves the original tag in source. Use this for
202
+ reusable docs fragments instead of copy/pasting shared content.
203
+ - **Builder Symbols:** Builder MDX pulls preserve Symbol blocks as
204
+ `<BuilderSymbol ... />`. When Builder returns enriched symbol content, the
205
+ pull also writes a referenced `.builder.mdx` file under
206
+ `content/builder/symbols/` and sets the Symbol block's `source` attribute.
207
+ Edit reusable symbol content in that emitted source file; do not retarget
208
+ `entry`, `model`, or `source` in the parent MDX unless a dedicated Builder
209
+ retargeting workflow is added.
198
210
  - **Picked folders and components:** browser-picked folders can be the
199
211
  source of truth for `.md`/`.mdx` files, but the browser does not expose an
200
212
  absolute path that Vite can compile. Component previews from a picked
@@ -26,6 +26,8 @@ import {
26
26
  } from "@tabler/icons-react";
27
27
  import { useState } from "react";
28
28
 
29
+ import { ContentReferencePreview } from "@/components/editor/ContentReferencePreview";
30
+
29
31
  function SidecarBadge({ rawRef }: { rawRef: string }) {
30
32
  return (
31
33
  <div className="mt-2 truncate text-[11px] text-muted-foreground">
@@ -180,7 +182,15 @@ export function BuilderSymbolRead({
180
182
  </div>
181
183
  <div className="mt-1 text-xs text-muted-foreground">
182
184
  {data.model || "model unknown"} / {data.entry || "entry unknown"}
185
+ {data.dynamic ? " / dynamic" : ""}
183
186
  </div>
187
+ {data.source ? (
188
+ <ContentReferencePreview
189
+ sourcePath={data.source}
190
+ title="Symbol source"
191
+ className="mb-0"
192
+ />
193
+ ) : null}
184
194
  <SidecarBadge rawRef={data.rawRef} />
185
195
  </section>
186
196
  );
@@ -47,6 +47,7 @@ const BUBBLE_TOOLBAR_EXCLUDED_NODE_TYPES = new Set([
47
47
  "image",
48
48
  "video",
49
49
  "audio",
50
+ "contentReference",
50
51
  "localMdxComponent",
51
52
  ]);
52
53
 
@@ -0,0 +1,185 @@
1
+ import { useT } from "@agent-native/core/client";
2
+ import { IconExternalLink, IconFileText } from "@tabler/icons-react";
3
+ import { lazy, Suspense, useMemo } from "react";
4
+ import { useNavigate } from "react-router";
5
+
6
+ import { Button } from "@/components/ui/button";
7
+ import { useDocument, useDocuments } from "@/hooks/use-documents";
8
+ import { cn } from "@/lib/utils";
9
+
10
+ const ReadonlyReferenceEditor = lazy(async () => {
11
+ const module = await import("./VisualEditor");
12
+ return { default: module.VisualEditor };
13
+ });
14
+
15
+ const MAX_CONTENT_REFERENCE_PREVIEW_DEPTH = 1;
16
+
17
+ function trimSlashes(path: string) {
18
+ return path.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
19
+ }
20
+
21
+ function dirname(path: string) {
22
+ const normalized = trimSlashes(path);
23
+ const index = normalized.lastIndexOf("/");
24
+ return index >= 0 ? normalized.slice(0, index) : "";
25
+ }
26
+
27
+ function normalizePathParts(path: string) {
28
+ const parts: string[] = [];
29
+ for (const part of path.split("/")) {
30
+ if (!part || part === ".") continue;
31
+ if (part === "..") {
32
+ if (parts.length === 0) return null;
33
+ parts.pop();
34
+ continue;
35
+ }
36
+ parts.push(part);
37
+ }
38
+ return parts.join("/");
39
+ }
40
+
41
+ export function resolveContentReferencePath(
42
+ sourcePath: string | null | undefined,
43
+ currentPath?: string | null,
44
+ ) {
45
+ if (typeof sourcePath !== "string" || !sourcePath.trim()) return null;
46
+ const normalized = sourcePath.replace(/\\/g, "/").trim();
47
+ if (/^[a-z][a-z0-9+.-]*:/i.test(normalized)) return null;
48
+ const base =
49
+ normalized.startsWith("./") || normalized.startsWith("../")
50
+ ? dirname(currentPath ?? "")
51
+ : "";
52
+ return normalizePathParts(base ? `${base}/${normalized}` : normalized);
53
+ }
54
+
55
+ export function ContentReferencePreview({
56
+ sourcePath,
57
+ currentPath,
58
+ title,
59
+ className,
60
+ referenceDepth = 0,
61
+ }: {
62
+ sourcePath?: string | null;
63
+ currentPath?: string | null;
64
+ title?: string | null;
65
+ className?: string;
66
+ referenceDepth?: number;
67
+ }) {
68
+ const t = useT();
69
+ const navigate = useNavigate();
70
+ const documentsQuery = useDocuments();
71
+ const resolvedPath = useMemo(
72
+ () => resolveContentReferencePath(sourcePath, currentPath),
73
+ [currentPath, sourcePath],
74
+ );
75
+ const document = useMemo(() => {
76
+ if (!resolvedPath) return null;
77
+ return (documentsQuery.data ?? []).find(
78
+ (candidate) =>
79
+ candidate.source?.mode === "local-files" &&
80
+ trimSlashes(candidate.source.path ?? "") === resolvedPath,
81
+ );
82
+ }, [documentsQuery.data, resolvedPath]);
83
+ const documentQuery = useDocument(document?.id ?? null);
84
+ const body = documentQuery.data?.content ?? "";
85
+ const displayTitle =
86
+ title?.trim() ||
87
+ documentQuery.data?.title ||
88
+ document?.title ||
89
+ t("editor.reference.defaultTitle");
90
+ const isSelfReference =
91
+ !!resolvedPath &&
92
+ !!currentPath &&
93
+ resolvedPath === trimSlashes(currentPath);
94
+ const isNestedTooDeep = referenceDepth >= MAX_CONTENT_REFERENCE_PREVIEW_DEPTH;
95
+
96
+ return (
97
+ <section
98
+ className={cn(
99
+ "content-reference-preview my-4 rounded-md border border-dashed bg-muted/20 text-sm",
100
+ className,
101
+ )}
102
+ data-content-reference={resolvedPath ?? sourcePath ?? ""}
103
+ >
104
+ <div className="flex min-h-10 items-center gap-2 border-b px-3 py-2">
105
+ <IconFileText className="size-4 shrink-0 text-muted-foreground" />
106
+ <div className="min-w-0 flex-1">
107
+ <div className="truncate font-medium text-foreground">
108
+ {displayTitle}
109
+ </div>
110
+ <div className="truncate text-xs text-muted-foreground">
111
+ {resolvedPath ?? sourcePath ?? t("editor.reference.pathMissing")}
112
+ </div>
113
+ </div>
114
+ {document ? (
115
+ <Button
116
+ type="button"
117
+ size="sm"
118
+ variant="ghost"
119
+ className="h-8 gap-1.5 px-2 text-xs"
120
+ onClick={() =>
121
+ navigate(`/page/${document.id}`, { flushSync: true })
122
+ }
123
+ >
124
+ <IconExternalLink className="size-3.5" />
125
+ {t("editor.reference.open")}
126
+ </Button>
127
+ ) : null}
128
+ </div>
129
+ <div className="max-h-[520px] overflow-auto px-3 py-3">
130
+ {!resolvedPath ? (
131
+ <div className="text-sm text-muted-foreground">
132
+ {t("editor.reference.missingPath")}
133
+ </div>
134
+ ) : isSelfReference ? (
135
+ <div className="text-sm text-muted-foreground">
136
+ {t("editor.reference.selfReference")}
137
+ </div>
138
+ ) : documentsQuery.isLoading ? (
139
+ <div className="text-sm text-muted-foreground">
140
+ {t("editor.reference.loading")}
141
+ </div>
142
+ ) : !document ? (
143
+ <div className="text-sm text-muted-foreground">
144
+ {t("editor.reference.notFound")}
145
+ </div>
146
+ ) : documentQuery.isLoading ? (
147
+ <div className="text-sm text-muted-foreground">
148
+ {t("editor.reference.loading")}
149
+ </div>
150
+ ) : documentQuery.isError ? (
151
+ <div className="text-sm text-muted-foreground">
152
+ {t("editor.reference.loadError")}
153
+ </div>
154
+ ) : isNestedTooDeep ? (
155
+ <div className="text-sm text-muted-foreground">
156
+ {t("editor.reference.nestedSkipped")}
157
+ </div>
158
+ ) : body.trim() ? (
159
+ <Suspense
160
+ fallback={
161
+ <div className="text-sm text-muted-foreground">
162
+ {t("editor.reference.loading")}
163
+ </div>
164
+ }
165
+ >
166
+ <ReadonlyReferenceEditor
167
+ key={document.id}
168
+ documentId={document.id}
169
+ content={body}
170
+ onChange={() => {}}
171
+ editable={false}
172
+ localFileMode
173
+ localFilePath={resolvedPath}
174
+ referenceDepth={referenceDepth + 1}
175
+ />
176
+ </Suspense>
177
+ ) : (
178
+ <div className="text-sm text-muted-foreground">
179
+ {t("editor.reference.empty")}
180
+ </div>
181
+ )}
182
+ </div>
183
+ </section>
184
+ );
185
+ }
@@ -1162,6 +1162,9 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1162
1162
  user={currentUser}
1163
1163
  editable={canEdit}
1164
1164
  localFileMode={isLocalFileDocument}
1165
+ localFilePath={
1166
+ isLocalFileDocument ? document.source?.path : null
1167
+ }
1165
1168
  onComment={
1166
1169
  canEdit && !isLocalFileDocument
1167
1170
  ? handleComment
@@ -52,6 +52,7 @@ import {
52
52
  commentHighlightKey,
53
53
  type CommentHighlightSpec,
54
54
  } from "./extensions/CommentHighlight";
55
+ import { ContentReferenceNode } from "./extensions/ContentReferenceNode";
55
56
  import { DragHandle } from "./extensions/DragHandle";
56
57
  import { ImageNode } from "./extensions/ImageNode";
57
58
  import {
@@ -745,6 +746,10 @@ interface VisualEditorProps {
745
746
  editable?: boolean;
746
747
  /** Local-file docs should not persist mount-time/schema normalization echoes. */
747
748
  localFileMode?: boolean;
749
+ /** Workspace-relative local artifact path for resolving inline references. */
750
+ localFilePath?: string | null;
751
+ /** Current nested local-file reference preview depth. */
752
+ referenceDepth?: number;
748
753
  /** Called when user selects text and clicks "Comment" in bubble toolbar. */
749
754
  onComment?: (
750
755
  quotedText: string,
@@ -891,6 +896,8 @@ interface VisualEditorExtensionOptions {
891
896
  onJoinTitle?: (text: string) => void;
892
897
  resolveNotionPageLink?: (notionPageId: string) => NotionPageLink | null;
893
898
  onOpenNotionPageLink?: (documentId: string) => void;
899
+ localFilePath?: string | null;
900
+ referenceDepth?: number;
894
901
  }
895
902
 
896
903
  function hasAncestorType(
@@ -1214,6 +1221,8 @@ export function createVisualEditorExtensions({
1214
1221
  onJoinTitle,
1215
1222
  resolveNotionPageLink,
1216
1223
  onOpenNotionPageLink,
1224
+ localFilePath,
1225
+ referenceDepth = 0,
1217
1226
  }: VisualEditorExtensionOptions = {}): Extensions {
1218
1227
  // Build on the SHARED editor core (StarterKit base + the Collaboration /
1219
1228
  // CollaborationCaret wiring + collab undo/redo gating + ordering), then inject
@@ -1298,6 +1307,10 @@ export function createVisualEditorExtensions({
1298
1307
  // `VisualEditor` below. Mounted after the Notion nodes and before the
1299
1308
  // Markdown extension so the NFM <-> doc round-trip recognizes the node.
1300
1309
  RegistryBlockNode,
1310
+ ContentReferenceNode.configure({
1311
+ currentPath: localFilePath ?? null,
1312
+ referenceDepth,
1313
+ }),
1301
1314
  LocalMdxComponentNode,
1302
1315
  CommentHighlight,
1303
1316
  DragHandle,
@@ -1568,6 +1581,8 @@ export function VisualEditor({
1568
1581
  user,
1569
1582
  editable = true,
1570
1583
  localFileMode = false,
1584
+ localFilePath,
1585
+ referenceDepth,
1571
1586
  onComment,
1572
1587
  commentThreads,
1573
1588
  activeThreadId,
@@ -1636,6 +1651,8 @@ export function VisualEditor({
1636
1651
  onJoinTitle,
1637
1652
  resolveNotionPageLink,
1638
1653
  onOpenNotionPageLink,
1654
+ localFilePath,
1655
+ referenceDepth,
1639
1656
  }),
1640
1657
  [
1641
1658
  documentId,
@@ -1648,6 +1665,8 @@ export function VisualEditor({
1648
1665
  onJoinTitle,
1649
1666
  resolveNotionPageLink,
1650
1667
  onOpenNotionPageLink,
1668
+ localFilePath,
1669
+ referenceDepth,
1651
1670
  ],
1652
1671
  );
1653
1672
 
@@ -0,0 +1,82 @@
1
+ import {
2
+ Node as TiptapNode,
3
+ NodeViewWrapper,
4
+ ReactNodeViewRenderer,
5
+ mergeAttributes,
6
+ type NodeViewProps,
7
+ } from "@tiptap/react";
8
+
9
+ import { ContentReferencePreview } from "../ContentReferencePreview";
10
+
11
+ function ContentReferenceView({ node, extension }: NodeViewProps) {
12
+ const sourcePath =
13
+ typeof node.attrs.sourcePath === "string" ? node.attrs.sourcePath : null;
14
+ const title = typeof node.attrs.title === "string" ? node.attrs.title : null;
15
+ const currentPath =
16
+ typeof extension.options.currentPath === "string"
17
+ ? extension.options.currentPath
18
+ : null;
19
+ const referenceDepth =
20
+ typeof extension.options.referenceDepth === "number"
21
+ ? extension.options.referenceDepth
22
+ : 0;
23
+
24
+ return (
25
+ <NodeViewWrapper
26
+ className="my-4"
27
+ contentEditable={false}
28
+ data-content-reference={sourcePath ?? ""}
29
+ >
30
+ <ContentReferencePreview
31
+ sourcePath={sourcePath}
32
+ currentPath={currentPath}
33
+ title={title}
34
+ referenceDepth={referenceDepth}
35
+ />
36
+ </NodeViewWrapper>
37
+ );
38
+ }
39
+
40
+ export const ContentReferenceNode = TiptapNode.create<{
41
+ currentPath?: string | null;
42
+ referenceDepth?: number;
43
+ }>({
44
+ name: "contentReference",
45
+ group: "block",
46
+ atom: true,
47
+ selectable: true,
48
+ draggable: true,
49
+
50
+ addOptions() {
51
+ return {
52
+ currentPath: null,
53
+ referenceDepth: 0,
54
+ };
55
+ },
56
+
57
+ addAttributes() {
58
+ return {
59
+ sourcePath: { default: "" },
60
+ title: { default: null },
61
+ __raw: { default: "" },
62
+ indent: { default: 0 },
63
+ };
64
+ },
65
+
66
+ parseHTML() {
67
+ return [{ tag: "div[data-content-reference]" }];
68
+ },
69
+
70
+ renderHTML({ HTMLAttributes }) {
71
+ return [
72
+ "div",
73
+ mergeAttributes(HTMLAttributes, {
74
+ "data-content-reference": HTMLAttributes.sourcePath,
75
+ }),
76
+ ];
77
+ },
78
+
79
+ addNodeView() {
80
+ return ReactNodeViewRenderer(ContentReferenceView);
81
+ },
82
+ });
@@ -305,6 +305,15 @@
305
305
  min-height: 6rem;
306
306
  }
307
307
 
308
+ .content-reference-preview .visual-editor-wrapper,
309
+ .content-reference-preview .visual-editor-wrapper .notion-editor {
310
+ min-height: 0;
311
+ }
312
+
313
+ .content-reference-preview .notion-editor {
314
+ font-size: 0.875rem;
315
+ }
316
+
308
317
  .notion-editor > *:first-child {
309
318
  margin-top: 0;
310
319
  }
@@ -142,6 +142,18 @@ const messages = {
142
142
  "還原會替所有人取代目前內容,且無法復原。不過目前狀態會先儲存為一個版本。",
143
143
  versionRestored: "版本已還原。",
144
144
  versionSavedAutomatically: "編輯時會自動儲存版本。",
145
+ reference: {
146
+ defaultTitle: "引用",
147
+ empty: "引用的文件是空的。",
148
+ loadError: "無法載入引用的文件。",
149
+ loading: "正在載入引用...",
150
+ missingPath: "引用路徑缺失或不受支援。",
151
+ nestedSkipped: "已略過巢狀引用預覽。",
152
+ notFound: "找不到引用的文件。",
153
+ open: "開啟",
154
+ pathMissing: "引用路徑缺失",
155
+ selfReference: "此引用指向目前文件。",
156
+ },
145
157
  media: {
146
158
  addAltTextDescription: "新增替代文字來描述該圖片。",
147
159
  addAudio: "新增音訊",
@@ -1503,6 +1503,18 @@ const enUS = {
1503
1503
  "Restoring will replace the live content for everyone and cannot be undone (though the current state is saved as a version first).",
1504
1504
  versionRestored: "Version restored.",
1505
1505
  versionSavedAutomatically: "Versions are saved automatically as you edit.",
1506
+ reference: {
1507
+ defaultTitle: "Reference",
1508
+ empty: "Referenced document is empty.",
1509
+ loadError: "Could not load referenced document.",
1510
+ loading: "Loading reference...",
1511
+ missingPath: "Reference path missing or unsupported.",
1512
+ nestedSkipped: "Nested reference preview skipped.",
1513
+ notFound: "Referenced document not found.",
1514
+ open: "Open",
1515
+ pathMissing: "Reference path missing",
1516
+ selfReference: "This reference points to the current document.",
1517
+ },
1506
1518
  media: editorMediaMessages,
1507
1519
  properties: editorPropertiesMessages,
1508
1520
  slash: editorSlashMessages,
@@ -6329,6 +6341,129 @@ const editorMessagesByLocale = {
6329
6341
  },
6330
6342
  } satisfies Partial<Record<LocaleCode, PartialMessages["editor"]>>;
6331
6343
 
6344
+ const contentReferenceMessagesByLocale = {
6345
+ "zh-CN": {
6346
+ defaultTitle: "引用",
6347
+ empty: "引用的文档为空。",
6348
+ loadError: "无法加载引用的文档。",
6349
+ loading: "正在加载引用...",
6350
+ missingPath: "引用路径缺失或不受支持。",
6351
+ nestedSkipped: "已跳过嵌套引用预览。",
6352
+ notFound: "找不到引用的文档。",
6353
+ open: "打开",
6354
+ pathMissing: "引用路径缺失",
6355
+ selfReference: "此引用指向当前文档。",
6356
+ },
6357
+ "zh-TW": {
6358
+ defaultTitle: "引用",
6359
+ empty: "引用的文件是空的。",
6360
+ loadError: "無法載入引用的文件。",
6361
+ loading: "正在載入引用...",
6362
+ missingPath: "引用路徑缺失或不受支援。",
6363
+ nestedSkipped: "已略過巢狀引用預覽。",
6364
+ notFound: "找不到引用的文件。",
6365
+ open: "開啟",
6366
+ pathMissing: "引用路徑缺失",
6367
+ selfReference: "此引用指向目前文件。",
6368
+ },
6369
+ "es-ES": {
6370
+ defaultTitle: "Referencia",
6371
+ empty: "El documento referenciado está vacío.",
6372
+ loadError: "No se pudo cargar el documento referenciado.",
6373
+ loading: "Cargando referencia...",
6374
+ missingPath: "La ruta de referencia falta o no es compatible.",
6375
+ nestedSkipped: "Se omitió la vista previa de la referencia anidada.",
6376
+ notFound: "No se encontró el documento referenciado.",
6377
+ open: "Abrir",
6378
+ pathMissing: "Falta la ruta de referencia",
6379
+ selfReference: "Esta referencia apunta al documento actual.",
6380
+ },
6381
+ "fr-FR": {
6382
+ defaultTitle: "Référence",
6383
+ empty: "Le document référencé est vide.",
6384
+ loadError: "Impossible de charger le document référencé.",
6385
+ loading: "Chargement de la référence...",
6386
+ missingPath: "Le chemin de référence est manquant ou non pris en charge.",
6387
+ nestedSkipped: "Aperçu de référence imbriquée ignoré.",
6388
+ notFound: "Document référencé introuvable.",
6389
+ open: "Ouvrir",
6390
+ pathMissing: "Chemin de référence manquant",
6391
+ selfReference: "Cette référence pointe vers le document actuel.",
6392
+ },
6393
+ "de-DE": {
6394
+ defaultTitle: "Referenz",
6395
+ empty: "Das referenzierte Dokument ist leer.",
6396
+ loadError: "Das referenzierte Dokument konnte nicht geladen werden.",
6397
+ loading: "Referenz wird geladen...",
6398
+ missingPath: "Referenzpfad fehlt oder wird nicht unterstützt.",
6399
+ nestedSkipped: "Vorschau der verschachtelten Referenz übersprungen.",
6400
+ notFound: "Referenziertes Dokument nicht gefunden.",
6401
+ open: "Öffnen",
6402
+ pathMissing: "Referenzpfad fehlt",
6403
+ selfReference: "Diese Referenz verweist auf das aktuelle Dokument.",
6404
+ },
6405
+ "ja-JP": {
6406
+ defaultTitle: "参照",
6407
+ empty: "参照先のドキュメントは空です。",
6408
+ loadError: "参照先のドキュメントを読み込めませんでした。",
6409
+ loading: "参照を読み込んでいます...",
6410
+ missingPath: "参照パスがないか、サポートされていません。",
6411
+ nestedSkipped: "ネストされた参照プレビューをスキップしました。",
6412
+ notFound: "参照先のドキュメントが見つかりません。",
6413
+ open: "開く",
6414
+ pathMissing: "参照パスがありません",
6415
+ selfReference: "この参照は現在のドキュメントを指しています。",
6416
+ },
6417
+ "ko-KR": {
6418
+ defaultTitle: "참조",
6419
+ empty: "참조된 문서가 비어 있습니다.",
6420
+ loadError: "참조된 문서를 불러올 수 없습니다.",
6421
+ loading: "참조를 불러오는 중...",
6422
+ missingPath: "참조 경로가 없거나 지원되지 않습니다.",
6423
+ nestedSkipped: "중첩된 참조 미리보기를 건너뛰었습니다.",
6424
+ notFound: "참조된 문서를 찾을 수 없습니다.",
6425
+ open: "열기",
6426
+ pathMissing: "참조 경로 없음",
6427
+ selfReference: "이 참조는 현재 문서를 가리킵니다.",
6428
+ },
6429
+ "pt-BR": {
6430
+ defaultTitle: "Referência",
6431
+ empty: "O documento referenciado está vazio.",
6432
+ loadError: "Não foi possível carregar o documento referenciado.",
6433
+ loading: "Carregando referência...",
6434
+ missingPath: "O caminho da referência está ausente ou não é compatível.",
6435
+ nestedSkipped: "Prévia de referência aninhada ignorada.",
6436
+ notFound: "Documento referenciado não encontrado.",
6437
+ open: "Abrir",
6438
+ pathMissing: "Caminho da referência ausente",
6439
+ selfReference: "Esta referência aponta para o documento atual.",
6440
+ },
6441
+ "hi-IN": {
6442
+ defaultTitle: "संदर्भ",
6443
+ empty: "संदर्भित दस्तावेज़ खाली है।",
6444
+ loadError: "संदर्भित दस्तावेज़ लोड नहीं किया जा सका।",
6445
+ loading: "संदर्भ लोड हो रहा है...",
6446
+ missingPath: "संदर्भ पथ गायब है या समर्थित नहीं है।",
6447
+ nestedSkipped: "नेस्टेड संदर्भ पूर्वावलोकन छोड़ दिया गया।",
6448
+ notFound: "संदर्भित दस्तावेज़ नहीं मिला।",
6449
+ open: "खोलें",
6450
+ pathMissing: "संदर्भ पथ गायब है",
6451
+ selfReference: "यह संदर्भ वर्तमान दस्तावेज़ की ओर इशारा करता है।",
6452
+ },
6453
+ "ar-SA": {
6454
+ defaultTitle: "مرجع",
6455
+ empty: "المستند المشار إليه فارغ.",
6456
+ loadError: "تعذر تحميل المستند المشار إليه.",
6457
+ loading: "جارٍ تحميل المرجع...",
6458
+ missingPath: "مسار المرجع مفقود أو غير مدعوم.",
6459
+ nestedSkipped: "تم تخطي معاينة المرجع المتداخل.",
6460
+ notFound: "لم يتم العثور على المستند المشار إليه.",
6461
+ open: "فتح",
6462
+ pathMissing: "مسار المرجع مفقود",
6463
+ selfReference: "يشير هذا المرجع إلى المستند الحالي.",
6464
+ },
6465
+ } satisfies Partial<Record<LocaleCode, typeof enUS.editor.reference>>;
6466
+
6332
6467
  function mergeMessages(overrides: PartialMessages): Messages {
6333
6468
  return {
6334
6469
  root: { ...enUS.root, ...overrides.root },
@@ -6350,6 +6485,7 @@ function mergeMessages(overrides: PartialMessages): Messages {
6350
6485
  ...overrides.editor?.properties?.filesMediaKinds,
6351
6486
  },
6352
6487
  },
6488
+ reference: { ...enUS.editor.reference, ...overrides.editor?.reference },
6353
6489
  slash: { ...enUS.editor.slash, ...overrides.editor?.slash },
6354
6490
  toolbar: { ...enUS.editor.toolbar, ...overrides.editor?.toolbar },
6355
6491
  },
@@ -6437,6 +6573,10 @@ function mergeMessagesForLocale(
6437
6573
  ...rawLiteralOverrides.editor,
6438
6574
  media: { ...base.editor.media, ...rawLiteralOverrides.editor?.media },
6439
6575
  properties: base.editor.properties,
6576
+ reference: {
6577
+ ...base.editor.reference,
6578
+ ...contentReferenceMessagesByLocale[locale],
6579
+ },
6440
6580
  slash: base.editor.slash,
6441
6581
  toolbar: {
6442
6582
  ...base.editor.toolbar,
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Reusable MDX references now preview linked local documents inline.
@@ -49,6 +49,8 @@ export interface BuilderTabbedContentData extends BuilderRawRefData {
49
49
  export interface BuilderSymbolData extends BuilderRawRefData {
50
50
  entry?: string;
51
51
  model?: string;
52
+ source?: string;
53
+ dynamic?: boolean;
52
54
  data?: Record<string, unknown>;
53
55
  }
54
56
 
@@ -104,6 +106,8 @@ export const builderSymbolSchema = z.object({
104
106
  ...rawRefSchema,
105
107
  entry: z.string().trim().max(240).optional(),
106
108
  model: z.string().trim().max(120).optional(),
109
+ source: z.string().trim().max(2_000).optional(),
110
+ dynamic: z.boolean().optional(),
107
111
  data: z.record(z.string(), z.unknown()).optional(),
108
112
  }) as unknown as z.ZodType<BuilderSymbolData>;
109
113
 
@@ -203,6 +207,8 @@ export const builderSymbolMdx: BlockMdxConfig<BuilderSymbolData> = {
203
207
  ...rawRefAttrs(data),
204
208
  entry: data.entry,
205
209
  model: data.model,
210
+ source: data.source,
211
+ dynamic: data.dynamic,
206
212
  data: data.data,
207
213
  }),
208
214
  fromAttrs: (attrs) => ({
@@ -211,6 +217,8 @@ export const builderSymbolMdx: BlockMdxConfig<BuilderSymbolData> = {
211
217
  componentName: attrs.string("componentName"),
212
218
  entry: attrs.string("entry"),
213
219
  model: attrs.string("model"),
220
+ source: attrs.string("source"),
221
+ dynamic: attrs.bool("dynamic"),
214
222
  data: attrs.object<Record<string, unknown>>("data"),
215
223
  }),
216
224
  };