@agent-native/core 0.37.3 → 0.39.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 (476) hide show
  1. package/README.md +19 -6
  2. package/dist/action.d.ts +60 -2
  3. package/dist/action.d.ts.map +1 -1
  4. package/dist/action.js +6 -2
  5. package/dist/action.js.map +1 -1
  6. package/dist/agent/production-agent.d.ts +12 -6
  7. package/dist/agent/production-agent.d.ts.map +1 -1
  8. package/dist/agent/production-agent.js +161 -11
  9. package/dist/agent/production-agent.js.map +1 -1
  10. package/dist/agent/types.d.ts +2 -0
  11. package/dist/agent/types.d.ts.map +1 -1
  12. package/dist/agent/types.js.map +1 -1
  13. package/dist/catalog.json +2 -2
  14. package/dist/cli/connect.d.ts.map +1 -1
  15. package/dist/cli/connect.js +15 -0
  16. package/dist/cli/connect.js.map +1 -1
  17. package/dist/cli/create.d.ts.map +1 -1
  18. package/dist/cli/create.js +8 -1
  19. package/dist/cli/create.js.map +1 -1
  20. package/dist/cli/index.js +10 -6
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/cli/plan-publish-store.d.ts +52 -0
  23. package/dist/cli/plan-publish-store.d.ts.map +1 -0
  24. package/dist/cli/plan-publish-store.js +103 -0
  25. package/dist/cli/plan-publish-store.js.map +1 -0
  26. package/dist/cli/skills.d.ts +30 -4
  27. package/dist/cli/skills.d.ts.map +1 -1
  28. package/dist/cli/skills.js +1240 -339
  29. package/dist/cli/skills.js.map +1 -1
  30. package/dist/cli/templates-meta.js +12 -12
  31. package/dist/cli/templates-meta.js.map +1 -1
  32. package/dist/client/AssistantChat.d.ts +3 -1
  33. package/dist/client/AssistantChat.d.ts.map +1 -1
  34. package/dist/client/AssistantChat.js +65 -15
  35. package/dist/client/AssistantChat.js.map +1 -1
  36. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  37. package/dist/client/MultiTabAssistantChat.js +20 -2
  38. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  39. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  40. package/dist/client/agent-chat-adapter.js +12 -0
  41. package/dist/client/agent-chat-adapter.js.map +1 -1
  42. package/dist/client/agent-engine-key.d.ts +24 -0
  43. package/dist/client/agent-engine-key.d.ts.map +1 -0
  44. package/dist/client/agent-engine-key.js +49 -0
  45. package/dist/client/agent-engine-key.js.map +1 -0
  46. package/dist/client/analytics.d.ts.map +1 -1
  47. package/dist/client/analytics.js +34 -0
  48. package/dist/client/analytics.js.map +1 -1
  49. package/dist/client/blocks/BlockView.d.ts +35 -0
  50. package/dist/client/blocks/BlockView.d.ts.map +1 -0
  51. package/dist/client/blocks/BlockView.js +45 -0
  52. package/dist/client/blocks/BlockView.js.map +1 -0
  53. package/dist/client/blocks/SchemaBlockEditor.d.ts +25 -0
  54. package/dist/client/blocks/SchemaBlockEditor.d.ts.map +1 -0
  55. package/dist/client/blocks/SchemaBlockEditor.js +165 -0
  56. package/dist/client/blocks/SchemaBlockEditor.js.map +1 -0
  57. package/dist/client/blocks/agent.d.ts +30 -0
  58. package/dist/client/blocks/agent.d.ts.map +1 -0
  59. package/dist/client/blocks/agent.js +61 -0
  60. package/dist/client/blocks/agent.js.map +1 -0
  61. package/dist/client/blocks/index.d.ts +51 -0
  62. package/dist/client/blocks/index.d.ts.map +1 -0
  63. package/dist/client/blocks/index.js +67 -0
  64. package/dist/client/blocks/index.js.map +1 -0
  65. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts +6 -0
  66. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -0
  67. package/dist/client/blocks/library/AnnotatedCodeBlock.js +135 -0
  68. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -0
  69. package/dist/client/blocks/library/ApiEndpointBlock.d.ts +20 -0
  70. package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -0
  71. package/dist/client/blocks/library/ApiEndpointBlock.js +131 -0
  72. package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -0
  73. package/dist/client/blocks/library/DataModelBlock.d.ts +28 -0
  74. package/dist/client/blocks/library/DataModelBlock.d.ts.map +1 -0
  75. package/dist/client/blocks/library/DataModelBlock.js +222 -0
  76. package/dist/client/blocks/library/DataModelBlock.js.map +1 -0
  77. package/dist/client/blocks/library/DiffBlock.d.ts +6 -0
  78. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -0
  79. package/dist/client/blocks/library/DiffBlock.js +293 -0
  80. package/dist/client/blocks/library/DiffBlock.js.map +1 -0
  81. package/dist/client/blocks/library/FileTreeBlock.d.ts +23 -0
  82. package/dist/client/blocks/library/FileTreeBlock.d.ts.map +1 -0
  83. package/dist/client/blocks/library/FileTreeBlock.js +225 -0
  84. package/dist/client/blocks/library/FileTreeBlock.js.map +1 -0
  85. package/dist/client/blocks/library/JsonExplorerBlock.d.ts +19 -0
  86. package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -0
  87. package/dist/client/blocks/library/JsonExplorerBlock.js +171 -0
  88. package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -0
  89. package/dist/client/blocks/library/MermaidBlock.d.ts +17 -0
  90. package/dist/client/blocks/library/MermaidBlock.d.ts.map +1 -0
  91. package/dist/client/blocks/library/MermaidBlock.js +131 -0
  92. package/dist/client/blocks/library/MermaidBlock.js.map +1 -0
  93. package/dist/client/blocks/library/OpenApiSpecBlock.d.ts +19 -0
  94. package/dist/client/blocks/library/OpenApiSpecBlock.d.ts.map +1 -0
  95. package/dist/client/blocks/library/OpenApiSpecBlock.js +494 -0
  96. package/dist/client/blocks/library/OpenApiSpecBlock.js.map +1 -0
  97. package/dist/client/blocks/library/annotated-code.config.d.ts +58 -0
  98. package/dist/client/blocks/library/annotated-code.config.d.ts.map +1 -0
  99. package/dist/client/blocks/library/annotated-code.config.js +53 -0
  100. package/dist/client/blocks/library/annotated-code.config.js.map +1 -0
  101. package/dist/client/blocks/library/api-endpoint.config.d.ts +71 -0
  102. package/dist/client/blocks/library/api-endpoint.config.d.ts.map +1 -0
  103. package/dist/client/blocks/library/api-endpoint.config.js +91 -0
  104. package/dist/client/blocks/library/api-endpoint.config.js.map +1 -0
  105. package/dist/client/blocks/library/checklist.config.d.ts +36 -0
  106. package/dist/client/blocks/library/checklist.config.d.ts.map +1 -0
  107. package/dist/client/blocks/library/checklist.config.js +25 -0
  108. package/dist/client/blocks/library/checklist.config.js.map +1 -0
  109. package/dist/client/blocks/library/checklist.d.ts +26 -0
  110. package/dist/client/blocks/library/checklist.d.ts.map +1 -0
  111. package/dist/client/blocks/library/checklist.js +78 -0
  112. package/dist/client/blocks/library/checklist.js.map +1 -0
  113. package/dist/client/blocks/library/code-tabs.config.d.ts +36 -0
  114. package/dist/client/blocks/library/code-tabs.config.d.ts.map +1 -0
  115. package/dist/client/blocks/library/code-tabs.config.js +30 -0
  116. package/dist/client/blocks/library/code-tabs.config.js.map +1 -0
  117. package/dist/client/blocks/library/code-tabs.d.ts +3 -0
  118. package/dist/client/blocks/library/code-tabs.d.ts.map +1 -0
  119. package/dist/client/blocks/library/code-tabs.js +165 -0
  120. package/dist/client/blocks/library/code-tabs.js.map +1 -0
  121. package/dist/client/blocks/library/data-model.config.d.ts +72 -0
  122. package/dist/client/blocks/library/data-model.config.d.ts.map +1 -0
  123. package/dist/client/blocks/library/data-model.config.js +59 -0
  124. package/dist/client/blocks/library/data-model.config.js.map +1 -0
  125. package/dist/client/blocks/library/dev-doc-ui.d.ts +49 -0
  126. package/dist/client/blocks/library/dev-doc-ui.d.ts.map +1 -0
  127. package/dist/client/blocks/library/dev-doc-ui.js +50 -0
  128. package/dist/client/blocks/library/dev-doc-ui.js.map +1 -0
  129. package/dist/client/blocks/library/diff.config.d.ts +41 -0
  130. package/dist/client/blocks/library/diff.config.d.ts.map +1 -0
  131. package/dist/client/blocks/library/diff.config.js +34 -0
  132. package/dist/client/blocks/library/diff.config.js.map +1 -0
  133. package/dist/client/blocks/library/file-tree.config.d.ts +59 -0
  134. package/dist/client/blocks/library/file-tree.config.d.ts.map +1 -0
  135. package/dist/client/blocks/library/file-tree.config.js +45 -0
  136. package/dist/client/blocks/library/file-tree.config.js.map +1 -0
  137. package/dist/client/blocks/library/html.config.d.ts +37 -0
  138. package/dist/client/blocks/library/html.config.d.ts.map +1 -0
  139. package/dist/client/blocks/library/html.config.js +46 -0
  140. package/dist/client/blocks/library/html.config.js.map +1 -0
  141. package/dist/client/blocks/library/html.d.ts +21 -0
  142. package/dist/client/blocks/library/html.d.ts.map +1 -0
  143. package/dist/client/blocks/library/html.js +72 -0
  144. package/dist/client/blocks/library/html.js.map +1 -0
  145. package/dist/client/blocks/library/json-explorer.config.d.ts +46 -0
  146. package/dist/client/blocks/library/json-explorer.config.d.ts.map +1 -0
  147. package/dist/client/blocks/library/json-explorer.config.js +28 -0
  148. package/dist/client/blocks/library/json-explorer.config.js.map +1 -0
  149. package/dist/client/blocks/library/mermaid.config.d.ts +32 -0
  150. package/dist/client/blocks/library/mermaid.config.d.ts.map +1 -0
  151. package/dist/client/blocks/library/mermaid.config.js +24 -0
  152. package/dist/client/blocks/library/mermaid.config.js.map +1 -0
  153. package/dist/client/blocks/library/openapi-spec.config.d.ts +49 -0
  154. package/dist/client/blocks/library/openapi-spec.config.d.ts.map +1 -0
  155. package/dist/client/blocks/library/openapi-spec.config.js +24 -0
  156. package/dist/client/blocks/library/openapi-spec.config.js.map +1 -0
  157. package/dist/client/blocks/library/server-specs.d.ts +35 -0
  158. package/dist/client/blocks/library/server-specs.d.ts.map +1 -0
  159. package/dist/client/blocks/library/server-specs.js +171 -0
  160. package/dist/client/blocks/library/server-specs.js.map +1 -0
  161. package/dist/client/blocks/library/specs.d.ts +29 -0
  162. package/dist/client/blocks/library/specs.d.ts.map +1 -0
  163. package/dist/client/blocks/library/specs.js +229 -0
  164. package/dist/client/blocks/library/specs.js.map +1 -0
  165. package/dist/client/blocks/library/table.config.d.ts +30 -0
  166. package/dist/client/blocks/library/table.config.d.ts.map +1 -0
  167. package/dist/client/blocks/library/table.config.js +22 -0
  168. package/dist/client/blocks/library/table.config.js.map +1 -0
  169. package/dist/client/blocks/library/table.d.ts +8 -0
  170. package/dist/client/blocks/library/table.d.ts.map +1 -0
  171. package/dist/client/blocks/library/table.js +109 -0
  172. package/dist/client/blocks/library/table.js.map +1 -0
  173. package/dist/client/blocks/library/tabs.config.d.ts +56 -0
  174. package/dist/client/blocks/library/tabs.config.d.ts.map +1 -0
  175. package/dist/client/blocks/library/tabs.config.js +36 -0
  176. package/dist/client/blocks/library/tabs.config.js.map +1 -0
  177. package/dist/client/blocks/library/tabs.d.ts +20 -0
  178. package/dist/client/blocks/library/tabs.d.ts.map +1 -0
  179. package/dist/client/blocks/library/tabs.js +123 -0
  180. package/dist/client/blocks/library/tabs.js.map +1 -0
  181. package/dist/client/blocks/mdx.d.ts +74 -0
  182. package/dist/client/blocks/mdx.d.ts.map +1 -0
  183. package/dist/client/blocks/mdx.js +205 -0
  184. package/dist/client/blocks/mdx.js.map +1 -0
  185. package/dist/client/blocks/provider.d.ts +25 -0
  186. package/dist/client/blocks/provider.d.ts.map +1 -0
  187. package/dist/client/blocks/provider.js +19 -0
  188. package/dist/client/blocks/provider.js.map +1 -0
  189. package/dist/client/blocks/registry.d.ts +32 -0
  190. package/dist/client/blocks/registry.d.ts.map +1 -0
  191. package/dist/client/blocks/registry.js +65 -0
  192. package/dist/client/blocks/registry.js.map +1 -0
  193. package/dist/client/blocks/schema-form/introspect.d.ts +31 -0
  194. package/dist/client/blocks/schema-form/introspect.d.ts.map +1 -0
  195. package/dist/client/blocks/schema-form/introspect.js +164 -0
  196. package/dist/client/blocks/schema-form/introspect.js.map +1 -0
  197. package/dist/client/blocks/server.d.ts +31 -0
  198. package/dist/client/blocks/server.d.ts.map +1 -0
  199. package/dist/client/blocks/server.js +41 -0
  200. package/dist/client/blocks/server.js.map +1 -0
  201. package/dist/client/blocks/types.d.ts +252 -0
  202. package/dist/client/blocks/types.d.ts.map +1 -0
  203. package/dist/client/blocks/types.js +5 -0
  204. package/dist/client/blocks/types.js.map +1 -0
  205. package/dist/client/composer/ComposerPlusMenu.js +10 -1
  206. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  207. package/dist/client/guided-questions.d.ts +68 -0
  208. package/dist/client/guided-questions.d.ts.map +1 -1
  209. package/dist/client/guided-questions.js +158 -3
  210. package/dist/client/guided-questions.js.map +1 -1
  211. package/dist/client/index.d.ts +6 -1
  212. package/dist/client/index.d.ts.map +1 -1
  213. package/dist/client/index.js +24 -1
  214. package/dist/client/index.js.map +1 -1
  215. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts +37 -0
  216. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +1 -0
  217. package/dist/client/rich-markdown-editor/BubbleToolbar.js +161 -0
  218. package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +1 -0
  219. package/dist/client/rich-markdown-editor/DragHandle.d.ts +52 -0
  220. package/dist/client/rich-markdown-editor/DragHandle.d.ts.map +1 -0
  221. package/dist/client/rich-markdown-editor/DragHandle.js +403 -0
  222. package/dist/client/rich-markdown-editor/DragHandle.js.map +1 -0
  223. package/dist/client/rich-markdown-editor/ImageExtension.d.ts +63 -0
  224. package/dist/client/rich-markdown-editor/ImageExtension.d.ts.map +1 -0
  225. package/dist/client/rich-markdown-editor/ImageExtension.js +242 -0
  226. package/dist/client/rich-markdown-editor/ImageExtension.js.map +1 -0
  227. package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts +97 -0
  228. package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts.map +1 -0
  229. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +214 -0
  230. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -0
  231. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +51 -0
  232. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts.map +1 -0
  233. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js +37 -0
  234. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js.map +1 -0
  235. package/dist/client/rich-markdown-editor/RunId.d.ts +28 -0
  236. package/dist/client/rich-markdown-editor/RunId.d.ts.map +1 -0
  237. package/dist/client/rich-markdown-editor/RunId.js +60 -0
  238. package/dist/client/rich-markdown-editor/RunId.js.map +1 -0
  239. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +85 -0
  240. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -0
  241. package/dist/client/rich-markdown-editor/SharedRichEditor.js +130 -0
  242. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -0
  243. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +36 -0
  244. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +1 -0
  245. package/dist/client/rich-markdown-editor/SlashCommandMenu.js +193 -0
  246. package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +1 -0
  247. package/dist/client/rich-markdown-editor/extensions.d.ts +166 -0
  248. package/dist/client/rich-markdown-editor/extensions.d.ts.map +1 -0
  249. package/dist/client/rich-markdown-editor/extensions.js +222 -0
  250. package/dist/client/rich-markdown-editor/extensions.js.map +1 -0
  251. package/dist/client/rich-markdown-editor/gfmDoc.d.ts +24 -0
  252. package/dist/client/rich-markdown-editor/gfmDoc.d.ts.map +1 -0
  253. package/dist/client/rich-markdown-editor/gfmDoc.js +83 -0
  254. package/dist/client/rich-markdown-editor/gfmDoc.js.map +1 -0
  255. package/dist/client/rich-markdown-editor/index.d.ts +14 -0
  256. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -0
  257. package/dist/client/rich-markdown-editor/index.js +14 -0
  258. package/dist/client/rich-markdown-editor/index.js.map +1 -0
  259. package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts +46 -0
  260. package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts.map +1 -0
  261. package/dist/client/rich-markdown-editor/registrySlashCommands.js +13 -0
  262. package/dist/client/rich-markdown-editor/registrySlashCommands.js.map +1 -0
  263. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts +18 -0
  264. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts.map +1 -0
  265. package/dist/client/rich-markdown-editor/uploadEditorImage.js +57 -0
  266. package/dist/client/rich-markdown-editor/uploadEditorImage.js.map +1 -0
  267. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +91 -0
  268. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -0
  269. package/dist/client/rich-markdown-editor/useCollabReconcile.js +375 -0
  270. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -0
  271. package/dist/client/track.d.ts +25 -0
  272. package/dist/client/track.d.ts.map +1 -0
  273. package/dist/client/track.js +53 -0
  274. package/dist/client/track.js.map +1 -0
  275. package/dist/client/use-action.d.ts.map +1 -1
  276. package/dist/client/use-action.js +6 -0
  277. package/dist/client/use-action.js.map +1 -1
  278. package/dist/client/use-session.d.ts +3 -2
  279. package/dist/client/use-session.d.ts.map +1 -1
  280. package/dist/client/use-session.js +3 -2
  281. package/dist/client/use-session.js.map +1 -1
  282. package/dist/deploy/build.d.ts +5 -0
  283. package/dist/deploy/build.d.ts.map +1 -1
  284. package/dist/deploy/build.js +67 -1
  285. package/dist/deploy/build.js.map +1 -1
  286. package/dist/extensions/schema.d.ts +1 -1
  287. package/dist/mcp/build-server.d.ts.map +1 -1
  288. package/dist/mcp/build-server.js +9 -2
  289. package/dist/mcp/build-server.js.map +1 -1
  290. package/dist/mcp/server.d.ts +1 -1
  291. package/dist/mcp/server.d.ts.map +1 -1
  292. package/dist/mcp/server.js +35 -2
  293. package/dist/mcp/server.js.map +1 -1
  294. package/dist/provider-api/index.d.ts +1 -1
  295. package/dist/provider-api/index.d.ts.map +1 -1
  296. package/dist/scripts/docs/search.d.ts.map +1 -1
  297. package/dist/scripts/docs/search.js +5 -2
  298. package/dist/scripts/docs/search.js.map +1 -1
  299. package/dist/scripts/runner.d.ts.map +1 -1
  300. package/dist/scripts/runner.js +16 -3
  301. package/dist/scripts/runner.js.map +1 -1
  302. package/dist/server/action-discovery.d.ts.map +1 -1
  303. package/dist/server/action-discovery.js +2 -0
  304. package/dist/server/action-discovery.js.map +1 -1
  305. package/dist/server/action-routes.d.ts.map +1 -1
  306. package/dist/server/action-routes.js +30 -4
  307. package/dist/server/action-routes.js.map +1 -1
  308. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  309. package/dist/server/agent-chat-plugin.js +65 -19
  310. package/dist/server/agent-chat-plugin.js.map +1 -1
  311. package/dist/server/agent-teams.d.ts.map +1 -1
  312. package/dist/server/agent-teams.js +8 -1
  313. package/dist/server/agent-teams.js.map +1 -1
  314. package/dist/server/agents-bundle.d.ts +27 -1
  315. package/dist/server/agents-bundle.d.ts.map +1 -1
  316. package/dist/server/agents-bundle.js +41 -3
  317. package/dist/server/agents-bundle.js.map +1 -1
  318. package/dist/server/auth.d.ts.map +1 -1
  319. package/dist/server/auth.js +76 -3
  320. package/dist/server/auth.js.map +1 -1
  321. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  322. package/dist/server/core-routes-plugin.js +60 -0
  323. package/dist/server/core-routes-plugin.js.map +1 -1
  324. package/dist/server/onboarding-html.d.ts.map +1 -1
  325. package/dist/server/onboarding-html.js +160 -22
  326. package/dist/server/onboarding-html.js.map +1 -1
  327. package/dist/server/sentry.d.ts.map +1 -1
  328. package/dist/server/sentry.js +6 -0
  329. package/dist/server/sentry.js.map +1 -1
  330. package/dist/server/social-og-image.d.ts +2 -1
  331. package/dist/server/social-og-image.d.ts.map +1 -1
  332. package/dist/server/social-og-image.js +24 -4
  333. package/dist/server/social-og-image.js.map +1 -1
  334. package/dist/sharing/schema.d.ts +1 -1
  335. package/dist/styles/agent-native.css +1 -0
  336. package/dist/styles/rich-markdown-editor.css +439 -0
  337. package/dist/templates/default/.agents/skills/actions/SKILL.md +4 -1
  338. package/dist/templates/default/.agents/skills/security/SKILL.md +13 -4
  339. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
  340. package/dist/templates/default/AGENTS.md +1 -0
  341. package/dist/templates/default/DEVELOPING.md +2 -0
  342. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
  343. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
  344. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
  345. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
  346. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
  347. package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
  348. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
  349. package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
  350. package/dist/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
  351. package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
  352. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
  353. package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
  354. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
  355. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
  356. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
  357. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
  358. package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
  359. package/dist/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
  360. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
  361. package/dist/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
  362. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
  363. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
  364. package/dist/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
  365. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
  366. package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
  367. package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
  368. package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
  369. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
  370. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
  371. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
  372. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
  373. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
  374. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
  375. package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
  376. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
  377. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
  378. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
  379. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
  380. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
  381. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
  382. package/dist/templates/workspace-core/AGENTS.md +5 -1
  383. package/dist/templates/workspace-root/AGENTS.md +5 -2
  384. package/dist/tracking/route.d.ts +43 -0
  385. package/dist/tracking/route.d.ts.map +1 -0
  386. package/dist/tracking/route.js +85 -0
  387. package/dist/tracking/route.js.map +1 -0
  388. package/dist/vite/client.d.ts.map +1 -1
  389. package/dist/vite/client.js +15 -0
  390. package/dist/vite/client.js.map +1 -1
  391. package/docs/content/a2a-protocol.md +18 -4
  392. package/docs/content/actions.md +87 -0
  393. package/docs/content/agent-mentions.md +2 -1
  394. package/docs/content/authentication.md +2 -1
  395. package/docs/content/client.md +64 -13
  396. package/docs/content/cloneable-saas.md +1 -1
  397. package/docs/content/code-agents-ui.md +17 -11
  398. package/docs/content/context-awareness.md +23 -28
  399. package/docs/content/creating-templates.md +1 -1
  400. package/docs/content/drop-in-agent.md +2 -0
  401. package/docs/content/getting-started.md +2 -2
  402. package/docs/content/key-concepts.md +2 -2
  403. package/docs/content/messaging.md +57 -15
  404. package/docs/content/migration-workbench.md +1 -1
  405. package/docs/content/multi-app-workspace.md +1 -1
  406. package/docs/content/multi-tenancy.md +17 -15
  407. package/docs/content/real-time-collaboration.md +1 -1
  408. package/docs/content/recurring-jobs.md +1 -1
  409. package/docs/content/security.md +2 -2
  410. package/docs/content/server.md +4 -4
  411. package/docs/content/skills-guide.md +30 -0
  412. package/docs/content/template-analytics.md +2 -2
  413. package/docs/content/template-assets.md +17 -1
  414. package/docs/content/template-brain.md +2 -2
  415. package/docs/content/template-calendar.md +1 -1
  416. package/docs/content/template-clips.md +3 -3
  417. package/docs/content/template-content.md +2 -2
  418. package/docs/content/template-design.md +2 -2
  419. package/docs/content/template-dispatch.md +3 -3
  420. package/docs/content/template-forms.md +14 -2
  421. package/docs/content/template-mail.md +1 -3
  422. package/docs/content/template-plan.md +133 -0
  423. package/docs/content/template-slides.md +5 -4
  424. package/docs/content/template-starter.md +4 -4
  425. package/docs/content/template-videos.md +6 -11
  426. package/docs/content/tracking.md +21 -1
  427. package/docs/content/visual-plans.md +74 -0
  428. package/docs/content/workspace.md +9 -9
  429. package/package.json +26 -11
  430. package/src/templates/default/.agents/skills/actions/SKILL.md +4 -1
  431. package/src/templates/default/.agents/skills/security/SKILL.md +13 -4
  432. package/src/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
  433. package/src/templates/default/AGENTS.md +1 -0
  434. package/src/templates/default/DEVELOPING.md +2 -0
  435. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
  436. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
  437. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
  438. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
  439. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
  440. package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
  441. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
  442. package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
  443. package/src/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
  444. package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
  445. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
  446. package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
  447. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
  448. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
  449. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
  450. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
  451. package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
  452. package/src/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
  453. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
  454. package/src/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
  455. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
  456. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
  457. package/src/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
  458. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
  459. package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
  460. package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
  461. package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
  462. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
  463. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
  464. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
  465. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
  466. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
  467. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
  468. package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
  469. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
  470. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
  471. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
  472. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
  473. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
  474. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
  475. package/src/templates/workspace-core/AGENTS.md +5 -1
  476. package/src/templates/workspace-root/AGENTS.md +5 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/extensions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Extension, Node, Mark } from \"@tiptap/core\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport type { StarterKitOptions } from \"@tiptap/starter-kit\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport Link from \"@tiptap/extension-link\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport { Table } from \"@tiptap/extension-table\";\nimport { TableRow } from \"@tiptap/extension-table-row\";\nimport { TableCell } from \"@tiptap/extension-table-cell\";\nimport { TableHeader } from \"@tiptap/extension-table-header\";\nimport { Markdown } from \"tiptap-markdown\";\nimport { CodeBlockLowlight } from \"@tiptap/extension-code-block-lowlight\";\nimport { createLowlight } from \"lowlight\";\nimport bash from \"highlight.js/lib/languages/bash\";\nimport css from \"highlight.js/lib/languages/css\";\nimport javascript from \"highlight.js/lib/languages/javascript\";\nimport json from \"highlight.js/lib/languages/json\";\nimport markdown from \"highlight.js/lib/languages/markdown\";\nimport python from \"highlight.js/lib/languages/python\";\nimport sql from \"highlight.js/lib/languages/sql\";\nimport typescript from \"highlight.js/lib/languages/typescript\";\nimport xml from \"highlight.js/lib/languages/xml\";\nimport yaml from \"highlight.js/lib/languages/yaml\";\nimport Collaboration from \"@tiptap/extension-collaboration\";\nimport CollaborationCaret from \"@tiptap/extension-collaboration-caret\";\n\n/**\n * Shared lowlight instance for the editor's syntax-highlighted code blocks. A\n * curated grammar set (aliases like ts/tsx, js/jsx, html, sh, py, yml, md come\n * for free from each grammar) keeps the editor bundle lean while matching the\n * languages the read-side Shiki surfaces (`code-tabs`) support. highlight.js is\n * synchronous, which is what a live ProseMirror editor needs — Shiki is async\n * and only used for read-only render paths.\n */\nconst codeLowlight = createLowlight({\n bash,\n css,\n javascript,\n json,\n markdown,\n python,\n sql,\n typescript,\n xml,\n yaml,\n});\nimport type { Doc as YDoc } from \"yjs\";\nimport type { Awareness } from \"y-protocols/awareness\";\nimport { createImageExtension, type ImageUploadFn } from \"./ImageExtension.js\";\n\n/**\n * Markdown dialect the editor parses/serializes.\n *\n * - `gfm` — GitHub-Flavored Markdown. No raw HTML passthrough. The byte-stable\n * serialization used by Plans (see RichMarkdownEditor.roundtrip.spec.ts).\n * - `nfm` — the Notion-Flavored Markdown superset used by the Content editor,\n * which opts into inline HTML so Notion-specific blocks round-trip.\n */\nexport type RichMarkdownDialect = \"gfm\" | \"nfm\";\n\n/**\n * Editor preset. Schema-neutral today (both presets share the base schema),\n * but threaded through so an app can branch schema/behavior per preset without\n * a new factory. The collab/markdown wiring is preset-independent.\n */\nexport type RichMarkdownEditorPreset = \"plan\" | \"content\";\n\n/** User info used to label this client's collaborative cursor. */\nexport interface RichMarkdownCollabUser {\n name: string;\n color: string;\n email?: string;\n}\n\n/** Optional collaborative-editing inputs for the shared editor. */\nexport interface SharedEditorCollab {\n /**\n * Yjs document for collaborative editing. When present the editor binds the\n * shared {@link Collaboration} (+ {@link CollaborationCaret} when awareness\n * is set) extensions and StarterKit's built-in undo/redo is disabled (Yjs\n * owns history). When absent the editor is a controlled `value`/`onChange`\n * editor.\n */\n ydoc?: YDoc | null;\n /** Shared awareness instance for live multi-user cursors. */\n awareness?: Awareness | null;\n /** Current user info for the collaborative cursor label. */\n user?: RichMarkdownCollabUser | null;\n}\n\n/** Toggle the optional base extensions on/off per app. All default to `true`. */\nexport interface SharedEditorFeatures {\n /** GFM pipe tables (Table + TableRow + TableHeader + TableCell). */\n tables?: boolean;\n /** Task / checklist lists (TaskList + TaskItem). */\n tasks?: boolean;\n /** Inline links (the `Link` mark). When off, links fall back to plain text. */\n link?: boolean;\n /** Fenced code blocks. Disabling lets an app inject its own code-block node. */\n codeBlock?: boolean;\n /**\n * The built-in {@link Placeholder} extension. Default `true`. Apps that need a\n * bespoke placeholder resolver (per-node-type labels, ancestor-aware text)\n * disable this and supply their own Placeholder via `extraExtensions`.\n */\n placeholder?: boolean;\n /**\n * The built-in dialect-keyed {@link Markdown} serializer. Default `true`.\n * Apps with a custom serializer (e.g. Content's NFM converter, which does NOT\n * round-trip through tiptap-markdown's storage) disable this and own the\n * serialize/parse pipeline themselves. The Markdown extension is still added\n * so paste/clipboard transforms work — disable it only when supplying your own\n * Markdown configuration via the {@link CreateSharedEditorExtensionsOptions.markdown}\n * option instead.\n */\n markdown?: boolean;\n /**\n * The shared block-level image node (`@tiptap/extension-image`). Default\n * `false` so existing embedders are unchanged. When `true`, images\n * serialize to GFM `![alt](src)` (source-syncable) and — when an\n * {@link CreateSharedEditorExtensionsOptions.onImageUpload} function is\n * supplied — paste / drop of local image files uploads through it. Content\n * leaves this off and injects its own richer image node via\n * `extraExtensions`, so the two never collide.\n */\n image?: boolean;\n}\n\nexport interface CreateSharedEditorExtensionsOptions {\n /** Markdown dialect; selects the keyed {@link Markdown} config. */\n dialect?: RichMarkdownDialect;\n /** Preset hook (schema-neutral today). */\n preset?: RichMarkdownEditorPreset;\n /** Empty-block placeholder text (headings get their own labels). */\n placeholder?: string;\n /** Toggle individual base extensions. */\n features?: SharedEditorFeatures;\n /**\n * Extra StarterKit options merged over the shared defaults. Lets an app turn\n * off StarterKit nodes it replaces (Content swaps in its own paragraph /\n * blockquote / code block) or pass a custom dropcursor, while still sharing\n * the rest of the StarterKit base + the collab undo/redo gating. The shared\n * defaults (`heading` levels 1-4, `link: false`, the default dropcursor, and\n * `undoRedo: false` in collab mode) are applied first and can be overridden\n * key-by-key here.\n */\n starterKit?: Partial<StarterKitOptions>;\n /**\n * Custom {@link Markdown} configuration. Replaces the dialect-keyed config from\n * {@link MARKDOWN_DIALECT_CONFIG} when provided. Only used when\n * `features.markdown !== false`; apps that own the whole markdown pipeline (no\n * tiptap-markdown serialization at all) should set `features.markdown: false`\n * and add their own configured Markdown extension via `extraExtensions`.\n */\n markdown?: Parameters<typeof Markdown.configure>[0];\n /**\n * App-specific extensions (Notion nodes, media, drag handles, comment\n * anchors, etc.) appended LAST so they bind over the shared base schema and\n * the optional Collaboration extensions still mount after them.\n */\n extraExtensions?: Array<Extension | Node | Mark>;\n /** Optional collaborative-editing wiring. */\n collab?: SharedEditorCollab | null;\n /**\n * Injectable image uploader for the shared image block. Only used when\n * `features.image` is on. Turns a picked / pasted / dropped image File into a\n * hosted `{ src, alt? }`. Plans pass `uploadEditorImage` (the framework\n * `upload-image` action). When omitted, the image block still renders and\n * round-trips `![alt](src)` markdown but cannot ingest local files.\n */\n onImageUpload?: ImageUploadFn | null;\n}\n\n/**\n * tiptap-markdown configuration, keyed by dialect. This is the single source of\n * truth for how each dialect parses/serializes markdown so the editor component\n * and the round-trip fidelity test can never drift apart.\n *\n * tiptap-markdown re-serializes the whole document on every edit, so the goal\n * for GFM is `serialize(parse(markdown)) === markdown` for the markdown plans\n * actually contain. We deliberately keep tiptap-markdown's own defaults\n * (`bulletListMarker: \"-\"`, `tightLists: true`, `linkify: false`,\n * `breaks: false`) because those produce the most byte-stable GFM. See\n * RichMarkdownEditor.roundtrip.spec.ts for the pinned corpus.\n *\n * NFM (Content) opts into inline HTML passthrough (`html: true`) so\n * Notion-specific blocks survive a markdown round-trip; the rest mirrors the\n * Content editor's existing `Markdown.configure` call.\n */\nexport const MARKDOWN_DIALECT_CONFIG: Record<\n RichMarkdownDialect,\n Parameters<typeof Markdown.configure>[0]\n> = {\n gfm: {\n // GFM plans are the common case and must never gain raw HTML as a second\n // representation.\n html: false,\n // Keep tiptap-markdown's defaults that minimise first-edit normalisation\n // churn (see roundtrip spec). Listed explicitly so the contract is\n // self-documenting rather than relying on the package defaults.\n bulletListMarker: \"-\",\n tightLists: true,\n linkify: false,\n breaks: false,\n transformPastedText: true,\n transformCopiedText: true,\n },\n nfm: {\n // NFM is a superset that allows inline HTML so Notion blocks round-trip.\n html: true,\n transformPastedText: true,\n transformCopiedText: true,\n },\n};\n\nconst DEFAULT_FEATURES: Required<SharedEditorFeatures> = {\n tables: true,\n tasks: true,\n link: true,\n codeBlock: true,\n placeholder: true,\n markdown: true,\n // Off by default: only Plans opt in today. Content injects its own richer\n // image node via `extraExtensions` and must not get a second `image` node.\n image: false,\n};\n\n/**\n * The ONE editor extension factory shared by every embedder (Plans today,\n * Content next). It assembles the base Tiptap schema (StarterKit + Placeholder\n * + Link + tasks + tables + code block), the dialect-keyed {@link Markdown}\n * serializer, the optional Collaboration stack, and finally any app-specific\n * `extraExtensions`.\n *\n * Ordering matters:\n * 1. Base schema (StarterKit first so its nodes/marks register; `starterKit`\n * overrides let an app disable replaced nodes / swap the dropcursor).\n * 2. dialect-keyed Markdown serializer (suppressible via `features.markdown`\n * for apps that own the whole serialize/parse pipeline, e.g. Content's NFM).\n * 3. `extraExtensions` (Notion/media/etc.) — appended before Collaboration so\n * apps can extend the schema and Collaboration still binds over the full\n * schema.\n * 4. Collaboration (+ CollaborationCaret) LAST so they bind over everything.\n *\n * Content (the NFM editor) drives this factory with `features.placeholder` and\n * `features.markdown` off, `features.tasks/tables/link` off where it ships its\n * own, a `starterKit` override disabling paragraph/blockquote/codeBlock, and all\n * Notion/media/fidelity nodes + its own Markdown(NFM)/Placeholder via\n * `extraExtensions` — so it shares the StarterKit base + the collab wiring while\n * owning its byte-identical NFM serializer.\n */\nexport function createSharedEditorExtensions({\n dialect = \"gfm\",\n // `preset` is accepted and forwarded for future preset-specific schema\n // branches; it is currently schema-neutral.\n preset: _preset = \"plan\",\n placeholder = \"Type '/' for commands...\",\n features,\n starterKit,\n markdown,\n extraExtensions = [],\n collab = null,\n onImageUpload = null,\n}: CreateSharedEditorExtensionsOptions = {}): Array<Extension | Node | Mark> {\n const feat = { ...DEFAULT_FEATURES, ...(features ?? {}) };\n const ydoc = collab?.ydoc ?? null;\n const awareness = collab?.awareness ?? null;\n const user = collab?.user ?? null;\n\n const exts: Array<Extension | Node | Mark> = [\n StarterKit.configure({\n heading: { levels: [1, 2, 3, 4] },\n link: false,\n // StarterKit's plain code block is always disabled; when enabled we add the\n // syntax-highlighting `CodeBlockLowlight` (same `codeBlock` node) below.\n codeBlock: false,\n dropcursor: { color: \"hsl(var(--ring))\", width: 2 },\n // Yjs owns undo/redo when Collaboration is active; the StarterKit history\n // plugin and the CRDT cannot both track undo without corrupting state.\n ...(ydoc ? { undoRedo: false } : {}),\n // App overrides last so embedders can disable replaced nodes (paragraph,\n // blockquote, code block) or swap the dropcursor while keeping the shared\n // base + the collab undo/redo gating above.\n ...(starterKit ?? {}),\n }),\n ];\n\n // Syntax-highlighted code block (replaces StarterKit's plain one) only when the\n // embedder opts in via `features.codeBlock`. Content disables it and ships its\n // own code node, so this affects Plans (and future opt-in apps) alone.\n if (feat.codeBlock) {\n exts.push(\n CodeBlockLowlight.configure({\n lowlight: codeLowlight,\n defaultLanguage: null,\n }),\n );\n }\n\n if (feat.placeholder) {\n exts.push(\n Placeholder.configure({\n placeholder: ({ node }) => {\n if (node.type.name === \"heading\") {\n const level = node.attrs.level;\n if (level === 1) return \"Heading 1\";\n if (level === 2) return \"Heading 2\";\n if (level === 3) return \"Heading 3\";\n return \"Heading 4\";\n }\n return placeholder;\n },\n showOnlyWhenEditable: true,\n showOnlyCurrent: true,\n }),\n );\n }\n\n if (feat.link) {\n exts.push(\n Link.configure({\n openOnClick: false,\n HTMLAttributes: { class: \"an-rich-md-link\" },\n }),\n );\n }\n\n if (feat.tasks) {\n exts.push(\n TaskList.configure({\n HTMLAttributes: { class: \"an-rich-md-task-list\" },\n }),\n TaskItem.configure({ nested: true }),\n );\n }\n\n if (feat.tables) {\n exts.push(\n Table.configure({\n resizable: false,\n HTMLAttributes: { class: \"an-rich-md-table\" },\n }),\n TableRow,\n TableHeader,\n TableCell,\n );\n }\n\n if (feat.markdown) {\n exts.push(Markdown.configure(markdown ?? MARKDOWN_DIALECT_CONFIG[dialect]));\n }\n\n // Shared block-level image node. The node is named `image`, so when\n // `features.markdown` is on, tiptap-markdown serializes it through its\n // built-in `defaultMarkdownSerializer.nodes.image` fallback → `![alt](src)`\n // (no width-as-HTML override here, so GFM stays byte-stable and\n // source-syncable). With an `onImageUpload` it accepts paste/drop uploads.\n if (feat.image) {\n exts.push(createImageExtension({ onImageUpload }));\n }\n\n // App-specific extensions (Notion/media/drag handles/comments). Appended\n // before Collaboration so they can extend the schema and Collaboration binds\n // over the full set.\n if (extraExtensions.length > 0) {\n exts.push(...extraExtensions);\n }\n\n // Collaborative editing via the shared Y.Doc. Markdown stays the canonical\n // saved representation (onChange serializes it); the Y.Doc is transient live\n // state only. Appended last so it binds over the configured schema above.\n if (ydoc) {\n exts.push(Collaboration.configure({ document: ydoc }));\n // Live multi-user cursors. Only mounted alongside a Y.Doc so the standalone\n // controlled editor (today's plan/content behavior) is untouched.\n if (awareness) {\n exts.push(\n CollaborationCaret.configure({\n provider: { awareness },\n user: user ?? { name: \"Anonymous\", color: \"#999\" },\n }),\n );\n }\n }\n\n return exts;\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { type JSONContent } from "@tiptap/core";
2
+ /**
3
+ * Parse a GFM markdown string into an array of top-level ProseMirror node JSON
4
+ * (paragraph / heading / list / table / code block / etc.), matching the live
5
+ * plan editor schema (`createSharedEditorExtensions({ dialect: "gfm",
6
+ * features: { image: true } })`) plus the {@link RunId} attribute.
7
+ *
8
+ * `tiptap-markdown` registers the markdown parser, so handing the raw markdown
9
+ * string to `setContent` deserializes it (the same path the live editor uses
10
+ * when it seeds `content: markdown`). Returns the doc's child nodes; an empty
11
+ * string yields a single empty paragraph.
12
+ */
13
+ export declare function gfmToProseJSON(markdown: string): JSONContent[];
14
+ /**
15
+ * Serialize an array of top-level ProseMirror node JSON into GFM markdown. The
16
+ * `runId` attribute is omitted by GFM (the {@link RunId} extension registers no
17
+ * markdown serializer), so it never leaks into the saved markdown.
18
+ *
19
+ * The nodes are wrapped in a `doc` and set on the shared editor, then the GFM
20
+ * markdown is read from the tiptap-markdown storage — the exact serializer the
21
+ * live editor persists with, so output is byte-stable with the live save path.
22
+ */
23
+ export declare function proseJSONToGfm(nodes: JSONContent[]): string;
24
+ //# sourceMappingURL=gfmDoc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gfmDoc.d.ts","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/gfmDoc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAyDxD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAM9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAK3D"}
@@ -0,0 +1,83 @@
1
+ import { Editor } from "@tiptap/core";
2
+ import { createSharedEditorExtensions } from "./extensions.js";
3
+ import { RunId } from "./RunId.js";
4
+ /**
5
+ * The GFM ↔ ProseMirror primitive for the plan single-doc editor.
6
+ *
7
+ * Plans keep `PlanContent.blocks[]` as the source of truth, but the editor is
8
+ * ONE ProseMirror/Tiptap document. The `doc ↔ blocks[]` serializer
9
+ * (`templates/plan/shared/plan-doc.ts`) needs to turn a `rich-text` block's GFM
10
+ * markdown into prose nodes and back. This module is that primitive.
11
+ *
12
+ * Both directions go through a SINGLE headless Tiptap {@link Editor} built from
13
+ * the exact same `createSharedEditorExtensions` config the live plan editor
14
+ * uses (`dialect: "gfm"`, `features.image: true`) plus the {@link RunId}
15
+ * extension, so the schema and the GFM serializer can never drift from the live
16
+ * editor. The instance is created lazily on first use and reused across calls.
17
+ *
18
+ * The headless editor needs a DOM (ProseMirror's `EditorView`). It works under
19
+ * `happy-dom` in vitest (see `gfmDoc.spec.ts`) and under the real browser DOM
20
+ * in production. `createElement` is used rather than mounting into the page so
21
+ * nothing is ever attached to the document.
22
+ */
23
+ let sharedEditor = null;
24
+ /**
25
+ * Lazily build (and memoize) the single headless editor. Throws if no DOM is
26
+ * available — this primitive is for the client / jsdom-style test envs only.
27
+ */
28
+ function getSharedEditor() {
29
+ if (sharedEditor)
30
+ return sharedEditor;
31
+ if (typeof document === "undefined") {
32
+ throw new Error("gfmDoc requires a DOM (document). It runs in the browser and in jsdom/happy-dom tests, not in a bare Node server context.");
33
+ }
34
+ sharedEditor = new Editor({
35
+ element: document.createElement("div"),
36
+ extensions: createSharedEditorExtensions({
37
+ dialect: "gfm",
38
+ features: { image: true },
39
+ extraExtensions: [RunId],
40
+ }),
41
+ content: "",
42
+ });
43
+ return sharedEditor;
44
+ }
45
+ /** Reads the GFM markdown out of the tiptap-markdown storage. */
46
+ function getMarkdown(editor) {
47
+ const storage = editor.storage;
48
+ return storage.markdown?.getMarkdown?.() ?? "";
49
+ }
50
+ /**
51
+ * Parse a GFM markdown string into an array of top-level ProseMirror node JSON
52
+ * (paragraph / heading / list / table / code block / etc.), matching the live
53
+ * plan editor schema (`createSharedEditorExtensions({ dialect: "gfm",
54
+ * features: { image: true } })`) plus the {@link RunId} attribute.
55
+ *
56
+ * `tiptap-markdown` registers the markdown parser, so handing the raw markdown
57
+ * string to `setContent` deserializes it (the same path the live editor uses
58
+ * when it seeds `content: markdown`). Returns the doc's child nodes; an empty
59
+ * string yields a single empty paragraph.
60
+ */
61
+ export function gfmToProseJSON(markdown) {
62
+ const editor = getSharedEditor();
63
+ // `emitUpdate: false` keeps this a pure transform with no side effects on any
64
+ // (non-existent) consumers of the headless editor's update stream.
65
+ editor.commands.setContent(markdown, { emitUpdate: false });
66
+ return editor.getJSON().content ?? [];
67
+ }
68
+ /**
69
+ * Serialize an array of top-level ProseMirror node JSON into GFM markdown. The
70
+ * `runId` attribute is omitted by GFM (the {@link RunId} extension registers no
71
+ * markdown serializer), so it never leaks into the saved markdown.
72
+ *
73
+ * The nodes are wrapped in a `doc` and set on the shared editor, then the GFM
74
+ * markdown is read from the tiptap-markdown storage — the exact serializer the
75
+ * live editor persists with, so output is byte-stable with the live save path.
76
+ */
77
+ export function proseJSONToGfm(nodes) {
78
+ const editor = getSharedEditor();
79
+ const content = nodes.length > 0 ? nodes : [{ type: "paragraph" }];
80
+ editor.commands.setContent({ type: "doc", content }, { emitUpdate: false });
81
+ return getMarkdown(editor);
82
+ }
83
+ //# sourceMappingURL=gfmDoc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gfmDoc.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/gfmDoc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC;;;;;;;;;;;;;;;;;;GAkBG;AAEH,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC;;;GAGG;AACH,SAAS,eAAe;IACtB,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,2HAA2H,CAC5H,CAAC;IACJ,CAAC;IACD,YAAY,GAAG,IAAI,MAAM,CAAC;QACxB,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACtC,UAAU,EAAE,4BAA4B,CAAC;YACvC,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;YACzB,eAAe,EAAE,CAAC,KAAK,CAAC;SACzB,CAAC;QACF,OAAO,EAAE,EAAE;KACZ,CAAC,CAAC;IACH,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,iEAAiE;AACjE,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,OAEtB,CAAC;IACF,OAAO,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,8EAA8E;IAC9E,mEAAmE;IACnE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IACnE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { Editor, type JSONContent } from \"@tiptap/core\";\nimport { createSharedEditorExtensions } from \"./extensions.js\";\nimport { RunId } from \"./RunId.js\";\n\n/**\n * The GFM ↔ ProseMirror primitive for the plan single-doc editor.\n *\n * Plans keep `PlanContent.blocks[]` as the source of truth, but the editor is\n * ONE ProseMirror/Tiptap document. The `doc ↔ blocks[]` serializer\n * (`templates/plan/shared/plan-doc.ts`) needs to turn a `rich-text` block's GFM\n * markdown into prose nodes and back. This module is that primitive.\n *\n * Both directions go through a SINGLE headless Tiptap {@link Editor} built from\n * the exact same `createSharedEditorExtensions` config the live plan editor\n * uses (`dialect: \"gfm\"`, `features.image: true`) plus the {@link RunId}\n * extension, so the schema and the GFM serializer can never drift from the live\n * editor. The instance is created lazily on first use and reused across calls.\n *\n * The headless editor needs a DOM (ProseMirror's `EditorView`). It works under\n * `happy-dom` in vitest (see `gfmDoc.spec.ts`) and under the real browser DOM\n * in production. `createElement` is used rather than mounting into the page so\n * nothing is ever attached to the document.\n */\n\nlet sharedEditor: Editor | null = null;\n\n/**\n * Lazily build (and memoize) the single headless editor. Throws if no DOM is\n * available — this primitive is for the client / jsdom-style test envs only.\n */\nfunction getSharedEditor(): Editor {\n if (sharedEditor) return sharedEditor;\n if (typeof document === \"undefined\") {\n throw new Error(\n \"gfmDoc requires a DOM (document). It runs in the browser and in jsdom/happy-dom tests, not in a bare Node server context.\",\n );\n }\n sharedEditor = new Editor({\n element: document.createElement(\"div\"),\n extensions: createSharedEditorExtensions({\n dialect: \"gfm\",\n features: { image: true },\n extraExtensions: [RunId],\n }),\n content: \"\",\n });\n return sharedEditor;\n}\n\n/** Reads the GFM markdown out of the tiptap-markdown storage. */\nfunction getMarkdown(editor: Editor): string {\n const storage = editor.storage as unknown as {\n markdown?: { getMarkdown?: () => string };\n };\n return storage.markdown?.getMarkdown?.() ?? \"\";\n}\n\n/**\n * Parse a GFM markdown string into an array of top-level ProseMirror node JSON\n * (paragraph / heading / list / table / code block / etc.), matching the live\n * plan editor schema (`createSharedEditorExtensions({ dialect: \"gfm\",\n * features: { image: true } })`) plus the {@link RunId} attribute.\n *\n * `tiptap-markdown` registers the markdown parser, so handing the raw markdown\n * string to `setContent` deserializes it (the same path the live editor uses\n * when it seeds `content: markdown`). Returns the doc's child nodes; an empty\n * string yields a single empty paragraph.\n */\nexport function gfmToProseJSON(markdown: string): JSONContent[] {\n const editor = getSharedEditor();\n // `emitUpdate: false` keeps this a pure transform with no side effects on any\n // (non-existent) consumers of the headless editor's update stream.\n editor.commands.setContent(markdown, { emitUpdate: false });\n return editor.getJSON().content ?? [];\n}\n\n/**\n * Serialize an array of top-level ProseMirror node JSON into GFM markdown. The\n * `runId` attribute is omitted by GFM (the {@link RunId} extension registers no\n * markdown serializer), so it never leaks into the saved markdown.\n *\n * The nodes are wrapped in a `doc` and set on the shared editor, then the GFM\n * markdown is read from the tiptap-markdown storage — the exact serializer the\n * live editor persists with, so output is byte-stable with the live save path.\n */\nexport function proseJSONToGfm(nodes: JSONContent[]): string {\n const editor = getSharedEditor();\n const content = nodes.length > 0 ? nodes : [{ type: \"paragraph\" }];\n editor.commands.setContent({ type: \"doc\", content }, { emitUpdate: false });\n return getMarkdown(editor);\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export { createSharedEditorExtensions, MARKDOWN_DIALECT_CONFIG, type RichMarkdownDialect, type RichMarkdownEditorPreset, type RichMarkdownCollabUser, type SharedEditorCollab, type SharedEditorFeatures, type CreateSharedEditorExtensionsOptions, } from "./extensions.js";
2
+ export { useCollabReconcile, getEditorMarkdown, type UseCollabReconcileOptions, type UseCollabReconcileResult, } from "./useCollabReconcile.js";
3
+ export { SlashCommandMenu, DEFAULT_SLASH_COMMANDS, createImageSlashCommand, type SlashCommandItem, type SlashCommandMenuProps, } from "./SlashCommandMenu.js";
4
+ export { SharedImage, createImageExtension, pickAndInsertImage, type ImageUploadFn, type SharedImageOptions, } from "./ImageExtension.js";
5
+ export { uploadEditorImage } from "./uploadEditorImage.js";
6
+ export { BubbleToolbar, buildDefaultBubbleItems, type BubbleToolbarItem, type BubbleToolbarProps, } from "./BubbleToolbar.js";
7
+ export { SharedRichEditor, type SharedRichEditorProps, } from "./SharedRichEditor.js";
8
+ export { RichMarkdownEditor, createRichMarkdownExtensions, type RichMarkdownEditorProps, type CreateRichMarkdownExtensionsOptions, } from "./RichMarkdownEditor.js";
9
+ export { RunId, RUN_ID_NODE_TYPES } from "./RunId.js";
10
+ export { gfmToProseJSON, proseJSONToGfm } from "./gfmDoc.js";
11
+ export { DragHandle, DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR, type DragHandleOptions, } from "./DragHandle.js";
12
+ export { createRegistryBlockNode, RegistryBlockNodeView, RegistryBlockDataProvider, useRegistryBlockData, type CreateRegistryBlockNodeOptions, type RegistryBlockDataValue, type RegistryBlockSideMapBlock, } from "./RegistryBlockNode.js";
13
+ export { buildRegistryBlockSlashItems, type BuildRegistryBlockSlashItemsOptions, } from "./registrySlashCommands.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,mCAAmC,GACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,mCAAmC,GACzC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,UAAU,EACV,oCAAoC,EACpC,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,GAC/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,4BAA4B,EAC5B,KAAK,mCAAmC,GACzC,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,14 @@
1
+ export { createSharedEditorExtensions, MARKDOWN_DIALECT_CONFIG, } from "./extensions.js";
2
+ export { useCollabReconcile, getEditorMarkdown, } from "./useCollabReconcile.js";
3
+ export { SlashCommandMenu, DEFAULT_SLASH_COMMANDS, createImageSlashCommand, } from "./SlashCommandMenu.js";
4
+ export { SharedImage, createImageExtension, pickAndInsertImage, } from "./ImageExtension.js";
5
+ export { uploadEditorImage } from "./uploadEditorImage.js";
6
+ export { BubbleToolbar, buildDefaultBubbleItems, } from "./BubbleToolbar.js";
7
+ export { SharedRichEditor, } from "./SharedRichEditor.js";
8
+ export { RichMarkdownEditor, createRichMarkdownExtensions, } from "./RichMarkdownEditor.js";
9
+ export { RunId, RUN_ID_NODE_TYPES } from "./RunId.js";
10
+ export { gfmToProseJSON, proseJSONToGfm } from "./gfmDoc.js";
11
+ export { DragHandle, DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR, } from "./DragHandle.js";
12
+ export { createRegistryBlockNode, RegistryBlockNodeView, RegistryBlockDataProvider, useRegistryBlockData, } from "./RegistryBlockNode.js";
13
+ export { buildRegistryBlockSlashItems, } from "./registrySlashCommands.js";
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,GAOxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAGlB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GAGxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,kBAAkB,GAGnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,aAAa,EACb,uBAAuB,GAGxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,GAEjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,4BAA4B,GAG7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,UAAU,EACV,oCAAoC,GAErC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,GAIrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,4BAA4B,GAE7B,MAAM,4BAA4B,CAAC","sourcesContent":["export {\n createSharedEditorExtensions,\n MARKDOWN_DIALECT_CONFIG,\n type RichMarkdownDialect,\n type RichMarkdownEditorPreset,\n type RichMarkdownCollabUser,\n type SharedEditorCollab,\n type SharedEditorFeatures,\n type CreateSharedEditorExtensionsOptions,\n} from \"./extensions.js\";\nexport {\n useCollabReconcile,\n getEditorMarkdown,\n type UseCollabReconcileOptions,\n type UseCollabReconcileResult,\n} from \"./useCollabReconcile.js\";\nexport {\n SlashCommandMenu,\n DEFAULT_SLASH_COMMANDS,\n createImageSlashCommand,\n type SlashCommandItem,\n type SlashCommandMenuProps,\n} from \"./SlashCommandMenu.js\";\nexport {\n SharedImage,\n createImageExtension,\n pickAndInsertImage,\n type ImageUploadFn,\n type SharedImageOptions,\n} from \"./ImageExtension.js\";\nexport { uploadEditorImage } from \"./uploadEditorImage.js\";\nexport {\n BubbleToolbar,\n buildDefaultBubbleItems,\n type BubbleToolbarItem,\n type BubbleToolbarProps,\n} from \"./BubbleToolbar.js\";\nexport {\n SharedRichEditor,\n type SharedRichEditorProps,\n} from \"./SharedRichEditor.js\";\nexport {\n RichMarkdownEditor,\n createRichMarkdownExtensions,\n type RichMarkdownEditorProps,\n type CreateRichMarkdownExtensionsOptions,\n} from \"./RichMarkdownEditor.js\";\nexport { RunId, RUN_ID_NODE_TYPES } from \"./RunId.js\";\nexport { gfmToProseJSON, proseJSONToGfm } from \"./gfmDoc.js\";\nexport {\n DragHandle,\n DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR,\n type DragHandleOptions,\n} from \"./DragHandle.js\";\nexport {\n createRegistryBlockNode,\n RegistryBlockNodeView,\n RegistryBlockDataProvider,\n useRegistryBlockData,\n type CreateRegistryBlockNodeOptions,\n type RegistryBlockDataValue,\n type RegistryBlockSideMapBlock,\n} from \"./RegistryBlockNode.js\";\nexport {\n buildRegistryBlockSlashItems,\n type BuildRegistryBlockSlashItemsOptions,\n} from \"./registrySlashCommands.js\";\n"]}
@@ -0,0 +1,46 @@
1
+ import type { BlockRegistry, BlockSpec } from "../blocks/index.js";
2
+ /**
3
+ * Shared builder for the registry-derived block slash commands both the plan and
4
+ * content editors offer. Both apps take every `BlockSpec` whose `placement`
5
+ * includes `"block"`, gate it by Notion-compatibility when the open document is
6
+ * linked to a Notion page, and emit one slash item per surviving spec that
7
+ * inserts that block's atom node. The only legitimate per-app differences are:
8
+ *
9
+ * - the ITEM SHAPE (plan uses a text-glyph `icon`, content a React component),
10
+ * - the Notion-compat PREDICATE (plan unions in prose-only NFM analogs, content
11
+ * reads the registry `notionCompatible` flag directly), and
12
+ * - the INSERT behavior (plan inserts a `planBlock` node, content a
13
+ * `registryBlock` node seeded with inline `__raw`).
14
+ *
15
+ * Those three are injected; everything else (the `list("block")` source, the
16
+ * Notion filter wiring, the one-item-per-spec mapping) lives here so adding a
17
+ * new library block only touches the registry, never the slash builders.
18
+ */
19
+ export interface BuildRegistryBlockSlashItemsOptions<TItem, TEditor> {
20
+ /**
21
+ * When `true`, only specs the predicate accepts are offered (the open document
22
+ * is linked to a Notion page, so blocks that can't round-trip to NFM are
23
+ * hidden). When unset/false, every block-placed spec is offered.
24
+ */
25
+ notionCompatibleOnly?: boolean;
26
+ /**
27
+ * Decide whether a spec round-trips to Notion. Defaults to the spec's own
28
+ * `notionCompatible` flag (content's rule). Plan passes a predicate that unions
29
+ * in prose-only NFM analogs not carried as registry flags.
30
+ */
31
+ isNotionCompatible?: (spec: BlockSpec) => boolean;
32
+ /** Build one app-shaped slash item from a surviving block spec. */
33
+ toItem: (spec: BlockSpec, insert: (editor: TEditor) => void) => TItem;
34
+ /**
35
+ * Insert this spec's block atom into the editor. Plan inserts a `planBlock`
36
+ * node; content inserts a `registryBlock` node seeded with inline `__raw`.
37
+ */
38
+ insertBlock: (editor: TEditor, spec: BlockSpec) => void;
39
+ }
40
+ /**
41
+ * Build the registry-derived block slash items, shared by plan and content. Each
42
+ * app prepends its own prose/base commands and wraps the result in its own item
43
+ * type via {@link BuildRegistryBlockSlashItemsOptions.toItem}.
44
+ */
45
+ export declare function buildRegistryBlockSlashItems<TItem, TEditor>(registry: BlockRegistry, options: BuildRegistryBlockSlashItemsOptions<TItem, TEditor>): TItem[];
46
+ //# sourceMappingURL=registrySlashCommands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registrySlashCommands.d.ts","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/registrySlashCommands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,mCAAmC,CAAC,KAAK,EAAE,OAAO;IACjE;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAClD,mEAAmE;IACnE,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,KAAK,KAAK,CAAC;IACtE;;;OAGG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,EACzD,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,mCAAmC,CAAC,KAAK,EAAE,OAAO,CAAC,GAC3D,KAAK,EAAE,CAST"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Build the registry-derived block slash items, shared by plan and content. Each
3
+ * app prepends its own prose/base commands and wraps the result in its own item
4
+ * type via {@link BuildRegistryBlockSlashItemsOptions.toItem}.
5
+ */
6
+ export function buildRegistryBlockSlashItems(registry, options) {
7
+ const isCompatible = options.isNotionCompatible ?? ((spec) => Boolean(spec.notionCompatible));
8
+ return registry
9
+ .list("block")
10
+ .filter((spec) => !options.notionCompatibleOnly || isCompatible(spec))
11
+ .map((spec) => options.toItem(spec, (editor) => options.insertBlock(editor, spec)));
12
+ }
13
+ //# sourceMappingURL=registrySlashCommands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registrySlashCommands.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/registrySlashCommands.ts"],"names":[],"mappings":"AAyCA;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAAuB,EACvB,OAA4D;IAE5D,MAAM,YAAY,GAChB,OAAO,CAAC,kBAAkB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC3E,OAAO,QAAQ;SACZ,IAAI,CAAC,OAAO,CAAC;SACb,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;SACrE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CACpE,CAAC;AACN,CAAC","sourcesContent":["import type { BlockRegistry, BlockSpec } from \"../blocks/index.js\";\n\n/**\n * Shared builder for the registry-derived block slash commands both the plan and\n * content editors offer. Both apps take every `BlockSpec` whose `placement`\n * includes `\"block\"`, gate it by Notion-compatibility when the open document is\n * linked to a Notion page, and emit one slash item per surviving spec that\n * inserts that block's atom node. The only legitimate per-app differences are:\n *\n * - the ITEM SHAPE (plan uses a text-glyph `icon`, content a React component),\n * - the Notion-compat PREDICATE (plan unions in prose-only NFM analogs, content\n * reads the registry `notionCompatible` flag directly), and\n * - the INSERT behavior (plan inserts a `planBlock` node, content a\n * `registryBlock` node seeded with inline `__raw`).\n *\n * Those three are injected; everything else (the `list(\"block\")` source, the\n * Notion filter wiring, the one-item-per-spec mapping) lives here so adding a\n * new library block only touches the registry, never the slash builders.\n */\nexport interface BuildRegistryBlockSlashItemsOptions<TItem, TEditor> {\n /**\n * When `true`, only specs the predicate accepts are offered (the open document\n * is linked to a Notion page, so blocks that can't round-trip to NFM are\n * hidden). When unset/false, every block-placed spec is offered.\n */\n notionCompatibleOnly?: boolean;\n /**\n * Decide whether a spec round-trips to Notion. Defaults to the spec's own\n * `notionCompatible` flag (content's rule). Plan passes a predicate that unions\n * in prose-only NFM analogs not carried as registry flags.\n */\n isNotionCompatible?: (spec: BlockSpec) => boolean;\n /** Build one app-shaped slash item from a surviving block spec. */\n toItem: (spec: BlockSpec, insert: (editor: TEditor) => void) => TItem;\n /**\n * Insert this spec's block atom into the editor. Plan inserts a `planBlock`\n * node; content inserts a `registryBlock` node seeded with inline `__raw`.\n */\n insertBlock: (editor: TEditor, spec: BlockSpec) => void;\n}\n\n/**\n * Build the registry-derived block slash items, shared by plan and content. Each\n * app prepends its own prose/base commands and wraps the result in its own item\n * type via {@link BuildRegistryBlockSlashItemsOptions.toItem}.\n */\nexport function buildRegistryBlockSlashItems<TItem, TEditor>(\n registry: BlockRegistry,\n options: BuildRegistryBlockSlashItemsOptions<TItem, TEditor>,\n): TItem[] {\n const isCompatible =\n options.isNotionCompatible ?? ((spec) => Boolean(spec.notionCompatible));\n return registry\n .list(\"block\")\n .filter((spec) => !options.notionCompatibleOnly || isCompatible(spec))\n .map((spec) =>\n options.toItem(spec, (editor) => options.insertBlock(editor, spec)),\n );\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type { ImageUploadFn } from "./ImageExtension.js";
2
+ /**
3
+ * The shared editor's default image uploader: upload a picked / pasted /
4
+ * dropped image File through the framework `upload-image` action and return the
5
+ * hosted CDN URL.
6
+ *
7
+ * This is the {@link ImageUploadFn} embedders pass to the shared image block so
8
+ * any app gets a real uploading image block with zero per-app upload code. The
9
+ * action re-hosts the bytes on the configured provider (Builder.io by default),
10
+ * is session-scoped, and returns a stable `![alt](url)` source — so a plan's
11
+ * inserted image autosaves as plain markdown through the existing
12
+ * `update-rich-text` path with no new persistence channel.
13
+ *
14
+ * @throws when the file cannot be read, the action returns no URL, or upload is
15
+ * not configured (with the action's "connect Builder.io" guidance).
16
+ */
17
+ export declare const uploadEditorImage: ImageUploadFn;
18
+ //# sourceMappingURL=uploadEditorImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploadEditorImage.d.ts","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/uploadEditorImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAgCzD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAsB/B,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { callAction } from "../use-action.js";
2
+ /**
3
+ * Read a {@link File} as a base64 data URL (`data:image/...;base64,...`).
4
+ *
5
+ * The framework `upload-image` action accepts a data URL (`data`) or a remote
6
+ * URL (`url`) — not raw multipart — so a browser file-picker must convert the
7
+ * File to a data URL first.
8
+ */
9
+ function fileToDataUrl(file) {
10
+ return new Promise((resolve, reject) => {
11
+ const reader = new FileReader();
12
+ reader.onload = () => {
13
+ const result = reader.result;
14
+ if (typeof result === "string") {
15
+ resolve(result);
16
+ }
17
+ else {
18
+ reject(new Error("Failed to read image file."));
19
+ }
20
+ };
21
+ reader.onerror = () => reject(reader.error ?? new Error("Failed to read image file."));
22
+ reader.readAsDataURL(file);
23
+ });
24
+ }
25
+ /**
26
+ * The shared editor's default image uploader: upload a picked / pasted /
27
+ * dropped image File through the framework `upload-image` action and return the
28
+ * hosted CDN URL.
29
+ *
30
+ * This is the {@link ImageUploadFn} embedders pass to the shared image block so
31
+ * any app gets a real uploading image block with zero per-app upload code. The
32
+ * action re-hosts the bytes on the configured provider (Builder.io by default),
33
+ * is session-scoped, and returns a stable `![alt](url)` source — so a plan's
34
+ * inserted image autosaves as plain markdown through the existing
35
+ * `update-rich-text` path with no new persistence channel.
36
+ *
37
+ * @throws when the file cannot be read, the action returns no URL, or upload is
38
+ * not configured (with the action's "connect Builder.io" guidance).
39
+ */
40
+ export const uploadEditorImage = async (file) => {
41
+ if (!file.type.startsWith("image/")) {
42
+ throw new Error("Only image files can be uploaded.");
43
+ }
44
+ const dataUrl = await fileToDataUrl(file);
45
+ const result = await callAction("upload-image", {
46
+ data: dataUrl,
47
+ filename: file.name || undefined,
48
+ });
49
+ if (!result || typeof result.url !== "string" || !result.url) {
50
+ throw new Error(result?.error ||
51
+ "Image upload failed. Connect Builder.io in Settings → File uploads, then try again.");
52
+ }
53
+ // Use the filename (sans extension) as a reasonable default alt text.
54
+ const alt = file.name ? file.name.replace(/\.[^./\\]+$/, "") : "";
55
+ return { src: result.url, alt };
56
+ };
57
+ //# sourceMappingURL=uploadEditorImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploadEditorImage.js","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/uploadEditorImage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,IAAU;IAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;YACnB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CACpB,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAQD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAkB,KAAK,EAAE,IAAU,EAAE,EAAE;IACnE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAA0B,cAAc,EAAE;QACvE,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,SAAS;KACjC,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,MAAM,EAAE,KAAK;YACX,qFAAqF,CACxF,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;AAClC,CAAC,CAAC","sourcesContent":["import { callAction } from \"../use-action.js\";\nimport type { ImageUploadFn } from \"./ImageExtension.js\";\n\n/**\n * Read a {@link File} as a base64 data URL (`data:image/...;base64,...`).\n *\n * The framework `upload-image` action accepts a data URL (`data`) or a remote\n * URL (`url`) — not raw multipart — so a browser file-picker must convert the\n * File to a data URL first.\n */\nfunction fileToDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result;\n if (typeof result === \"string\") {\n resolve(result);\n } else {\n reject(new Error(\"Failed to read image file.\"));\n }\n };\n reader.onerror = () =>\n reject(reader.error ?? new Error(\"Failed to read image file.\"));\n reader.readAsDataURL(file);\n });\n}\n\ninterface UploadImageActionResult {\n url?: string;\n error?: string;\n configured?: boolean;\n}\n\n/**\n * The shared editor's default image uploader: upload a picked / pasted /\n * dropped image File through the framework `upload-image` action and return the\n * hosted CDN URL.\n *\n * This is the {@link ImageUploadFn} embedders pass to the shared image block so\n * any app gets a real uploading image block with zero per-app upload code. The\n * action re-hosts the bytes on the configured provider (Builder.io by default),\n * is session-scoped, and returns a stable `![alt](url)` source — so a plan's\n * inserted image autosaves as plain markdown through the existing\n * `update-rich-text` path with no new persistence channel.\n *\n * @throws when the file cannot be read, the action returns no URL, or upload is\n * not configured (with the action's \"connect Builder.io\" guidance).\n */\nexport const uploadEditorImage: ImageUploadFn = async (file: File) => {\n if (!file.type.startsWith(\"image/\")) {\n throw new Error(\"Only image files can be uploaded.\");\n }\n\n const dataUrl = await fileToDataUrl(file);\n\n const result = await callAction<UploadImageActionResult>(\"upload-image\", {\n data: dataUrl,\n filename: file.name || undefined,\n });\n\n if (!result || typeof result.url !== \"string\" || !result.url) {\n throw new Error(\n result?.error ||\n \"Image upload failed. Connect Builder.io in Settings → File uploads, then try again.\",\n );\n }\n\n // Use the filename (sans extension) as a reasonable default alt text.\n const alt = file.name ? file.name.replace(/\\.[^./\\\\]+$/, \"\") : \"\";\n return { src: result.url, alt };\n};\n"]}
@@ -0,0 +1,91 @@
1
+ import { type MutableRefObject } from "react";
2
+ import type { Editor } from "@tiptap/react";
3
+ import type { Transaction } from "@tiptap/pm/state";
4
+ import type { Doc as YDoc } from "yjs";
5
+ import type { Awareness } from "y-protocols/awareness";
6
+ /** Reads the current markdown out of the tiptap-markdown storage. */
7
+ export declare function getEditorMarkdown(editor: Editor): string;
8
+ export interface UseCollabReconcileOptions {
9
+ /** The live editor, or null until it mounts. */
10
+ editor: Editor | null;
11
+ /** Shared Y.Doc when collaborating; null disables all collab paths. */
12
+ ydoc?: YDoc | null;
13
+ /** Shared awareness; null keeps the sole-client lead path. */
14
+ awareness?: Awareness | null;
15
+ /** Authoritative markdown value (SQL source of truth). */
16
+ value: string;
17
+ /** Timestamp of the authoritative value; gates newer-than reconcile. */
18
+ contentUpdatedAt?: string | null;
19
+ /** Whether the editor accepts edits. Reconcile/seed only run for the live editor. */
20
+ editable: boolean;
21
+ /**
22
+ * Reads the current markdown from the editor. Injected so a dialect could
23
+ * swap serializers; defaults to the tiptap-markdown storage reader. For an app
24
+ * with a custom serializer (e.g. Content's `docToNfm(editor.getJSON())`), pass
25
+ * it here so the seed/reconcile equality checks compare like-for-like.
26
+ */
27
+ getMarkdown?: (editor: Editor) => string;
28
+ /**
29
+ * Applies the authoritative `value` into the editor. Defaults to passing the
30
+ * raw markdown string to `editor.commands.setContent`. Apps whose serializer
31
+ * is NOT tiptap-markdown (Content parses `nfmToDoc(value)` into a PM doc)
32
+ * override this so seed + reconcile write the correct content shape. The
33
+ * supplied `options` carry the history/whitespace flags the default path uses;
34
+ * a custom implementation should forward them when relevant.
35
+ */
36
+ setContent?: (editor: Editor, value: string, options: {
37
+ emitUpdate?: boolean;
38
+ addToHistory?: boolean;
39
+ }) => void;
40
+ /**
41
+ * Normalizes the authoritative `value` to the canonical markdown the editor
42
+ * would emit, so the "already in sync / our own echo" equality checks match a
43
+ * serializer that re-canonicalizes (Content's `canonicalizeNfm`). Defaults to
44
+ * identity (GFM already round-trips byte-stably).
45
+ */
46
+ normalizeValue?: (value: string) => string;
47
+ /**
48
+ * Decides whether the empty-doc seed should run for the current shared
49
+ * fragment. Defaults to "fragment has no nodes, or the editor holds no
50
+ * semantic markdown". Apps with sentinel-empty content (Content's
51
+ * `<empty-block/>` filler) override this. Receives the live fragment length
52
+ * and the editor's current markdown.
53
+ */
54
+ shouldSeed?: (info: {
55
+ value: string;
56
+ currentMarkdown: string;
57
+ fragmentLength: number;
58
+ }) => boolean;
59
+ /**
60
+ * The initial "applied" watermark. Default mirrors `contentUpdatedAt`, so a
61
+ * fresh mount whose Y.Doc already matches SQL doesn't re-apply. Pass `null`
62
+ * to force the first reconcile pass to adopt authoritative SQL even at the
63
+ * same timestamp — Content does this so a stale persisted Y.Doc (an agent that
64
+ * edited the CLOSED doc) is corrected on open. The editor is keyed per
65
+ * document upstream, so this only affects the first mount of each doc.
66
+ */
67
+ initialAppliedUpdatedAt?: string | null;
68
+ }
69
+ export interface UseCollabReconcileResult {
70
+ /** True when a Y.Doc is bound (collaborative editing active). */
71
+ collab: boolean;
72
+ /**
73
+ * Set true around any programmatic `setContent` so the editor's `onUpdate`
74
+ * can ignore the resulting transaction (it isn't a user edit).
75
+ */
76
+ isSettingContentRef: MutableRefObject<boolean>;
77
+ /**
78
+ * Call from `onUpdate` BEFORE serializing. Returns true when the update must
79
+ * be ignored: editor not editable, mid-programmatic-setContent, or (in collab
80
+ * mode) a remote-origin transaction. Also records the local typing time.
81
+ */
82
+ shouldIgnoreUpdate: (transaction: Transaction) => boolean;
83
+ /**
84
+ * Call from `onUpdate` AFTER computing the markdown to emit. Returns false
85
+ * when the value must NOT be persisted yet (an empty collab doc before the
86
+ * seed has run); records it as the last-emitted value otherwise.
87
+ */
88
+ registerEmitted: (markdown: string) => boolean;
89
+ }
90
+ export declare function useCollabReconcile({ editor, ydoc, awareness, value, contentUpdatedAt, editable, getMarkdown, setContent, normalizeValue, shouldSeed, initialAppliedUpdatedAt, }: UseCollabReconcileOptions): UseCollabReconcileResult;
91
+ //# sourceMappingURL=useCollabReconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCollabReconcile.d.ts","sourceRoot":"","sources":["../../../src/client/rich-markdown-editor/useCollabReconcile.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,GAAG,IAAI,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKxD;AAqBD,MAAM,WAAW,yBAAyB;IACxC,gDAAgD;IAChD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uEAAuE;IACvE,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,qFAAqF;IACrF,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CACX,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KACtD,IAAI,CAAC;IACV;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;KACxB,KAAK,OAAO,CAAC;IACd;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACvC,iEAAiE;IACjE,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,mBAAmB,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC/C;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC;IAC1D;;;;OAIG;IACH,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CAChD;AAoED,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,IAAW,EACX,SAAgB,EAChB,KAAK,EACL,gBAAgB,EAChB,QAAQ,EACR,WAA+B,EAC/B,UAA8B,EAC9B,cAAyB,EACzB,UAA8B,EAC9B,uBAAuB,GACxB,EAAE,yBAAyB,GAAG,wBAAwB,CA4StD"}