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.
- package/README.md +70 -11
- package/bin/collabmd.js +3 -0
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-C-nmgL5g.js +1 -0
- package/dist/client/assets/JetBrainsMono-Regular-BQaDgvhP.woff2 +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-CdVZqicp.js +1 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-I39sYjHI.js → architectureDiagram-5GKGNRK7-wUo0bXif.js} +3 -3
- package/dist/client/assets/babel-CY5KOv-I.js +16 -0
- package/dist/client/assets/{blockDiagram-NRAW4CY4-C6DtJy5Y.js → blockDiagram-I7D4REHJ-BRSK3m49.js} +4 -4
- package/dist/client/assets/browser-utils-DbXSMI-6.js +1 -0
- package/dist/client/assets/{c4Diagram-UCG6FXSJ-CtWtxS9_.js → c4Diagram-7LVT6UL2-yD2poxqw.js} +1 -1
- package/dist/client/assets/channel-Fa4GS_-F.js +1 -0
- package/dist/client/assets/chunk-2E4U76K2-BPnTT-J3.js +2 -0
- package/dist/client/assets/{chunk-TEH6E4GO-DVayPj-q.js → chunk-4HAMMTFA-DStbIfJ1.js} +20 -20
- package/dist/client/assets/{chunk-75Z2AOVW-CdFSaPjz.js → chunk-75Z2AOVW-C5pGd3W9.js} +1 -1
- package/dist/client/assets/{chunk-CLGD4ZFX-DQLgbQrv.js → chunk-CLGD4ZFX-BMeArk03.js} +1 -1
- package/dist/client/assets/chunk-DU6HZSFF-Zkp69c6c.js +127 -0
- package/dist/client/assets/{chunk-F27PBJKO-CNHIFhjo.js → chunk-F27PBJKO-D4xNct1r.js} +1 -1
- package/dist/client/assets/{chunk-GMAD6QVW-CbcBqPM5.js → chunk-GMAD6QVW-NZ6WpDb8.js} +1 -1
- package/dist/client/assets/{chunk-OBVCFTLP-BJR7u1jh.js → chunk-GVQU2GXP-D8SDprfX.js} +1 -1
- package/dist/client/assets/{chunk-G27WJ6UU-D9-eg537.js → chunk-IMKFNOWR-D8jEuU3Q.js} +2 -2
- package/dist/client/assets/{chunk-JQ64N6SF-DSFNH4bh.js → chunk-L3NEJ4N5-aijKP-eh.js} +1 -1
- package/dist/client/assets/chunk-OSK3NFVY-CCbLQAMa.js +10 -0
- package/dist/client/assets/{chunk-P2QGCYS3-BRpqY32H.js → chunk-P2QGCYS3-Oag_FdCq.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-Cb4SlVZF.js → chunk-POPQ4Y6H-CYnpIgXT.js} +1 -1
- package/dist/client/assets/{chunk-PWAF6VOD-Cz8IwBB5.js → chunk-PWAF6VOD-JSNrcBmP.js} +1 -1
- package/dist/client/assets/{chunk-RM4UPSZO-CWRwxNWJ.js → chunk-RM4UPSZO-DOWllDY8.js} +4 -4
- package/dist/client/assets/{chunk-RHFEMEQ7-CWY8cf4H.js → chunk-SHT3W25Y-BiQGljao.js} +5 -5
- package/dist/client/assets/{chunk-SVP7TREG-CyHOmcac.js → chunk-SVP7TREG-DB485R5x.js} +1 -1
- package/dist/client/assets/{chunk-LCL6LL3I-DmDkVukh.js → chunk-TICWLB2K-8rAVvoS3.js} +4 -4
- package/dist/client/assets/{chunk-CKBBP62Z-DG26UiBv.js → chunk-TLUHSLCS-DTY5v0aj.js} +2 -2
- package/dist/client/assets/classDiagram-ZZMXUADV-BsQWoR3Q.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-BsQWoR3Q.js +1 -0
- package/dist/client/assets/{comment-thread-store-CdcwrObc.js → comment-thread-store-CX98zR6q.js} +1 -1
- package/dist/client/assets/comment-threads-BnRwo5B9.js +4 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CdTPi2yO.js → cynefinDiagram-5FMLGOSQ-rTz9RhFH.js} +1 -1
- package/dist/client/assets/{dagre-3AP2YEHR-5gtJtd0O.js → dagre-GXQ25YYZ-Cr67wLpQ.js} +2 -2
- package/dist/client/assets/{diagram-S7CK7UJ4-BudWz9WU.js → diagram-S7CK7UJ4-DywERe__.js} +2 -2
- package/dist/client/assets/{diagram-UQ7AKVKN-3v4rbH-s.js → diagram-UQ7AKVKN-CNYlXtu4.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-0H1a61Bn.js +3 -0
- package/dist/client/assets/{diagram-VX7I27RA-C_-rj0sw.js → diagram-VX7I27RA-CsJbsx5F.js} +1 -1
- package/dist/client/assets/{diagram-Z3DM3KII-B4yxavgj.js → diagram-Z3DM3KII-D0mLxEgI.js} +1 -1
- package/dist/client/assets/dist--hk9I5HQ.js +1 -0
- package/dist/client/assets/{dist-DutPuFmC.js → dist-B1XEa-Zs.js} +1 -1
- package/dist/client/assets/dist-Bd1JucQF.js +1 -0
- package/dist/client/assets/{dist-DZAAWTG-.js → dist-C0G3AaXG.js} +1 -1
- package/dist/client/assets/dist-ChRoo3IB.js +9 -0
- package/dist/client/assets/dist-Dm4w5UId.js +1 -0
- package/dist/client/assets/{dist-B_yQaEv_.js → dist-DpYDHR9p.js} +1 -1
- package/dist/client/assets/{dist-CietwTVS.js → dist-DzNmC81X.js} +1 -1
- package/dist/client/assets/{dist-DDUn5zTz.js → dist-GvvCNBe4.js} +1 -1
- package/dist/client/assets/dist-JaU3aRlD.js +19 -0
- package/dist/client/assets/{dist-Bw3VIE_v.js → dist-TW8iFRyW.js} +1 -1
- package/dist/client/assets/{dist-Dir5dDKZ.js → dist-jVU5Be5P.js} +1 -1
- package/dist/client/assets/document-formatter-rDDjRfZ2.js +2 -0
- package/dist/client/assets/drawioEditor-JubEEha7.js +9 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-HeTxHpCU.js +1 -0
- package/dist/client/assets/editor-session-Bk6oIvSr.js +54 -0
- package/dist/client/assets/embedded-editor-base-BlCgz6mw.css +1 -0
- package/dist/client/assets/{erDiagram-SSCWMZ5O-C-iy6VkX.js → erDiagram-RLTQ6QDP-CbrDdd5P.js} +2 -2
- package/dist/client/assets/{es-CAsWR6hG.js → es-Bfdp096f.js} +13 -13
- package/dist/client/assets/estree-CuT_pB8K.js +44 -0
- package/dist/client/assets/excalidraw-element-link-YLIaTnVF.js +7 -0
- package/dist/client/assets/{excalidraw-scene-BOben2gr.js → excalidraw-scene-6uROebca.js} +1 -1
- package/dist/client/assets/{excalidraw-editor-BlcN6umJ.css → excalidrawEditor-BbSbI80a.css} +1 -1
- package/dist/client/assets/excalidrawEditor-dBMbRX_S.js +9 -0
- package/dist/client/assets/export-page-CRRQ2NEl.js +57 -0
- package/dist/client/assets/exportDocument-BlQRd9_m.js +2 -0
- package/dist/client/assets/exportDocument-CNSbjZwu.css +1 -0
- package/dist/client/assets/{file-icon-svg-CQAjlWjK.js → file-icon-svg-Y_kpF957.js} +1 -1
- package/dist/client/assets/file-kind-BwMIcZbi.js +1 -0
- package/dist/client/assets/file-search-DDLyyLDU.js +1 -0
- package/dist/client/assets/flowDiagram-HODETNUW-D5Gy0wmg.js +1 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DtKHAbez.js → ganttDiagram-EL5Y4UJY-BHgOYiZz.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-oue8fQ5o.js → gitGraphDiagram-WWUBYQGX-Dl__X3Sk.js} +1 -1
- package/dist/client/assets/html-Cdnr2qzU.js +25 -0
- package/dist/client/assets/image-ZVKINSPA-DgzW5zAy.js +1 -0
- package/dist/client/assets/index-D3RER1SZ.js +1023 -0
- package/dist/client/assets/index-DREVKl_K.css +1 -0
- package/dist/client/assets/{infoDiagram-RXCK75RN-BMzo6KIn.js → infoDiagram-27XIBGKW-DBpoANC9.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BIM3h287.js → ishikawaDiagram-5VMMS53U-BMPC6hfp.js} +1 -1
- package/dist/client/assets/{journeyDiagram-EYS64GPL-mF6Lh8O-.js → journeyDiagram-3NMN7TZE-B1sApUmM.js} +2 -2
- package/dist/client/assets/{kanban-definition-3QL26DDD-DLN2NyoR.js → kanban-definition-UXKFOSKX-C9yP4td1.js} +4 -4
- package/dist/client/assets/{line-BfTWJmgf.js → line-BFl3ujec.js} +1 -1
- package/dist/client/assets/markdown-CByV-4CU.js +70 -0
- package/dist/client/assets/{mermaid.core-CLZBlpIW.js → mermaid.core-BrY09czX.js} +5 -5
- package/dist/client/assets/mermaid.core-DfcNfOTv.js +1 -0
- package/dist/client/assets/{mindmap-definition-FBJOCRG2-CRyHaHTk.js → mindmap-definition-YA3MSWOX-BUQHcYbK.js} +8 -8
- package/dist/client/assets/pegDiagram-XKGWAZYB-Bi2Iml7Z.js +1 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-B5OZPb88.js → pieDiagram-E7YTZNPT-_gYXnMoi.js} +1 -1
- package/dist/client/assets/preview-render-compiler-CfxJYldJ.js +41 -0
- package/dist/client/assets/preview-render-compiler-Cu8_i9iS.js +1 -0
- package/dist/client/assets/{preview-render-worker-BmN79bVc.js → preview-render-worker-c4Yi93qW.js} +41 -35
- package/dist/client/assets/prod-BiJL30sl.js +1 -0
- package/dist/client/assets/prod-qAk7rHa4.js +177 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Drrw14YH.js → quadrantDiagram-AXDQQJYC-DwexhEhd.js} +1 -1
- package/dist/client/assets/quick-switcher-controller-BoIK_wuG.js +1 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BVA5UbMu.js +1 -0
- package/dist/client/assets/{requirementDiagram-EFPCY7ZU-CRZG6mRB.js → requirementDiagram-BXWQKSXE-C4cKwiIw.js} +2 -2
- package/dist/client/assets/runtime-config-DcmnGcXU.js +1 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-DvarEJpo.js → sankeyDiagram-P5KCCOFB-B5HHkRT2.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-B4oWlb-w.js → sequenceDiagram-WJ2MYXX4-BX6jqJFD.js} +6 -6
- package/dist/client/assets/standalone-6z5x8CWe.js +29 -0
- package/dist/client/assets/{stateDiagram-HBIQ2CUA-qbHIIqRZ.js → stateDiagram-D77RDMKH-CmqxyRGx.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-zoLLQVyh.js +1 -0
- package/dist/client/assets/{swimlanes-XN3QIQJK-xB6CtUGj.js → swimlanes-42K2YHIH-Bmgb9Zld.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DS-KQN37.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-Lj_yTNlY.js → timeline-definition-24CTP7MA-BA-lVH6P.js} +1 -1
- package/dist/client/assets/vault-api-client-iZLhMJKe.js +6 -0
- package/dist/client/assets/{vennDiagram-4TSXK5OY-BekRp5Y0.js → vennDiagram-4TSXK5OY-DNdUC_Xj.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-kdnV_Hdm.js → wardleyDiagram-VM6X3IG4-C2oY-YbF.js} +1 -1
- package/dist/client/assets/wiki-link-resolver-DFIwErjc.js +1 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DufGwNSB.js → xychartDiagram-S5SC5T6Z-CoIR8CBX.js} +1 -1
- package/dist/client/assets/yaml-9ltHPDNO.js +154 -0
- package/dist/client/assets/{yjs-provider-reset-guard-DE0vINDP.js → yjs-provider-reset-guard-9ul1qF6k.js} +1 -1
- package/dist/client/drawio-editor.html +11 -3
- package/dist/client/excalidraw-editor.html +45 -2
- package/dist/client/export-document.html +3 -3
- package/dist/client/index.html +106 -52
- package/integrations/pi/index.ts +94 -0
- package/package.json +41 -29
- package/src/client/app/drawio-editor.html +2 -2
- package/src/client/app/excalidraw-editor.html +2 -2
- package/src/client/app/export-document.html +1 -1
- package/src/client/app/index.html +88 -50
- package/src/client/app/main-entry.js +15 -1
- package/src/client/application/app-shell/chat-feature.js +7 -22
- package/src/client/application/app-shell/export-feature.js +17 -1
- package/src/client/application/app-shell/git-feature.js +51 -14
- package/src/client/application/app-shell/presence-feature.js +8 -25
- package/src/client/application/app-shell/ui-feature-identity.js +13 -0
- package/src/client/application/app-shell/ui-feature-shell.js +199 -99
- package/src/client/application/app-shell/ui-feature-sidebar.js +43 -7
- package/src/client/application/app-shell/ui-feature-tab-activity.js +19 -6
- package/src/client/application/app-shell/ui-feature-toolbar.js +16 -129
- package/src/client/application/app-shell-elements.js +8 -0
- package/src/client/application/preview-render-compiler.js +1 -87
- package/src/client/application/preview-render-scheduler.js +8 -24
- package/src/client/application/preview-renderer.js +2 -2
- package/src/client/application/webmcp-diagram-renderer.js +47 -0
- package/src/client/application/workspace-coordinator.js +23 -4
- package/src/client/application/workspace-preview-controller.js +120 -2
- package/src/client/application/workspace-route-controller.js +11 -1
- package/src/client/assets/vendor/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
- package/src/client/assets/vendor/jetbrains-mono/OFL.txt +93 -0
- package/src/client/bootstrap/collabmd-app-shell.js +99 -6
- package/src/client/domain/document-formatter.js +193 -0
- package/src/client/domain/excalidraw-element-link.js +73 -0
- package/src/client/domain/excalidraw-scene.js +21 -0
- package/src/client/domain/file-search.js +73 -0
- package/src/client/domain/git-labels.js +5 -0
- package/src/client/domain/hash-routes.js +8 -0
- package/src/client/domain/room.js +1 -5
- package/src/client/domain/runtime-paths.js +5 -0
- package/src/client/domain/vault-paths.js +6 -4
- package/src/client/domain/wiki-link-completions.js +20 -20
- package/src/client/drawio-editor.js +8 -3
- package/src/client/excalidraw-editor.js +287 -16
- package/src/client/export/export-host.js +59 -36
- package/src/client/export/export-page.js +14 -4
- package/src/client/export/export-pipeline.js +270 -42
- package/src/client/infrastructure/agent-connection-api-client.js +23 -0
- package/src/client/infrastructure/auth-client.js +3 -13
- package/src/client/infrastructure/editor-session.js +15 -0
- package/src/client/infrastructure/editor-view-adapter.js +73 -14
- package/src/client/infrastructure/excalidraw-room-client.js +80 -1
- package/src/client/infrastructure/git-api-client.js +39 -33
- package/src/client/infrastructure/lobby-presence.js +2 -5
- package/src/client/infrastructure/runtime-config.js +11 -1
- package/src/client/infrastructure/tab-activity-lock.js +2 -5
- package/src/client/infrastructure/vault-api-client.js +33 -26
- package/src/client/infrastructure/webmcp-tool-registry.js +283 -0
- package/src/client/infrastructure/workspace-sync-client.js +6 -4
- package/src/client/presentation/agent-connection-controller.js +255 -0
- package/src/client/presentation/backlinks-panel.js +3 -0
- package/src/client/presentation/bases-preview-controller.js +59 -26
- package/src/client/presentation/comment-ui/comment-ui-card.js +4 -2
- package/src/client/presentation/create-menu-presenter.js +19 -16
- package/src/client/presentation/excalidraw-embed-controller.js +164 -4
- package/src/client/presentation/file-action-controller.js +15 -2
- package/src/client/presentation/file-explorer-controller.js +3 -0
- package/src/client/presentation/file-explorer-view.js +71 -12
- package/src/client/presentation/file-history-view-controller.js +19 -12
- package/src/client/presentation/file-tree-state.js +1 -11
- package/src/client/presentation/git-diff-view-controller.js +70 -53
- package/src/client/presentation/git-panel-controller.js +86 -32
- package/src/client/presentation/image-lightbox-controller.js +20 -16
- package/src/client/presentation/layout-controller.js +3 -1
- package/src/client/presentation/quick-switcher-controller.js +74 -232
- package/src/client/presentation/quick-switcher-text-search.js +10 -14
- package/src/client/styles/components/navigation.css +1 -2
- package/src/client/styles/components/scrollbars.css +10 -0
- package/src/client/styles/export-document.css +44 -29
- package/src/client/styles/features/agent-connection.css +202 -0
- package/src/client/styles/features/collaboration-chat.css +8 -1
- package/src/client/styles/features/collaboration-dialogs.css +16 -1
- package/src/client/styles/features/collaboration-presence.css +30 -5
- package/src/client/styles/features/diff-toolbar.css +1 -1
- package/src/client/styles/features/media-lightbox.css +12 -3
- package/src/client/styles/features/preview-markdown.css +54 -0
- package/src/client/styles/features/quick-switcher.css +20 -11
- package/src/client/styles/foundation/themes.css +2 -0
- package/src/client/styles/foundation/tokens.css +8 -0
- package/src/client/styles/layout/editor-page.css +25 -11
- package/src/client/styles/layout/responsive.css +2 -20
- package/src/client/styles/layout/shell.css +77 -24
- package/src/client/styles/layout/sidebar.css +7 -4
- package/src/client/styles/layout/view-modes.css +2 -0
- package/src/client/styles/overrides/codemirror.css +31 -19
- package/src/client/styles/primitives/controls.css +21 -54
- package/src/client/styles/style.css +1 -0
- package/src/client/styles/surfaces/excalidraw-editor.css +42 -0
- package/src/domain/agent-tool-definitions.js +796 -0
- package/src/domain/collabmd-content-capabilities.js +149 -0
- package/src/domain/collaboration-protocol.js +2 -0
- package/src/domain/comment-threads.js +3 -5
- package/src/domain/diagram-source.js +50 -0
- package/src/domain/editable-content-revision.js +10 -0
- package/src/domain/editable-text.js +3 -0
- package/src/domain/exact-text-edits.js +69 -0
- package/src/domain/excalidraw-agent-scene.js +522 -0
- package/src/domain/excalidraw-agent-verification.js +460 -0
- package/src/domain/excalidraw-room-codec.js +1 -5
- package/src/domain/file-kind.js +12 -1
- package/src/domain/video-embed.js +76 -0
- package/src/server/application/agent-connection-service.js +178 -0
- package/src/server/application/agent-content-service.js +773 -0
- package/src/server/application/workspace-reconciliation.js +5 -7
- package/src/server/config/env.js +51 -1
- package/src/server/create-app-server.js +36 -0
- package/src/server/domain/bases/base-query-service.js +1 -5
- package/src/server/domain/collaboration/collaboration-room.js +121 -25
- package/src/server/domain/collaboration/protocol.js +4 -0
- package/src/server/domain/hosted-workspace.js +21 -0
- package/src/server/domain/markdown-reference-extractor.js +15 -1
- package/src/server/domain/ripgrep-search-service.js +110 -37
- package/src/server/infrastructure/git/git-service.js +19 -1
- package/src/server/infrastructure/git/history-service.js +1 -1
- package/src/server/infrastructure/git/local-exclude.js +25 -0
- package/src/server/infrastructure/git/parsers.js +19 -17
- package/src/server/infrastructure/git/path-utils.js +0 -16
- package/src/server/infrastructure/git/status-service.js +1 -1
- package/src/server/infrastructure/git/untracked-files.js +12 -21
- package/src/server/infrastructure/http/create-agent-api-handler.js +171 -0
- package/src/server/infrastructure/http/create-git-api-command-handler.js +32 -0
- package/src/server/infrastructure/http/create-request-handler.js +28 -0
- package/src/server/infrastructure/http/create-static-handler.js +6 -0
- package/src/server/infrastructure/mcp/create-agent-mcp-handler.js +199 -0
- package/src/server/infrastructure/persistence/agent-connection-store.js +120 -0
- package/src/server/infrastructure/persistence/path-utils.js +10 -4
- package/src/server/infrastructure/persistence/pull-backup-store.js +2 -27
- package/src/server/infrastructure/persistence/vault-file-store.js +11 -2
- package/src/server/shared/agent-tool-image.js +22 -0
- package/src/server/shared/agent-tool-rate-limiter.js +20 -0
- package/src/server/startup/git-remote-bootstrap.js +5 -33
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js +0 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-BNDLzJ7L.js +0 -1
- package/dist/client/assets/browser-utils--H_DkyEF.js +0 -1
- package/dist/client/assets/channel-CaoKA_We.js +0 -1
- package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +0 -2
- package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +0 -127
- package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +0 -10
- package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +0 -1
- package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +0 -1
- package/dist/client/assets/comment-threads-9J6Em-_y.js +0 -4
- package/dist/client/assets/comment-ui-shared-DWkk9Vh3.js +0 -7
- package/dist/client/assets/diagram-VSXAHHWV-CQRVEZR7.js +0 -3
- package/dist/client/assets/dist-73RPdcyU.js +0 -1
- package/dist/client/assets/dist-CH-sQu3r.js +0 -1
- package/dist/client/assets/drawio-editor-BjrxTe3l.js +0 -9
- package/dist/client/assets/drawioEditor-DUVZjSSr.js +0 -2
- package/dist/client/assets/ebnfDiagram-PWID7BFC-OXa8VEp1.js +0 -1
- package/dist/client/assets/editor-session-DfZuRgB_.js +0 -54
- package/dist/client/assets/embedded-editor-base-DvMynhKu.css +0 -1
- package/dist/client/assets/excalidraw-editor-D7pnUCLH.js +0 -9
- package/dist/client/assets/excalidraw-mermaid-stub-BNckbX2n.js +0 -1
- package/dist/client/assets/excalidraw-mermaid-stub-DE5FTiZB.js +0 -1
- package/dist/client/assets/excalidrawEditor-B0jOK3lv.js +0 -2
- package/dist/client/assets/export-page-Bs3xE1fg.js +0 -57
- package/dist/client/assets/exportDocument-Dg9MjkIk.js +0 -2
- package/dist/client/assets/exportDocument-PnYU3v1s.css +0 -1
- package/dist/client/assets/file-kind-BbqgGzpc.js +0 -1
- package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +0 -1
- package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +0 -1
- package/dist/client/assets/index-BIpgxyGZ.css +0 -1
- package/dist/client/assets/index-Z5sI0Bj-.js +0 -2
- package/dist/client/assets/main-Dwnj9Gaq.js +0 -903
- package/dist/client/assets/pegDiagram-XKGWAZYB-B31fKPR2.js +0 -1
- package/dist/client/assets/preview-render-compiler-BApvlLLo.js +0 -35
- package/dist/client/assets/preview-render-compiler-BQ_3h9vD.js +0 -1
- package/dist/client/assets/preview-render-profile-CE-5rVTC.js +0 -1
- package/dist/client/assets/prod-BiYPMR1i.js +0 -177
- package/dist/client/assets/prod-VxdGZ5Ly.js +0 -1
- package/dist/client/assets/quick-switcher-controller-ButWPmCI.js +0 -12
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BPifP0MB.js +0 -1
- package/dist/client/assets/runtime-config-BLrEKVO1.js +0 -1
- package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +0 -1
- package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +0 -8
- package/dist/client/assets/vault-api-client-_LpV1aIn.js +0 -6
- package/dist/client/assets/vault-utils-wdQ0RNR9.js +0 -1
- package/src/client/app/drawio-editor-entry.js +0 -1
- package/src/client/app/excalidraw-editor-entry.js +0 -1
- package/src/client/excalidraw-mermaid-stub.js +0 -7
- package/src/client/main.js +0 -16
- /package/dist/client/assets/{drawio-editor-UQQ8XHou.css → drawioEditor-UQQ8XHou.css} +0 -0
- /package/dist/client/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { setDiagramActionButtonIcon } from '../domain/diagram-action-icons.js';
|
|
2
|
+
import { parseExcalidrawElementLink } from '../domain/excalidraw-element-link.js';
|
|
2
3
|
import { reconcileEmbedEntries } from './excalidraw-embed-reconciler.js';
|
|
3
|
-
import { resolveAppUrl, resolveWsServerOverride } from '../domain/runtime-paths.js';
|
|
4
|
+
import { resolveAppPath, resolveAppUrl, resolveWsServerOverride } from '../domain/runtime-paths.js';
|
|
4
5
|
import {
|
|
5
6
|
cancelIdleRender,
|
|
6
7
|
isNearViewport,
|
|
@@ -26,6 +27,7 @@ export class ExcalidrawEmbedController {
|
|
|
26
27
|
constructor({
|
|
27
28
|
getTheme,
|
|
28
29
|
getLocalUser,
|
|
30
|
+
onOpenElement = null,
|
|
29
31
|
onOpenFile = null,
|
|
30
32
|
onStopFollowing = null,
|
|
31
33
|
onToggleQuickSwitcher = null,
|
|
@@ -35,6 +37,7 @@ export class ExcalidrawEmbedController {
|
|
|
35
37
|
}) {
|
|
36
38
|
this.getTheme = getTheme;
|
|
37
39
|
this.getLocalUser = getLocalUser;
|
|
40
|
+
this.onOpenElement = onOpenElement;
|
|
38
41
|
this.onOpenFile = onOpenFile;
|
|
39
42
|
this.onStopFollowing = onStopFollowing;
|
|
40
43
|
this.onToggleQuickSwitcher = onToggleQuickSwitcher;
|
|
@@ -56,6 +59,8 @@ export class ExcalidrawEmbedController {
|
|
|
56
59
|
this.followedPeerIdsByFilePath = new Map();
|
|
57
60
|
this.pendingDisconnectRequests = new Map();
|
|
58
61
|
this.disconnectRequestCounter = 0;
|
|
62
|
+
this.pendingAgentBridgeRequests = new Map();
|
|
63
|
+
this.agentBridgeRequestCounter = 0;
|
|
59
64
|
|
|
60
65
|
this._onMessage = this._onMessage.bind(this);
|
|
61
66
|
this._onKeyDown = this._onKeyDown.bind(this);
|
|
@@ -96,6 +101,10 @@ export class ExcalidrawEmbedController {
|
|
|
96
101
|
request.resolve(false);
|
|
97
102
|
});
|
|
98
103
|
this.pendingDisconnectRequests.clear();
|
|
104
|
+
this.pendingAgentBridgeRequests.forEach((request) => {
|
|
105
|
+
request.resolve({ status: 'destroyed' });
|
|
106
|
+
});
|
|
107
|
+
this.pendingAgentBridgeRequests.clear();
|
|
99
108
|
this.followedPeerIdsByFilePath.clear();
|
|
100
109
|
this.overlayRoot?.remove();
|
|
101
110
|
this.overlayRoot = null;
|
|
@@ -251,6 +260,28 @@ export class ExcalidrawEmbedController {
|
|
|
251
260
|
return true;
|
|
252
261
|
}
|
|
253
262
|
|
|
263
|
+
openElement(filePath, elementId, elementType = 'element') {
|
|
264
|
+
if (!filePath || !elementId) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const entry = this._findEntryByFilePath(filePath);
|
|
269
|
+
if (!entry) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
entry.pendingElementFocus = {
|
|
274
|
+
elementId: String(elementId),
|
|
275
|
+
elementType: elementType === 'group' ? 'group' : 'element',
|
|
276
|
+
};
|
|
277
|
+
if (entry.isReady) {
|
|
278
|
+
this._postPendingElement(entry);
|
|
279
|
+
} else if (!entry.wrapper) {
|
|
280
|
+
this._enqueueHydration(entry, { prioritize: true });
|
|
281
|
+
}
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
|
|
254
285
|
prepareFileDisconnect(filePath, { timeoutMs = 10000 } = {}) {
|
|
255
286
|
const entry = this._findEntryByFilePath(filePath);
|
|
256
287
|
if (!entry?.iframe?.contentWindow) {
|
|
@@ -310,6 +341,73 @@ export class ExcalidrawEmbedController {
|
|
|
310
341
|
});
|
|
311
342
|
}
|
|
312
343
|
|
|
344
|
+
flushPendingAgentWrites(filePath, { signal = null, timeoutMs = 1500 } = {}) {
|
|
345
|
+
const entry = this._findEntryByFilePath(filePath);
|
|
346
|
+
if (
|
|
347
|
+
!entry?.isReady
|
|
348
|
+
|| !entry.iframe?.contentWindow
|
|
349
|
+
|| this._getEntryMode(entry) !== 'edit'
|
|
350
|
+
) {
|
|
351
|
+
return Promise.resolve({ status: 'not-active' });
|
|
352
|
+
}
|
|
353
|
+
return this._requestAgentBridge(
|
|
354
|
+
entry,
|
|
355
|
+
'flush-agent-writes',
|
|
356
|
+
{},
|
|
357
|
+
{ signal, timeoutMs },
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
waitForAgentPaint(filePath, revision, {
|
|
362
|
+
afterRevision = '',
|
|
363
|
+
signal = null,
|
|
364
|
+
timeoutMs = 5000,
|
|
365
|
+
} = {}) {
|
|
366
|
+
const entry = this._findEntryByFilePath(filePath);
|
|
367
|
+
if (!entry?.isReady || !entry.iframe?.contentWindow || !revision) {
|
|
368
|
+
return Promise.resolve({ status: 'not-active' });
|
|
369
|
+
}
|
|
370
|
+
return this._requestAgentBridge(
|
|
371
|
+
entry,
|
|
372
|
+
'wait-for-agent-revision',
|
|
373
|
+
{ afterRevision, revision },
|
|
374
|
+
{ signal, timeoutMs },
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
_requestAgentBridge(entry, type, payload, { signal, timeoutMs }) {
|
|
379
|
+
const requestId = `agent-bridge-${++this.agentBridgeRequestCounter}`;
|
|
380
|
+
return new Promise((resolve) => {
|
|
381
|
+
const finish = (value) => {
|
|
382
|
+
const request = this.pendingAgentBridgeRequests.get(requestId);
|
|
383
|
+
if (!request) return;
|
|
384
|
+
window.clearTimeout(request.timeoutId);
|
|
385
|
+
signal?.removeEventListener?.('abort', request.abort);
|
|
386
|
+
this.pendingAgentBridgeRequests.delete(requestId);
|
|
387
|
+
resolve(value);
|
|
388
|
+
};
|
|
389
|
+
const abort = () => finish({ status: 'cancelled' });
|
|
390
|
+
const timeoutId = window.setTimeout(() => finish({ status: 'timeout' }), timeoutMs);
|
|
391
|
+
this.pendingAgentBridgeRequests.set(requestId, {
|
|
392
|
+
abort,
|
|
393
|
+
entry,
|
|
394
|
+
resolve: finish,
|
|
395
|
+
timeoutId,
|
|
396
|
+
});
|
|
397
|
+
signal?.addEventListener?.('abort', abort, { once: true });
|
|
398
|
+
if (signal?.aborted) {
|
|
399
|
+
abort();
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
this._postMessageToEntry(entry, {
|
|
403
|
+
...payload,
|
|
404
|
+
requestId,
|
|
405
|
+
source: 'collabmd-host',
|
|
406
|
+
type,
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
313
411
|
_ensurePlaceholderObserver() {
|
|
314
412
|
if (!this.previewContainer) {
|
|
315
413
|
return;
|
|
@@ -419,6 +517,9 @@ export class ExcalidrawEmbedController {
|
|
|
419
517
|
|
|
420
518
|
if (!entry.wrapper) {
|
|
421
519
|
const mount = this._createEmbedContainer(entry);
|
|
520
|
+
if (!mount) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
422
523
|
entry.header = mount.header;
|
|
423
524
|
entry.wrapper = mount.wrapper;
|
|
424
525
|
entry.iframe = mount.iframe;
|
|
@@ -491,6 +592,7 @@ export class ExcalidrawEmbedController {
|
|
|
491
592
|
reusedEntry.key = nextEntry.key;
|
|
492
593
|
reusedEntry.label = nextEntry.label;
|
|
493
594
|
reusedEntry.placeholder = nextEntry.placeholder;
|
|
595
|
+
reusedEntry.pendingElementFocus = null;
|
|
494
596
|
reusedEntry.queued = false;
|
|
495
597
|
nextEntries.set(key, reusedEntry);
|
|
496
598
|
});
|
|
@@ -644,7 +746,12 @@ export class ExcalidrawEmbedController {
|
|
|
644
746
|
}
|
|
645
747
|
|
|
646
748
|
_buildIframeUrl(entry) {
|
|
647
|
-
|
|
749
|
+
let iframeUrl;
|
|
750
|
+
try {
|
|
751
|
+
iframeUrl = new URL(resolveAppUrl(EDITOR_IFRAME_PATH));
|
|
752
|
+
} catch {
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
648
755
|
const theme = this.getTheme?.() || 'dark';
|
|
649
756
|
|
|
650
757
|
iframeUrl.searchParams.set('file', entry.filePath);
|
|
@@ -687,6 +794,11 @@ export class ExcalidrawEmbedController {
|
|
|
687
794
|
}
|
|
688
795
|
|
|
689
796
|
_createEmbedContainer(entry) {
|
|
797
|
+
const iframeUrl = this._buildIframeUrl(entry);
|
|
798
|
+
if (!iframeUrl) {
|
|
799
|
+
return null;
|
|
800
|
+
}
|
|
801
|
+
|
|
690
802
|
const wrapper = document.createElement('div');
|
|
691
803
|
wrapper.className = 'excalidraw-embed diagram-preview-shell';
|
|
692
804
|
wrapper.dataset.embedKey = entry.key;
|
|
@@ -727,7 +839,7 @@ export class ExcalidrawEmbedController {
|
|
|
727
839
|
iframe.className = 'excalidraw-embed-iframe';
|
|
728
840
|
iframe.dataset.instanceId = String(++this.instanceCounter);
|
|
729
841
|
entry.instanceId = iframe.dataset.instanceId;
|
|
730
|
-
iframe.src =
|
|
842
|
+
iframe.src = iframeUrl.toString();
|
|
731
843
|
// The controller already lazy-hydrates embeds near the viewport, so the
|
|
732
844
|
// iframe should start loading immediately once it has been mounted.
|
|
733
845
|
iframe.setAttribute('loading', 'eager');
|
|
@@ -1030,6 +1142,7 @@ export class ExcalidrawEmbedController {
|
|
|
1030
1142
|
entry.bootMode = null;
|
|
1031
1143
|
entry.loadedFilePath = null;
|
|
1032
1144
|
entry.loadedMode = null;
|
|
1145
|
+
entry.pendingElementFocus = null;
|
|
1033
1146
|
entry.placeholder = null;
|
|
1034
1147
|
if (entry.wrapper.parentElement !== warmCacheRoot) {
|
|
1035
1148
|
warmCacheRoot.appendChild(entry.wrapper);
|
|
@@ -1053,7 +1166,11 @@ export class ExcalidrawEmbedController {
|
|
|
1053
1166
|
entry.bootMode = this._getEntryMode(entry);
|
|
1054
1167
|
entry.loadedFilePath = null;
|
|
1055
1168
|
entry.loadedMode = null;
|
|
1056
|
-
|
|
1169
|
+
const iframeUrl = this._buildIframeUrl(entry);
|
|
1170
|
+
if (!iframeUrl) {
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
entry.iframe.src = iframeUrl.toString();
|
|
1057
1174
|
this._armEntryBootTimeout(entry);
|
|
1058
1175
|
}
|
|
1059
1176
|
|
|
@@ -1218,6 +1335,7 @@ export class ExcalidrawEmbedController {
|
|
|
1218
1335
|
});
|
|
1219
1336
|
this._syncEntryFollowState(entry);
|
|
1220
1337
|
this._postPendingCommentThread?.(entry);
|
|
1338
|
+
this._postPendingElement?.(entry);
|
|
1221
1339
|
if (this._entryNeedsHardReload(entry)) {
|
|
1222
1340
|
void this._hydrateEntry(entry);
|
|
1223
1341
|
}
|
|
@@ -1234,6 +1352,17 @@ export class ExcalidrawEmbedController {
|
|
|
1234
1352
|
return;
|
|
1235
1353
|
}
|
|
1236
1354
|
|
|
1355
|
+
if (msg.type === 'open-element-link') {
|
|
1356
|
+
const target = parseExcalidrawElementLink(msg.href, {
|
|
1357
|
+
appPath: resolveAppPath('/'),
|
|
1358
|
+
origin: window.location.origin,
|
|
1359
|
+
});
|
|
1360
|
+
if (target) {
|
|
1361
|
+
this.onOpenElement?.(target);
|
|
1362
|
+
}
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1237
1366
|
if (msg.type === 'error') {
|
|
1238
1367
|
if (entry.isParked) {
|
|
1239
1368
|
return;
|
|
@@ -1252,6 +1381,23 @@ export class ExcalidrawEmbedController {
|
|
|
1252
1381
|
return;
|
|
1253
1382
|
}
|
|
1254
1383
|
|
|
1384
|
+
if (
|
|
1385
|
+
msg.type === 'agent-writes-flushed'
|
|
1386
|
+
|| msg.type === 'agent-revision-painted'
|
|
1387
|
+
|| msg.type === 'agent-revision-not-painted'
|
|
1388
|
+
) {
|
|
1389
|
+
const request = this.pendingAgentBridgeRequests.get(msg.requestId);
|
|
1390
|
+
if (request?.entry === entry) {
|
|
1391
|
+
request.resolve({
|
|
1392
|
+
...(msg.revision ? { revision: msg.revision } : {}),
|
|
1393
|
+
status: msg.status || (msg.type === 'agent-writes-flushed'
|
|
1394
|
+
? 'flushed'
|
|
1395
|
+
: (msg.type === 'agent-revision-painted' ? 'painted' : 'not-painted')),
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1255
1401
|
if (msg.type === 'disconnect-blocked') {
|
|
1256
1402
|
entry.authorityState = msg.state || 'reconnecting-readonly';
|
|
1257
1403
|
this.toastController?.show?.('Waiting for the diagram to reconnect before leaving');
|
|
@@ -1300,6 +1446,20 @@ export class ExcalidrawEmbedController {
|
|
|
1300
1446
|
entry.pendingCommentThreadId = null;
|
|
1301
1447
|
}
|
|
1302
1448
|
|
|
1449
|
+
_postPendingElement(entry) {
|
|
1450
|
+
if (!entry?.isReady || !entry.pendingElementFocus) {
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
this._postMessageToEntry(entry, {
|
|
1455
|
+
elementId: entry.pendingElementFocus.elementId,
|
|
1456
|
+
elementType: entry.pendingElementFocus.elementType,
|
|
1457
|
+
source: 'collabmd-host',
|
|
1458
|
+
type: 'focus-element',
|
|
1459
|
+
});
|
|
1460
|
+
entry.pendingElementFocus = null;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1303
1463
|
_requestPreviewViewportFit(entry) {
|
|
1304
1464
|
if (this._isFilePreviewEntry(entry)) {
|
|
1305
1465
|
return;
|
|
@@ -61,6 +61,7 @@ export class FileActionController {
|
|
|
61
61
|
mobileBreakpointQuery = (typeof window !== 'undefined' && typeof window.matchMedia === 'function')
|
|
62
62
|
? window.matchMedia('(max-width: 768px)')
|
|
63
63
|
: { matches: false },
|
|
64
|
+
onDirectoryExport,
|
|
64
65
|
onFileDelete,
|
|
65
66
|
onFileSelect,
|
|
66
67
|
onShowFileExtensionsChange,
|
|
@@ -72,6 +73,7 @@ export class FileActionController {
|
|
|
72
73
|
view,
|
|
73
74
|
refresh,
|
|
74
75
|
}) {
|
|
76
|
+
this.onDirectoryExport = onDirectoryExport;
|
|
75
77
|
this.onFileDelete = onFileDelete;
|
|
76
78
|
this.onFileSelect = onFileSelect;
|
|
77
79
|
this.onShowFileExtensionsChange = onShowFileExtensionsChange;
|
|
@@ -226,15 +228,26 @@ export class FileActionController {
|
|
|
226
228
|
|
|
227
229
|
getDirectoryContextMenuItems(directoryPath) {
|
|
228
230
|
return [
|
|
229
|
-
|
|
231
|
+
{
|
|
232
|
+
label: 'New…',
|
|
233
|
+
onSelect: ({ anchor } = {}) => this.openCreateMenu({ anchor, parentDir: directoryPath }),
|
|
234
|
+
},
|
|
230
235
|
{
|
|
231
236
|
label: 'Rename / move',
|
|
232
237
|
onSelect: () => this.handleRenameDirectory(directoryPath),
|
|
233
238
|
},
|
|
234
239
|
{
|
|
235
|
-
label: 'Download',
|
|
240
|
+
label: 'Download source ZIP',
|
|
236
241
|
onSelect: () => this.handleDownloadDirectory(directoryPath),
|
|
237
242
|
},
|
|
243
|
+
{
|
|
244
|
+
label: 'Export HTML',
|
|
245
|
+
onSelect: () => this.onDirectoryExport?.(directoryPath, 'html'),
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
label: 'Print / save PDF',
|
|
249
|
+
onSelect: () => this.onDirectoryExport?.(directoryPath, 'pdf'),
|
|
250
|
+
},
|
|
238
251
|
{
|
|
239
252
|
label: 'Delete',
|
|
240
253
|
danger: true,
|
|
@@ -8,6 +8,7 @@ export class FileExplorerController {
|
|
|
8
8
|
mobileBreakpointQuery = window.matchMedia('(max-width: 768px)'),
|
|
9
9
|
onFileSelect,
|
|
10
10
|
onFileDelete,
|
|
11
|
+
onDirectoryExport,
|
|
11
12
|
pendingWorkspaceRequestIds = null,
|
|
12
13
|
onShowFileExtensionsChange,
|
|
13
14
|
showFileExtensions = false,
|
|
@@ -16,6 +17,7 @@ export class FileExplorerController {
|
|
|
16
17
|
}) {
|
|
17
18
|
this.onFileSelect = onFileSelect;
|
|
18
19
|
this.onFileDelete = onFileDelete;
|
|
20
|
+
this.onDirectoryExport = onDirectoryExport;
|
|
19
21
|
this.onShowFileExtensionsChange = onShowFileExtensionsChange;
|
|
20
22
|
this.toastController = toastController;
|
|
21
23
|
this.vaultClient = vaultClient;
|
|
@@ -56,6 +58,7 @@ export class FileExplorerController {
|
|
|
56
58
|
});
|
|
57
59
|
this.actionController = new FileActionController({
|
|
58
60
|
mobileBreakpointQuery,
|
|
61
|
+
onDirectoryExport: this.onDirectoryExport,
|
|
59
62
|
onFileDelete: this.onFileDelete,
|
|
60
63
|
onFileSelect: this.onFileSelect,
|
|
61
64
|
onShowFileExtensionsChange: (enabled) => {
|
|
@@ -58,7 +58,10 @@ export class FileExplorerView {
|
|
|
58
58
|
this.longPressContext = null;
|
|
59
59
|
this.suppressedActivationTarget = null;
|
|
60
60
|
this.contextMenuCloseHandler = null;
|
|
61
|
+
this.contextMenuCloseTimer = null;
|
|
62
|
+
this.contextMenuAnchor = null;
|
|
61
63
|
this.actionSheetCloseHandler = null;
|
|
64
|
+
this.blockingModalHandler = () => this.removeContextMenu();
|
|
62
65
|
this.dragSource = null;
|
|
63
66
|
this.currentSearchQuery = '';
|
|
64
67
|
this.activeDropTarget = null;
|
|
@@ -336,6 +339,8 @@ export class FileExplorerView {
|
|
|
336
339
|
button.setAttribute('aria-expanded', String(isExpanded));
|
|
337
340
|
button.dataset.path = node.path;
|
|
338
341
|
button.dataset.entryType = 'directory';
|
|
342
|
+
// Dynamic labels are escaped and icons are application-owned markup.
|
|
343
|
+
// pi-lens-ignore: no-inner-html-js
|
|
339
344
|
button.innerHTML = `
|
|
340
345
|
<svg class="file-tree-chevron${isExpanded ? ' expanded' : ''}" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
|
|
341
346
|
<svg class="file-tree-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
|
@@ -502,6 +507,8 @@ export class FileExplorerView {
|
|
|
502
507
|
${parentPath ? `<span class="file-tree-search-path">${escapeHtml(parentPath)}</span>` : ''}
|
|
503
508
|
</span>`
|
|
504
509
|
: `<span class="file-tree-name">${escapeHtml(displayName)}</span>`;
|
|
510
|
+
// Dynamic labels are escaped and icons are application-owned markup.
|
|
511
|
+
// pi-lens-ignore: no-inner-html-js
|
|
505
512
|
button.innerHTML = `
|
|
506
513
|
${getVaultFileIconSvg(filePath)}
|
|
507
514
|
${nameMarkup}
|
|
@@ -965,6 +972,8 @@ export class FileExplorerView {
|
|
|
965
972
|
return;
|
|
966
973
|
}
|
|
967
974
|
|
|
975
|
+
const contextAnchor = event.currentTarget instanceof Element ? event.currentTarget : event.target;
|
|
976
|
+
this.contextMenuAnchor = contextAnchor instanceof HTMLElement ? contextAnchor : null;
|
|
968
977
|
if (this.isMobileViewport()) {
|
|
969
978
|
this.showActionSheet(items);
|
|
970
979
|
return;
|
|
@@ -972,14 +981,18 @@ export class FileExplorerView {
|
|
|
972
981
|
|
|
973
982
|
const menu = document.createElement('div');
|
|
974
983
|
menu.className = 'file-context-menu';
|
|
984
|
+
menu.setAttribute('role', 'menu');
|
|
985
|
+
menu.setAttribute('aria-label', 'File actions');
|
|
975
986
|
|
|
976
987
|
for (const item of items) {
|
|
977
988
|
const button = document.createElement('button');
|
|
989
|
+
button.type = 'button';
|
|
978
990
|
button.className = `file-context-item${item.danger ? ' file-context-danger' : ''}`;
|
|
991
|
+
button.setAttribute('role', 'menuitem');
|
|
979
992
|
button.textContent = item.label;
|
|
980
993
|
button.addEventListener('click', () => {
|
|
981
994
|
this.removeContextMenu();
|
|
982
|
-
item.onSelect?.();
|
|
995
|
+
item.onSelect?.({ anchor: contextAnchor });
|
|
983
996
|
});
|
|
984
997
|
menu.appendChild(button);
|
|
985
998
|
}
|
|
@@ -998,17 +1011,47 @@ export class FileExplorerView {
|
|
|
998
1011
|
}
|
|
999
1012
|
};
|
|
1000
1013
|
this.contextMenuCloseHandler = close;
|
|
1001
|
-
|
|
1014
|
+
const handleKeydown = (keyEvent) => {
|
|
1015
|
+
const buttons = Array.from(menu.querySelectorAll('[role="menuitem"]'));
|
|
1016
|
+
const index = Math.max(0, buttons.indexOf(document.activeElement));
|
|
1017
|
+
if (keyEvent.key === 'Escape') {
|
|
1018
|
+
keyEvent.preventDefault();
|
|
1019
|
+
this.removeContextMenu();
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
if (keyEvent.key === 'Tab') {
|
|
1023
|
+
this.removeContextMenu({ restoreFocus: false });
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
const nextIndex = keyEvent.key === 'Home'
|
|
1027
|
+
? 0
|
|
1028
|
+
: keyEvent.key === 'End'
|
|
1029
|
+
? buttons.length - 1
|
|
1030
|
+
: keyEvent.key === 'ArrowDown'
|
|
1031
|
+
? (index + 1) % buttons.length
|
|
1032
|
+
: keyEvent.key === 'ArrowUp'
|
|
1033
|
+
? (index - 1 + buttons.length) % buttons.length
|
|
1034
|
+
: -1;
|
|
1035
|
+
if (nextIndex >= 0) {
|
|
1036
|
+
keyEvent.preventDefault();
|
|
1037
|
+
buttons[nextIndex]?.focus();
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
menu.addEventListener('keydown', handleKeydown);
|
|
1041
|
+
document.addEventListener('collabmd:close-custom-modals', this.blockingModalHandler);
|
|
1042
|
+
this.contextMenuCloseTimer = setTimeout(() => {
|
|
1043
|
+
this.contextMenuCloseTimer = null;
|
|
1044
|
+
if (menu.isConnected && this.contextMenuCloseHandler === close) {
|
|
1045
|
+
document.addEventListener('click', close);
|
|
1046
|
+
}
|
|
1047
|
+
}, 0);
|
|
1048
|
+
menu.querySelector('[role="menuitem"]')?.focus();
|
|
1002
1049
|
}
|
|
1003
1050
|
|
|
1004
1051
|
showActionSheet(items) {
|
|
1005
|
-
const
|
|
1006
|
-
backdrop.type = 'button';
|
|
1007
|
-
backdrop.className = 'file-action-sheet-backdrop';
|
|
1008
|
-
backdrop.setAttribute('aria-label', 'Close file actions');
|
|
1009
|
-
|
|
1010
|
-
const sheet = document.createElement('div');
|
|
1052
|
+
const sheet = document.createElement('dialog');
|
|
1011
1053
|
sheet.className = 'file-action-sheet';
|
|
1054
|
+
sheet.setAttribute('aria-label', 'File actions');
|
|
1012
1055
|
|
|
1013
1056
|
items.forEach((item) => {
|
|
1014
1057
|
const button = document.createElement('button');
|
|
@@ -1037,26 +1080,42 @@ export class FileExplorerView {
|
|
|
1037
1080
|
});
|
|
1038
1081
|
sheet.appendChild(cancelButton);
|
|
1039
1082
|
|
|
1040
|
-
|
|
1083
|
+
sheet.addEventListener('cancel', (event) => {
|
|
1084
|
+
event.preventDefault();
|
|
1041
1085
|
this.removeContextMenu();
|
|
1042
1086
|
});
|
|
1087
|
+
sheet.addEventListener('click', (event) => {
|
|
1088
|
+
const bounds = sheet.getBoundingClientRect();
|
|
1089
|
+
if (event.clientX < bounds.left || event.clientX > bounds.right
|
|
1090
|
+
|| event.clientY < bounds.top || event.clientY > bounds.bottom) this.removeContextMenu();
|
|
1091
|
+
});
|
|
1043
1092
|
|
|
1044
|
-
document.body.append(
|
|
1093
|
+
document.body.append(sheet);
|
|
1094
|
+
document.addEventListener('collabmd:close-custom-modals', this.blockingModalHandler);
|
|
1045
1095
|
this.actionSheetCloseHandler = () => {
|
|
1046
|
-
|
|
1096
|
+
if (sheet.open) sheet.close();
|
|
1047
1097
|
sheet.remove();
|
|
1048
1098
|
this.actionSheetCloseHandler = null;
|
|
1049
1099
|
};
|
|
1100
|
+
sheet.showModal();
|
|
1101
|
+
sheet.querySelector('button:not(:disabled)')?.focus();
|
|
1050
1102
|
}
|
|
1051
1103
|
|
|
1052
|
-
removeContextMenu() {
|
|
1104
|
+
removeContextMenu({ restoreFocus = true } = {}) {
|
|
1053
1105
|
this.cancelLongPress();
|
|
1054
1106
|
this.clearDragFeedback();
|
|
1055
1107
|
document.querySelectorAll('.file-context-menu').forEach((menu) => menu.remove());
|
|
1108
|
+
if (this.contextMenuCloseTimer !== null) {
|
|
1109
|
+
clearTimeout(this.contextMenuCloseTimer);
|
|
1110
|
+
this.contextMenuCloseTimer = null;
|
|
1111
|
+
}
|
|
1056
1112
|
if (this.contextMenuCloseHandler) {
|
|
1057
1113
|
document.removeEventListener('click', this.contextMenuCloseHandler);
|
|
1058
1114
|
this.contextMenuCloseHandler = null;
|
|
1059
1115
|
}
|
|
1116
|
+
document.removeEventListener('collabmd:close-custom-modals', this.blockingModalHandler);
|
|
1060
1117
|
this.actionSheetCloseHandler?.();
|
|
1118
|
+
if (restoreFocus) this.contextMenuAnchor?.focus?.();
|
|
1119
|
+
this.contextMenuAnchor = null;
|
|
1061
1120
|
}
|
|
1062
1121
|
}
|
|
@@ -526,6 +526,7 @@ export class FileHistoryViewController {
|
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
if (this.stats) {
|
|
529
|
+
// pi-lens-ignore: no-inner-html-js
|
|
529
530
|
this.stats.innerHTML = `
|
|
530
531
|
<span class="ui-stat-token ui-stat-token--add diff-stats-add">+${additions}</span>
|
|
531
532
|
<span class="ui-stat-token ui-stat-token--del diff-stats-del">-${deletions}</span>
|
|
@@ -543,12 +544,14 @@ export class FileHistoryViewController {
|
|
|
543
544
|
this.actionsDivider?.classList.add('hidden');
|
|
544
545
|
this.editorActionsGroup?.classList.remove('hidden');
|
|
545
546
|
this.modeButtons.forEach((button) => {
|
|
547
|
+
const active = button.getAttribute('data-diff-mode') === this.diffMode;
|
|
546
548
|
button.classList.toggle('hidden', !hasSelection);
|
|
547
|
-
button.classList.toggle('active',
|
|
549
|
+
button.classList.toggle('active', active);
|
|
550
|
+
button.setAttribute?.('aria-pressed', String(active));
|
|
548
551
|
});
|
|
549
552
|
this.openEditorButton?.toggleAttribute('disabled', !this.currentFilePath);
|
|
550
553
|
if (this.openEditorButton) {
|
|
551
|
-
this.openEditorButton.textContent = 'Open
|
|
554
|
+
this.openEditorButton.textContent = 'Open file';
|
|
552
555
|
}
|
|
553
556
|
this.primaryActionButton?.toggleAttribute('disabled', true);
|
|
554
557
|
this.commitButton?.toggleAttribute('disabled', true);
|
|
@@ -561,20 +564,21 @@ export class FileHistoryViewController {
|
|
|
561
564
|
this.page?.classList.remove('hidden');
|
|
562
565
|
if (this.content) {
|
|
563
566
|
this.content.classList.add('diff-content--history');
|
|
564
|
-
this.content.innerHTML = '<div class="git-panel-empty">Loading file history
|
|
567
|
+
this.content.innerHTML = '<div class="git-panel-empty" role="status" aria-live="polite">Loading file history…</div>';
|
|
565
568
|
}
|
|
566
569
|
this.historyListElement = null;
|
|
567
570
|
this.syncToolbar();
|
|
568
571
|
}
|
|
569
572
|
|
|
570
|
-
renderEmpty(message) {
|
|
573
|
+
renderEmpty(message, { alert = false } = {}) {
|
|
571
574
|
if (!this.isActive) {
|
|
572
575
|
return;
|
|
573
576
|
}
|
|
574
577
|
this.page?.classList.remove('hidden');
|
|
575
578
|
if (this.content) {
|
|
576
579
|
this.content.classList.add('diff-content--history');
|
|
577
|
-
|
|
580
|
+
// pi-lens-ignore: no-inner-html-js
|
|
581
|
+
this.content.innerHTML = `<div class="git-panel-empty"${alert ? ' role="alert"' : ''}>${escapeHtml(message)}</div>`;
|
|
578
582
|
}
|
|
579
583
|
this.historyListElement = null;
|
|
580
584
|
this.syncToolbar();
|
|
@@ -689,7 +693,7 @@ export class FileHistoryViewController {
|
|
|
689
693
|
type="button"
|
|
690
694
|
data-file-history-open-selected-diff
|
|
691
695
|
>
|
|
692
|
-
Open
|
|
696
|
+
Open standalone diff
|
|
693
697
|
</button>
|
|
694
698
|
${entry.type === 'commit' ? `
|
|
695
699
|
<button
|
|
@@ -697,7 +701,7 @@ export class FileHistoryViewController {
|
|
|
697
701
|
type="button"
|
|
698
702
|
data-file-history-open-selected-preview
|
|
699
703
|
>
|
|
700
|
-
Preview
|
|
704
|
+
Preview file
|
|
701
705
|
</button>
|
|
702
706
|
` : ''}
|
|
703
707
|
</div>
|
|
@@ -714,8 +718,10 @@ export class FileHistoryViewController {
|
|
|
714
718
|
if (selection.loading) {
|
|
715
719
|
return `
|
|
716
720
|
<section class="diff-file-block file-history-diff-block">
|
|
717
|
-
|
|
718
|
-
|
|
721
|
+
<div class="diff-file-header">
|
|
722
|
+
<span class="diff-file-path">${escapeHtml(entry.pathAtCommit || this.currentFilePath || '')}</span>
|
|
723
|
+
</div>
|
|
724
|
+
<div class="diff-empty-state" role="status" aria-live="polite">Loading diff…</div>
|
|
719
725
|
</section>
|
|
720
726
|
`;
|
|
721
727
|
}
|
|
@@ -724,7 +730,7 @@ export class FileHistoryViewController {
|
|
|
724
730
|
return `
|
|
725
731
|
<section class="diff-file-block file-history-diff-block">
|
|
726
732
|
${this.renderDiffFileHeader({ path: entry.pathAtCommit || this.currentFilePath || '' })}
|
|
727
|
-
<div class="diff-empty-state">${escapeHtml(selection.error)}</div>
|
|
733
|
+
<div class="diff-empty-state" role="alert">${escapeHtml(selection.error)}</div>
|
|
728
734
|
</section>
|
|
729
735
|
`;
|
|
730
736
|
}
|
|
@@ -760,7 +766,7 @@ export class FileHistoryViewController {
|
|
|
760
766
|
|
|
761
767
|
const hasRows = Boolean(this.localChanges) || (this.history.commits?.length ?? 0) > 0;
|
|
762
768
|
if (!hasRows) {
|
|
763
|
-
this.renderEmpty(this.history.error || 'No history found for this file.');
|
|
769
|
+
this.renderEmpty(this.history.error || 'No history found for this file.', { alert: Boolean(this.history.error) });
|
|
764
770
|
return;
|
|
765
771
|
}
|
|
766
772
|
|
|
@@ -770,6 +776,7 @@ export class FileHistoryViewController {
|
|
|
770
776
|
|
|
771
777
|
this.content.classList.add('diff-content--history');
|
|
772
778
|
const selection = this.getSelectedDetailState();
|
|
779
|
+
// pi-lens-ignore: no-inner-html-js
|
|
773
780
|
this.content.innerHTML = `
|
|
774
781
|
<section class="file-history-shell">
|
|
775
782
|
<aside class="file-history-sidebar" aria-label="File history entries">
|
|
@@ -789,7 +796,7 @@ export class FileHistoryViewController {
|
|
|
789
796
|
data-file-history-load-more
|
|
790
797
|
${this.history.loadingMore ? 'disabled' : ''}
|
|
791
798
|
>
|
|
792
|
-
${this.history.loadingMore ? 'Loading
|
|
799
|
+
${this.history.loadingMore ? 'Loading…' : 'Load more'}
|
|
793
800
|
</button>
|
|
794
801
|
</div>
|
|
795
802
|
` : ''}
|
|
@@ -13,17 +13,7 @@ function flattenTree(nodes, files = [], searchEntries = [], fileEntries = []) {
|
|
|
13
13
|
type: node.type,
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
if (
|
|
17
|
-
node.type === 'file'
|
|
18
|
-
|| node.type === 'base'
|
|
19
|
-
|| node.type === 'excalidraw'
|
|
20
|
-
|| node.type === 'drawio'
|
|
21
|
-
|| node.type === 'mermaid'
|
|
22
|
-
|| node.type === 'plantuml'
|
|
23
|
-
|| node.type === 'structurizr'
|
|
24
|
-
|| node.type === 'pdf'
|
|
25
|
-
|| node.type === 'image'
|
|
26
|
-
) {
|
|
16
|
+
if (node.type !== 'directory') {
|
|
27
17
|
files.push(node.path);
|
|
28
18
|
fileEntries.push({
|
|
29
19
|
mtimeMs: node.mtimeMs,
|