termdock 1.4.195 → 1.4.196
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/dist/client/assets/{App-BbIl0DAa.js → App-DHPY_Qw6.js} +10 -10
- package/dist/client/assets/App-DHPY_Qw6.js.br +0 -0
- package/dist/client/assets/App-DHPY_Qw6.js.gz +0 -0
- package/dist/client/assets/{ChangeWalkthroughPanel-CT7mLy_e.js → ChangeWalkthroughPanel-Dl6vEiEH.js} +1 -1
- package/dist/client/assets/ChangeWalkthroughPanel-Dl6vEiEH.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-Dl6vEiEH.js.gz +0 -0
- package/dist/client/assets/{DagPlayground-Bsf4bv7e.js → DagPlayground-Dush1TIN.js} +1 -1
- package/dist/client/assets/DagPlayground-Dush1TIN.js.br +0 -0
- package/dist/client/assets/DagPlayground-Dush1TIN.js.gz +0 -0
- package/dist/client/assets/{DiffLab-BjiZcUSn.js → DiffLab-T8DSZ9CZ.js} +1 -1
- package/dist/client/assets/DiffLab-T8DSZ9CZ.js.br +0 -0
- package/dist/client/assets/DiffLab-T8DSZ9CZ.js.gz +0 -0
- package/dist/client/assets/{DiffReview-DmkAyOh4.js → DiffReview-CWqBYEQi.js} +1 -1
- package/dist/client/assets/DiffReview-CWqBYEQi.js.br +0 -0
- package/dist/client/assets/DiffReview-CWqBYEQi.js.gz +0 -0
- package/dist/client/assets/{DiffReviewLab-wXYUmdna.js → DiffReviewLab-HiliQgzS.js} +1 -1
- package/dist/client/assets/DiffReviewLab-HiliQgzS.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-HiliQgzS.js.gz +0 -0
- package/dist/client/assets/{DiffViewer-BlwwMnsB.js → DiffViewer-BOzmZ9Vg.js} +1 -1
- package/dist/client/assets/DiffViewer-BOzmZ9Vg.js.br +0 -0
- package/dist/client/assets/DiffViewer-BOzmZ9Vg.js.gz +0 -0
- package/dist/client/assets/{ModelPreview-DGIaQAcq.js → ModelPreview-BScN6pYp.js} +1 -1
- package/dist/client/assets/ModelPreview-BScN6pYp.js.br +0 -0
- package/dist/client/assets/ModelPreview-BScN6pYp.js.gz +0 -0
- package/dist/client/assets/{RightSidebar-PgJ0XzEh.js → RightSidebar-Cwwgb4aF.js} +4 -4
- package/dist/client/assets/RightSidebar-Cwwgb4aF.js.br +0 -0
- package/dist/client/assets/RightSidebar-Cwwgb4aF.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-B_sCIKms.js → abnfDiagram-VCTEODGH-_Jotrwh5.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-_Jotrwh5.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-_Jotrwh5.js.gz +0 -0
- package/dist/client/assets/{app-5zC_J9mq.js → app-D3EW-RfP.js} +3 -3
- package/dist/client/assets/app-D3EW-RfP.js.br +0 -0
- package/dist/client/assets/app-D3EW-RfP.js.gz +0 -0
- package/dist/client/assets/{arc-Ps2GTfJ3.js → arc--QK4vqUb.js} +1 -1
- package/dist/client/assets/arc--QK4vqUb.js.br +0 -0
- package/dist/client/assets/arc--QK4vqUb.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-DxKfqPAR.js → architectureDiagram-5GKGNRK7-BwHR__6X.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-BwHR__6X.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-BwHR__6X.js.gz +0 -0
- package/dist/client/assets/{blockDiagram-I7D4REHJ-BNL8tkC0.js → blockDiagram-I7D4REHJ-DZEMZMfx.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-DZEMZMfx.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-DZEMZMfx.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-hyEavwo6.js → c4Diagram-7LVT6UL2-CWWPwhkP.js} +1 -1
- package/dist/client/assets/c4Diagram-7LVT6UL2-CWWPwhkP.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-CWWPwhkP.js.gz +0 -0
- package/dist/client/assets/channel-DXepE6hM.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-DN_HrxPz.js → chunk-2Q5K7J3B-Ciwe6Jpr.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-BofAFEcC.js → chunk-5VM5RSS4-C1uXRBQl.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-CLNw1JDM.js → chunk-F27PBJKO-BBroEsMn.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-BBroEsMn.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-BBroEsMn.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-DsVDl8p7.js → chunk-IMKFNOWR-DulvBTQW.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-DulvBTQW.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-DulvBTQW.js.gz +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-CdfzOrPC.js → chunk-JWPE2WC7-C1iD62gS.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-MXmTC-sG.js → chunk-POPQ4Y6H-1XZwzFea.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DfwfQAY6.js → chunk-SVP7TREG-DPeh3BNp.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-DPeh3BNp.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DPeh3BNp.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-N3OPIvmU.js → chunk-TICWLB2K-DeFRSdCH.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-DeFRSdCH.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DeFRSdCH.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-IurIojt5.js → chunk-XXDRQBXY-DxUnOflr.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-IgYlwyDS.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-IgYlwyDS.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-DHbDHTvp.js → cose-bilkent-JH36ORCC-RFbthyXT.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-RFbthyXT.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-RFbthyXT.js.gz +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX-DyTW2Iyi.js → cynefin-OW5HDTMX-BynwJL-i.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-BynwJL-i.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-BynwJL-i.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-DEan3pcN.js → cynefinDiagram-5FMLGOSQ-DuOeJl1-.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DuOeJl1-.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DuOeJl1-.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-Rnw2v1uV.js → dagre-GXQ25YYZ-B5OYEUlw.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-B5OYEUlw.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-B5OYEUlw.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-CmBa29S9.js → diagram-S7CK7UJ4-KI8T0yjS.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-KI8T0yjS.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-KI8T0yjS.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-Cqzmpane.js → diagram-UQ7AKVKN-Cj2J871X.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-Cj2J871X.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-Cj2J871X.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-CrHTQozH.js → diagram-VSXAHHWV-CCBeqUWu.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-CCBeqUWu.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-CCBeqUWu.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-C7nQgan9.js → diagram-VX7I27RA-BsYs3AWZ.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-BsYs3AWZ.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-BsYs3AWZ.js.gz +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-93X66n3v.js → diagram-Z3DM3KII-mOM3kQo5.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-mOM3kQo5.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-mOM3kQo5.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-LfScrrH8.js → ebnfDiagram-PWID7BFC-fu_iYLIF.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-fu_iYLIF.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-fu_iYLIF.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-DAWKsrIB.js → erDiagram-RLTQ6QDP-BJ8uQuv-.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-BJ8uQuv-.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BJ8uQuv-.js.gz +0 -0
- package/dist/client/assets/{flowDiagram-HODETNUW-CcdXfpU7.js → flowDiagram-HODETNUW-BZyUxfJS.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-BZyUxfJS.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-BZyUxfJS.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DPLNbHSY.js → ganttDiagram-EL5Y4UJY-z5KFkNWU.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-z5KFkNWU.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-z5KFkNWU.js.gz +0 -0
- package/dist/client/assets/{gestureArbiter-B5PxTluh.js → gestureArbiter-C9YKpiBS.js} +1 -1
- package/dist/client/assets/gestureArbiter-C9YKpiBS.js.br +0 -0
- package/dist/client/assets/gestureArbiter-C9YKpiBS.js.gz +0 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-P741cwUf.js → gitGraphDiagram-WWUBYQGX-BrJHb2xD.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BrJHb2xD.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BrJHb2xD.js.gz +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-xrl-VW74.js → infoDiagram-27XIBGKW-CSL9Nne-.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BJmiVWrB.js → ishikawaDiagram-5VMMS53U-DRcYfZrL.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BJmiVWrB.js.br → ishikawaDiagram-5VMMS53U-DRcYfZrL.js.br} +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-DRcYfZrL.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-DZX8uYK2.js → journeyDiagram-3NMN7TZE-B1Ihp7iG.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-B1Ihp7iG.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-B1Ihp7iG.js.gz +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-1SmdXf0S.js → kanban-definition-UXKFOSKX-B4B0y8d-.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-B4B0y8d-.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-B4B0y8d-.js.gz +0 -0
- package/dist/client/assets/{layout-De4QxmMN.js → layout-BlVpm00F.js} +1 -1
- package/dist/client/assets/layout-BlVpm00F.js.br +0 -0
- package/dist/client/assets/layout-BlVpm00F.js.gz +0 -0
- package/dist/client/assets/{linear-Dc93ZnhP.js → linear-6hHPwm_d.js} +1 -1
- package/dist/client/assets/linear-6hHPwm_d.js.br +0 -0
- package/dist/client/assets/linear-6hHPwm_d.js.gz +0 -0
- package/dist/client/assets/{mermaid.core-Ny4ifEul.js → mermaid.core-DPcnsfOi.js} +5 -5
- package/dist/client/assets/mermaid.core-DPcnsfOi.js.br +0 -0
- package/dist/client/assets/mermaid.core-DPcnsfOi.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-CE75rUrK.js → mindmap-definition-YA3MSWOX-BJKiRn8E.js} +1 -1
- package/dist/client/assets/mindmap-definition-YA3MSWOX-BJKiRn8E.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-BJKiRn8E.js.gz +0 -0
- package/dist/client/assets/{passwordBootstrap-BuXV9qsA.js → passwordBootstrap-DOeA8hBZ.js} +1 -1
- package/dist/client/assets/passwordBootstrap-DOeA8hBZ.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-DOeA8hBZ.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-CR8E9wWF.js → pegDiagram-XKGWAZYB-DED8CspT.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-DED8CspT.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DED8CspT.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-CKZz2-Iz.js → pieDiagram-E7YTZNPT-9IcWqNZq.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-9IcWqNZq.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-9IcWqNZq.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-w0wqPGg1.js → quadrantDiagram-AXDQQJYC-CrmjzpEv.js} +1 -1
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-CrmjzpEv.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-CrmjzpEv.js.gz +0 -0
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-CWYxj4Iu.js → railroadDiagram-O6MQD6OU-BRbKdDeO.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BRbKdDeO.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BRbKdDeO.js.gz +0 -0
- package/dist/client/assets/{referenceLongPress-xQTJmyUv.js → referenceLongPress-DFDR-igt.js} +1 -1
- package/dist/client/assets/referenceLongPress-DFDR-igt.js.br +0 -0
- package/dist/client/assets/referenceLongPress-DFDR-igt.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-DzcUlIZo.js → requirementDiagram-BXWQKSXE-CKnTGXKk.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-CKnTGXKk.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-CKnTGXKk.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-B1KFzqqb.js → sankeyDiagram-P5KCCOFB-DCg3-qjH.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-DCg3-qjH.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-DCg3-qjH.js.gz +0 -0
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-Bph5Zy95.js → sequenceDiagram-WJ2MYXX4-BdKp72oL.js} +1 -1
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BdKp72oL.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BdKp72oL.js.gz +0 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-B22qdSe2.js → sizeCapture-INFHLROL-bClrPVvk.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-bClrPVvk.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-bClrPVvk.js.gz +0 -0
- package/dist/client/assets/{sparkles-iFGazcNw.js → sparkles-CD2zRzzp.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-qt4ZIeIU.js → stateDiagram-D77RDMKH-IW4ojktz.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-IW4ojktz.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-IW4ojktz.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-UzQ4VZ52.js +1 -0
- package/dist/client/assets/{swimlanes-42K2YHIH-BLCfdR2d.js → swimlanes-42K2YHIH-DPEqSZHZ.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH-DPEqSZHZ.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-DPEqSZHZ.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-wnRqK4Za.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-B1KrZ6Jd.js → timeline-definition-24CTP7MA-DyWBGHcQ.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-DyWBGHcQ.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-DyWBGHcQ.js.gz +0 -0
- package/dist/client/assets/{triangle-alert-BNMREFNU.js → triangle-alert-Cm8GVelT.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-DWNDoCmv.js → vennDiagram-4TSXK5OY-D96Q8vI8.js} +1 -1
- package/dist/client/assets/vennDiagram-4TSXK5OY-D96Q8vI8.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-D96Q8vI8.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-kdVZqb5Z.js → wardleyDiagram-VM6X3IG4-jMfmwhTE.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-jMfmwhTE.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-jMfmwhTE.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-C1U9Cr8F.js → xychartDiagram-S5SC5T6Z-DjbvL4uH.js} +1 -1
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-DjbvL4uH.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-DjbvL4uH.js.gz +0 -0
- package/dist/client/index.html +1 -1
- package/dist/client/index.html.br +0 -0
- package/dist/client/index.html.gz +0 -0
- package/dist/client/sw.js +1 -1
- package/dist/client/sw.js.br +0 -0
- package/dist/client/sw.js.gz +0 -0
- package/dist/server/agent/collaborationCli.js +7 -4
- package/dist/server/agent/collaborationDeliveryWorker.js +29 -24
- package/dist/server/agent/collaborationPrompt.js +41 -13
- package/dist/server/agent/collaborationProtocol.js +37 -0
- package/dist/server/agent/collaborationRoutes.js +42 -5
- package/dist/server/agent/collaborationStore.js +18 -1
- package/dist/server/routes/terminal.js +26 -5
- package/package.json +1 -1
- package/runtime-manifest.json +3 -3
- package/dist/client/assets/App-BbIl0DAa.js.br +0 -0
- package/dist/client/assets/App-BbIl0DAa.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-CT7mLy_e.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-CT7mLy_e.js.gz +0 -0
- package/dist/client/assets/DagPlayground-Bsf4bv7e.js.br +0 -0
- package/dist/client/assets/DagPlayground-Bsf4bv7e.js.gz +0 -0
- package/dist/client/assets/DiffLab-BjiZcUSn.js.br +0 -0
- package/dist/client/assets/DiffLab-BjiZcUSn.js.gz +0 -0
- package/dist/client/assets/DiffReview-DmkAyOh4.js.br +0 -0
- package/dist/client/assets/DiffReview-DmkAyOh4.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-wXYUmdna.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-wXYUmdna.js.gz +0 -0
- package/dist/client/assets/DiffViewer-BlwwMnsB.js.br +0 -0
- package/dist/client/assets/DiffViewer-BlwwMnsB.js.gz +0 -0
- package/dist/client/assets/ModelPreview-DGIaQAcq.js.br +0 -0
- package/dist/client/assets/ModelPreview-DGIaQAcq.js.gz +0 -0
- package/dist/client/assets/RightSidebar-PgJ0XzEh.js.br +0 -0
- package/dist/client/assets/RightSidebar-PgJ0XzEh.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-B_sCIKms.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-B_sCIKms.js.gz +0 -0
- package/dist/client/assets/app-5zC_J9mq.js.br +0 -0
- package/dist/client/assets/app-5zC_J9mq.js.gz +0 -0
- package/dist/client/assets/arc-Ps2GTfJ3.js.br +0 -0
- package/dist/client/assets/arc-Ps2GTfJ3.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DxKfqPAR.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DxKfqPAR.js.gz +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BNL8tkC0.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BNL8tkC0.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-hyEavwo6.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-hyEavwo6.js.gz +0 -0
- package/dist/client/assets/channel-Bkfq4dnz.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-CLNw1JDM.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-CLNw1JDM.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-DsVDl8p7.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-DsVDl8p7.js.gz +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DfwfQAY6.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DfwfQAY6.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-N3OPIvmU.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-N3OPIvmU.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-Dahb2o7K.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-Dahb2o7K.js +0 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-DHbDHTvp.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-DHbDHTvp.js.gz +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-DyTW2Iyi.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-DyTW2Iyi.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DEan3pcN.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DEan3pcN.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-Rnw2v1uV.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-Rnw2v1uV.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-CmBa29S9.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-CmBa29S9.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-Cqzmpane.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-Cqzmpane.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-CrHTQozH.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-CrHTQozH.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-C7nQgan9.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-C7nQgan9.js.gz +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-93X66n3v.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-93X66n3v.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-LfScrrH8.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-LfScrrH8.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-DAWKsrIB.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-DAWKsrIB.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-CcdXfpU7.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-CcdXfpU7.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-DPLNbHSY.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-DPLNbHSY.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-B5PxTluh.js.br +0 -0
- package/dist/client/assets/gestureArbiter-B5PxTluh.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-P741cwUf.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-P741cwUf.js.gz +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-BJmiVWrB.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DZX8uYK2.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DZX8uYK2.js.gz +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-1SmdXf0S.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-1SmdXf0S.js.gz +0 -0
- package/dist/client/assets/layout-De4QxmMN.js.br +0 -0
- package/dist/client/assets/layout-De4QxmMN.js.gz +0 -0
- package/dist/client/assets/linear-Dc93ZnhP.js.br +0 -0
- package/dist/client/assets/linear-Dc93ZnhP.js.gz +0 -0
- package/dist/client/assets/mermaid.core-Ny4ifEul.js.br +0 -0
- package/dist/client/assets/mermaid.core-Ny4ifEul.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CE75rUrK.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CE75rUrK.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-BuXV9qsA.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-BuXV9qsA.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-CR8E9wWF.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-CR8E9wWF.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CKZz2-Iz.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CKZz2-Iz.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-w0wqPGg1.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-w0wqPGg1.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-CWYxj4Iu.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-CWYxj4Iu.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-xQTJmyUv.js.br +0 -0
- package/dist/client/assets/referenceLongPress-xQTJmyUv.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-DzcUlIZo.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-DzcUlIZo.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-B1KFzqqb.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-B1KFzqqb.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Bph5Zy95.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Bph5Zy95.js.gz +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-B22qdSe2.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-B22qdSe2.js.gz +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-qt4ZIeIU.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-qt4ZIeIU.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-xKezo5Hj.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-BLCfdR2d.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-BLCfdR2d.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-CNA032xr.js +0 -8
- package/dist/client/assets/timeline-definition-24CTP7MA-B1KrZ6Jd.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-B1KrZ6Jd.js.gz +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-DWNDoCmv.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-DWNDoCmv.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-kdVZqb5Z.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-kdVZqb5Z.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-C1U9Cr8F.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-C1U9Cr8F.js.gz +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { canonicalShortId } from './collaborationProtocol.js';
|
|
1
2
|
import { sanitizeCollaborationRole } from './collaborationStore.js';
|
|
2
3
|
const SHELL_RULE = '─'.repeat(30);
|
|
3
4
|
/** Body larger than this (in UTF-8 bytes) is replaced by a retrieval pointer
|
|
@@ -25,51 +26,78 @@ export function sanitizeCollaborationName(name, max = 40) {
|
|
|
25
26
|
.trim();
|
|
26
27
|
return cleaned.length > max ? `${cleaned.slice(0, max - 1)}…` : cleaned;
|
|
27
28
|
}
|
|
28
|
-
/** The
|
|
29
|
-
*
|
|
29
|
+
/** The id form a delivery shows and the confirm gate searches for, per message.
|
|
30
|
+
* Canonical UUIDs shorten to their 8-character prefix (a 36-character id wraps
|
|
31
|
+
* in a narrow pane and has to be retyped by whoever answers it); ids that are
|
|
32
|
+
* not canonical UUIDs pass through untouched. A prefix shared by two messages
|
|
33
|
+
* in the same delivery would make a `includes` search match the wrong block —
|
|
34
|
+
* including against the other one's line still sitting in terminal history —
|
|
35
|
+
* so every colliding message falls back to its full id. The batch is the unit
|
|
36
|
+
* because one delivery is what a confirm search scans against.
|
|
37
|
+
*
|
|
38
|
+
* Delivered text and the confirm gate must both derive the token here: if the
|
|
39
|
+
* text carried a short id while the gate searched the full one, the gate could
|
|
40
|
+
* never match a delivery again and would re-write it until the attempt bound
|
|
41
|
+
* (the "one message arrived three times" regression). */
|
|
42
|
+
export function collaborationMessageAnchorTokens(messages) {
|
|
43
|
+
const counts = new Map();
|
|
44
|
+
for (const message of messages) {
|
|
45
|
+
const short = canonicalShortId(message.id);
|
|
46
|
+
counts.set(short, (counts.get(short) ?? 0) + 1);
|
|
47
|
+
}
|
|
48
|
+
return new Map(messages.map((message) => {
|
|
49
|
+
const short = canonicalShortId(message.id);
|
|
50
|
+
return [message.id, counts.get(short) === 1 ? short : message.id];
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
/** The one line of a delivered block that carries the message's id, chosen by
|
|
54
|
+
* what the recipient can actually do with it: an agent-sourced message gets the
|
|
30
55
|
* reply command, a user message gets the read-back command (`td collab reply`
|
|
31
56
|
* refuses user messages — NO_REPLY_TARGET — so naming it there would be a dead
|
|
32
|
-
* command).
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* by the "carries its id" test in
|
|
36
|
-
|
|
57
|
+
* command). Both routes accept the short form (the CLI resolves id prefixes),
|
|
58
|
+
* so whichever token collaborationMessageAnchorTokens picks for this delivery is what
|
|
59
|
+
* the recipient can paste back. Every message must carry its token regardless
|
|
60
|
+
* of source: the invariant is pinned by the "carries its id" test in
|
|
61
|
+
* collaborationPrompt.test.ts. */
|
|
62
|
+
export function collaborationMessageAnchorLine(message, token = canonicalShortId(message.id)) {
|
|
37
63
|
return message.fromSessionId
|
|
38
|
-
? `回复:td collab reply ${
|
|
39
|
-
: `详情:td collab message get ${
|
|
64
|
+
? `回复:td collab reply ${token} "回复内容" --text`
|
|
65
|
+
: `详情:td collab message get ${token} --json`;
|
|
40
66
|
}
|
|
41
67
|
/** A single delivered message: `来自:X · kind` over a fenced body, with the
|
|
42
68
|
* anchor line (reply route / read-back route) kept outside the fence. A fan-out
|
|
43
69
|
* dispatch (message.fanOutIds present) is flagged `· 群发` and names the
|
|
44
70
|
* sibling recipients on their own line, so a broadcast is never mistaken for
|
|
45
71
|
* a one-to-one assignment — raw ids fall back to the sanitized id itself. */
|
|
46
|
-
function formatCollaborationMessage(message, source, fannedNames, fence) {
|
|
72
|
+
function formatCollaborationMessage(message, source, fannedNames, fence, token) {
|
|
47
73
|
const lines = [`来自:${source} · ${message.kind}${fannedNames.length ? ' · 群发' : ''}`];
|
|
48
74
|
if (fannedNames.length)
|
|
49
75
|
lines.push(`同时发给了:${fannedNames.join('、')}`);
|
|
50
76
|
lines.push('', fence, message.content, fence);
|
|
51
77
|
if (message.task)
|
|
52
78
|
lines.push('', `任务上报:${JSON.stringify(message.task)}`);
|
|
53
|
-
lines.push('', collaborationMessageAnchorLine(message));
|
|
79
|
+
lines.push('', collaborationMessageAnchorLine(message, token));
|
|
54
80
|
return lines.join('\n');
|
|
55
81
|
}
|
|
56
82
|
export function formatCollaborationDelivery(input) {
|
|
57
83
|
const groupsById = new Map(input.groups.map((group) => [group.id, group]));
|
|
58
84
|
const sessionsById = new Map(input.sessions.map((session) => [session.sessionId, session]));
|
|
85
|
+
const tokens = collaborationMessageAnchorTokens(input.messages);
|
|
59
86
|
const blocks = [];
|
|
60
87
|
for (const message of input.messages) {
|
|
61
88
|
const sourceSession = message.fromSessionId ? sessionsById.get(message.fromSessionId) : null;
|
|
62
89
|
const source = message.fromSessionId
|
|
63
90
|
? sanitizeCollaborationName(sourceSession?.name ?? message.fromSessionId)
|
|
64
91
|
: '用户';
|
|
92
|
+
const token = tokens.get(message.id) ?? message.id;
|
|
65
93
|
const bytes = Buffer.byteLength(message.content);
|
|
66
94
|
const body = bytes > MAX_INLINE_BODY_BYTES
|
|
67
|
-
? `大消息已完整保存(${bytes} 字节)。使用 td collab message get ${
|
|
95
|
+
? `大消息已完整保存(${bytes} 字节)。使用 td collab message get ${token} --json 获取正文;不要把这条提示当作消息正文。`
|
|
68
96
|
: message.content;
|
|
69
97
|
const fence = '`'.repeat(Math.max(3, ...Array.from(body.matchAll(/`+/g), (match) => match[0].length + 1)));
|
|
70
98
|
const fannedNames = (message.fanOutIds ?? [])
|
|
71
99
|
.map((sessionId) => sanitizeCollaborationName(sessionsById.get(sessionId)?.name ?? sessionId));
|
|
72
|
-
blocks.push(formatCollaborationMessage({ ...message, content: body }, source, fannedNames, fence));
|
|
100
|
+
blocks.push(formatCollaborationMessage({ ...message, content: body }, source, fannedNames, fence, token));
|
|
73
101
|
}
|
|
74
102
|
// The shell header names the group only when every block belongs to one;
|
|
75
103
|
// a mixed batch drops the header entirely (no single-group claim to make).
|
|
@@ -18,6 +18,43 @@ export class CollaborationError extends Error {
|
|
|
18
18
|
this.httpStatus = httpStatus;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/** Canonical message and group ids are UUIDs; a delivered terminal shows only
|
|
22
|
+
* the first 8 characters, because a 36-character id wraps in a narrow pane
|
|
23
|
+
* and has to be retyped by whoever answers it. Shortening is display-only and
|
|
24
|
+
* one-way: storage, wire format, receipts and federation always carry the
|
|
25
|
+
* full id, and every lookup resolves a prefix back to it. Ids that are not
|
|
26
|
+
* canonical UUIDs pass through untouched — a hand-written session id
|
|
27
|
+
* (`40bc89py`), a `remote:<origin>:<id>` address or a `cross-<uuid>` federated
|
|
28
|
+
* group are either already short or decoded by their own structural rules
|
|
29
|
+
* (`split(':')`), so truncating them would corrupt the parse. */
|
|
30
|
+
export const SHORT_ID_LENGTH = 8;
|
|
31
|
+
/** Shortest input accepted as a prefix; below this a lookup is exact-match
|
|
32
|
+
* only, so a one-character typo never turns into an ambiguity error. */
|
|
33
|
+
export const MIN_ID_PREFIX_LENGTH = 4;
|
|
34
|
+
const CANONICAL_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
35
|
+
export function canonicalShortId(id) {
|
|
36
|
+
return CANONICAL_ID.test(id) ? id.slice(0, SHORT_ID_LENGTH) : id;
|
|
37
|
+
}
|
|
38
|
+
/** Resolve what a user typed against the ids that exist, git-style: an exact
|
|
39
|
+
* match always wins, otherwise a prefix of at least MIN_ID_PREFIX_LENGTH
|
|
40
|
+
* characters resolves when it is unique. Callers turn 'ambiguous' into an
|
|
41
|
+
* error built by ambiguousIdMessage. */
|
|
42
|
+
export function resolveIdPrefix(ids, input) {
|
|
43
|
+
if (ids.includes(input))
|
|
44
|
+
return { status: 'ok', id: input };
|
|
45
|
+
if (input.length < MIN_ID_PREFIX_LENGTH)
|
|
46
|
+
return { status: 'not-found' };
|
|
47
|
+
const matches = ids.filter((id) => id.startsWith(input));
|
|
48
|
+
if (matches.length === 1)
|
|
49
|
+
return { status: 'ok', id: matches[0] };
|
|
50
|
+
return matches.length ? { status: 'ambiguous', matches } : { status: 'not-found' };
|
|
51
|
+
}
|
|
52
|
+
/** Both message and group lookups answer an ambiguous prefix the same way: say
|
|
53
|
+
* how many matched, never which ones (a prefix search can reach another
|
|
54
|
+
* session's ids), and name the way out. */
|
|
55
|
+
export function ambiguousIdMessage(kind, count) {
|
|
56
|
+
return `${kind} id 前缀匹配到 ${count} 个对象,请提供更长的前缀或完整 id`;
|
|
57
|
+
}
|
|
21
58
|
export function validateExtras(input) {
|
|
22
59
|
if (input.idempotencyKey !== undefined && (typeof input.idempotencyKey !== 'string' || !input.idempotencyKey.trim() || input.idempotencyKey.length > 256)) {
|
|
23
60
|
throw new CollaborationError('INVALID_IDEMPOTENCY_KEY', 'idempotency key must contain 1–256 characters');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { COLLAB_LIMITS, CollaborationError, extrasFromBody } from './collaborationProtocol.js';
|
|
2
|
+
import { COLLAB_LIMITS, CollaborationError, ambiguousIdMessage, extrasFromBody } from './collaborationProtocol.js';
|
|
3
3
|
/** Member names arrive agent-authored over a CLI; control characters would
|
|
4
4
|
* corrupt terminal shells, tmux options and persisted records. Fold them to
|
|
5
5
|
* spaces, collapse runs, and cap the length (display sanitization for the
|
|
@@ -30,8 +30,17 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
|
|
|
30
30
|
}
|
|
31
31
|
res.json({ ok: true, route: await rebind(sessionId, pane ?? null) });
|
|
32
32
|
}));
|
|
33
|
+
/** Accepts the 8-character id a terminal shows as well as the full one; an
|
|
34
|
+
* ambiguous prefix is refused rather than guessed, so a reply can never
|
|
35
|
+
* land on the wrong thread. */
|
|
36
|
+
const resolveMessage = (id) => {
|
|
37
|
+
const resolved = store.resolveMessageId(id);
|
|
38
|
+
if (resolved.status === 'ambiguous')
|
|
39
|
+
throw new CollaborationError('MESSAGE_ID_AMBIGUOUS', ambiguousIdMessage('消息', resolved.matches.length));
|
|
40
|
+
return resolved.status === 'ok' ? store.getMessage(resolved.id) : null;
|
|
41
|
+
};
|
|
33
42
|
const ownMessage = (id, sessionId, recipientOnly = false) => {
|
|
34
|
-
const message =
|
|
43
|
+
const message = resolveMessage(id);
|
|
35
44
|
if (!message || (message.toSessionId !== sessionId && (recipientOnly || message.fromSessionId !== sessionId)))
|
|
36
45
|
throw new CollaborationError('MESSAGE_NOT_FOUND', 'Message does not belong to this session', 404);
|
|
37
46
|
return message;
|
|
@@ -83,8 +92,18 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
|
|
|
83
92
|
const targets = requestedTargets.length > 0 ? requestedTargets : (target ? [target] : []);
|
|
84
93
|
if (!targets.length)
|
|
85
94
|
throw new CollaborationError('NO_TARGET', 'send requires a targetSessionId (or toSessionIds for a fan-out)', 400);
|
|
95
|
+
// `--group` may be the 8-character id; an unresolvable one must stay a
|
|
96
|
+
// GROUP_NOT_FOUND below instead of silently falling back to the only
|
|
97
|
+
// shared group, which would send to a set the sender did not name.
|
|
98
|
+
let requestedGroupId = typeof req.body.group_id === 'string' ? req.body.group_id : '';
|
|
99
|
+
if (requestedGroupId) {
|
|
100
|
+
const resolved = store.resolveGroupId(requestedGroupId);
|
|
101
|
+
if (resolved.status === 'ambiguous')
|
|
102
|
+
throw new CollaborationError('GROUP_ID_AMBIGUOUS', ambiguousIdMessage('协作组', resolved.matches.length));
|
|
103
|
+
requestedGroupId = resolved.status === 'ok' ? resolved.id : requestedGroupId;
|
|
104
|
+
}
|
|
86
105
|
const groups = store.groupsForSession(sessionId)
|
|
87
|
-
.filter((group) => targets.every((candidate) => group.sessionIds.includes(candidate)) && (!
|
|
106
|
+
.filter((group) => targets.every((candidate) => group.sessionIds.includes(candidate)) && (!requestedGroupId || group.id === requestedGroupId));
|
|
88
107
|
if (!groups.length)
|
|
89
108
|
throw new CollaborationError('GROUP_NOT_FOUND', 'Sender and recipients must share the specified group');
|
|
90
109
|
if (groups.length > 1 && !req.body.group_id)
|
|
@@ -129,9 +148,24 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
|
|
|
129
148
|
const since = sinceText === undefined ? undefined : /^\d+$/.test(sinceText) ? Number(sinceText) : Date.parse(sinceText);
|
|
130
149
|
if (since !== undefined && !Number.isFinite(since))
|
|
131
150
|
throw new CollaborationError('INVALID_SINCE', 'since must be an ISO timestamp or epoch milliseconds');
|
|
151
|
+
// `--group` accepts the 8-character id; an unresolvable or ambiguous one
|
|
152
|
+
// keeps the caller's text, which matches no group and yields an empty page
|
|
153
|
+
// (the pre-existing behavior for an unknown group filter).
|
|
154
|
+
let groupFilter = string('group');
|
|
155
|
+
if (groupFilter) {
|
|
156
|
+
const resolved = store.resolveGroupId(groupFilter);
|
|
157
|
+
if (resolved.status === 'ok')
|
|
158
|
+
groupFilter = resolved.id;
|
|
159
|
+
}
|
|
160
|
+
let threadFilter = string('thread');
|
|
161
|
+
if (threadFilter) {
|
|
162
|
+
const resolved = store.resolveThreadId(threadFilter);
|
|
163
|
+
if (resolved.status === 'ok')
|
|
164
|
+
threadFilter = resolved.id;
|
|
165
|
+
}
|
|
132
166
|
const page = store.page(sessionId, { unread: string('unread') === 'true', since, afterId: string('after_id'), cursor: string('cursor'),
|
|
133
167
|
consumer: string('consumer'), limit: string('limit') ? Number(string('limit')) : undefined,
|
|
134
|
-
from: string('from'), group:
|
|
168
|
+
from: string('from'), group: groupFilter, thread: threadFilter, kind: string('kind'), responseKind: string('response_kind'), order: string('order') });
|
|
135
169
|
// Fan-out edges carry sibling recipients; the names map lets the CLI text
|
|
136
170
|
// renderer show 同时发给了:… as people instead of bare session ids. The
|
|
137
171
|
// fallback to the raw id stays server-side agnostic (federated/offline).
|
|
@@ -143,7 +177,10 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
|
|
|
143
177
|
res.json({ ok: true, consumer: req.body.consumer, cursor: req.body.cursor });
|
|
144
178
|
}));
|
|
145
179
|
const groupOf = (id, sessionId) => {
|
|
146
|
-
const
|
|
180
|
+
const resolved = store.resolveGroupId(id);
|
|
181
|
+
if (resolved.status === 'ambiguous')
|
|
182
|
+
throw new CollaborationError('GROUP_ID_AMBIGUOUS', ambiguousIdMessage('协作组', resolved.matches.length));
|
|
183
|
+
const group = resolved.status === 'ok' ? store.getGroup(resolved.id) : null;
|
|
147
184
|
if (!group || group.deleted)
|
|
148
185
|
throw new CollaborationError('GROUP_NOT_FOUND', 'Collaboration group not found', 404);
|
|
149
186
|
if (!group.sessionIds.includes(sessionId))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import crypto from 'node:crypto';
|
|
4
|
-
import { COLLAB_LIMITS, CollaborationError, STATUS_RANK, validateExtras } from './collaborationProtocol.js';
|
|
4
|
+
import { COLLAB_LIMITS, CollaborationError, STATUS_RANK, resolveIdPrefix, validateExtras } from './collaborationProtocol.js';
|
|
5
5
|
/** Characters that would corrupt a role line injected into the delivery shell
|
|
6
6
|
* (`你的定位:...`) or smuggle terminal output. Unlike names, roles are plain
|
|
7
7
|
* prose — 「」 and · are harmless there — so only control sequences are barred. */
|
|
@@ -57,6 +57,13 @@ export class CollaborationStore {
|
|
|
57
57
|
getGroup(id) {
|
|
58
58
|
return this.document.groups.find((group) => group.id === id) ?? null;
|
|
59
59
|
}
|
|
60
|
+
/** Typed lookups accept the 8-character id a terminal shows as well as the
|
|
61
|
+
* full one: exact match first, then a unique prefix. Ambiguity is reported,
|
|
62
|
+
* never guessed at, and resolution happens before any send so the
|
|
63
|
+
* idempotency payload hash still sees the full id. */
|
|
64
|
+
resolveGroupId(id) {
|
|
65
|
+
return resolveIdPrefix(this.document.groups.map((group) => group.id), id);
|
|
66
|
+
}
|
|
60
67
|
save(input) {
|
|
61
68
|
const now = Date.now();
|
|
62
69
|
const existing = input.id ? this.document.groups.find((group) => group.id === input.id) : null;
|
|
@@ -222,6 +229,16 @@ export class CollaborationStore {
|
|
|
222
229
|
this.expire();
|
|
223
230
|
return this.document.messages.find((message) => message.id === id) ?? null;
|
|
224
231
|
}
|
|
232
|
+
resolveMessageId(id) {
|
|
233
|
+
this.expire();
|
|
234
|
+
return resolveIdPrefix(this.document.messages.map((message) => message.id), id);
|
|
235
|
+
}
|
|
236
|
+
/** Thread ids are shown shortened alongside message ids, so the `--thread`
|
|
237
|
+
* filter has to take one back the same way. */
|
|
238
|
+
resolveThreadId(id) {
|
|
239
|
+
this.expire();
|
|
240
|
+
return resolveIdPrefix([...new Set(this.document.messages.map((message) => message.threadId).filter((threadId) => Boolean(threadId)))], id);
|
|
241
|
+
}
|
|
225
242
|
inbox(sessionId, options = {}) {
|
|
226
243
|
this.expire();
|
|
227
244
|
const matches = this.document.messages.filter((message) => message.toSessionId === sessionId && (!options.pendingOnly || message.status === 'pending'));
|
|
@@ -40,6 +40,7 @@ import { collaborationRoutes } from '../agent/collaborationRoutes.js';
|
|
|
40
40
|
import { COLLAB_LIMITS, extrasFromBody } from '../agent/collaborationProtocol.js';
|
|
41
41
|
import { CollaborationStore } from '../agent/collaborationStore.js';
|
|
42
42
|
import { COLLAB_NAME_FORBIDDEN, formatCollaborationDelivery } from '../agent/collaborationPrompt.js';
|
|
43
|
+
import { ambiguousIdMessage } from '../agent/collaborationProtocol.js';
|
|
43
44
|
import { buildCollaborationSpawnCommand, resolveCollaborationSpawnMode } from '../agent/collaborationSpawn.js';
|
|
44
45
|
import { SessionSearchStore } from '../agent/sessionSearchStore.js';
|
|
45
46
|
import { resolveCollaborationBackend, resolveCollaborationSessionId } from '../agent/sessionBindingRecovery.js';
|
|
@@ -5519,8 +5520,20 @@ router.post('/operations/collaboration-federation', (req, res) => {
|
|
|
5519
5520
|
});
|
|
5520
5521
|
router.use('/operations', collaborationGroupRoutes({ store: collaborationStore,
|
|
5521
5522
|
sessions: () => globalSessionState.sessions.map(orchestrationSessionSnapshot) }));
|
|
5523
|
+
/** Group id from a URL param: the 8-character id a terminal shows resolves to
|
|
5524
|
+
* its full id, an ambiguous prefix is refused with 409, and anything else is
|
|
5525
|
+
* simply "no such group" — the same 404 each route already answers. */
|
|
5526
|
+
function resolveGroupParam(id) {
|
|
5527
|
+
const resolved = collaborationStore.resolveGroupId(id);
|
|
5528
|
+
if (resolved.status === 'ambiguous')
|
|
5529
|
+
return { group: null, ambiguous: resolved.matches.length };
|
|
5530
|
+
return { group: resolved.status === 'ok' ? collaborationStore.getGroup(resolved.id) : null, ambiguous: 0 };
|
|
5531
|
+
}
|
|
5532
|
+
const ambiguousGroupResponse = (res, count) => res.status(409).json({ error: ambiguousIdMessage('协作组', count), code: 'GROUP_ID_AMBIGUOUS' });
|
|
5522
5533
|
router.post('/operations/collaboration-groups/:groupId/spawn', async (req, res) => {
|
|
5523
|
-
const group =
|
|
5534
|
+
const { group, ambiguous } = resolveGroupParam(req.params.groupId);
|
|
5535
|
+
if (ambiguous)
|
|
5536
|
+
return ambiguousGroupResponse(res, ambiguous);
|
|
5524
5537
|
if (!group)
|
|
5525
5538
|
return res.status(404).json({ error: '协作组不存在' });
|
|
5526
5539
|
try {
|
|
@@ -5533,14 +5546,18 @@ router.post('/operations/collaboration-groups/:groupId/spawn', async (req, res)
|
|
|
5533
5546
|
}
|
|
5534
5547
|
});
|
|
5535
5548
|
router.get('/operations/collaboration-groups/:groupId/messages', (req, res) => {
|
|
5536
|
-
const group =
|
|
5549
|
+
const { group, ambiguous } = resolveGroupParam(req.params.groupId);
|
|
5550
|
+
if (ambiguous)
|
|
5551
|
+
return ambiguousGroupResponse(res, ambiguous);
|
|
5537
5552
|
if (!group)
|
|
5538
5553
|
return res.status(404).json({ error: '协作组不存在' });
|
|
5539
5554
|
res.json({ messages: collaborationStore.listMessages(group.id, Number(req.query.limit) || 200) });
|
|
5540
5555
|
});
|
|
5541
5556
|
router.post('/operations/collaboration-groups/:groupId/messages', (req, res) => {
|
|
5542
5557
|
try {
|
|
5543
|
-
const group =
|
|
5558
|
+
const { group, ambiguous } = resolveGroupParam(req.params.groupId);
|
|
5559
|
+
if (ambiguous)
|
|
5560
|
+
return ambiguousGroupResponse(res, ambiguous);
|
|
5544
5561
|
if (!group)
|
|
5545
5562
|
return res.status(404).json({ error: '协作组不存在' });
|
|
5546
5563
|
const fromSessionId = resolveFrontendSessionId(req.body ?? {});
|
|
@@ -5592,7 +5609,9 @@ router.post('/operations/orchestration/members', (req, res) => {
|
|
|
5592
5609
|
const groupId = typeof req.body?.groupId === 'string' ? req.body.groupId.trim() : '';
|
|
5593
5610
|
const targetSessionId = typeof req.body?.targetSessionId === 'string' ? req.body.targetSessionId.trim() : '';
|
|
5594
5611
|
const action = req.body?.action === 'remove' ? 'remove' : req.body?.action === 'add' ? 'add' : null;
|
|
5595
|
-
const group =
|
|
5612
|
+
const { group, ambiguous } = resolveGroupParam(groupId);
|
|
5613
|
+
if (ambiguous)
|
|
5614
|
+
return ambiguousGroupResponse(res, ambiguous);
|
|
5596
5615
|
if (!sourceSessionId)
|
|
5597
5616
|
return res.status(400).json({ error: '无法识别当前会话;请从 Termdock 会话内运行 td collab' });
|
|
5598
5617
|
if (!group || !group.sessionIds.includes(sourceSessionId))
|
|
@@ -5613,7 +5632,9 @@ router.post('/operations/orchestration/members', (req, res) => {
|
|
|
5613
5632
|
router.post('/operations/orchestration/spawn', async (req, res) => {
|
|
5614
5633
|
const sourceSessionId = resolveFrontendSessionId(req.body ?? {});
|
|
5615
5634
|
const groupId = typeof req.body?.groupId === 'string' ? req.body.groupId.trim() : '';
|
|
5616
|
-
const group =
|
|
5635
|
+
const { group, ambiguous } = resolveGroupParam(groupId);
|
|
5636
|
+
if (ambiguous)
|
|
5637
|
+
return ambiguousGroupResponse(res, ambiguous);
|
|
5617
5638
|
if (!sourceSessionId)
|
|
5618
5639
|
return res.status(400).json({ error: '无法识别当前会话;请从 Termdock 会话内运行 td collab' });
|
|
5619
5640
|
if (!group || !group.sessionIds.includes(sourceSessionId))
|
package/package.json
CHANGED
package/runtime-manifest.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "termdock",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.196",
|
|
5
5
|
"runtimeProtocolVersion": 1,
|
|
6
6
|
"minimumDesktopVersion": "1.4.46",
|
|
7
7
|
"nodeMajor": 22,
|
|
8
8
|
"dependencyHash": "sha256-K4KyYJuVoQDpZsBM8ZX1Rw3MddOxAzVdp/cPm0iGZz0=",
|
|
9
|
-
"serverBundleHash": "sha256-
|
|
10
|
-
"clientBundleHash": "sha256-
|
|
9
|
+
"serverBundleHash": "sha256-T/KLnvRkLhdOmsag6ksQv7ZoSL8RTw328UNIFTUC3/4=",
|
|
10
|
+
"clientBundleHash": "sha256-EQPT/w33vRGcZlyZoRHKmtgmEPWiRSGjRGHBx2SAwOw=",
|
|
11
11
|
"entrypoint": "dist/server/cli.js",
|
|
12
12
|
"clientEntrypoint": "dist/client/index.html"
|
|
13
13
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as a,C as n}from"./mermaid.core-Ny4ifEul.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as t,C as e}from"./chunk-TICWLB2K-N3OPIvmU.js";import{d as i}from"./mermaid.core-Ny4ifEul.js";import"./chunk-5VM5RSS4-BofAFEcC.js";import"./chunk-XXDRQBXY-IurIojt5.js";import"./chunk-POPQ4Y6H-MXmTC-sG.js";import"./chunk-F27PBJKO-CLNw1JDM.js";import"./purify.es-4eNOHKSq.js";import"./app-5zC_J9mq.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as t,C as e}from"./chunk-TICWLB2K-N3OPIvmU.js";import{d as i}from"./mermaid.core-Ny4ifEul.js";import"./chunk-5VM5RSS4-BofAFEcC.js";import"./chunk-XXDRQBXY-IurIojt5.js";import"./chunk-POPQ4Y6H-MXmTC-sG.js";import"./chunk-F27PBJKO-CLNw1JDM.js";import"./purify.es-4eNOHKSq.js";import"./app-5zC_J9mq.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|