collabmd 0.1.47 → 0.1.49

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 (305) hide show
  1. package/README.md +70 -11
  2. package/bin/collabmd.js +3 -0
  3. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-C-nmgL5g.js +1 -0
  4. package/dist/client/assets/JetBrainsMono-Regular-BQaDgvhP.woff2 +0 -0
  5. package/dist/client/assets/abnfDiagram-VCTEODGH-CdVZqicp.js +1 -0
  6. package/dist/client/assets/{architectureDiagram-5GKGNRK7-I39sYjHI.js → architectureDiagram-5GKGNRK7-wUo0bXif.js} +3 -3
  7. package/dist/client/assets/babel-CY5KOv-I.js +16 -0
  8. package/dist/client/assets/{blockDiagram-NRAW4CY4-C6DtJy5Y.js → blockDiagram-I7D4REHJ-BRSK3m49.js} +4 -4
  9. package/dist/client/assets/browser-utils-DbXSMI-6.js +1 -0
  10. package/dist/client/assets/{c4Diagram-UCG6FXSJ-CtWtxS9_.js → c4Diagram-7LVT6UL2-yD2poxqw.js} +1 -1
  11. package/dist/client/assets/channel-Fa4GS_-F.js +1 -0
  12. package/dist/client/assets/chunk-2E4U76K2-BPnTT-J3.js +2 -0
  13. package/dist/client/assets/{chunk-TEH6E4GO-DVayPj-q.js → chunk-4HAMMTFA-DStbIfJ1.js} +20 -20
  14. package/dist/client/assets/{chunk-75Z2AOVW-CdFSaPjz.js → chunk-75Z2AOVW-C5pGd3W9.js} +1 -1
  15. package/dist/client/assets/{chunk-CLGD4ZFX-DQLgbQrv.js → chunk-CLGD4ZFX-BMeArk03.js} +1 -1
  16. package/dist/client/assets/chunk-DU6HZSFF-Zkp69c6c.js +127 -0
  17. package/dist/client/assets/{chunk-F27PBJKO-CNHIFhjo.js → chunk-F27PBJKO-D4xNct1r.js} +1 -1
  18. package/dist/client/assets/{chunk-GMAD6QVW-CbcBqPM5.js → chunk-GMAD6QVW-NZ6WpDb8.js} +1 -1
  19. package/dist/client/assets/{chunk-OBVCFTLP-BJR7u1jh.js → chunk-GVQU2GXP-D8SDprfX.js} +1 -1
  20. package/dist/client/assets/{chunk-G27WJ6UU-D9-eg537.js → chunk-IMKFNOWR-D8jEuU3Q.js} +2 -2
  21. package/dist/client/assets/{chunk-JQ64N6SF-DSFNH4bh.js → chunk-L3NEJ4N5-aijKP-eh.js} +1 -1
  22. package/dist/client/assets/chunk-OSK3NFVY-CCbLQAMa.js +10 -0
  23. package/dist/client/assets/{chunk-P2QGCYS3-BRpqY32H.js → chunk-P2QGCYS3-Oag_FdCq.js} +1 -1
  24. package/dist/client/assets/{chunk-POPQ4Y6H-Cb4SlVZF.js → chunk-POPQ4Y6H-CYnpIgXT.js} +1 -1
  25. package/dist/client/assets/{chunk-PWAF6VOD-Cz8IwBB5.js → chunk-PWAF6VOD-JSNrcBmP.js} +1 -1
  26. package/dist/client/assets/{chunk-RM4UPSZO-CWRwxNWJ.js → chunk-RM4UPSZO-DOWllDY8.js} +4 -4
  27. package/dist/client/assets/{chunk-RHFEMEQ7-CWY8cf4H.js → chunk-SHT3W25Y-BiQGljao.js} +5 -5
  28. package/dist/client/assets/{chunk-SVP7TREG-CyHOmcac.js → chunk-SVP7TREG-DB485R5x.js} +1 -1
  29. package/dist/client/assets/{chunk-LCL6LL3I-DmDkVukh.js → chunk-TICWLB2K-8rAVvoS3.js} +4 -4
  30. package/dist/client/assets/{chunk-CKBBP62Z-DG26UiBv.js → chunk-TLUHSLCS-DTY5v0aj.js} +2 -2
  31. package/dist/client/assets/classDiagram-ZZMXUADV-BsQWoR3Q.js +1 -0
  32. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BsQWoR3Q.js +1 -0
  33. package/dist/client/assets/{comment-thread-store-CdcwrObc.js → comment-thread-store-CX98zR6q.js} +1 -1
  34. package/dist/client/assets/comment-threads-BnRwo5B9.js +4 -0
  35. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CdTPi2yO.js → cynefinDiagram-5FMLGOSQ-rTz9RhFH.js} +1 -1
  36. package/dist/client/assets/{dagre-3AP2YEHR-5gtJtd0O.js → dagre-GXQ25YYZ-Cr67wLpQ.js} +2 -2
  37. package/dist/client/assets/{diagram-S7CK7UJ4-BudWz9WU.js → diagram-S7CK7UJ4-DywERe__.js} +2 -2
  38. package/dist/client/assets/{diagram-UQ7AKVKN-3v4rbH-s.js → diagram-UQ7AKVKN-CNYlXtu4.js} +1 -1
  39. package/dist/client/assets/diagram-VSXAHHWV-0H1a61Bn.js +3 -0
  40. package/dist/client/assets/{diagram-VX7I27RA-C_-rj0sw.js → diagram-VX7I27RA-CsJbsx5F.js} +1 -1
  41. package/dist/client/assets/{diagram-Z3DM3KII-B4yxavgj.js → diagram-Z3DM3KII-D0mLxEgI.js} +1 -1
  42. package/dist/client/assets/dist--hk9I5HQ.js +1 -0
  43. package/dist/client/assets/{dist-DutPuFmC.js → dist-B1XEa-Zs.js} +1 -1
  44. package/dist/client/assets/dist-Bd1JucQF.js +1 -0
  45. package/dist/client/assets/{dist-DZAAWTG-.js → dist-C0G3AaXG.js} +1 -1
  46. package/dist/client/assets/dist-ChRoo3IB.js +9 -0
  47. package/dist/client/assets/dist-Dm4w5UId.js +1 -0
  48. package/dist/client/assets/{dist-B_yQaEv_.js → dist-DpYDHR9p.js} +1 -1
  49. package/dist/client/assets/{dist-CietwTVS.js → dist-DzNmC81X.js} +1 -1
  50. package/dist/client/assets/{dist-DDUn5zTz.js → dist-GvvCNBe4.js} +1 -1
  51. package/dist/client/assets/dist-JaU3aRlD.js +19 -0
  52. package/dist/client/assets/{dist-Bw3VIE_v.js → dist-TW8iFRyW.js} +1 -1
  53. package/dist/client/assets/{dist-Dir5dDKZ.js → dist-jVU5Be5P.js} +1 -1
  54. package/dist/client/assets/document-formatter-rDDjRfZ2.js +2 -0
  55. package/dist/client/assets/drawioEditor-JubEEha7.js +9 -0
  56. package/dist/client/assets/ebnfDiagram-PWID7BFC-HeTxHpCU.js +1 -0
  57. package/dist/client/assets/editor-session-Bk6oIvSr.js +54 -0
  58. package/dist/client/assets/embedded-editor-base-BlCgz6mw.css +1 -0
  59. package/dist/client/assets/{erDiagram-SSCWMZ5O-C-iy6VkX.js → erDiagram-RLTQ6QDP-CbrDdd5P.js} +2 -2
  60. package/dist/client/assets/{es-CAsWR6hG.js → es-Bfdp096f.js} +13 -13
  61. package/dist/client/assets/estree-CuT_pB8K.js +44 -0
  62. package/dist/client/assets/excalidraw-element-link-YLIaTnVF.js +7 -0
  63. package/dist/client/assets/{excalidraw-scene-BOben2gr.js → excalidraw-scene-6uROebca.js} +1 -1
  64. package/dist/client/assets/{excalidraw-editor-BlcN6umJ.css → excalidrawEditor-BbSbI80a.css} +1 -1
  65. package/dist/client/assets/excalidrawEditor-dBMbRX_S.js +9 -0
  66. package/dist/client/assets/export-page-CRRQ2NEl.js +57 -0
  67. package/dist/client/assets/exportDocument-BlQRd9_m.js +2 -0
  68. package/dist/client/assets/exportDocument-CNSbjZwu.css +1 -0
  69. package/dist/client/assets/{file-icon-svg-CQAjlWjK.js → file-icon-svg-Y_kpF957.js} +1 -1
  70. package/dist/client/assets/file-kind-BwMIcZbi.js +1 -0
  71. package/dist/client/assets/file-search-DDLyyLDU.js +1 -0
  72. package/dist/client/assets/flowDiagram-HODETNUW-D5Gy0wmg.js +1 -0
  73. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DtKHAbez.js → ganttDiagram-EL5Y4UJY-BHgOYiZz.js} +1 -1
  74. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-oue8fQ5o.js → gitGraphDiagram-WWUBYQGX-Dl__X3Sk.js} +1 -1
  75. package/dist/client/assets/html-Cdnr2qzU.js +25 -0
  76. package/dist/client/assets/image-ZVKINSPA-DgzW5zAy.js +1 -0
  77. package/dist/client/assets/index-D3RER1SZ.js +1023 -0
  78. package/dist/client/assets/index-DREVKl_K.css +1 -0
  79. package/dist/client/assets/{infoDiagram-RXCK75RN-BMzo6KIn.js → infoDiagram-27XIBGKW-DBpoANC9.js} +1 -1
  80. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BIM3h287.js → ishikawaDiagram-5VMMS53U-BMPC6hfp.js} +1 -1
  81. package/dist/client/assets/{journeyDiagram-EYS64GPL-mF6Lh8O-.js → journeyDiagram-3NMN7TZE-B1sApUmM.js} +2 -2
  82. package/dist/client/assets/{kanban-definition-3QL26DDD-DLN2NyoR.js → kanban-definition-UXKFOSKX-C9yP4td1.js} +4 -4
  83. package/dist/client/assets/{line-BfTWJmgf.js → line-BFl3ujec.js} +1 -1
  84. package/dist/client/assets/markdown-CByV-4CU.js +70 -0
  85. package/dist/client/assets/{mermaid.core-CLZBlpIW.js → mermaid.core-BrY09czX.js} +5 -5
  86. package/dist/client/assets/mermaid.core-DfcNfOTv.js +1 -0
  87. package/dist/client/assets/{mindmap-definition-FBJOCRG2-CRyHaHTk.js → mindmap-definition-YA3MSWOX-BUQHcYbK.js} +8 -8
  88. package/dist/client/assets/pegDiagram-XKGWAZYB-Bi2Iml7Z.js +1 -0
  89. package/dist/client/assets/{pieDiagram-E7YTZNPT-B5OZPb88.js → pieDiagram-E7YTZNPT-_gYXnMoi.js} +1 -1
  90. package/dist/client/assets/preview-render-compiler-CfxJYldJ.js +41 -0
  91. package/dist/client/assets/preview-render-compiler-Cu8_i9iS.js +1 -0
  92. package/dist/client/assets/{preview-render-worker-BmN79bVc.js → preview-render-worker-c4Yi93qW.js} +41 -35
  93. package/dist/client/assets/prod-BiJL30sl.js +1 -0
  94. package/dist/client/assets/prod-qAk7rHa4.js +177 -0
  95. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Drrw14YH.js → quadrantDiagram-AXDQQJYC-DwexhEhd.js} +1 -1
  96. package/dist/client/assets/quick-switcher-controller-BoIK_wuG.js +1 -0
  97. package/dist/client/assets/railroadDiagram-O6MQD6OU-BVA5UbMu.js +1 -0
  98. package/dist/client/assets/{requirementDiagram-EFPCY7ZU-CRZG6mRB.js → requirementDiagram-BXWQKSXE-C4cKwiIw.js} +2 -2
  99. package/dist/client/assets/runtime-config-DcmnGcXU.js +1 -0
  100. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-DvarEJpo.js → sankeyDiagram-P5KCCOFB-B5HHkRT2.js} +1 -1
  101. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-B4oWlb-w.js → sequenceDiagram-WJ2MYXX4-BX6jqJFD.js} +6 -6
  102. package/dist/client/assets/standalone-6z5x8CWe.js +29 -0
  103. package/dist/client/assets/{stateDiagram-HBIQ2CUA-qbHIIqRZ.js → stateDiagram-D77RDMKH-CmqxyRGx.js} +1 -1
  104. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-zoLLQVyh.js +1 -0
  105. package/dist/client/assets/{swimlanes-XN3QIQJK-xB6CtUGj.js → swimlanes-42K2YHIH-Bmgb9Zld.js} +1 -1
  106. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DS-KQN37.js +8 -0
  107. package/dist/client/assets/{timeline-definition-24CTP7MA-Lj_yTNlY.js → timeline-definition-24CTP7MA-BA-lVH6P.js} +1 -1
  108. package/dist/client/assets/vault-api-client-iZLhMJKe.js +6 -0
  109. package/dist/client/assets/{vennDiagram-4TSXK5OY-BekRp5Y0.js → vennDiagram-4TSXK5OY-DNdUC_Xj.js} +1 -1
  110. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-kdnV_Hdm.js → wardleyDiagram-VM6X3IG4-C2oY-YbF.js} +1 -1
  111. package/dist/client/assets/wiki-link-resolver-DFIwErjc.js +1 -0
  112. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DufGwNSB.js → xychartDiagram-S5SC5T6Z-CoIR8CBX.js} +1 -1
  113. package/dist/client/assets/yaml-9ltHPDNO.js +154 -0
  114. package/dist/client/assets/{yjs-provider-reset-guard-DE0vINDP.js → yjs-provider-reset-guard-9ul1qF6k.js} +1 -1
  115. package/dist/client/drawio-editor.html +11 -3
  116. package/dist/client/excalidraw-editor.html +45 -2
  117. package/dist/client/export-document.html +3 -3
  118. package/dist/client/index.html +106 -52
  119. package/integrations/pi/index.ts +94 -0
  120. package/package.json +41 -29
  121. package/src/client/app/drawio-editor.html +2 -2
  122. package/src/client/app/excalidraw-editor.html +2 -2
  123. package/src/client/app/export-document.html +1 -1
  124. package/src/client/app/index.html +88 -50
  125. package/src/client/app/main-entry.js +15 -1
  126. package/src/client/application/app-shell/chat-feature.js +7 -22
  127. package/src/client/application/app-shell/export-feature.js +17 -1
  128. package/src/client/application/app-shell/git-feature.js +51 -14
  129. package/src/client/application/app-shell/presence-feature.js +8 -25
  130. package/src/client/application/app-shell/ui-feature-identity.js +13 -0
  131. package/src/client/application/app-shell/ui-feature-shell.js +199 -99
  132. package/src/client/application/app-shell/ui-feature-sidebar.js +43 -7
  133. package/src/client/application/app-shell/ui-feature-tab-activity.js +19 -6
  134. package/src/client/application/app-shell/ui-feature-toolbar.js +16 -129
  135. package/src/client/application/app-shell-elements.js +8 -0
  136. package/src/client/application/preview-render-compiler.js +1 -87
  137. package/src/client/application/preview-render-scheduler.js +8 -24
  138. package/src/client/application/preview-renderer.js +2 -2
  139. package/src/client/application/webmcp-diagram-renderer.js +47 -0
  140. package/src/client/application/workspace-coordinator.js +23 -4
  141. package/src/client/application/workspace-preview-controller.js +120 -2
  142. package/src/client/application/workspace-route-controller.js +11 -1
  143. package/src/client/assets/vendor/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
  144. package/src/client/assets/vendor/jetbrains-mono/OFL.txt +93 -0
  145. package/src/client/bootstrap/collabmd-app-shell.js +99 -6
  146. package/src/client/domain/document-formatter.js +193 -0
  147. package/src/client/domain/excalidraw-element-link.js +73 -0
  148. package/src/client/domain/excalidraw-scene.js +21 -0
  149. package/src/client/domain/file-search.js +73 -0
  150. package/src/client/domain/git-labels.js +5 -0
  151. package/src/client/domain/hash-routes.js +8 -0
  152. package/src/client/domain/room.js +1 -5
  153. package/src/client/domain/runtime-paths.js +5 -0
  154. package/src/client/domain/vault-paths.js +6 -4
  155. package/src/client/domain/wiki-link-completions.js +20 -20
  156. package/src/client/drawio-editor.js +8 -3
  157. package/src/client/excalidraw-editor.js +287 -16
  158. package/src/client/export/export-host.js +59 -36
  159. package/src/client/export/export-page.js +14 -4
  160. package/src/client/export/export-pipeline.js +270 -42
  161. package/src/client/infrastructure/agent-connection-api-client.js +23 -0
  162. package/src/client/infrastructure/auth-client.js +3 -13
  163. package/src/client/infrastructure/editor-session.js +15 -0
  164. package/src/client/infrastructure/editor-view-adapter.js +73 -14
  165. package/src/client/infrastructure/excalidraw-room-client.js +80 -1
  166. package/src/client/infrastructure/git-api-client.js +39 -33
  167. package/src/client/infrastructure/lobby-presence.js +2 -5
  168. package/src/client/infrastructure/runtime-config.js +11 -1
  169. package/src/client/infrastructure/tab-activity-lock.js +2 -5
  170. package/src/client/infrastructure/vault-api-client.js +33 -26
  171. package/src/client/infrastructure/webmcp-tool-registry.js +283 -0
  172. package/src/client/infrastructure/workspace-sync-client.js +6 -4
  173. package/src/client/presentation/agent-connection-controller.js +255 -0
  174. package/src/client/presentation/backlinks-panel.js +3 -0
  175. package/src/client/presentation/bases-preview-controller.js +59 -26
  176. package/src/client/presentation/comment-ui/comment-ui-card.js +4 -2
  177. package/src/client/presentation/create-menu-presenter.js +19 -16
  178. package/src/client/presentation/excalidraw-embed-controller.js +164 -4
  179. package/src/client/presentation/file-action-controller.js +15 -2
  180. package/src/client/presentation/file-explorer-controller.js +3 -0
  181. package/src/client/presentation/file-explorer-view.js +71 -12
  182. package/src/client/presentation/file-history-view-controller.js +19 -12
  183. package/src/client/presentation/file-tree-state.js +1 -11
  184. package/src/client/presentation/git-diff-view-controller.js +70 -53
  185. package/src/client/presentation/git-panel-controller.js +86 -32
  186. package/src/client/presentation/image-lightbox-controller.js +20 -16
  187. package/src/client/presentation/layout-controller.js +3 -1
  188. package/src/client/presentation/quick-switcher-controller.js +74 -232
  189. package/src/client/presentation/quick-switcher-text-search.js +10 -14
  190. package/src/client/styles/components/navigation.css +1 -2
  191. package/src/client/styles/components/scrollbars.css +10 -0
  192. package/src/client/styles/export-document.css +44 -29
  193. package/src/client/styles/features/agent-connection.css +202 -0
  194. package/src/client/styles/features/collaboration-chat.css +8 -1
  195. package/src/client/styles/features/collaboration-dialogs.css +16 -1
  196. package/src/client/styles/features/collaboration-presence.css +30 -5
  197. package/src/client/styles/features/diff-toolbar.css +1 -1
  198. package/src/client/styles/features/media-lightbox.css +12 -3
  199. package/src/client/styles/features/preview-markdown.css +54 -0
  200. package/src/client/styles/features/quick-switcher.css +20 -11
  201. package/src/client/styles/foundation/themes.css +2 -0
  202. package/src/client/styles/foundation/tokens.css +8 -0
  203. package/src/client/styles/layout/editor-page.css +25 -11
  204. package/src/client/styles/layout/responsive.css +2 -20
  205. package/src/client/styles/layout/shell.css +77 -24
  206. package/src/client/styles/layout/sidebar.css +7 -4
  207. package/src/client/styles/layout/view-modes.css +2 -0
  208. package/src/client/styles/overrides/codemirror.css +31 -19
  209. package/src/client/styles/primitives/controls.css +21 -54
  210. package/src/client/styles/style.css +1 -0
  211. package/src/client/styles/surfaces/excalidraw-editor.css +42 -0
  212. package/src/domain/agent-tool-definitions.js +796 -0
  213. package/src/domain/collabmd-content-capabilities.js +149 -0
  214. package/src/domain/collaboration-protocol.js +2 -0
  215. package/src/domain/comment-threads.js +3 -5
  216. package/src/domain/diagram-source.js +50 -0
  217. package/src/domain/editable-content-revision.js +10 -0
  218. package/src/domain/editable-text.js +3 -0
  219. package/src/domain/exact-text-edits.js +69 -0
  220. package/src/domain/excalidraw-agent-scene.js +522 -0
  221. package/src/domain/excalidraw-agent-verification.js +460 -0
  222. package/src/domain/excalidraw-room-codec.js +1 -5
  223. package/src/domain/file-kind.js +12 -1
  224. package/src/domain/video-embed.js +76 -0
  225. package/src/server/application/agent-connection-service.js +178 -0
  226. package/src/server/application/agent-content-service.js +773 -0
  227. package/src/server/application/workspace-reconciliation.js +5 -7
  228. package/src/server/config/env.js +51 -1
  229. package/src/server/create-app-server.js +36 -0
  230. package/src/server/domain/bases/base-query-service.js +1 -5
  231. package/src/server/domain/collaboration/collaboration-room.js +121 -25
  232. package/src/server/domain/collaboration/protocol.js +4 -0
  233. package/src/server/domain/hosted-workspace.js +21 -0
  234. package/src/server/domain/markdown-reference-extractor.js +15 -1
  235. package/src/server/domain/ripgrep-search-service.js +110 -37
  236. package/src/server/infrastructure/git/git-service.js +19 -1
  237. package/src/server/infrastructure/git/history-service.js +1 -1
  238. package/src/server/infrastructure/git/local-exclude.js +25 -0
  239. package/src/server/infrastructure/git/parsers.js +19 -17
  240. package/src/server/infrastructure/git/path-utils.js +0 -16
  241. package/src/server/infrastructure/git/status-service.js +1 -1
  242. package/src/server/infrastructure/git/untracked-files.js +12 -21
  243. package/src/server/infrastructure/http/create-agent-api-handler.js +171 -0
  244. package/src/server/infrastructure/http/create-git-api-command-handler.js +32 -0
  245. package/src/server/infrastructure/http/create-request-handler.js +28 -0
  246. package/src/server/infrastructure/http/create-static-handler.js +6 -0
  247. package/src/server/infrastructure/mcp/create-agent-mcp-handler.js +199 -0
  248. package/src/server/infrastructure/persistence/agent-connection-store.js +120 -0
  249. package/src/server/infrastructure/persistence/path-utils.js +10 -4
  250. package/src/server/infrastructure/persistence/pull-backup-store.js +2 -27
  251. package/src/server/infrastructure/persistence/vault-file-store.js +11 -2
  252. package/src/server/shared/agent-tool-image.js +22 -0
  253. package/src/server/shared/agent-tool-rate-limiter.js +20 -0
  254. package/src/server/startup/git-remote-bootstrap.js +5 -33
  255. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js +0 -1
  256. package/dist/client/assets/abnfDiagram-VCTEODGH-BNDLzJ7L.js +0 -1
  257. package/dist/client/assets/browser-utils--H_DkyEF.js +0 -1
  258. package/dist/client/assets/channel-CaoKA_We.js +0 -1
  259. package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +0 -2
  260. package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +0 -127
  261. package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +0 -10
  262. package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +0 -1
  263. package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +0 -1
  264. package/dist/client/assets/comment-threads-9J6Em-_y.js +0 -4
  265. package/dist/client/assets/comment-ui-shared-DWkk9Vh3.js +0 -7
  266. package/dist/client/assets/diagram-VSXAHHWV-CQRVEZR7.js +0 -3
  267. package/dist/client/assets/dist-73RPdcyU.js +0 -1
  268. package/dist/client/assets/dist-CH-sQu3r.js +0 -1
  269. package/dist/client/assets/drawio-editor-BjrxTe3l.js +0 -9
  270. package/dist/client/assets/drawioEditor-DUVZjSSr.js +0 -2
  271. package/dist/client/assets/ebnfDiagram-PWID7BFC-OXa8VEp1.js +0 -1
  272. package/dist/client/assets/editor-session-DfZuRgB_.js +0 -54
  273. package/dist/client/assets/embedded-editor-base-DvMynhKu.css +0 -1
  274. package/dist/client/assets/excalidraw-editor-D7pnUCLH.js +0 -9
  275. package/dist/client/assets/excalidraw-mermaid-stub-BNckbX2n.js +0 -1
  276. package/dist/client/assets/excalidraw-mermaid-stub-DE5FTiZB.js +0 -1
  277. package/dist/client/assets/excalidrawEditor-B0jOK3lv.js +0 -2
  278. package/dist/client/assets/export-page-Bs3xE1fg.js +0 -57
  279. package/dist/client/assets/exportDocument-Dg9MjkIk.js +0 -2
  280. package/dist/client/assets/exportDocument-PnYU3v1s.css +0 -1
  281. package/dist/client/assets/file-kind-BbqgGzpc.js +0 -1
  282. package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +0 -1
  283. package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +0 -1
  284. package/dist/client/assets/index-BIpgxyGZ.css +0 -1
  285. package/dist/client/assets/index-Z5sI0Bj-.js +0 -2
  286. package/dist/client/assets/main-Dwnj9Gaq.js +0 -903
  287. package/dist/client/assets/pegDiagram-XKGWAZYB-B31fKPR2.js +0 -1
  288. package/dist/client/assets/preview-render-compiler-BApvlLLo.js +0 -35
  289. package/dist/client/assets/preview-render-compiler-BQ_3h9vD.js +0 -1
  290. package/dist/client/assets/preview-render-profile-CE-5rVTC.js +0 -1
  291. package/dist/client/assets/prod-BiYPMR1i.js +0 -177
  292. package/dist/client/assets/prod-VxdGZ5Ly.js +0 -1
  293. package/dist/client/assets/quick-switcher-controller-ButWPmCI.js +0 -12
  294. package/dist/client/assets/railroadDiagram-O6MQD6OU-BPifP0MB.js +0 -1
  295. package/dist/client/assets/runtime-config-BLrEKVO1.js +0 -1
  296. package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +0 -1
  297. package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +0 -8
  298. package/dist/client/assets/vault-api-client-_LpV1aIn.js +0 -6
  299. package/dist/client/assets/vault-utils-wdQ0RNR9.js +0 -1
  300. package/src/client/app/drawio-editor-entry.js +0 -1
  301. package/src/client/app/excalidraw-editor-entry.js +0 -1
  302. package/src/client/excalidraw-mermaid-stub.js +0 -7
  303. package/src/client/main.js +0 -16
  304. /package/dist/client/assets/{drawio-editor-UQQ8XHou.css → drawioEditor-UQQ8XHou.css} +0 -0
  305. /package/dist/client/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
@@ -16,11 +16,7 @@ import {
16
16
  } from '../domain/workspace-state.js';
17
17
 
18
18
  function createEventId() {
19
- if (globalThis.crypto?.randomUUID) {
20
- return globalThis.crypto.randomUUID();
21
- }
22
-
23
- return `workspace-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
19
+ return globalThis.crypto.randomUUID();
24
20
  }
25
21
 
26
22
  function countWorkspacePaths(workspaceChange = {}) {
@@ -306,7 +302,7 @@ export class WorkspaceReconciliation {
306
302
  });
307
303
  }
308
304
 
309
- async writeEditableContent({ content, origin = 'api', path, requestId = null } = {}) {
305
+ async writeEditableContent({ content, origin = 'api', path, requestId = null, sourceRef = null } = {}) {
310
306
  const result = await this.vaultFileStore.writeEditableVaultContent(path, content);
311
307
  if (!result.ok) {
312
308
  return result;
@@ -316,6 +312,7 @@ export class WorkspaceReconciliation {
316
312
  action: 'write-file',
317
313
  origin,
318
314
  requestId,
315
+ sourceRef,
319
316
  workspaceChange: createWorkspaceChange({
320
317
  changedPaths: [path],
321
318
  }),
@@ -344,7 +341,7 @@ export class WorkspaceReconciliation {
344
341
  return result;
345
342
  }
346
343
 
347
- async createFile({ content = '', origin = 'api', path, requestId = null } = {}) {
344
+ async createFile({ content = '', origin = 'api', path, requestId = null, sourceRef = null } = {}) {
348
345
  const result = await this.vaultFileStore.createFile(path, content);
349
346
  if (!result.ok) {
350
347
  return result;
@@ -354,6 +351,7 @@ export class WorkspaceReconciliation {
354
351
  action: 'create-file',
355
352
  origin,
356
353
  requestId,
354
+ sourceRef,
357
355
  workspaceChange: createWorkspaceChange({
358
356
  changedPaths: [path],
359
357
  }),
@@ -406,11 +406,55 @@ function loadHostedConfig(overrides = {}, { authStrategy, vaultDir } = {}) {
406
406
  };
407
407
  }
408
408
 
409
+ function loadAgentAccessConfig(overrides = {}, { basePath, oidc, vaultDir } = {}) {
410
+ const enabled = overrides.enabled ?? parseBooleanFlag(
411
+ process.env.COLLABMD_AGENT_ACCESS_ENABLED,
412
+ false,
413
+ );
414
+ const publicHostname = oidc?.publicBaseUrl
415
+ ? new URL(oidc.publicBaseUrl).hostname.toLowerCase()
416
+ : '';
417
+ return {
418
+ allowedHosts: Array.from(new Set([
419
+ 'localhost',
420
+ '127.0.0.1',
421
+ '::1',
422
+ publicHostname,
423
+ ...normalizeCsvList(
424
+ overrides.allowedHosts ?? process.env.COLLABMD_AGENT_ALLOWED_HOSTS,
425
+ ).map((host) => host.toLowerCase()),
426
+ ].filter(Boolean))),
427
+ connectionTtlMs: parsePositiveInt(
428
+ overrides.connectionTtlMs ?? process.env.COLLABMD_AGENT_CONNECTION_TTL_MS,
429
+ 30 * 24 * 60 * 60 * 1000,
430
+ ),
431
+ dbPath: resolve(
432
+ overrides.dbPath
433
+ ?? process.env.COLLABMD_AGENT_METADATA_DB_PATH
434
+ ?? resolve(vaultDir, '.collabmd/agent-access.sqlite'),
435
+ ),
436
+ requestsPerMinute: parsePositiveInt(
437
+ overrides.requestsPerMinute ?? process.env.COLLABMD_AGENT_REQUESTS_PER_MINUTE,
438
+ 120,
439
+ ),
440
+ enabled,
441
+ endpoint: `${basePath}/mcp`,
442
+ };
443
+ }
444
+
445
+ function resolvePublicDir(nodeEnv) {
446
+ if (nodeEnv === 'test' && process.env.COLLABMD_E2E_PUBLIC_DIR) {
447
+ return resolve(process.env.COLLABMD_E2E_PUBLIC_DIR);
448
+ }
449
+
450
+ return resolve(projectRoot, 'dist/client');
451
+ }
452
+
409
453
  export function loadConfig(overrides = {}) {
410
454
  const nodeEnv = process.env.NODE_ENV || 'development';
411
455
  const vaultDir = resolveConfiguredVaultDir(overrides);
412
456
  const basePath = normalizeAppBasePath(process.env.BASE_PATH || '');
413
- const publicDir = resolve(projectRoot, 'dist/client');
457
+ const publicDir = resolvePublicDir(nodeEnv);
414
458
  const authOverrides = overrides.auth ?? {};
415
459
  const authStrategy = normalizeAuthStrategy(
416
460
  authOverrides.strategy
@@ -427,6 +471,11 @@ export function loadConfig(overrides = {}) {
427
471
  : null;
428
472
  const git = loadGitConfig(overrides.git);
429
473
  const hosted = loadHostedConfig(overrides.hosted, { authStrategy, vaultDir });
474
+ const agentAccess = loadAgentAccessConfig(overrides.agentAccess, {
475
+ basePath,
476
+ oidc,
477
+ vaultDir,
478
+ });
430
479
  const structurizr = loadStructurizrConfig(overrides.structurizr, { vaultDir });
431
480
  const build = loadBuildInfo({
432
481
  explicitBuildId: process.env.COLLABMD_BUILD_ID,
@@ -435,6 +484,7 @@ export function loadConfig(overrides = {}) {
435
484
  });
436
485
 
437
486
  return {
487
+ agentAccess,
438
488
  auth: {
439
489
  generatedPassword: passwordWasGenerated ? password : '',
440
490
  oidc,
@@ -2,6 +2,8 @@ import { createServer } from 'http';
2
2
  import { resolve } from 'node:path';
3
3
 
4
4
  import { loadConfig } from './config/env.js';
5
+ import { AgentConnectionService } from './application/agent-connection-service.js';
6
+ import { AgentContentService } from './application/agent-content-service.js';
5
7
  import { createAuthService } from './auth/create-auth-service.js';
6
8
  import { logPerfEvent } from './config/perf-logging.js';
7
9
  import { BacklinkIndex } from './domain/backlink-index.js';
@@ -10,6 +12,7 @@ import { CollaborationDocumentStore } from './domain/collaboration/collaboration
10
12
  import { CollaborationRoom } from './domain/collaboration/collaboration-room.js';
11
13
  import { renderDocx } from './domain/docx-exporter.js';
12
14
  import { GitService } from './infrastructure/git/git-service.js';
15
+ import { ensureCollabMetadataGitExclude } from './infrastructure/git/local-exclude.js';
13
16
  import { GitHubAppClient } from './infrastructure/github/github-app-client.js';
14
17
  import { GitHubSetupFlow } from './infrastructure/github/github-setup-flow.js';
15
18
  import { HostedWorkspaceService } from './domain/hosted-workspace.js';
@@ -18,6 +21,7 @@ import { StructurizrWorkspaceService } from './infrastructure/structurizr/struct
18
21
  import { RoomRegistry } from './domain/collaboration/room-registry.js';
19
22
  import { RipgrepSearchService } from './domain/ripgrep-search-service.js';
20
23
  import { createRequestHandler } from './infrastructure/http/create-request-handler.js';
24
+ import { AgentConnectionStore } from './infrastructure/persistence/agent-connection-store.js';
21
25
  import { HostedMetadataStore } from './infrastructure/persistence/hosted-metadata-store.js';
22
26
  import { VaultFileStore } from './infrastructure/persistence/vault-file-store.js';
23
27
  import { attachCollaborationGateway } from './infrastructure/websocket/attach-collaboration-gateway.js';
@@ -141,6 +145,23 @@ export function createAppServer(config = loadConfig()) {
141
145
  vaultDir: vaultFileStore.vaultDir,
142
146
  }),
143
147
  });
148
+ const agentConnectionStore = new AgentConnectionStore({
149
+ dbPath: config.agentAccess.dbPath,
150
+ });
151
+ const agentConnectionService = new AgentConnectionService({
152
+ authStrategy: config.auth.strategy,
153
+ connectionTtlMs: config.agentAccess.connectionTtlMs,
154
+ hostedWorkspaceService,
155
+ store: agentConnectionStore,
156
+ });
157
+ const agentContentService = new AgentContentService({
158
+ backlinkIndex,
159
+ plantUmlRenderer,
160
+ roomRegistry,
161
+ searchService,
162
+ vaultFileStore,
163
+ workspaceMutationCoordinator,
164
+ });
144
165
  vaultFileStore.setManagedWriteTracker(workspaceMutationCoordinator);
145
166
  fileSystemSyncService = new FileSystemSyncService({
146
167
  mutationCoordinator: workspaceMutationCoordinator,
@@ -164,6 +185,10 @@ export function createAppServer(config = loadConfig()) {
164
185
  hostedWorkspaceService,
165
186
  githubSetupFlow,
166
187
  structurizrWorkspaceService,
188
+ {
189
+ connectionService: agentConnectionService,
190
+ contentService: agentContentService,
191
+ },
167
192
  );
168
193
  const httpServer = createServer((req, res) => {
169
194
  requestHandler(req, res).catch((error) => {
@@ -194,7 +219,13 @@ export function createAppServer(config = loadConfig()) {
194
219
  async function listen() {
195
220
  const startupStartedAt = Date.now();
196
221
 
222
+ if (await gitService.isGitRepo()) {
223
+ await ensureCollabMetadataGitExclude(config.vaultDir);
224
+ }
197
225
  await hostedWorkspaceService.initialize();
226
+ if (config.agentAccess.enabled && config.auth.strategy !== 'none') {
227
+ await agentConnectionService.initialize();
228
+ }
198
229
 
199
230
  const searchCapabilityStartedAt = Date.now();
200
231
  config.search = await searchService.initialize();
@@ -306,6 +337,9 @@ export function createAppServer(config = loadConfig()) {
306
337
  closeHttpServer(httpServer),
307
338
  config.git?.cleanup?.(),
308
339
  hostedWorkspaceService.close(),
340
+ config.agentAccess.enabled && config.auth.strategy !== 'none'
341
+ ? agentConnectionStore.close()
342
+ : Promise.resolve(),
309
343
  ]);
310
344
  })().then(() => undefined);
311
345
 
@@ -314,6 +348,8 @@ export function createAppServer(config = loadConfig()) {
314
348
 
315
349
  return {
316
350
  close,
351
+ agentConnectionService,
352
+ agentContentService,
317
353
  collaborationGateway,
318
354
  config,
319
355
  httpServer,
@@ -87,17 +87,13 @@ function insertSortedBounded(rows, row, {
87
87
  }
88
88
  }
89
89
 
90
- function escapeRegExp(value = '') {
91
- return String(value ?? '').replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
92
- }
93
-
94
90
  function pruneFilterNodeForProperty(filterNode, propertyId = '') {
95
91
  if (!propertyId || !filterNode) {
96
92
  return filterNode;
97
93
  }
98
94
 
99
95
  if (typeof filterNode === 'string') {
100
- const escapedPropertyId = escapeRegExp(propertyId);
96
+ const escapedPropertyId = RegExp.escape(String(propertyId));
101
97
  const propertyFilterPattern = new RegExp(
102
98
  `^!?${escapedPropertyId}(?:\\.(?:contains|startsWith|endsWith|isEmpty)\\(.*\\)|\\s*(?:==|!=|>=|<=|>|<)\\s*.+)$`,
103
99
  'u',
@@ -4,12 +4,18 @@ import * as syncProtocol from 'y-protocols/sync';
4
4
  import * as encoding from 'lib0/encoding';
5
5
  import * as decoding from 'lib0/decoding';
6
6
 
7
- import { MSG_AWARENESS, MSG_SYNC } from './protocol.js';
7
+ import {
8
+ MSG_AGENT_FLUSH,
9
+ MSG_AGENT_FLUSH_ACK,
10
+ MSG_AWARENESS,
11
+ MSG_SYNC,
12
+ } from './protocol.js';
8
13
  import { CollaborationDocumentStore } from './collaboration-document-store.js';
9
14
  import { logPerfEvent } from '../../config/perf-logging.js';
10
15
  import { populateCommentThreads, serializeCommentThreads } from '../../../domain/comment-threads.js';
11
16
  import { getVaultFileKind } from '../../../domain/file-kind.js';
12
17
  import {
18
+ applySceneDiffToExcalidrawRoom,
13
19
  EXCALIDRAW_APP_STATE_KEY,
14
20
  EXCALIDRAW_ELEMENTS_KEY,
15
21
  EXCALIDRAW_FILES_KEY,
@@ -21,6 +27,7 @@ import {
21
27
  tryParseExcalidrawSceneJson,
22
28
  } from '../../../domain/excalidraw-room-codec.js';
23
29
  import { isDrawioLeaseRoom } from '../../../domain/drawio-room.js';
30
+ import { normalizeEditableText } from '../../../domain/editable-text.js';
24
31
  import { normalizeWorkspaceEvent } from '../../../domain/workspace-change.js';
25
32
  import { WORKSPACE_EVENT_MAX_MESSAGES, WORKSPACE_ROOM_NAME } from '../../../domain/workspace-room.js';
26
33
 
@@ -130,9 +137,6 @@ function isWorkspaceRoom(name) {
130
137
  return name === WORKSPACE_ROOM_NAME;
131
138
  }
132
139
 
133
- function normalizeEditableText(content) {
134
- return String(content ?? '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
135
- }
136
140
 
137
141
  function isContentCleanOrigin(origin) {
138
142
  return origin === 'hydrate'
@@ -171,6 +175,34 @@ function computeTextReplacement(currentContent, nextContent) {
171
175
  };
172
176
  }
173
177
 
178
+ function reconcileTextContent(baselineContent, currentContent, externalContent) {
179
+ const localReplacement = computeTextReplacement(baselineContent, currentContent);
180
+ const externalReplacement = computeTextReplacement(baselineContent, externalContent);
181
+ if (!externalReplacement) {
182
+ return { content: currentContent, preservesPendingChanges: true };
183
+ }
184
+
185
+ const localEnd = localReplacement.start + localReplacement.deleteCount;
186
+ const externalEnd = externalReplacement.start + externalReplacement.deleteCount;
187
+ let externalStart;
188
+ if (localEnd <= externalReplacement.start) {
189
+ externalStart = externalReplacement.start
190
+ + localReplacement.insertText.length
191
+ - localReplacement.deleteCount;
192
+ } else if (externalEnd <= localReplacement.start) {
193
+ externalStart = externalReplacement.start;
194
+ } else {
195
+ return { content: externalContent, preservesPendingChanges: false };
196
+ }
197
+
198
+ return {
199
+ content: currentContent.slice(0, externalStart)
200
+ + externalReplacement.insertText
201
+ + currentContent.slice(externalStart + externalReplacement.deleteCount),
202
+ preservesPendingChanges: true,
203
+ };
204
+ }
205
+
174
206
  export class CollaborationRoom {
175
207
  constructor({
176
208
  documentStore = null,
@@ -504,7 +536,8 @@ export class CollaborationRoom {
504
536
  snapshot: Y.encodeStateAsUpdate(this.doc),
505
537
  });
506
538
  if (includeContent) {
507
- this.resetContentBaseline();
539
+ this.persistedContentBaseline = content;
540
+ this.refreshContentDirty();
508
541
  }
509
542
  })();
510
543
 
@@ -568,29 +601,37 @@ export class CollaborationRoom {
568
601
  }
569
602
 
570
603
  const ytext = this.doc.getText('codemirror');
604
+ const currentContent = ytext.toString();
571
605
  const normalizedContent = normalizeEditableText(content);
572
- const replacement = computeTextReplacement(ytext.toString(), normalizedContent);
573
- if (!replacement && !replaceCommentThreads) {
574
- this.resetContentBaseline();
575
- return { highlightRange: null, ok: true, skipped: true };
576
- }
577
-
578
- this.doc.transact(() => {
579
- if (replacement?.deleteCount) {
580
- ytext.delete(replacement.start, replacement.deleteCount);
581
- }
582
- if (replacement?.insertText) {
583
- ytext.insert(replacement.start, replacement.insertText);
584
- }
585
- if (replaceCommentThreads) {
586
- if (comments.length > 0) {
587
- comments.delete(0, comments.length);
606
+ const reconciliation = this.refreshContentDirty() && this.persistedContentBaseline !== null
607
+ ? reconcileTextContent(this.persistedContentBaseline, currentContent, normalizedContent)
608
+ : { content: normalizedContent, preservesPendingChanges: false };
609
+ const replacement = computeTextReplacement(currentContent, reconciliation.content);
610
+ const skipped = !replacement && !replaceCommentThreads;
611
+ if (!skipped) {
612
+ this.doc.transact(() => {
613
+ if (replacement?.deleteCount) {
614
+ ytext.delete(replacement.start, replacement.deleteCount);
588
615
  }
589
- populateCommentThreads(comments, commentThreads);
590
- }
591
- }, 'workspace-reconcile');
616
+ if (replacement?.insertText) {
617
+ ytext.insert(replacement.start, replacement.insertText);
618
+ }
619
+ if (replaceCommentThreads) {
620
+ if (comments.length > 0) {
621
+ comments.delete(0, comments.length);
622
+ }
623
+ populateCommentThreads(comments, commentThreads);
624
+ }
625
+ }, 'workspace-reconcile');
626
+ }
592
627
 
593
- this.resetContentBaseline();
628
+ if (reconciliation.preservesPendingChanges) {
629
+ this.persistedContentBaseline = normalizedContent;
630
+ this.refreshContentDirty();
631
+ this.schedulePersist();
632
+ } else {
633
+ this.resetContentBaseline();
634
+ }
594
635
  return {
595
636
  highlightRange: replacement
596
637
  ? {
@@ -599,6 +640,7 @@ export class CollaborationRoom {
599
640
  }
600
641
  : null,
601
642
  ok: true,
643
+ ...(skipped && { skipped: true }),
602
644
  };
603
645
  }
604
646
 
@@ -832,6 +874,47 @@ export class CollaborationRoom {
832
874
  return true;
833
875
  }
834
876
 
877
+ isHydrated() {
878
+ return this.hydrated;
879
+ }
880
+
881
+ readEditableContent() {
882
+ if (!this.hydrated || this.deleted || this.destroyed || isExcalidrawRoom(this.name)) {
883
+ return null;
884
+ }
885
+ return this.doc.getText('codemirror').toString();
886
+ }
887
+
888
+ applyExactTextChanges(changes, { origin = 'agent' } = {}) {
889
+ if (!this.hydrated || this.deleted || this.destroyed || isExcalidrawRoom(this.name)) {
890
+ throw new Error('The collaborative document is unavailable');
891
+ }
892
+ const ytext = this.doc.getText('codemirror');
893
+ this.doc.transact(() => {
894
+ for (let index = changes.length - 1; index >= 0; index -= 1) {
895
+ const change = changes[index];
896
+ if (change.to > change.from) {
897
+ ytext.delete(change.from, change.to - change.from);
898
+ }
899
+ if (change.insert) {
900
+ ytext.insert(change.from, change.insert);
901
+ }
902
+ }
903
+ }, origin);
904
+ return changes.length;
905
+ }
906
+
907
+ applyExcalidrawScene(scene, { origin = 'agent' } = {}) {
908
+ if (!this.hydrated || this.deleted || this.destroyed || !isExcalidrawRoom(this.name)) {
909
+ throw new Error('The collaborative Excalidraw document is unavailable');
910
+ }
911
+ let changed = false;
912
+ this.doc.transact(() => {
913
+ changed = applySceneDiffToExcalidrawRoom(this.doc, scene);
914
+ }, origin);
915
+ return changed;
916
+ }
917
+
835
918
  getPersistedContent() {
836
919
  if (isWorkspaceRoom(this.name)) {
837
920
  return null;
@@ -897,6 +980,19 @@ export class CollaborationRoom {
897
980
  break;
898
981
  }
899
982
 
983
+ case MSG_AGENT_FLUSH: {
984
+ const requestId = decoding.readVarString(decoder);
985
+ if (!requestId || requestId.length > 128) {
986
+ break;
987
+ }
988
+
989
+ const encoder = encoding.createEncoder();
990
+ encoding.writeVarUint(encoder, MSG_AGENT_FLUSH_ACK);
991
+ encoding.writeVarString(encoder, requestId);
992
+ sendMessage.call(this, ws, encoding.toUint8Array(encoder), this);
993
+ break;
994
+ }
995
+
900
996
  default:
901
997
  console.warn(`[room:${this.name}] Unsupported message type: ${messageType}`);
902
998
  }
@@ -1,2 +1,6 @@
1
1
  export const MSG_SYNC = 0;
2
2
  export const MSG_AWARENESS = 1;
3
+ export {
4
+ MSG_AGENT_FLUSH,
5
+ MSG_AGENT_FLUSH_ACK,
6
+ } from '../../../domain/collaboration-protocol.js';
@@ -730,6 +730,27 @@ export class HostedWorkspaceService {
730
730
  return { ok: true };
731
731
  }
732
732
 
733
+ async recordAgentConnectionEvent({ connection, type, user }) {
734
+ if (!this.enabled) return;
735
+ const access = await this.authorizeWorkspaceAccess({ user });
736
+ if (!access.ok) {
737
+ throw createHostedError(access.statusCode, access.body.error, access.body.code);
738
+ }
739
+ await this.store.createAuditEvent(createAuditEvent({
740
+ actor: access.membership,
741
+ metadata: {
742
+ clientKind: connection.clientKind,
743
+ connectionId: connection.id,
744
+ expiresAt: connection.expiresAt,
745
+ label: connection.label,
746
+ scopes: connection.scopes,
747
+ },
748
+ targetRole: access.membership.role,
749
+ timestamp: nowMs(),
750
+ type,
751
+ }));
752
+ }
753
+
733
754
  async listAuditEvents(user) {
734
755
  await this.requireAdmin(user);
735
756
  return (await this.store.listAuditEvents()).map(publicAuditEvent);
@@ -130,6 +130,18 @@ export function createReferenceTargetAliasMap(renamedEntries = []) {
130
130
 
131
131
  return aliases;
132
132
  }
133
+ export function collectMarkdownImageSources(markdownText = '') {
134
+ const sources = [];
135
+ String(markdownText ?? '').split('\n').forEach((line, lineIndex) => {
136
+ MARKDOWN_IMAGE_OPEN_RE.lastIndex = 0;
137
+ while (MARKDOWN_IMAGE_OPEN_RE.exec(line) !== null) {
138
+ const source = parseMarkdownImageDestination(line.slice(MARKDOWN_IMAGE_OPEN_RE.lastIndex));
139
+ if (source) sources.push({ line: lineIndex + 1, source });
140
+ }
141
+ });
142
+ return sources;
143
+ }
144
+
133
145
 
134
146
  export function collectMarkdownReferences(markdownText = '', {
135
147
  sourceFilePath = '',
@@ -139,7 +151,7 @@ export function collectMarkdownReferences(markdownText = '', {
139
151
  const references = [];
140
152
  const lines = String(markdownText ?? '').split('\n');
141
153
 
142
- for (const line of lines) {
154
+ for (const [lineIndex, line] of lines.entries()) {
143
155
  const context = line.trim();
144
156
 
145
157
  INTERNAL_LINK_RE.lastIndex = 0;
@@ -155,6 +167,7 @@ export function collectMarkdownReferences(markdownText = '', {
155
167
  references.push({
156
168
  context,
157
169
  isEmbed: Boolean(linkMatch[1]),
170
+ line: lineIndex + 1,
158
171
  rawTarget,
159
172
  rawTargetKey: normalizeReferenceTargetKey(rawTarget),
160
173
  resolvedPath,
@@ -176,6 +189,7 @@ export function collectMarkdownReferences(markdownText = '', {
176
189
  references.push({
177
190
  context,
178
191
  isEmbed: true,
192
+ line: lineIndex + 1,
179
193
  rawTarget,
180
194
  rawTargetKey: normalizeReferenceTargetKey(targetPath),
181
195
  resolvedPath,