@agent-native/core 0.79.27 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +26 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
  13. package/corpus/core/docs/content/template-design.mdx +45 -0
  14. package/corpus/core/package.json +2 -1
  15. package/corpus/core/src/agent/engine/index.ts +1 -0
  16. package/corpus/core/src/agent/engine/registry.ts +40 -0
  17. package/corpus/core/src/agent/production-agent.ts +6 -2
  18. package/corpus/core/src/cli/design-connect.ts +490 -0
  19. package/corpus/core/src/cli/index.ts +16 -0
  20. package/corpus/core/src/cli/skills.ts +126 -3
  21. package/corpus/core/src/client/AssistantChat.tsx +43 -7
  22. package/corpus/core/src/client/agent-chat.ts +27 -3
  23. package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
  24. package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
  25. package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
  26. package/corpus/core/src/client/chat/message-components.tsx +1 -1
  27. package/corpus/core/src/client/chat-model-groups.ts +1 -2
  28. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
  29. package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
  30. package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
  31. package/corpus/core/src/client/frame-protocol.ts +17 -2
  32. package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
  33. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
  34. package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
  35. package/corpus/core/src/server/transcribe-voice.ts +57 -22
  36. package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
  37. package/corpus/core/src/styles/agent-native.css +56 -7
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  39. package/corpus/core/src/vite/client.ts +2 -0
  40. package/corpus/core/src/voice/index.ts +18 -0
  41. package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
  42. package/corpus/core/src/voice/voice-context.ts +217 -0
  43. package/corpus/core/src/voice/voice-replacements.ts +75 -0
  44. package/corpus/templates/analytics/AGENTS.md +4 -3
  45. package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
  46. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
  47. package/corpus/templates/analytics/app/global.css +0 -4
  48. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  49. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  50. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
  51. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
  52. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
  53. package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
  54. package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
  55. package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  56. package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
  57. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
  58. package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
  59. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
  60. package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
  61. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
  62. package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  63. package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
  64. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
  65. package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
  66. package/corpus/templates/brain/app/i18n-data.ts +20 -0
  67. package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  68. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
  69. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
  70. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  71. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  72. package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  73. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
  74. package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  75. package/corpus/templates/clips/AGENTS.md +4 -0
  76. package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
  77. package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
  78. package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
  79. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  80. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
  81. package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
  82. package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  83. package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
  84. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
  85. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
  86. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
  87. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
  88. package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  89. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
  90. package/corpus/templates/design/AGENTS.md +95 -5
  91. package/corpus/templates/design/DESIGN.md +82 -0
  92. package/corpus/templates/design/DEVELOPING.md +43 -0
  93. package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
  94. package/corpus/templates/design/actions/apply-shader.ts +277 -0
  95. package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
  96. package/corpus/templates/design/actions/connect-localhost.ts +183 -0
  97. package/corpus/templates/design/actions/edit-design.ts +195 -42
  98. package/corpus/templates/design/actions/generate-design.ts +71 -1
  99. package/corpus/templates/design/actions/generate-screens.ts +193 -0
  100. package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
  101. package/corpus/templates/design/actions/get-shader.ts +119 -0
  102. package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
  103. package/corpus/templates/design/actions/navigate.ts +55 -2
  104. package/corpus/templates/design/actions/view-screen.ts +68 -1
  105. package/corpus/templates/design/agent-native.app-skill.json +10 -0
  106. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
  107. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
  108. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
  109. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
  110. package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
  111. package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
  112. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
  113. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
  114. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
  115. package/corpus/templates/design/app/components/design/index.ts +0 -5
  116. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
  117. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
  118. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
  119. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
  120. package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
  121. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
  122. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
  123. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
  124. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
  125. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
  126. package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
  127. package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
  128. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
  129. package/corpus/templates/design/app/components/design/types.ts +23 -0
  130. package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
  131. package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
  132. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
  133. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
  134. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
  135. package/corpus/templates/design/app/global.css +121 -3
  136. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
  137. package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
  138. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
  139. package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
  140. package/corpus/templates/design/app/i18n-data.ts +2790 -1
  141. package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
  142. package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
  144. package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
  145. package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
  146. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
  147. package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
  148. package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
  149. package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  150. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
  151. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
  154. package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
  159. package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
  160. package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
  161. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
  162. package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
  163. package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
  164. package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
  165. package/corpus/templates/design/package.json +1 -0
  166. package/corpus/templates/design/server/db/schema.ts +26 -0
  167. package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
  168. package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
  169. package/corpus/templates/design/shared/api.ts +27 -0
  170. package/corpus/templates/design/shared/canvas-frames.ts +103 -0
  171. package/corpus/templates/design/shared/canvas-math.ts +1058 -0
  172. package/corpus/templates/design/shared/code-layer.ts +2212 -0
  173. package/corpus/templates/design/shared/color-utils.ts +180 -0
  174. package/corpus/templates/design/shared/generation-session.ts +61 -0
  175. package/corpus/templates/design/shared/shader-presets.ts +782 -0
  176. package/corpus/templates/design/shared/shader-safety.ts +137 -0
  177. package/corpus/templates/design/shared/source-mode.ts +237 -0
  178. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
  179. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  180. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  181. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  182. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  183. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  184. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  185. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  186. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  187. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  188. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  189. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  190. package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  191. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  192. package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  193. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
  194. package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
  195. package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
  196. package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
  197. package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
  198. package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
  199. package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
  200. package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
  201. package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
  202. package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
  203. package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
  204. package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
  205. package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  206. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
  207. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
  208. package/corpus/templates/plan/app/global.css +61 -78
  209. package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
  210. package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  211. package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
  212. package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
  213. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
  214. package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  215. package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
  216. package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
  217. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
  218. package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
  219. package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
  220. package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
  221. package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
  222. package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
  223. package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
  224. package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
  225. package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
  226. package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
  227. package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
  228. package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
  229. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  230. package/dist/agent/engine/index.d.ts +1 -1
  231. package/dist/agent/engine/index.d.ts.map +1 -1
  232. package/dist/agent/engine/index.js +1 -1
  233. package/dist/agent/engine/index.js.map +1 -1
  234. package/dist/agent/engine/registry.d.ts +9 -0
  235. package/dist/agent/engine/registry.d.ts.map +1 -1
  236. package/dist/agent/engine/registry.js +37 -0
  237. package/dist/agent/engine/registry.js.map +1 -1
  238. package/dist/agent/production-agent.d.ts.map +1 -1
  239. package/dist/agent/production-agent.js +4 -3
  240. package/dist/agent/production-agent.js.map +1 -1
  241. package/dist/cli/design-connect.d.ts +52 -0
  242. package/dist/cli/design-connect.d.ts.map +1 -0
  243. package/dist/cli/design-connect.js +409 -0
  244. package/dist/cli/design-connect.js.map +1 -0
  245. package/dist/cli/index.js +15 -0
  246. package/dist/cli/index.js.map +1 -1
  247. package/dist/cli/skills.d.ts +3 -0
  248. package/dist/cli/skills.d.ts.map +1 -1
  249. package/dist/cli/skills.js +121 -3
  250. package/dist/cli/skills.js.map +1 -1
  251. package/dist/client/AssistantChat.d.ts.map +1 -1
  252. package/dist/client/AssistantChat.js +38 -8
  253. package/dist/client/AssistantChat.js.map +1 -1
  254. package/dist/client/agent-chat.d.ts +6 -0
  255. package/dist/client/agent-chat.d.ts.map +1 -1
  256. package/dist/client/agent-chat.js +17 -3
  257. package/dist/client/agent-chat.js.map +1 -1
  258. package/dist/client/blocks/library/MermaidBlock.js +1 -1
  259. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  260. package/dist/client/blocks/library/diagram.js +1 -1
  261. package/dist/client/blocks/library/diagram.js.map +1 -1
  262. package/dist/client/blocks/library/wireframe.js +1 -1
  263. package/dist/client/blocks/library/wireframe.js.map +1 -1
  264. package/dist/client/chat/message-components.js +1 -1
  265. package/dist/client/chat/message-components.js.map +1 -1
  266. package/dist/client/chat-model-groups.d.ts.map +1 -1
  267. package/dist/client/chat-model-groups.js +1 -2
  268. package/dist/client/chat-model-groups.js.map +1 -1
  269. package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
  270. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  271. package/dist/client/components/LiveCursorOverlay.js +19 -40
  272. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  273. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  274. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  275. package/dist/client/composer/TiptapComposer.js +86 -24
  276. package/dist/client/composer/TiptapComposer.js.map +1 -1
  277. package/dist/client/composer/useVoiceDictation.d.ts +9 -0
  278. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  279. package/dist/client/composer/useVoiceDictation.js +154 -32
  280. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  281. package/dist/client/frame-protocol.d.ts +17 -2
  282. package/dist/client/frame-protocol.d.ts.map +1 -1
  283. package/dist/client/frame-protocol.js.map +1 -1
  284. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
  285. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
  286. package/dist/client/sharing/ShareButton.d.ts +2 -0
  287. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  288. package/dist/client/sharing/ShareButton.js +7 -6
  289. package/dist/client/sharing/ShareButton.js.map +1 -1
  290. package/dist/client/use-agent-engine-configured.d.ts +5 -0
  291. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  292. package/dist/client/use-agent-engine-configured.js +51 -25
  293. package/dist/client/use-agent-engine-configured.js.map +1 -1
  294. package/dist/collab/awareness.d.ts +2 -2
  295. package/dist/collab/awareness.d.ts.map +1 -1
  296. package/dist/collab/routes.d.ts +1 -1
  297. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  298. package/dist/notifications/routes.d.ts +3 -3
  299. package/dist/observability/routes.d.ts +8 -8
  300. package/dist/progress/routes.d.ts +1 -1
  301. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  302. package/dist/server/transcribe-voice.d.ts.map +1 -1
  303. package/dist/server/transcribe-voice.js +40 -24
  304. package/dist/server/transcribe-voice.js.map +1 -1
  305. package/dist/shared/mcp-embed-headers.d.ts +1 -0
  306. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  307. package/dist/shared/mcp-embed-headers.js +20 -1
  308. package/dist/shared/mcp-embed-headers.js.map +1 -1
  309. package/dist/styles/agent-native.css +56 -7
  310. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  311. package/dist/vite/client.d.ts.map +1 -1
  312. package/dist/vite/client.js +2 -0
  313. package/dist/vite/client.js.map +1 -1
  314. package/dist/voice/index.d.ts +5 -0
  315. package/dist/voice/index.d.ts.map +1 -0
  316. package/dist/voice/index.js +4 -0
  317. package/dist/voice/index.js.map +1 -0
  318. package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
  319. package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
  320. package/dist/voice/voice-cleanup-prompt.js +26 -0
  321. package/dist/voice/voice-cleanup-prompt.js.map +1 -0
  322. package/dist/voice/voice-context.d.ts +25 -0
  323. package/dist/voice/voice-context.d.ts.map +1 -0
  324. package/dist/voice/voice-context.js +156 -0
  325. package/dist/voice/voice-context.js.map +1 -0
  326. package/dist/voice/voice-replacements.d.ts +4 -0
  327. package/dist/voice/voice-replacements.d.ts.map +1 -0
  328. package/dist/voice/voice-replacements.js +52 -0
  329. package/dist/voice/voice-replacements.js.map +1 -0
  330. package/docs/content/locales/ar-SA/template-design.mdx +41 -0
  331. package/docs/content/locales/de-DE/template-design.mdx +51 -0
  332. package/docs/content/locales/es-ES/template-design.mdx +50 -0
  333. package/docs/content/locales/fr-FR/template-design.mdx +49 -0
  334. package/docs/content/locales/hi-IN/template-design.mdx +44 -0
  335. package/docs/content/locales/ja-JP/template-design.mdx +46 -0
  336. package/docs/content/locales/ko-KR/template-design.mdx +44 -0
  337. package/docs/content/locales/pt-BR/template-design.mdx +48 -0
  338. package/docs/content/locales/zh-CN/template-design.mdx +36 -0
  339. package/docs/content/locales/zh-TW/template-design.mdx +38 -0
  340. package/docs/content/template-design.mdx +45 -0
  341. package/package.json +2 -1
  342. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  343. package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
  344. package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
  345. package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
  346. package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
@@ -1 +1 @@
1
- {"version":3,"file":"RegistryBlockNode.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/RegistryBlockNode.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACL,aAAa,EACb,MAAM,EACN,SAAS,GAEV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,IAAI,EACJ,eAAe,EACf,qBAAqB,EACrB,eAAe,GAEhB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,OAAO,EACP,QAAQ,GAGT,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,gBAAgB,EAChB,wBAAwB,GAGzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AA2FnE,MAAM,wBAAwB,GAC5B,aAAa,CAAqC,IAAI,CAAC,CAAC;AAE1D,MAAM,UAAU,yBAAyB,CAEvC,EACA,KAAK,EACL,QAAQ,GAIT;IACC,OAAO,CACL,KAAC,wBAAwB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAC5C,QAAQ,GACyB,CACrC,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,oBAAoB;IAGlC,OAAO,UAAU,CACf,wBAAwB,CACgB,CAAC;AAC7C,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAmB;IAClD,IAAI,MAAM,CAAC,OAAO,CAAC,iDAAiD,CAAC,EAAE,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+EAA+E;IAC/E,6EAA6E;IAC7E,wEAAwE;IACxE,4EAA4E;IAC5E,+EAA+E;IAC/E,4EAA4E;IAC5E,8EAA8E;IAC9E,+EAA+E;IAC/E,+EAA+E;IAC/E,IACE,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,qCAAqC,CAAC,EACrD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC5D,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnE,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAoB;IACxD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,MAAM,aAAa,GAAG,wBAAwB,EAAE,CAAC;IACjD,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IAEvC,4EAA4E;IAC5E,wEAAwE;IACxE,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,8EAA8E;IAC9E,8EAA8E;IAC9E,4EAA4E;IAC5E,+CAA+C;IAC/C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAGpC,IAAI,CAAC,CAAC;IAChB,MAAM,SAAS,GAAG,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,SAAS,EAAE,IAAI,CAAC;IACjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5B,MAAM,KAAK,GACT,SAAS,IAAI,WAAW,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC;QAC/D,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE;QAC1C,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,eAAe,GAAG,CAAC,QAAiB,EAAE,IAA0B,EAAE,EAAE;QACxE,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnD,OAAO,EAAE,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtD,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC;IAC5C,2EAA2E;IAC3E,4EAA4E;IAC5E,2CAA2C;IAC3C,MAAM,sBAAsB,GAC1B,CAAC,OAAO,EAAE,UAAU,IAAI,KAAK,CAAC;QAC9B,CAAC,OAAO,EAAE,wBAAwB,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC;IAE5D,+EAA+E;IAC/E,kEAAkE;IAClE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CACL,KAAC,eAAe,IAAC,SAAS,EAAC,iBAAiB,mBAAgB,OAAO,YACjE,cACE,eAAe,EAAE,KAAK,iCAEtB,SAAS,EAAC,oHAAoH,YAE7H,SAAS,CAAC,CAAC,CAAC,WAAW,SAAS,SAAS,CAAC,CAAC,CAAC,gBAAgB,GACzD,GACU,CACnB,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,EAAE,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,CAAC,KAAmC,EAAE,EAAE;QACzD,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,MAAM,YAAY,WAAW,IAAI,uBAAuB,CAAC,MAAM,CAAC;YAClE,OAAO;QACT,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACvE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO;QACpC,IAAI,CAAC;YACH,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;YAC9B,IAAI,CAAC,QAAQ,CACX,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CACtE,CAAC;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC,CAAC;IACF,MAAM,gBAAgB,GAAG,CAAC,KAAmC,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,eAAe,CACb,MAAM,YAAY,WAAW;YAC3B,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,KAAK,KAAK,CAAC,aAAa,CACpE,CAAC;IACJ,CAAC,CAAC;IAEF,uCAAuC;IACvC,wEAAwE;IACxE,4EAA4E;IAC5E,0EAA0E;IAC1E,8EAA8E;IAC9E,cAAc;IACd,+EAA+E;IAC/E,2EAA2E;IAC3E,+EAA+E;IAC/E,yEAAyE;IACzE,sDAAsD;IACtD,+CAA+C;IAC/C,IAAI,IAAe,CAAC;IACpB,IAAI,WAAW,GAAc,IAAI,CAAC;IAClC,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAI,KAA2B,CAAC,IAAI,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,QAAQ,GAAG,CACf,KAAC,IAAI,IACH,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,aAAa,CAAC,GAAG,GACtB,CACH,CAAC;QACF,IAAI,GAAG,QAAQ,CAAC;QAChB,MAAM,YAAY,GAChB,QAAQ;YACR,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;YAChC,CAAC,CAAC,OAAO,EAAE,iBAAiB,CAAC;QAC/B,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CACxB,KAAC,IAAI,IACH,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,eAAe,EACzB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,aAAa,CAAC,GAAG,GACtB,CACH,CAAC,CAAC,CAAC,CACF,KAAC,iBAAiB,IAChB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,EACjD,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,GAAG,EAAE,aAAa,CAAC,GAAG,GACtB,CACH,CAAC;YACF,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,OAAO,IAAI,aAAa,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;gBAC/D,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC;oBAChD,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,IAAI,EAAE,SAAS;oBACf,YAAY,EAAE,YAAY;oBAC1B,OAAO,EAAE,KAAK,CAAC,EAAE;oBACjB,SAAS;oBACT,UAAU,EAAE,KAAK,CAAC,KAAK;oBACvB,YAAY,EAAE,KAAK,CAAC,OAAO;oBAC3B,SAAS;oBACT,OAAO,EAAE,CACP,iBACE,IAAI,EAAC,QAAQ,+CAED,QAAQ,IAAI,CAAC,KAAK,EAAE,EAChC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EACjC,SAAS,EAAC,0RAA0R,kBACtR,SAAS,IAAI,YAAY,YAEvC,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAC1B,CACV;oBACD,QAAQ,EAAE,UAAU;iBACrB,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBAC/B,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC7B,cAAK,SAAS,EAAC,MAAM,YAAE,UAAU,GAAO,CACzC,CAAC,CAAC,CAAC,IAAI,CAAC;YACX,CAAC;iBAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBAC9B,IAAI,GAAG,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,EAAE,iBAAiB,EAAE,CAAC;QACtC,2EAA2E;QAC3E,wEAAwE;QACxE,yEAAyE;QACzE,MAAM,SAAS,GACb,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACjE,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QAChE,IAAI,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3B,yEAAyE;YACzE,wEAAwE;YACxE,MAAM,YAAY,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,KAAK,EAAE;gBAC5D,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC;aAClD,CAAC,CAAC;YACH,WAAW,GAAG,CACZ,KAAC,qBAAqB,IACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,EACf,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,aAAa,EAAE,GAAG,CAAC,iBAAiB,EACvD,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,EACnD,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,YAAY,GAC1B,CACH,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,CACL,cAAK,SAAS,EAAC,mGAAmG,YAC/G,KAAK,CAAC,KAAK,IAAI,SAAS,IAAI,mBAAmB,GAC5C,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,eAAe,IACd,SAAS,EAAC,iBAAiB,mBACZ,OAAO,qBAIL,SAAS,IAAI,SAAS,8BACb,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,8BAC/B,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EACjE,kBAAkB,EAAE,UAAU,YAE9B,eACE,eAAe,EAAE,KAAK,iCAEtB,SAAS,EAAC,iCAAiC,EAC3C,YAAY,EAAE,gBAAgB,EAC9B,WAAW,EAAE,gBAAgB,EAC7B,YAAY,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,aAEzC,sBAAsB,IAAI,CACzB,eACE,SAAS,EAAC,yBAAyB,EACnC,KAAK,EAAC,oEAAoE,qCAGrE,CACR,EACA,IAAI,EACJ,WAAW,IAAI,CACd,cAAK,SAAS,EAAC,mDAAmD,YAC/D,WAAW,GACR,CACP,IACG,GACU,CACnB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EACpC,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,YAAY,GAcb;IACC,MAAM,mBAAmB,GAAG,OAAO,CACjC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EACzC,CAAC,KAAK,CAAC,IAAI,CAAC,CACb,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACxD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAElE,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,mBAAmB,CAAC,CAAC;QAC9B,aAAa,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAEpC,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAY,CAAC;YAC9C,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAC9D,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CACd,iBACE,IAAI,EAAC,QAAQ,+CAED,QAAQ,KAAK,CAAC,KAAK,IAAI,OAAO,EAAE,EAC5C,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EACjC,SAAS,EAAC,0RAA0R,kBACtR,QAAQ,IAAI,IAAI,YAE9B,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAC1B,CACV,CAAC;IACF,MAAM,UAAU,GAAG,CACjB,eAAK,SAAS,EAAC,YAAY,aACzB,kDAEE,SAAS,EAAC,sMAAsM,EAChN,KAAK,EAAE,KAAK,kBACE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;oBAClB,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC7B,IAAI,UAAU;wBAAE,aAAa,CAAC,IAAI,CAAC,CAAC;gBACtC,CAAC,GACD,EACD,UAAU,CAAC,CAAC,CAAC,CACZ,aAAG,SAAS,EAAC,0BAA0B,EAAC,IAAI,EAAC,OAAO,+BACnC,UAAU,IACvB,CACL,CAAC,CAAC,CAAC,IAAI,EACR,cAAK,SAAS,EAAC,kBAAkB,YAC/B,iBACE,IAAI,EAAC,QAAQ,iCAEb,SAAS,EAAC,oHAAoH,EAC9H,OAAO,EAAE,SAAS,qBAGX,GACL,IACF,CACP,CAAC;IACF,MAAM,MAAM,GAAG,YAAY,IAAI,UAAU,CAAC;IAC1C,IAAI,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACvD,OAAO,iBAAiB,CAAC;QACvB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,OAAO;QAC7B,IAAI;QACJ,YAAY;QACZ,OAAO,EAAE,KAAK,CAAC,EAAE;QACjB,SAAS,EACP,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ;YACpD,CAAC,CAAC,CAAE,KAAqC,CAAC,IAAI,IAAI,EAAE,CAAC;YACrD,CAAC,CAAC,QAAQ;QACd,UAAU,EAAE,KAAK,CAAC,KAAK;QACvB,YAAY,EAAE,KAAK,CAAC,OAAO;QAC3B,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,OAAO;QACP,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC;AACL,CAAC;AA6BD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAuC;IAEvC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC;IAC/D,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,GAAG,QAAQ,WAAW,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,IAAI,SAAS,CAAC,GAAG,QAAQ,eAAe,CAAC,CAAC;IAEnE;;;;OAIG;IACH,SAAS,cAAc,CAAC,KAAkB;QAMxC,MAAM,KAAK,GAKN,EAAE,CAAC;QACR,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAClC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC;oBACT,GAAG;oBACH,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;oBAC7C,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;oBACzC,aAAa,EACX,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,KAAK,QAAQ;wBAC1C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa;wBAC1B,CAAC,CAAC,SAAS;iBAChB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACH,SAAS,sBAAsB,CAAC,KAAkB;QAChD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QAClB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7D,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzC,IAAI,IAAI,EAAE,CAAC;oBACT,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE;wBAC1C,GAAG,IAAI,CAAC,KAAK;wBACb,OAAO,EAAE,OAAO;wBAChB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI;qBAC5D,CAAC,CAAC;oBACH,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtD,CAAC;IAED,MAAM,qBAAqB,GAAG,CAAC,KAAkB,EAAE,EAAE,CACnD,KAAK,CAAC,SAAS,YAAY,aAAa;QACxC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;IAE9C,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAE,EAAE;QAC7C,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QACjE,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,OAAO,IAAI,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK;QACL,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QAEf,aAAa;YACX,OAAO;gBACL,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC1B,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACxB,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;gBACxB,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;gBAC1B,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;gBAChC,8DAA8D;gBAC9D,uEAAuE;gBACvE,mBAAmB;gBACnB,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;aAC1C,CAAC;QACJ,CAAC;QAED,SAAS;YACP,OAAO;gBACL;oBACE,GAAG,EAAE,OAAO,OAAO,GAAG;oBACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;wBACpB,MAAM,IAAI,GAAG,OAAsB,CAAC;wBACpC,OAAO;4BACL,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE;4BACrD,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,EAAE;4BACjD,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,IAAI;4BAC9C,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,IAAI;4BAClD,aAAa,EAAE,IAAI,CAAC,YAAY,CAAC,sBAAsB,CAAC,IAAI,IAAI;yBACjE,CAAC;oBACJ,CAAC;iBACF;aACF,CAAC;QACJ,CAAC;QAED,UAAU,CAAC,EAAE,cAAc,EAAE;YAC3B,OAAO;gBACL,KAAK;gBACL,eAAe,CAAC,cAAc,EAAE;oBAC9B,CAAC,OAAO,CAAC,EAAE,EAAE;oBACb,iBAAiB,EAAE,cAAc,CAAC,SAAS,IAAI,EAAE;oBACjD,eAAe,EAAE,cAAc,CAAC,OAAO,IAAI,EAAE;oBAC7C,YAAY,EAAE,cAAc,CAAC,KAAK,IAAI,SAAS;oBAC/C,cAAc,EAAE,cAAc,CAAC,OAAO,IAAI,SAAS;oBACnD,sBAAsB,EAAE,cAAc,CAAC,aAAa,IAAI,SAAS;iBAClE,CAAC;aACH,CAAC;QACJ,CAAC;QAED,WAAW;YACT,OAAO,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;QACtD,CAAC;QAED,qBAAqB;YACnB,OAAO;gBACL,IAAI,MAAM,CAAC;oBACT,GAAG,EAAE,SAAS;oBACd,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,QAAQ;wBACjD,iEAAiE;wBACjE,IACE,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAChC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAC/B;4BACD,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,EAC3D,CAAC;4BACD,OAAO,IAAI,CAAC;wBACd,CAAC;wBACD,OAAO,sBAAsB,CAAC,QAAQ,CAAC,CAAC;oBAC1C,CAAC;iBACF,CAAC;gBACF,IAAI,MAAM,CAAC;oBACT,GAAG,EAAE,gBAAgB;oBACrB,KAAK,EAAE;wBACL,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;4BACpD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM;gCAAE,OAAO,KAAK,CAAC;4BACzD,IACE,KAAK,CAAC,MAAM,YAAY,WAAW;gCACnC,uBAAuB,CAAC,KAAK,CAAC,MAAM,CAAC,EACrC,CAAC;gCACD,OAAO,KAAK,CAAC;4BACf,CAAC;4BACD,KAAK,CAAC,cAAc,EAAE,CAAC;4BACvB,IAAI,CAAC,QAAQ,CACX,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CACxB,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAC9C,CACF,CAAC;4BACF,IAAI,CAAC,KAAK,EAAE,CAAC;4BACb,OAAO,IAAI,CAAC;wBACd,CAAC;wBACD,aAAa,CAAC,IAAI,EAAE,KAAK;4BACvB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;gCAC7D,OAAO,KAAK,CAAC;4BACf,KAAK,CAAC,cAAc,EAAE,CAAC;4BACvB,OAAO,IAAI,CAAC;wBACd,CAAC;wBACD,eAAe,CAAC,IAAI;4BAClB,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBAC3C,CAAC;wBACD,WAAW,CAAC,IAAI,EAAE,KAAK;4BACrB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;gCAAE,OAAO,KAAK,CAAC;4BACrD,KAAK,CAAC,cAAc,EAAE,CAAC;4BACvB,OAAO,IAAI,CAAC;wBACd,CAAC;wBACD,eAAe,EAAE;4BACf,WAAW,CAAC,IAAI,EAAE,KAAK;gCACrB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;oCAAE,OAAO,KAAK,CAAC;gCACrD,MAAM,UAAU,GAAG,KAAmB,CAAC;gCACvC,IACE,CAAC,UAAU,CAAC,SAAS;oCACrB,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC;wCACzC,UAAU,CAAC,SAAS,KAAK,6BAA6B,CAAC,EACzD,CAAC;oCACD,OAAO,KAAK,CAAC;gCACf,CAAC;gCACD,KAAK,CAAC,cAAc,EAAE,CAAC;gCACvB,OAAO,IAAI,CAAC;4BACd,CAAC;yBACF;qBACF;iBACF,CAAC;aACH,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { IconPencil } from \"@tabler/icons-react\";\nimport {\n NodeSelection,\n Plugin,\n PluginKey,\n type EditorState,\n} from \"@tiptap/pm/state\";\nimport {\n Node,\n NodeViewWrapper,\n ReactNodeViewRenderer,\n mergeAttributes,\n type NodeViewProps,\n} from \"@tiptap/react\";\nimport {\n createContext,\n useEffect,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n type MouseEvent as ReactMouseEvent,\n} from \"react\";\n\nimport {\n blockEditSurface,\n useOptionalBlockRegistry,\n type BlockDataChangeMeta,\n type BlockRenderContext,\n} from \"../blocks/index.js\";\nimport { SchemaBlockEditor } from \"../blocks/SchemaBlockEditor.js\";\n\n/* -------------------------------------------------------------------------- */\n/* The generic registry-block side-map + Tiptap NodeView, lifted into core. */\n/* */\n/* This is the app-agnostic NodeView that renders registered block specs */\n/* inside a `SharedRichEditor` document. Hosts mount the node produced by */\n/* {@link createRegistryBlockNode} as an extra extension and wrap the editor */\n/* in a {@link RegistryBlockDataProvider}, sourcing the typed block `data` */\n/* from their own authoritative store (for example, PlanContent.blocks). The */\n/* node itself carries only lightweight identity attrs (type/id/title/summary) */\n/* plus an optional `__raw` verbatim-MDX attr for byte-stable source */\n/* round-trips; the heavy typed `data` is threaded through the side-map */\n/* context, keeping the doc small and the block data the single source of */\n/* truth. */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------------- */\n/* C. Block-data side-map context */\n/* -------------------------------------------------------------------------- */\n\n/** The minimal block shape the NodeView renders through `<BlockView>`. */\nexport interface RegistryBlockSideMapBlock {\n id: string;\n title?: string;\n summary?: string;\n data: unknown;\n}\n\n/**\n * The side-map an editor host supplies so the registry NodeView can resolve a\n * block's full typed `data` (and commit edits) by its stable id, without ever\n * storing that data in the ProseMirror doc.\n */\nexport interface RegistryBlockDataValue<\n TBlock extends RegistryBlockSideMapBlock = RegistryBlockSideMapBlock,\n> {\n /** Resolve a block's full record (incl. `data`) by its stable id. */\n getBlock: (blockId: string) => TBlock | undefined;\n /** Commit a new `data` value for a block (edit-mode only). */\n onBlockDataChange: (\n blockId: string,\n nextData: unknown,\n meta?: BlockDataChangeMeta,\n ) => void;\n /** Whether the document (and thus its blocks) is editable. */\n editable: boolean;\n /**\n * When true, blocks whose type has no Notion (NFM) analog are badged so the\n * author knows they won't sync. The host decides which types are incompatible\n * via {@link isNotionIncompatibleType}; this flag just toggles the badge on.\n */\n notionSync?: boolean;\n /**\n * Decide whether a block type is Notion-incompatible (no NFM analog). Only\n * consulted when {@link notionSync} is true. Injected by the host so the\n * single registry-level allowlist (plan's `isNotionCompatibleBlockType`, or\n * content's registry-derived gate) drives the badge — core stays policy-free.\n */\n isNotionIncompatibleType?: (blockType: string) => boolean;\n /**\n * Render a block whose type is NOT in the registry through the host's own\n * dispatcher (plan: `PlanBlockView` for decision / legacy visual-questions /\n * image; omitted in hosts with no legacy types), so every block type renders\n * in the document instead of a bare fallback.\n */\n renderLegacyBlock?: (\n block: TBlock,\n options: { editing: boolean },\n ) => ReactNode;\n /**\n * Optional: render a schema-driven (or otherwise custom) editor for a legacy\n * block in place of the raw-JSON fallback. Receives an `onChange` that commits\n * the block's new `data`. Return `null`/`undefined` to keep the JSON editor for\n * that block type. The returned editor is expected to autosave through\n * `onChange` (no Save button is shown), matching registered panel blocks.\n */\n renderLegacyBlockEditor?: (\n block: TBlock,\n args: { onChange: (nextData: unknown) => void },\n ) => ReactNode;\n /**\n * Return `true` for legacy block types that render their OWN edit affordance\n * inside `renderLegacyBlock` (e.g. an image block with its own hover toolbar).\n * For those types the node view renders the legacy block in edit mode and adds\n * NO separate corner edit surface (no pencil / JSON / form popover), so the\n * block owns a single, self-contained control overlay.\n */\n legacyBlockSelfEdits?: (blockType: string) => boolean;\n}\n\nconst RegistryBlockDataContext =\n createContext<RegistryBlockDataValue<any> | null>(null);\n\nexport function RegistryBlockDataProvider<\n TBlock extends RegistryBlockSideMapBlock = RegistryBlockSideMapBlock,\n>({\n value,\n children,\n}: {\n value: RegistryBlockDataValue<TBlock>;\n children: ReactNode;\n}) {\n return (\n <RegistryBlockDataContext.Provider value={value}>\n {children}\n </RegistryBlockDataContext.Provider>\n );\n}\n\n/** Read the registry block side-map. Returns `null` outside a provider. */\nexport function useRegistryBlockData<\n TBlock extends RegistryBlockSideMapBlock = RegistryBlockSideMapBlock,\n>(): RegistryBlockDataValue<TBlock> | null {\n return useContext(\n RegistryBlockDataContext,\n ) as RegistryBlockDataValue<TBlock> | null;\n}\n\nfunction clickedInteractiveChild(target: HTMLElement) {\n if (target.closest(\"button,input,textarea,select,a,[role='textbox']\")) {\n return true;\n }\n\n // The block drag-handle grip is a `role=\"button\"` div that lives in the editor\n // wrapper, and nested container blocks (columns/tabs) render their own inner\n // editors — each its own grip. A container block's `onMouseDownCapture`\n // selection handler runs in a SEPARATE React root (Tiptap mounts every node\n // view as its own root), so its `stopPropagation()` halts the NATIVE mousedown\n // right there, before it can reach an inner grip or inner editor. Treat the\n // grip and anything inside a nested editor region as interactive so the outer\n // container never hijacks a mousedown meant for inner machinery — this is what\n // makes dragging a block OUT of / BETWEEN columns (a nested grip) work at all.\n if (\n target.closest(\".drag-handle\") ||\n target.closest(\".plan-nested-document-editor-region\")\n ) {\n return true;\n }\n\n const blockNode = target.closest(\".plan-block-node\");\n const editable = target.closest(\"[contenteditable='true']\");\n return !!blockNode && !!editable && blockNode.contains(editable);\n}\n\n/* -------------------------------------------------------------------------- */\n/* B. RegistryBlockNodeView (React) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Renders one registry-block atom. The block is non-editable as far as\n * ProseMirror is concerned (`contentEditable={false}`); all interaction happens\n * inside the registry-driven `<BlockView>`. Read vs edit is toggled by\n * `props.selected` (the node is \"selected\" in the editor) AND the document being\n * editable. `data-plan-interactive` keeps existing host click-guards from\n * treating clicks inside the block as document clicks.\n */\nexport function RegistryBlockNodeView(props: NodeViewProps) {\n const blockType = String(props.node.attrs.blockType ?? \"\");\n const blockId = String(props.node.attrs.blockId ?? \"\");\n const [panelOpen, setPanelOpen] = useState(false);\n const [shellHovered, setShellHovered] = useState(false);\n\n const registryValue = useOptionalBlockRegistry();\n const sideMap = useRegistryBlockData();\n\n // Optimistic edit override. `onBlockDataChange` commits into the host's own\n // store (a ref the side-map context can't observe), so an edit does NOT\n // re-render this node — the new data only reaches the view on the next full\n // document reconcile, which lands after the autosave round-trip (seconds\n // later) and is skipped entirely when the host treats the save as its own\n // echo. That left quick toggles like the callout tone buttons visually frozen\n // until reload. Holding the just-edited data locally re-renders this one node\n // immediately, then releases once the authoritative block catches up to (or\n // moves past) the value the edit was based on.\n const [pendingEdit, setPendingEdit] = useState<{\n data: unknown;\n base: unknown;\n } | null>(null);\n const liveBlock = sideMap?.getBlock(blockId);\n const liveData = liveBlock?.data;\n useEffect(() => {\n if (pendingEdit && !Object.is(liveData, pendingEdit.base)) {\n setPendingEdit(null);\n }\n }, [liveData, pendingEdit]);\n const block =\n liveBlock && pendingEdit && Object.is(liveData, pendingEdit.base)\n ? { ...liveBlock, data: pendingEdit.data }\n : liveBlock;\n const commitBlockData = (nextData: unknown, meta?: BlockDataChangeMeta) => {\n setPendingEdit({ data: nextData, base: liveData });\n sideMap?.onBlockDataChange(blockId, nextData, meta);\n };\n const editable = sideMap?.editable ?? false;\n // In Notion-sync mode, flag blocks that have no Notion (NFM) analog so the\n // author sees what won't push. Prose blocks aren't registry-block nodes, so\n // this only ever covers structured blocks.\n const incompatibleWithNotion =\n (sideMap?.notionSync ?? false) &&\n (sideMap?.isNotionIncompatibleType?.(blockType) ?? false);\n\n // The block data isn't in the side-map yet (e.g. a freshly inserted node whose\n // store entry hasn't been seeded). Render a graceful placeholder.\n if (!block) {\n return (\n <NodeViewWrapper className=\"plan-block-node\" data-block-id={blockId}>\n <div\n contentEditable={false}\n data-plan-interactive\n className=\"plan-block-node__placeholder rounded-md border border-dashed border-border px-3 py-2 text-sm text-muted-foreground\"\n >\n {blockType ? `Loading ${blockType} block…` : \"Loading block…\"}\n </div>\n </NodeViewWrapper>\n );\n }\n\n const spec = registryValue?.registry.get(blockType);\n const selectNode = (event: ReactMouseEvent<HTMLElement>) => {\n if (!editable) return;\n const target = event.target;\n if (target instanceof HTMLElement && clickedInteractiveChild(target))\n return;\n const pos = typeof props.getPos === \"function\" ? props.getPos() : null;\n if (typeof pos !== \"number\") return;\n try {\n event.preventDefault();\n event.stopPropagation();\n const { view } = props.editor;\n view.dispatch(\n view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos)),\n );\n view.focus();\n } catch {\n // Ignore stale positions during React/ProseMirror reconciliation.\n }\n };\n const updateShellHover = (event: ReactMouseEvent<HTMLElement>) => {\n const target = event.target;\n setShellHovered(\n target instanceof HTMLElement &&\n target.closest(\".plan-block-node__shell\") === event.currentTarget,\n );\n };\n\n // Choose how to render the block body:\n // 1. Registered spec → read view by default; direct-manipulation specs\n // (`editSurface: \"inline\" | \"container\"`) render their editor in place,\n // read-only-in-edit-mode specs (`\"none\"`) keep their read view, while\n // artifact/config specs (`\"panel\"`) keep the read view plus a corner edit\n // button.\n // 2. No spec, but the side-map provides `renderLegacyBlock` → delegate to the\n // host's dispatcher (decision, legacy visual-questions, image, and any\n // other type rendered by a bespoke component rather than the registry), so\n // EVERY block type renders in the document exactly as it does in the\n // per-block reader — never a bare title fallback.\n // 3. Neither → a small non-crashing fallback.\n let body: ReactNode;\n let editSurface: ReactNode = null;\n if (registryValue && spec) {\n const blockData = (block as { data: unknown }).data;\n const Read = spec.Read;\n const readNode = (\n <Read\n data={blockData}\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={registryValue.ctx}\n />\n );\n body = readNode;\n const canEditBlock =\n editable &&\n spec.placement.includes(\"block\") &&\n !!sideMap?.onBlockDataChange;\n if (canEditBlock) {\n const Edit = spec.Edit;\n const editorNode = Edit ? (\n <Edit\n data={blockData}\n onChange={commitBlockData}\n editable\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={registryValue.ctx}\n />\n ) : (\n <SchemaBlockEditor\n data={blockData}\n onChange={(nextData) => commitBlockData(nextData)}\n schema={spec.schema}\n editable\n blockId={block.id}\n ctx={registryValue.ctx}\n />\n );\n const surface = blockEditSurface(spec);\n if (surface === \"panel\" && registryValue.ctx.renderEditSurface) {\n editSurface = registryValue.ctx.renderEditSurface({\n title: spec.label,\n open: panelOpen,\n onOpenChange: setPanelOpen,\n blockId: block.id,\n blockType,\n blockTitle: block.title,\n blockSummary: block.summary,\n blockData,\n trigger: (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Edit ${spec.label}`}\n onClick={() => setPanelOpen(true)}\n className=\"an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background/85 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100\"\n data-visible={panelOpen || shellHovered}\n >\n <IconPencil className=\"size-4\" />\n </button>\n ),\n children: editorNode,\n });\n } else if (surface === \"panel\") {\n editSurface = props.selected ? (\n <div className=\"mt-3\">{editorNode}</div>\n ) : null;\n } else if (surface !== \"none\") {\n body = editorNode;\n }\n }\n } else if (sideMap?.renderLegacyBlock) {\n // Self-editing legacy blocks (e.g. image) render their own edit affordance\n // inside their overlay, so render them in edit mode and add NO separate\n // corner edit surface — the block owns a single, self-contained overlay.\n const selfEdits =\n editable && Boolean(sideMap.legacyBlockSelfEdits?.(blockType));\n body = sideMap.renderLegacyBlock(block, { editing: selfEdits });\n if (editable && !selfEdits) {\n // Prefer a host-provided schema/custom editor (a real form) over the raw\n // JSON fallback when the host knows how to edit this legacy block type.\n const customEditor = sideMap.renderLegacyBlockEditor?.(block, {\n onChange: (nextData) => commitBlockData(nextData),\n });\n editSurface = (\n <LegacyJsonEditSurface\n block={block}\n open={panelOpen}\n onOpenChange={setPanelOpen}\n renderEditSurface={registryValue?.ctx.renderEditSurface}\n onChange={(nextBlock) => commitBlockData(nextBlock)}\n selected={shellHovered}\n customEditor={customEditor}\n />\n );\n }\n } else {\n body = (\n <div className=\"plan-block-node__fallback rounded-md border border-border px-3 py-2 text-sm text-muted-foreground\">\n {block.title || blockType || \"Unsupported block\"}\n </div>\n );\n }\n\n return (\n <NodeViewWrapper\n className=\"plan-block-node\"\n data-block-id={blockId}\n // Mirror the block type onto the wrapper so the document flow can detect a\n // RUN of consecutive blocks of the same type (e.g. api-endpoint) and\n // collapse the divider + gap between them, matching the read-only path.\n data-block-type={blockType || undefined}\n data-plan-block-selected={props.selected ? \"\" : undefined}\n data-notion-incompatible={incompatibleWithNotion ? \"\" : undefined}\n onMouseDownCapture={selectNode}\n >\n <div\n contentEditable={false}\n data-plan-interactive\n className=\"plan-block-node__shell relative\"\n onMouseEnter={updateShellHover}\n onMouseMove={updateShellHover}\n onMouseLeave={() => setShellHovered(false)}\n >\n {incompatibleWithNotion && (\n <span\n className=\"plan-block-notion-badge\"\n title=\"This block type has no Notion equivalent and won't sync to Notion.\"\n >\n Won't sync to Notion\n </span>\n )}\n {body}\n {editSurface && (\n <div className=\"plan-block-node__edit absolute right-2 top-2 z-20\">\n {editSurface}\n </div>\n )}\n </div>\n </NodeViewWrapper>\n );\n}\n\nexport function LegacyJsonEditSurface({\n block,\n open,\n onOpenChange,\n renderEditSurface,\n onChange,\n selected,\n customEditor,\n}: {\n block: RegistryBlockSideMapBlock;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n renderEditSurface?: BlockRenderContext[\"renderEditSurface\"];\n onChange: (nextData: unknown) => void;\n selected: boolean;\n /**\n * A host-provided form editor (e.g. {@link SchemaBlockEditor}). When present it\n * replaces the raw-JSON textarea + Save button; the form autosaves through its\n * own `onChange`.\n */\n customEditor?: ReactNode;\n}) {\n const serializedBlockData = useMemo(\n () => JSON.stringify(block.data, null, 2),\n [block.data],\n );\n const [draft, setDraft] = useState(serializedBlockData);\n const [parseError, setParseError] = useState<string | null>(null);\n\n useEffect(() => {\n setDraft(serializedBlockData);\n setParseError(null);\n }, [block.id, serializedBlockData]);\n\n const saveDraft = () => {\n try {\n const nextData = JSON.parse(draft) as unknown;\n setParseError(null);\n onChange(nextData);\n onOpenChange(false);\n } catch (error) {\n setParseError(\n error instanceof Error ? error.message : \"Invalid JSON data.\",\n );\n }\n };\n\n const trigger = (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Edit ${block.title ?? \"block\"}`}\n onClick={() => onOpenChange(true)}\n className=\"an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background/85 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100\"\n data-visible={selected || open}\n >\n <IconPencil className=\"size-4\" />\n </button>\n );\n const jsonEditor = (\n <div className=\"grid gap-3\">\n <textarea\n data-plan-interactive\n className=\"min-h-64 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={draft}\n aria-invalid={parseError ? true : undefined}\n onChange={(event) => {\n setDraft(event.target.value);\n if (parseError) setParseError(null);\n }}\n />\n {parseError ? (\n <p className=\"text-xs text-destructive\" role=\"alert\">\n Invalid JSON: {parseError}\n </p>\n ) : null}\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex h-8 items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground\"\n onClick={saveDraft}\n >\n Save\n </button>\n </div>\n </div>\n );\n const editor = customEditor ?? jsonEditor;\n if (!renderEditSurface) return open ? editor : trigger;\n return renderEditSurface({\n title: block.title ?? \"Block\",\n open,\n onOpenChange,\n blockId: block.id,\n blockType:\n typeof (block as { type?: unknown }).type === \"string\"\n ? ((block as unknown as { type: string }).type ?? \"\")\n : \"legacy\",\n blockTitle: block.title,\n blockSummary: block.summary,\n blockData: block.data,\n trigger,\n children: editor,\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* A. registry-block Tiptap node factory */\n/* -------------------------------------------------------------------------- */\n\n/** Options for {@link createRegistryBlockNode}. */\nexport interface CreateRegistryBlockNodeOptions {\n /**\n * The Tiptap node name (e.g. `\"planBlock\"`). Hosts that serialize the doc by\n * node name (plan's `plan-doc.ts` keys off `\"planBlock\"`) must pass the exact\n * name their serializer expects.\n */\n nodeName: string;\n /**\n * The HTML data-attribute that marks a serialized registry block on copy/paste\n * round-trip (e.g. `\"data-plan-block\"`).\n */\n dataTag: string;\n /**\n * Mint a fresh, unique block id for a given block type. Used by the dedupe\n * plugin to re-mint duplicate / missing ids (paste/duplicate). Plan passes\n * `createPlanBlockId`.\n */\n mintId: (blockType: string) => string;\n /** Node group (default `\"block\"`). */\n group?: string;\n}\n\n/**\n * Build the generic registry-block Tiptap atom node. Returns a Tiptap `Node`\n * that:\n * - carries identity attrs `blockType` / `blockId` / `title` / `summary`, a\n * `sourceBlockId` (set when a duplicate is re-minted, so the host can copy the\n * original block's data), and an optional `__raw` verbatim-MDX attr for\n * byte-stable source round-trips;\n * - is an atom + isolating + draggable block that renders through\n * {@link RegistryBlockNodeView} (via `ReactNodeViewRenderer`);\n * - installs a dedupe `appendTransaction` plugin that re-mints any duplicate or\n * empty `blockId` (the classic paste/duplicate case), preserving the original\n * block's id + side-map data and tagging its own transaction so it never\n * loops.\n */\nexport function createRegistryBlockNode(\n options: CreateRegistryBlockNodeOptions,\n) {\n const { nodeName, dataTag, mintId, group = \"block\" } = options;\n const dedupeKey = new PluginKey(`${nodeName}DedupeIds`);\n const keyboardGuardKey = new PluginKey(`${nodeName}KeyboardGuard`);\n\n /**\n * Collect every `blockId` currently present on this node type in a doc, with\n * the position of each node, so duplicate ids (from paste/duplicate) can be\n * detected and re-minted.\n */\n function collectEntries(state: EditorState): Array<{\n pos: number;\n blockType: string;\n blockId: string;\n sourceBlockId?: string;\n }> {\n const found: Array<{\n pos: number;\n blockType: string;\n blockId: string;\n sourceBlockId?: string;\n }> = [];\n state.doc.descendants((node, pos) => {\n if (node.type.name === nodeName) {\n found.push({\n pos,\n blockType: String(node.attrs.blockType ?? \"\"),\n blockId: String(node.attrs.blockId ?? \"\"),\n sourceBlockId:\n typeof node.attrs.sourceBlockId === \"string\"\n ? node.attrs.sourceBlockId\n : undefined,\n });\n }\n return true;\n });\n return found;\n }\n\n /**\n * Build a transaction that re-mints any duplicate / missing ids in `state`, or\n * `null` when nothing needs changing. Only the *later* duplicate (and any node\n * with an empty id) is re-minted, so the original keeps its id and side-map\n * data.\n */\n function buildDedupeTransaction(state: EditorState) {\n const entries = collectEntries(state);\n if (entries.length === 0) return null;\n\n const seen = new Set<string>();\n let tr = state.tr;\n let changed = false;\n\n for (const entry of entries) {\n const needsNewId = !entry.blockId || seen.has(entry.blockId);\n if (needsNewId) {\n const freshId = mintId(entry.blockType || \"block\");\n const node = state.doc.nodeAt(entry.pos);\n if (node) {\n tr = tr.setNodeMarkup(entry.pos, undefined, {\n ...node.attrs,\n blockId: freshId,\n sourceBlockId: entry.sourceBlockId || entry.blockId || null,\n });\n changed = true;\n }\n seen.add(freshId);\n } else {\n seen.add(entry.blockId);\n }\n }\n\n return changed ? tr.setMeta(dedupeKey, true) : null;\n }\n\n const selectedRegistryBlock = (state: EditorState) =>\n state.selection instanceof NodeSelection &&\n state.selection.node.type.name === nodeName;\n\n const isMutatingKey = (event: KeyboardEvent) => {\n if (event.altKey || event.ctrlKey || event.metaKey) return false;\n if (event.key === \"Enter\") return true;\n return event.key.length === 1;\n };\n\n return Node.create({\n name: nodeName,\n group,\n atom: true,\n draggable: true,\n selectable: true,\n isolating: true,\n\n addAttributes() {\n return {\n blockType: { default: \"\" },\n blockId: { default: \"\" },\n title: { default: null },\n summary: { default: null },\n sourceBlockId: { default: null },\n // Optional verbatim source for hosts that need byte-identical\n // source-format round-trips without React (server pull, hashing). Plan\n // never sets this.\n __raw: { default: null, rendered: false },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: `div[${dataTag}]`,\n getAttrs: (element) => {\n const node = element as HTMLElement;\n return {\n blockType: node.getAttribute(\"data-block-type\") || \"\",\n blockId: node.getAttribute(\"data-block-id\") || \"\",\n title: node.getAttribute(\"data-title\") || null,\n summary: node.getAttribute(\"data-summary\") || null,\n sourceBlockId: node.getAttribute(\"data-source-block-id\") || null,\n };\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n [dataTag]: \"\",\n \"data-block-type\": HTMLAttributes.blockType ?? \"\",\n \"data-block-id\": HTMLAttributes.blockId ?? \"\",\n \"data-title\": HTMLAttributes.title ?? undefined,\n \"data-summary\": HTMLAttributes.summary ?? undefined,\n \"data-source-block-id\": HTMLAttributes.sourceBlockId ?? undefined,\n }),\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(RegistryBlockNodeView);\n },\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: dedupeKey,\n appendTransaction(transactions, _oldState, newState) {\n // Ignore our own re-mint, and skip when nothing changed the doc.\n if (\n transactions.some((transaction) =>\n transaction.getMeta(dedupeKey),\n ) ||\n !transactions.some((transaction) => transaction.docChanged)\n ) {\n return null;\n }\n return buildDedupeTransaction(newState);\n },\n }),\n new Plugin({\n key: keyboardGuardKey,\n props: {\n handleClickOn(view, _pos, node, nodePos, event, direct) {\n if (node.type.name !== nodeName || !direct) return false;\n if (\n event.target instanceof HTMLElement &&\n clickedInteractiveChild(event.target)\n ) {\n return false;\n }\n event.preventDefault();\n view.dispatch(\n view.state.tr.setSelection(\n NodeSelection.create(view.state.doc, nodePos),\n ),\n );\n view.focus();\n return true;\n },\n handleKeyDown(view, event) {\n if (!selectedRegistryBlock(view.state) || !isMutatingKey(event))\n return false;\n event.preventDefault();\n return true;\n },\n handleTextInput(view) {\n return selectedRegistryBlock(view.state);\n },\n handlePaste(view, event) {\n if (!selectedRegistryBlock(view.state)) return false;\n event.preventDefault();\n return true;\n },\n handleDOMEvents: {\n beforeinput(view, event) {\n if (!selectedRegistryBlock(view.state)) return false;\n const inputEvent = event as InputEvent;\n if (\n !inputEvent.inputType ||\n (!inputEvent.inputType.startsWith(\"insert\") &&\n inputEvent.inputType !== \"formatSetBlockTextDirection\")\n ) {\n return false;\n }\n event.preventDefault();\n return true;\n },\n },\n },\n }),\n ];\n },\n });\n}\n"]}
1
+ {"version":3,"file":"RegistryBlockNode.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/RegistryBlockNode.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconPencil } from \"@tabler/icons-react\";\nimport {\n NodeSelection,\n Plugin,\n PluginKey,\n type EditorState,\n} from \"@tiptap/pm/state\";\nimport {\n Node,\n NodeViewWrapper,\n ReactNodeViewRenderer,\n mergeAttributes,\n type NodeViewProps,\n} from \"@tiptap/react\";\nimport {\n createContext,\n useEffect,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n type MouseEvent as ReactMouseEvent,\n} from \"react\";\n\nimport {\n blockEditSurface,\n useOptionalBlockRegistry,\n type BlockDataChangeMeta,\n type BlockRenderContext,\n} from \"../blocks/index.js\";\nimport { SchemaBlockEditor } from \"../blocks/SchemaBlockEditor.js\";\n\n/* -------------------------------------------------------------------------- */\n/* The generic registry-block side-map + Tiptap NodeView, lifted into core. */\n/* */\n/* This is the app-agnostic NodeView that renders registered block specs */\n/* inside a `SharedRichEditor` document. Hosts mount the node produced by */\n/* {@link createRegistryBlockNode} as an extra extension and wrap the editor */\n/* in a {@link RegistryBlockDataProvider}, sourcing the typed block `data` */\n/* from their own authoritative store (for example, PlanContent.blocks). The */\n/* node itself carries only lightweight identity attrs (type/id/title/summary) */\n/* plus an optional `__raw` verbatim-MDX attr for byte-stable source */\n/* round-trips; the heavy typed `data` is threaded through the side-map */\n/* context, keeping the doc small and the block data the single source of */\n/* truth. */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------------- */\n/* C. Block-data side-map context */\n/* -------------------------------------------------------------------------- */\n\n/** The minimal block shape the NodeView renders through `<BlockView>`. */\nexport interface RegistryBlockSideMapBlock {\n id: string;\n title?: string;\n summary?: string;\n data: unknown;\n}\n\n/**\n * The side-map an editor host supplies so the registry NodeView can resolve a\n * block's full typed `data` (and commit edits) by its stable id, without ever\n * storing that data in the ProseMirror doc.\n */\nexport interface RegistryBlockDataValue<\n TBlock extends RegistryBlockSideMapBlock = RegistryBlockSideMapBlock,\n> {\n /** Resolve a block's full record (incl. `data`) by its stable id. */\n getBlock: (blockId: string) => TBlock | undefined;\n /** Commit a new `data` value for a block (edit-mode only). */\n onBlockDataChange: (\n blockId: string,\n nextData: unknown,\n meta?: BlockDataChangeMeta,\n ) => void;\n /** Whether the document (and thus its blocks) is editable. */\n editable: boolean;\n /**\n * When true, blocks whose type has no Notion (NFM) analog are badged so the\n * author knows they won't sync. The host decides which types are incompatible\n * via {@link isNotionIncompatibleType}; this flag just toggles the badge on.\n */\n notionSync?: boolean;\n /**\n * Decide whether a block type is Notion-incompatible (no NFM analog). Only\n * consulted when {@link notionSync} is true. Injected by the host so the\n * single registry-level allowlist (plan's `isNotionCompatibleBlockType`, or\n * content's registry-derived gate) drives the badge — core stays policy-free.\n */\n isNotionIncompatibleType?: (blockType: string) => boolean;\n /**\n * Render a block whose type is NOT in the registry through the host's own\n * dispatcher (plan: `PlanBlockView` for decision / legacy visual-questions /\n * image; omitted in hosts with no legacy types), so every block type renders\n * in the document instead of a bare fallback.\n */\n renderLegacyBlock?: (\n block: TBlock,\n options: { editing: boolean },\n ) => ReactNode;\n /**\n * Optional: render a schema-driven (or otherwise custom) editor for a legacy\n * block in place of the raw-JSON fallback. Receives an `onChange` that commits\n * the block's new `data`. Return `null`/`undefined` to keep the JSON editor for\n * that block type. The returned editor is expected to autosave through\n * `onChange` (no Save button is shown), matching registered panel blocks.\n */\n renderLegacyBlockEditor?: (\n block: TBlock,\n args: { onChange: (nextData: unknown) => void },\n ) => ReactNode;\n /**\n * Return `true` for legacy block types that render their OWN edit affordance\n * inside `renderLegacyBlock` (e.g. an image block with its own hover toolbar).\n * For those types the node view renders the legacy block in edit mode and adds\n * NO separate corner edit surface (no pencil / JSON / form popover), so the\n * block owns a single, self-contained control overlay.\n */\n legacyBlockSelfEdits?: (blockType: string) => boolean;\n}\n\nconst RegistryBlockDataContext =\n createContext<RegistryBlockDataValue<any> | null>(null);\n\nexport function RegistryBlockDataProvider<\n TBlock extends RegistryBlockSideMapBlock = RegistryBlockSideMapBlock,\n>({\n value,\n children,\n}: {\n value: RegistryBlockDataValue<TBlock>;\n children: ReactNode;\n}) {\n return (\n <RegistryBlockDataContext.Provider value={value}>\n {children}\n </RegistryBlockDataContext.Provider>\n );\n}\n\n/** Read the registry block side-map. Returns `null` outside a provider. */\nexport function useRegistryBlockData<\n TBlock extends RegistryBlockSideMapBlock = RegistryBlockSideMapBlock,\n>(): RegistryBlockDataValue<TBlock> | null {\n return useContext(\n RegistryBlockDataContext,\n ) as RegistryBlockDataValue<TBlock> | null;\n}\n\nfunction clickedInteractiveChild(target: HTMLElement) {\n if (target.closest(\"button,input,textarea,select,a,[role='textbox']\")) {\n return true;\n }\n\n // The block drag-handle grip is a `role=\"button\"` div that lives in the editor\n // wrapper, and nested container blocks (columns/tabs) render their own inner\n // editors — each its own grip. A container block's `onMouseDownCapture`\n // selection handler runs in a SEPARATE React root (Tiptap mounts every node\n // view as its own root), so its `stopPropagation()` halts the NATIVE mousedown\n // right there, before it can reach an inner grip or inner editor. Treat the\n // grip and anything inside a nested editor region as interactive so the outer\n // container never hijacks a mousedown meant for inner machinery — this is what\n // makes dragging a block OUT of / BETWEEN columns (a nested grip) work at all.\n if (\n target.closest(\".drag-handle\") ||\n target.closest(\".plan-nested-document-editor-region\")\n ) {\n return true;\n }\n\n const blockNode = target.closest(\".plan-block-node\");\n const editable = target.closest(\"[contenteditable='true']\");\n return !!blockNode && !!editable && blockNode.contains(editable);\n}\n\n/* -------------------------------------------------------------------------- */\n/* B. RegistryBlockNodeView (React) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Renders one registry-block atom. The block is non-editable as far as\n * ProseMirror is concerned (`contentEditable={false}`); all interaction happens\n * inside the registry-driven `<BlockView>`. Read vs edit is toggled by\n * `props.selected` (the node is \"selected\" in the editor) AND the document being\n * editable. `data-plan-interactive` keeps existing host click-guards from\n * treating clicks inside the block as document clicks.\n */\nexport function RegistryBlockNodeView(props: NodeViewProps) {\n const blockType = String(props.node.attrs.blockType ?? \"\");\n const blockId = String(props.node.attrs.blockId ?? \"\");\n const [panelOpen, setPanelOpen] = useState(false);\n const [shellHovered, setShellHovered] = useState(false);\n\n const registryValue = useOptionalBlockRegistry();\n const sideMap = useRegistryBlockData();\n\n // Optimistic edit override. `onBlockDataChange` commits into the host's own\n // store (a ref the side-map context can't observe), so an edit does NOT\n // re-render this node — the new data only reaches the view on the next full\n // document reconcile, which lands after the autosave round-trip (seconds\n // later) and is skipped entirely when the host treats the save as its own\n // echo. That left quick toggles like the callout tone buttons visually frozen\n // until reload. Holding the just-edited data locally re-renders this one node\n // immediately, then releases once the authoritative block catches up to (or\n // moves past) the value the edit was based on.\n const [pendingEdit, setPendingEdit] = useState<{\n data: unknown;\n base: unknown;\n } | null>(null);\n const liveBlock = sideMap?.getBlock(blockId);\n const liveData = liveBlock?.data;\n useEffect(() => {\n if (pendingEdit && !Object.is(liveData, pendingEdit.base)) {\n setPendingEdit(null);\n }\n }, [liveData, pendingEdit]);\n const block =\n liveBlock && pendingEdit && Object.is(liveData, pendingEdit.base)\n ? { ...liveBlock, data: pendingEdit.data }\n : liveBlock;\n const commitBlockData = (nextData: unknown, meta?: BlockDataChangeMeta) => {\n setPendingEdit({ data: nextData, base: liveData });\n sideMap?.onBlockDataChange(blockId, nextData, meta);\n };\n const editable = sideMap?.editable ?? false;\n // In Notion-sync mode, flag blocks that have no Notion (NFM) analog so the\n // author sees what won't push. Prose blocks aren't registry-block nodes, so\n // this only ever covers structured blocks.\n const incompatibleWithNotion =\n (sideMap?.notionSync ?? false) &&\n (sideMap?.isNotionIncompatibleType?.(blockType) ?? false);\n\n // The block data isn't in the side-map yet (e.g. a freshly inserted node whose\n // store entry hasn't been seeded). Render a graceful placeholder.\n if (!block) {\n return (\n <NodeViewWrapper className=\"plan-block-node\" data-block-id={blockId}>\n <div\n contentEditable={false}\n data-plan-interactive\n className=\"plan-block-node__placeholder rounded-md border border-dashed border-border px-3 py-2 text-sm text-muted-foreground\"\n >\n {blockType ? `Loading ${blockType} block…` : \"Loading block…\"}\n </div>\n </NodeViewWrapper>\n );\n }\n\n const spec = registryValue?.registry.get(blockType);\n const selectNode = (event: ReactMouseEvent<HTMLElement>) => {\n if (!editable) return;\n const target = event.target;\n if (target instanceof HTMLElement && clickedInteractiveChild(target))\n return;\n const pos = typeof props.getPos === \"function\" ? props.getPos() : null;\n if (typeof pos !== \"number\") return;\n try {\n event.preventDefault();\n event.stopPropagation();\n const { view } = props.editor;\n view.dispatch(\n view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos)),\n );\n view.focus();\n } catch {\n // Ignore stale positions during React/ProseMirror reconciliation.\n }\n };\n const updateShellHover = (event: ReactMouseEvent<HTMLElement>) => {\n const target = event.target;\n setShellHovered(\n target instanceof HTMLElement &&\n target.closest(\".plan-block-node__shell\") === event.currentTarget,\n );\n };\n\n // Choose how to render the block body:\n // 1. Registered spec → read view by default; direct-manipulation specs\n // (`editSurface: \"inline\" | \"container\"`) render their editor in place,\n // read-only-in-edit-mode specs (`\"none\"`) keep their read view, while\n // artifact/config specs (`\"panel\"`) keep the read view plus a corner edit\n // button.\n // 2. No spec, but the side-map provides `renderLegacyBlock` → delegate to the\n // host's dispatcher (decision, legacy visual-questions, image, and any\n // other type rendered by a bespoke component rather than the registry), so\n // EVERY block type renders in the document exactly as it does in the\n // per-block reader — never a bare title fallback.\n // 3. Neither → a small non-crashing fallback.\n let body: ReactNode;\n let editSurface: ReactNode = null;\n if (registryValue && spec) {\n const blockData = (block as { data: unknown }).data;\n const Read = spec.Read;\n const readNode = (\n <Read\n data={blockData}\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={registryValue.ctx}\n />\n );\n body = readNode;\n const canEditBlock =\n editable &&\n spec.placement.includes(\"block\") &&\n !!sideMap?.onBlockDataChange;\n if (canEditBlock) {\n const Edit = spec.Edit;\n const editorNode = Edit ? (\n <Edit\n data={blockData}\n onChange={commitBlockData}\n editable\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={registryValue.ctx}\n />\n ) : (\n <SchemaBlockEditor\n data={blockData}\n onChange={(nextData) => commitBlockData(nextData)}\n schema={spec.schema}\n editable\n blockId={block.id}\n ctx={registryValue.ctx}\n />\n );\n const surface = blockEditSurface(spec);\n if (surface === \"panel\" && registryValue.ctx.renderEditSurface) {\n editSurface = registryValue.ctx.renderEditSurface({\n title: spec.label,\n open: panelOpen,\n onOpenChange: setPanelOpen,\n blockId: block.id,\n blockType,\n blockTitle: block.title,\n blockSummary: block.summary,\n blockData,\n trigger: (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Edit ${spec.label}`}\n onClick={() => setPanelOpen(true)}\n className=\"an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100\"\n data-visible={panelOpen || shellHovered}\n >\n <IconPencil className=\"size-4\" />\n </button>\n ),\n children: editorNode,\n });\n } else if (surface === \"panel\") {\n editSurface = props.selected ? (\n <div className=\"mt-3\">{editorNode}</div>\n ) : null;\n } else if (surface !== \"none\") {\n body = editorNode;\n }\n }\n } else if (sideMap?.renderLegacyBlock) {\n // Self-editing legacy blocks (e.g. image) render their own edit affordance\n // inside their overlay, so render them in edit mode and add NO separate\n // corner edit surface — the block owns a single, self-contained overlay.\n const selfEdits =\n editable && Boolean(sideMap.legacyBlockSelfEdits?.(blockType));\n body = sideMap.renderLegacyBlock(block, { editing: selfEdits });\n if (editable && !selfEdits) {\n // Prefer a host-provided schema/custom editor (a real form) over the raw\n // JSON fallback when the host knows how to edit this legacy block type.\n const customEditor = sideMap.renderLegacyBlockEditor?.(block, {\n onChange: (nextData) => commitBlockData(nextData),\n });\n editSurface = (\n <LegacyJsonEditSurface\n block={block}\n open={panelOpen}\n onOpenChange={setPanelOpen}\n renderEditSurface={registryValue?.ctx.renderEditSurface}\n onChange={(nextBlock) => commitBlockData(nextBlock)}\n selected={shellHovered}\n customEditor={customEditor}\n />\n );\n }\n } else {\n body = (\n <div className=\"plan-block-node__fallback rounded-md border border-border px-3 py-2 text-sm text-muted-foreground\">\n {block.title || blockType || \"Unsupported block\"}\n </div>\n );\n }\n\n return (\n <NodeViewWrapper\n className=\"plan-block-node\"\n data-block-id={blockId}\n // Mirror the block type onto the wrapper so the document flow can detect a\n // RUN of consecutive blocks of the same type (e.g. api-endpoint) and\n // collapse the divider + gap between them, matching the read-only path.\n data-block-type={blockType || undefined}\n data-plan-block-selected={props.selected ? \"\" : undefined}\n data-notion-incompatible={incompatibleWithNotion ? \"\" : undefined}\n onMouseDownCapture={selectNode}\n >\n <div\n contentEditable={false}\n data-plan-interactive\n className=\"plan-block-node__shell relative\"\n onMouseEnter={updateShellHover}\n onMouseMove={updateShellHover}\n onMouseLeave={() => setShellHovered(false)}\n >\n {incompatibleWithNotion && (\n <span\n className=\"plan-block-notion-badge\"\n title=\"This block type has no Notion equivalent and won't sync to Notion.\"\n >\n Won't sync to Notion\n </span>\n )}\n {body}\n {editSurface && (\n <div className=\"plan-block-node__edit absolute right-2 top-2 z-20\">\n {editSurface}\n </div>\n )}\n </div>\n </NodeViewWrapper>\n );\n}\n\nexport function LegacyJsonEditSurface({\n block,\n open,\n onOpenChange,\n renderEditSurface,\n onChange,\n selected,\n customEditor,\n}: {\n block: RegistryBlockSideMapBlock;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n renderEditSurface?: BlockRenderContext[\"renderEditSurface\"];\n onChange: (nextData: unknown) => void;\n selected: boolean;\n /**\n * A host-provided form editor (e.g. {@link SchemaBlockEditor}). When present it\n * replaces the raw-JSON textarea + Save button; the form autosaves through its\n * own `onChange`.\n */\n customEditor?: ReactNode;\n}) {\n const serializedBlockData = useMemo(\n () => JSON.stringify(block.data, null, 2),\n [block.data],\n );\n const [draft, setDraft] = useState(serializedBlockData);\n const [parseError, setParseError] = useState<string | null>(null);\n\n useEffect(() => {\n setDraft(serializedBlockData);\n setParseError(null);\n }, [block.id, serializedBlockData]);\n\n const saveDraft = () => {\n try {\n const nextData = JSON.parse(draft) as unknown;\n setParseError(null);\n onChange(nextData);\n onOpenChange(false);\n } catch (error) {\n setParseError(\n error instanceof Error ? error.message : \"Invalid JSON data.\",\n );\n }\n };\n\n const trigger = (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Edit ${block.title ?? \"block\"}`}\n onClick={() => onOpenChange(true)}\n className=\"an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100\"\n data-visible={selected || open}\n >\n <IconPencil className=\"size-4\" />\n </button>\n );\n const jsonEditor = (\n <div className=\"grid gap-3\">\n <textarea\n data-plan-interactive\n className=\"min-h-64 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={draft}\n aria-invalid={parseError ? true : undefined}\n onChange={(event) => {\n setDraft(event.target.value);\n if (parseError) setParseError(null);\n }}\n />\n {parseError ? (\n <p className=\"text-xs text-destructive\" role=\"alert\">\n Invalid JSON: {parseError}\n </p>\n ) : null}\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex h-8 items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground\"\n onClick={saveDraft}\n >\n Save\n </button>\n </div>\n </div>\n );\n const editor = customEditor ?? jsonEditor;\n if (!renderEditSurface) return open ? editor : trigger;\n return renderEditSurface({\n title: block.title ?? \"Block\",\n open,\n onOpenChange,\n blockId: block.id,\n blockType:\n typeof (block as { type?: unknown }).type === \"string\"\n ? ((block as unknown as { type: string }).type ?? \"\")\n : \"legacy\",\n blockTitle: block.title,\n blockSummary: block.summary,\n blockData: block.data,\n trigger,\n children: editor,\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* A. registry-block Tiptap node factory */\n/* -------------------------------------------------------------------------- */\n\n/** Options for {@link createRegistryBlockNode}. */\nexport interface CreateRegistryBlockNodeOptions {\n /**\n * The Tiptap node name (e.g. `\"planBlock\"`). Hosts that serialize the doc by\n * node name (plan's `plan-doc.ts` keys off `\"planBlock\"`) must pass the exact\n * name their serializer expects.\n */\n nodeName: string;\n /**\n * The HTML data-attribute that marks a serialized registry block on copy/paste\n * round-trip (e.g. `\"data-plan-block\"`).\n */\n dataTag: string;\n /**\n * Mint a fresh, unique block id for a given block type. Used by the dedupe\n * plugin to re-mint duplicate / missing ids (paste/duplicate). Plan passes\n * `createPlanBlockId`.\n */\n mintId: (blockType: string) => string;\n /** Node group (default `\"block\"`). */\n group?: string;\n}\n\n/**\n * Build the generic registry-block Tiptap atom node. Returns a Tiptap `Node`\n * that:\n * - carries identity attrs `blockType` / `blockId` / `title` / `summary`, a\n * `sourceBlockId` (set when a duplicate is re-minted, so the host can copy the\n * original block's data), and an optional `__raw` verbatim-MDX attr for\n * byte-stable source round-trips;\n * - is an atom + isolating + draggable block that renders through\n * {@link RegistryBlockNodeView} (via `ReactNodeViewRenderer`);\n * - installs a dedupe `appendTransaction` plugin that re-mints any duplicate or\n * empty `blockId` (the classic paste/duplicate case), preserving the original\n * block's id + side-map data and tagging its own transaction so it never\n * loops.\n */\nexport function createRegistryBlockNode(\n options: CreateRegistryBlockNodeOptions,\n) {\n const { nodeName, dataTag, mintId, group = \"block\" } = options;\n const dedupeKey = new PluginKey(`${nodeName}DedupeIds`);\n const keyboardGuardKey = new PluginKey(`${nodeName}KeyboardGuard`);\n\n /**\n * Collect every `blockId` currently present on this node type in a doc, with\n * the position of each node, so duplicate ids (from paste/duplicate) can be\n * detected and re-minted.\n */\n function collectEntries(state: EditorState): Array<{\n pos: number;\n blockType: string;\n blockId: string;\n sourceBlockId?: string;\n }> {\n const found: Array<{\n pos: number;\n blockType: string;\n blockId: string;\n sourceBlockId?: string;\n }> = [];\n state.doc.descendants((node, pos) => {\n if (node.type.name === nodeName) {\n found.push({\n pos,\n blockType: String(node.attrs.blockType ?? \"\"),\n blockId: String(node.attrs.blockId ?? \"\"),\n sourceBlockId:\n typeof node.attrs.sourceBlockId === \"string\"\n ? node.attrs.sourceBlockId\n : undefined,\n });\n }\n return true;\n });\n return found;\n }\n\n /**\n * Build a transaction that re-mints any duplicate / missing ids in `state`, or\n * `null` when nothing needs changing. Only the *later* duplicate (and any node\n * with an empty id) is re-minted, so the original keeps its id and side-map\n * data.\n */\n function buildDedupeTransaction(state: EditorState) {\n const entries = collectEntries(state);\n if (entries.length === 0) return null;\n\n const seen = new Set<string>();\n let tr = state.tr;\n let changed = false;\n\n for (const entry of entries) {\n const needsNewId = !entry.blockId || seen.has(entry.blockId);\n if (needsNewId) {\n const freshId = mintId(entry.blockType || \"block\");\n const node = state.doc.nodeAt(entry.pos);\n if (node) {\n tr = tr.setNodeMarkup(entry.pos, undefined, {\n ...node.attrs,\n blockId: freshId,\n sourceBlockId: entry.sourceBlockId || entry.blockId || null,\n });\n changed = true;\n }\n seen.add(freshId);\n } else {\n seen.add(entry.blockId);\n }\n }\n\n return changed ? tr.setMeta(dedupeKey, true) : null;\n }\n\n const selectedRegistryBlock = (state: EditorState) =>\n state.selection instanceof NodeSelection &&\n state.selection.node.type.name === nodeName;\n\n const isMutatingKey = (event: KeyboardEvent) => {\n if (event.altKey || event.ctrlKey || event.metaKey) return false;\n if (event.key === \"Enter\") return true;\n return event.key.length === 1;\n };\n\n return Node.create({\n name: nodeName,\n group,\n atom: true,\n draggable: true,\n selectable: true,\n isolating: true,\n\n addAttributes() {\n return {\n blockType: { default: \"\" },\n blockId: { default: \"\" },\n title: { default: null },\n summary: { default: null },\n sourceBlockId: { default: null },\n // Optional verbatim source for hosts that need byte-identical\n // source-format round-trips without React (server pull, hashing). Plan\n // never sets this.\n __raw: { default: null, rendered: false },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: `div[${dataTag}]`,\n getAttrs: (element) => {\n const node = element as HTMLElement;\n return {\n blockType: node.getAttribute(\"data-block-type\") || \"\",\n blockId: node.getAttribute(\"data-block-id\") || \"\",\n title: node.getAttribute(\"data-title\") || null,\n summary: node.getAttribute(\"data-summary\") || null,\n sourceBlockId: node.getAttribute(\"data-source-block-id\") || null,\n };\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n [dataTag]: \"\",\n \"data-block-type\": HTMLAttributes.blockType ?? \"\",\n \"data-block-id\": HTMLAttributes.blockId ?? \"\",\n \"data-title\": HTMLAttributes.title ?? undefined,\n \"data-summary\": HTMLAttributes.summary ?? undefined,\n \"data-source-block-id\": HTMLAttributes.sourceBlockId ?? undefined,\n }),\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(RegistryBlockNodeView);\n },\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: dedupeKey,\n appendTransaction(transactions, _oldState, newState) {\n // Ignore our own re-mint, and skip when nothing changed the doc.\n if (\n transactions.some((transaction) =>\n transaction.getMeta(dedupeKey),\n ) ||\n !transactions.some((transaction) => transaction.docChanged)\n ) {\n return null;\n }\n return buildDedupeTransaction(newState);\n },\n }),\n new Plugin({\n key: keyboardGuardKey,\n props: {\n handleClickOn(view, _pos, node, nodePos, event, direct) {\n if (node.type.name !== nodeName || !direct) return false;\n if (\n event.target instanceof HTMLElement &&\n clickedInteractiveChild(event.target)\n ) {\n return false;\n }\n event.preventDefault();\n view.dispatch(\n view.state.tr.setSelection(\n NodeSelection.create(view.state.doc, nodePos),\n ),\n );\n view.focus();\n return true;\n },\n handleKeyDown(view, event) {\n if (!selectedRegistryBlock(view.state) || !isMutatingKey(event))\n return false;\n event.preventDefault();\n return true;\n },\n handleTextInput(view) {\n return selectedRegistryBlock(view.state);\n },\n handlePaste(view, event) {\n if (!selectedRegistryBlock(view.state)) return false;\n event.preventDefault();\n return true;\n },\n handleDOMEvents: {\n beforeinput(view, event) {\n if (!selectedRegistryBlock(view.state)) return false;\n const inputEvent = event as InputEvent;\n if (\n !inputEvent.inputType ||\n (!inputEvent.inputType.startsWith(\"insert\") &&\n inputEvent.inputType !== \"formatSetBlockTextDirection\")\n ) {\n return false;\n }\n event.preventDefault();\n return true;\n },\n },\n },\n }),\n ];\n },\n });\n}\n"]}
@@ -8,6 +8,8 @@ export interface ShareButtonProps {
8
8
  variant?: "compact" | "label";
9
9
  /** Optional trigger style. Defaults to the Google-Docs-style "Share" label. */
10
10
  trigger?: "label" | "icon";
11
+ /** Hide the visibility/share glyph in the label trigger. */
12
+ hideTriggerIcon?: boolean;
11
13
  /** Optional className applied to the trigger button. */
12
14
  triggerClassName?: string;
13
15
  /** Notified when the share popover opens or closes. Hosts that render the
@@ -1 +1 @@
1
- {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"AAeA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAiBf,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;oDACgD;IAChD,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;+EAE2E;IAC3E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;6DACyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;qEAEiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAChC;kEAC8D;IAC9D,iBAAiB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACrC;;;iBAGa;IACb,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAChC;;;8DAG0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,4DAA4D;IAC5D,4BAA4B,CAAC,EAAE,SAAS,CAAC;IACzC;;kDAE8C;IAC9C,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,oEAAoE;IACpE,8BAA8B,CAAC,EAAE,SAAS,CAAC;IAC3C,iEAAiE;IACjE,cAAc,CAAC,EAAE,OAAO,CACtB,MAAM,CAAC,UAAU,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAC7D,CAAC;IACF,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,SAAS,CAAC;IAC/B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;sBAEkB;IAClB,mBAAmB,CAAC,EAAE;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,SAAS,CAAC;QACxB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,CAAC;CACH;AAED,KAAK,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AA8F/C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BAiJlD"}
1
+ {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"AAeA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAiBf,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;oDACgD;IAChD,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;+EAE2E;IAC3E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;6DACyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;qEAEiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAChC;kEAC8D;IAC9D,iBAAiB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACrC;;;iBAGa;IACb,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAChC;;;8DAG0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,4DAA4D;IAC5D,4BAA4B,CAAC,EAAE,SAAS,CAAC;IACzC;;kDAE8C;IAC9C,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,oEAAoE;IACpE,8BAA8B,CAAC,EAAE,SAAS,CAAC;IAC3C,iEAAiE;IACjE,cAAc,CAAC,EAAE,OAAO,CACtB,MAAM,CAAC,UAAU,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAC7D,CAAC;IACF,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,SAAS,CAAC;IAC/B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;sBAEkB;IAClB,mBAAmB,CAAC,EAAE;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,SAAS,CAAC;QACxB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,CAAC;CACH;AAED,KAAK,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AA8F/C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BAoJlD"}
@@ -14,7 +14,7 @@ const BUTTON_BASE = "inline-flex items-center justify-center gap-2 whitespace-no
14
14
  const BUTTON_OUTLINE_SM = cn(BUTTON_BASE, "h-9 px-3 border border-[hsl(var(--sidebar-border,var(--input)))] bg-[hsl(var(--sidebar-background,var(--background)))] text-foreground hover:bg-[hsl(var(--sidebar-accent,var(--accent)))] hover:text-[hsl(var(--sidebar-accent-foreground,var(--accent-foreground)))]");
15
15
  const BUTTON_PRIMARY_SM = cn(BUTTON_BASE, "h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90");
16
16
  const BUTTON_GHOST_ICON = cn(BUTTON_BASE, "h-7 w-7 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground");
17
- const SHARE_POPOVER_SURFACE = "border-[hsl(var(--sidebar-border,var(--border)))] bg-[hsl(var(--sidebar-background,var(--popover)))]";
17
+ const SHARE_POPOVER_SURFACE = "border border-border bg-popover text-popover-foreground";
18
18
  const MEMBER_SUGGESTION_LIMIT = 25;
19
19
  const MEMBER_SEARCH_DEBOUNCE_MS = 140;
20
20
  const VIS_META = {
@@ -139,8 +139,9 @@ export function ShareButton(props) {
139
139
  : currentVisibility === "org"
140
140
  ? IconBuilding
141
141
  : IconLock;
142
+ const showTriggerIcon = iconOnly || !props.hideTriggerIcon;
142
143
  const TriggerIcon = iconOnly ? IconShare3 : VisibilityIcon;
143
- return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: cn(iconOnly ? BUTTON_GHOST_ICON : BUTTON_OUTLINE_SM, props.triggerClassName), "aria-label": iconOnly ? "Share" : undefined, children: [loaded || iconOnly ? (_jsx(TriggerIcon, { size: 16, strokeWidth: 1.75 })) : (_jsx("span", { "aria-hidden": true, className: "inline-block h-4 w-4 rounded-sm bg-muted animate-pulse" })), !iconOnly && _jsx("span", { children: "Share" })] }) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: cn("z-[2000] w-[min(460px,92vw)] rounded-lg p-4 shadow-lg", SHARE_POPOVER_SURFACE), onOpenAutoFocus: (e) => e.preventDefault(), children: _jsx(SharePanel, { ...props, sharesQuery: sharesQuery, visibilityOverride: pendingVisibility, onVisibilityChange: handleVisibilityChange, onClose: () => handleOpenChange(false) }) })] }));
144
+ return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: cn(iconOnly ? BUTTON_GHOST_ICON : BUTTON_OUTLINE_SM, props.triggerClassName), "aria-label": iconOnly ? "Share" : undefined, children: [showTriggerIcon ? (loaded || iconOnly ? (_jsx(TriggerIcon, { size: 16, strokeWidth: 1.75 })) : (_jsx("span", { "aria-hidden": true, className: "inline-block h-4 w-4 rounded-sm bg-muted animate-pulse" }))) : null, !iconOnly && _jsx("span", { children: "Share" })] }) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: cn("z-[2000] w-[min(460px,92vw)] rounded-lg p-4 shadow-lg", SHARE_POPOVER_SURFACE), onOpenAutoFocus: (e) => e.preventDefault(), children: _jsx(SharePanel, { ...props, sharesQuery: sharesQuery, visibilityOverride: pendingVisibility, onVisibilityChange: handleVisibilityChange, onClose: () => handleOpenChange(false) }) })] }));
144
145
  }
145
146
  function useOrgMemberSearch(query, enabled) {
146
147
  const search = query.trim();
@@ -505,7 +506,7 @@ function SharePanel(props) {
505
506
  : displayName(s.principalId, knownMembers) }), canManage ? (_jsx(RoleSelect, { value: s.role, onChange: (r) => handleChangeRole(s, r), disabled: inFlight.has(keyOf(s)), plain: true })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: cap(s.role) })), canManage ? (_jsx("button", { type: "button", "aria-label": "Remove", onClick: () => handleRemove(s), disabled: inFlight.has(keyOf(s)), className: BUTTON_GHOST_ICON, children: _jsx(IconTrash, { size: 14 }) })) : null] }, keyOf(s)))), !shares.length && !data?.ownerEmail ? (_jsx("li", { className: "px-1 py-1.5 text-sm text-muted-foreground", children: "No one has access yet." })) : null] }), _jsx("div", { className: "mb-2 text-sm font-semibold", children: generalAccessLabel }), _jsxs("div", { className: "mb-4 flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(meta.Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { value: visibility, onChange: handleVisibility, disabled: !canManage, visibilityCopy: props.visibilityCopy, allowPublic: policy.allowPublic }), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground", children: [_jsx("span", { children: meta.description }), visibility === "org" && props.hideInSearchControl ? (_jsx(AdvancedAccessPopover, { control: props.hideInSearchControl, canManage: canManage, onToggle: handleHideInSearch })) : null] })] })] }), props.accessNote ? (_jsx("div", { className: "mb-4 rounded-md border border-border bg-muted/35 p-3 text-xs text-muted-foreground", children: props.accessNote })) : null, showShareLinks && shareUrlPlacement === "bottom" ? shareLinks : null, _jsx("div", { className: "mt-2 flex justify-end", children: _jsx("button", { type: "button", onClick: handleDone, className: BUTTON_PRIMARY_SM, children: "Done" }) })] }));
506
507
  }
507
508
  function AdvancedAccessPopover({ control, canManage, onToggle, }) {
508
- return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", disabled: !canManage, className: "inline-flex items-center gap-1 rounded-sm px-1 py-0.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50", children: ["Advanced", _jsx(IconChevronDown, { size: 12, strokeWidth: 1.8 })] }) }), _jsx(PopoverContent, { align: "start", sideOffset: 6, onOpenAutoFocus: (event) => event.preventDefault(), className: cn("z-[2300] w-72 p-3 shadow-lg", SHARE_POPOVER_SURFACE), children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: "Advanced access" }), _jsx("div", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: "Control how organization access appears in search." })] }), _jsxs("button", { type: "button", role: "switch", "aria-checked": control.checked, disabled: !canManage || control.pending, onClick: onToggle, className: cn("flex w-full items-start gap-3 rounded-md border border-border/70 bg-background px-3 py-2.5 text-start transition-colors hover:bg-accent/45 disabled:cursor-not-allowed disabled:opacity-60", control.checked && "border-border bg-accent/35 text-foreground"), children: [_jsx("span", { "aria-hidden": true, className: cn("relative mt-0.5 inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border bg-muted-foreground/25 transition-colors", control.checked && "border-primary/70 bg-primary"), children: _jsx("span", { className: cn("ml-0.5 size-4 rounded-full bg-background shadow-sm transition-transform", control.checked && "translate-x-4") }) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex items-center gap-1.5 text-sm font-medium text-foreground", children: [_jsx(IconSearchOff, { size: 14, strokeWidth: 1.8 }), control.label ?? "Hide in search"] }), _jsx("span", { className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: control.description ??
509
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", disabled: !canManage, className: "inline-flex items-center gap-1 rounded-sm px-1 py-0.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50", children: ["Advanced", _jsx(IconChevronDown, { size: 12, strokeWidth: 1.8 })] }) }), _jsx(PopoverContent, { align: "start", sideOffset: 6, onOpenAutoFocus: (event) => event.preventDefault(), className: cn("z-[2300] w-72 p-3 shadow-lg", SHARE_POPOVER_SURFACE), children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: "Advanced access" }), _jsx("div", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: "Control how organization access appears in search." })] }), _jsxs("button", { type: "button", role: "switch", "aria-checked": control.checked, disabled: !canManage || control.pending, onClick: onToggle, className: cn("flex w-full items-start gap-3 rounded-md border border-border/70 bg-card px-3 py-2.5 text-start transition-colors hover:bg-accent/45 disabled:cursor-not-allowed disabled:opacity-60", control.checked && "border-border bg-accent/35 text-foreground"), children: [_jsx("span", { "aria-hidden": true, className: cn("relative mt-0.5 inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border bg-muted-foreground/25 transition-colors", control.checked && "border-primary/70 bg-primary"), children: _jsx("span", { className: cn("ml-0.5 size-4 rounded-full bg-popover shadow-sm transition-transform", control.checked && "translate-x-4") }) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex items-center gap-1.5 text-sm font-medium text-foreground", children: [_jsx(IconSearchOff, { size: 14, strokeWidth: 1.8 }), control.label ?? "Hide in search"] }), _jsx("span", { className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: control.description ??
509
510
  "People with the link can still open this." })] })] })] }) })] }));
510
511
  }
511
512
  function MemberAutocomplete({ value, open, onOpenChange, onValueChange, onSelectMember, onSubmit, placeholder, suggestions, search, }) {
@@ -596,7 +597,7 @@ function MemberAutocomplete({ value, open, onOpenChange, onValueChange, onSelect
596
597
  onOpenChange(false);
597
598
  }
598
599
  }, 0);
599
- }, onKeyDown: handleKeyDown, autoComplete: "off", className: "h-9 w-full min-w-0 rounded-md border border-input bg-background ps-8 pe-8 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background" }), search.isLoading ? (_jsx(IconLoader2, { "aria-hidden": true, size: 15, strokeWidth: 1.8, className: "pointer-events-none absolute end-2.5 top-1/2 -translate-y-1/2 animate-spin text-muted-foreground" })) : null] }) }), _jsx(PopoverContent, { align: "start", sideOffset: 4, onOpenAutoFocus: (event) => event.preventDefault(), className: cn("z-[2200] w-[var(--radix-popper-anchor-width)] min-w-[18rem] rounded-md p-1 shadow-lg", SHARE_POPOVER_SURFACE), children: _jsxs("div", { id: listboxId, role: "listbox", className: "max-h-56 overflow-y-auto overflow-x-hidden", onScroll: handleScroll, children: [suggestions.map((member, index) => {
600
+ }, onKeyDown: handleKeyDown, autoComplete: "off", className: "h-9 w-full min-w-0 rounded-md border border-input bg-card ps-8 pe-8 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background" }), search.isLoading ? (_jsx(IconLoader2, { "aria-hidden": true, size: 15, strokeWidth: 1.8, className: "pointer-events-none absolute end-2.5 top-1/2 -translate-y-1/2 animate-spin text-muted-foreground" })) : null] }) }), _jsx(PopoverContent, { align: "start", sideOffset: 4, onOpenAutoFocus: (event) => event.preventDefault(), className: cn("z-[2200] w-[var(--radix-popper-anchor-width)] min-w-[18rem] rounded-md p-1 shadow-lg", SHARE_POPOVER_SURFACE), children: _jsxs("div", { id: listboxId, role: "listbox", className: "max-h-56 overflow-y-auto overflow-x-hidden", onScroll: handleScroll, children: [suggestions.map((member, index) => {
600
601
  const active = index === activeIndex;
601
602
  return (_jsxs("div", { id: optionId(listboxId, index), role: "option", "aria-selected": active, onMouseDown: (event) => event.preventDefault(), onMouseEnter: () => setActiveIndex(index), onClick: () => chooseMember(member), className: cn("flex cursor-pointer select-none flex-col rounded-sm px-3 py-2 text-sm outline-none", active
602
603
  ? "bg-accent text-accent-foreground"
@@ -626,7 +627,7 @@ function CopyLinkField({ value, label = "Share link", description, }) {
626
627
  setCopied(false);
627
628
  }
628
629
  };
629
- return (_jsxs("div", { className: "mb-4", children: [_jsx("div", { className: "mb-2 text-sm font-semibold", children: label }), description ? (_jsx("div", { className: "mb-2 text-xs text-muted-foreground", children: description })) : null, _jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("input", { readOnly: true, value: value, className: "h-9 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm text-muted-foreground outline-none", onFocus: (event) => event.currentTarget.select() }), _jsxs("button", { type: "button", onClick: handleCopy, className: "inline-flex h-9 shrink-0 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground hover:bg-accent", children: [copied ? _jsx(IconCheck, { size: 15 }) : _jsx(IconCopy, { size: 15 }), copied ? "Copied" : "Copy"] })] })] }));
630
+ return (_jsxs("div", { className: "mb-4", children: [_jsx("div", { className: "mb-2 text-sm font-semibold", children: label }), description ? (_jsx("div", { className: "mb-2 text-xs text-muted-foreground", children: description })) : null, _jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("input", { readOnly: true, value: value, className: "h-9 min-w-0 flex-1 rounded-md border border-input bg-card px-3 text-sm text-muted-foreground outline-none", onFocus: (event) => event.currentTarget.select() }), _jsxs("button", { type: "button", onClick: handleCopy, className: "inline-flex h-9 shrink-0 items-center gap-2 rounded-md border border-input bg-card px-3 text-sm font-medium text-foreground hover:bg-accent", children: [copied ? _jsx(IconCheck, { size: 15 }) : _jsx(IconCopy, { size: 15 }), copied ? "Copied" : "Copy"] })] })] }));
630
631
  }
631
632
  // ---------------------------------------------------------------------------
632
633
  // Radix Select wrappers styled like shadcn Select (no native <select> anywhere)
@@ -640,7 +641,7 @@ function RoleSelect(props) {
640
641
  const current = ROLE_OPTIONS.find((o) => o.value === props.value) ?? ROLE_OPTIONS[0];
641
642
  return (_jsxs(Select.Root, { value: props.value, onValueChange: (v) => props.onChange(v), disabled: props.disabled, children: [_jsxs(Select.Trigger, { className: props.plain
642
643
  ? cn(BUTTON_BASE, "h-7 px-2 bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground")
643
- : cn(BUTTON_BASE, "h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground"), "aria-label": "Role", children: [_jsx(Select.Value, { children: current.label }), _jsx(Select.Icon, { children: _jsx(IconChevronDown, { size: 14 }) })] }), _jsx(Select.Portal, { children: _jsx(Select.Content, { className: selectContentClass, position: "popper", sideOffset: 4, children: _jsx(Select.Viewport, { children: _jsx(SelectItems, { items: ROLE_OPTIONS }) }) }) })] }));
644
+ : cn(BUTTON_BASE, "h-9 px-3 border border-input bg-card hover:bg-accent hover:text-accent-foreground"), "aria-label": "Role", children: [_jsx(Select.Value, { children: current.label }), _jsx(Select.Icon, { children: _jsx(IconChevronDown, { size: 14 }) })] }), _jsx(Select.Portal, { children: _jsx(Select.Content, { className: selectContentClass, position: "popper", sideOffset: 4, children: _jsx(Select.Viewport, { children: _jsx(SelectItems, { items: ROLE_OPTIONS }) }) }) })] }));
644
645
  }
645
646
  function VisibilitySelect(props) {
646
647
  const allowPublic = props.allowPublic !== false;