chalkbridge 1.0.1 → 1.0.4
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/CHANGELOG.md +47 -0
- package/README.md +16 -0
- package/dist/{chunk-SHJT5BF3.js → chunk-U2ZMSGNS.js} +22 -6
- package/dist/cli.js +238 -25
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/ui-dist/assets/{abnfDiagram-VCTEODGH-BJtEDuNS.js → abnfDiagram-VCTEODGH-C_cqCKun.js} +1 -1
- package/ui-dist/assets/{ar-SA-G6X2FPQ2-B6obDqD5.js → ar-SA-G6X2FPQ2-CEKRHtmX.js} +1 -1
- package/ui-dist/assets/architecture-7GRP2DOG-fqG4giDT.js +1 -0
- package/ui-dist/assets/{architectureDiagram-5GKGNRK7-CvbQe1_v.js → architectureDiagram-5GKGNRK7-BuWVonvB.js} +1 -1
- package/ui-dist/assets/{az-AZ-76LH7QW2-CfV9ZZWy.js → az-AZ-76LH7QW2-mn2Y6BCY.js} +1 -1
- package/ui-dist/assets/{bg-BG-XCXSNQG7-DUA8YPCl.js → bg-BG-XCXSNQG7-CraLx0fE.js} +1 -1
- package/ui-dist/assets/{blockDiagram-NRAW4CY4-DocsEmiD.js → blockDiagram-NRAW4CY4-83XozRPe.js} +1 -1
- package/ui-dist/assets/{bn-BD-2XOGV67Q-DvE_tajm.js → bn-BD-2XOGV67Q-CsTrJsPu.js} +1 -1
- package/ui-dist/assets/{c4Diagram-UCG6FXSJ-Tx_g_cO9.js → c4Diagram-UCG6FXSJ-DTdS8B8G.js} +1 -1
- package/ui-dist/assets/{ca-ES-6MX7JW3Y-DHdtT9lh.js → ca-ES-6MX7JW3Y-DD8cv_ze.js} +1 -1
- package/ui-dist/assets/channel-BOrwYBHk.js +1 -0
- package/ui-dist/assets/{chunk-75Z2AOVW-LAZTrfqO.js → chunk-75Z2AOVW-DQDqkKP0.js} +1 -1
- package/ui-dist/assets/{chunk-DU6HZSFF-DYQVLGqe.js → chunk-DU6HZSFF-_YwywVCK.js} +1 -1
- package/ui-dist/assets/{chunk-EIO257PC-B41AYx2_.js → chunk-EIO257PC-CLwbKeso.js} +1 -1
- package/ui-dist/assets/{chunk-F27PBJKO-BTHkH7Vo.js → chunk-F27PBJKO-BwhryBf6.js} +1 -1
- package/ui-dist/assets/{chunk-G27WJ6UU-BBBWLXXO.js → chunk-G27WJ6UU-BixSJdhz.js} +1 -1
- package/ui-dist/assets/{chunk-GMAD6QVW-BkvPd3CL.js → chunk-GMAD6QVW-Bp7aUQup.js} +1 -1
- package/ui-dist/assets/{chunk-JQ64N6SF-CKrtUr61.js → chunk-JQ64N6SF-Dt5bAScf.js} +1 -1
- package/ui-dist/assets/{chunk-LCL6LL3I-B4K72jRj.js → chunk-LCL6LL3I-B5MsvPPp.js} +1 -1
- package/ui-dist/assets/{chunk-OBVCFTLP-CMCEQnr_.js → chunk-OBVCFTLP-DBqcHzNF.js} +1 -1
- package/ui-dist/assets/{chunk-P2QGCYS3-BNpg6XHk.js → chunk-P2QGCYS3-TMRACTMO.js} +1 -1
- package/ui-dist/assets/{chunk-POPQ4Y6H-BaAoqHUX.js → chunk-POPQ4Y6H-BsmX_MmQ.js} +1 -1
- package/ui-dist/assets/{chunk-PWAF6VOD-CGQ4p70E.js → chunk-PWAF6VOD-g4MniF8u.js} +1 -1
- package/ui-dist/assets/{chunk-R7TYR2AO-B2S7-r2z.js → chunk-R7TYR2AO-S7THFl9x.js} +1 -1
- package/ui-dist/assets/{chunk-RHFEMEQ7-C_ziruXk.js → chunk-RHFEMEQ7-CZYull6D.js} +1 -1
- package/ui-dist/assets/{chunk-SVP7TREG-FJEPEsgF.js → chunk-SVP7TREG-DCss0vmb.js} +1 -1
- package/ui-dist/assets/{chunk-TEH6E4GO-BvKV-yBX.js → chunk-TEH6E4GO-B-6h5v_5.js} +1 -1
- package/ui-dist/assets/classDiagram-DTDB5LWJ-Dm2kcSSm.js +1 -0
- package/ui-dist/assets/classDiagram-v2-JRS7N3AN-Dm2kcSSm.js +1 -0
- package/ui-dist/assets/{cs-CZ-2BRQDIVT-BamYs5wC.js → cs-CZ-2BRQDIVT-C9fIM1z5.js} +1 -1
- package/ui-dist/assets/{cynefin-OW5HDTMX-Cj_nyyy3.js → cynefin-OW5HDTMX-CtdCt-Da.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-5FMLGOSQ-B3Rm8-dE.js → cynefinDiagram-5FMLGOSQ-CF9L7X85.js} +1 -1
- package/ui-dist/assets/{da-DK-5WZEPLOC-B8baJSus.js → da-DK-5WZEPLOC-DXGP9-TU.js} +1 -1
- package/ui-dist/assets/{dagre-3AP2YEHR-BesdyiUo.js → dagre-3AP2YEHR-Bt0GOj3f.js} +1 -1
- package/ui-dist/assets/{de-DE-XR44H4JA-DKPtPOlk.js → de-DE-XR44H4JA-ChR8kF4h.js} +1 -1
- package/ui-dist/assets/{diagram-S7CK7UJ4-jeIUYTnQ.js → diagram-S7CK7UJ4-D2NIL20U.js} +1 -1
- package/ui-dist/assets/{diagram-UQ7AKVKN-BmAlHtLI.js → diagram-UQ7AKVKN-Dty3qvRq.js} +1 -1
- package/ui-dist/assets/{diagram-VSXAHHWV-B-S5XoGb.js → diagram-VSXAHHWV-znpNlomZ.js} +1 -1
- package/ui-dist/assets/{diagram-VX7I27RA--KrWarId.js → diagram-VX7I27RA-DMKYB58y.js} +1 -1
- package/ui-dist/assets/{diagram-Z3DM3KII-B7MnKinD.js → diagram-Z3DM3KII-BLsAgfm1.js} +1 -1
- package/ui-dist/assets/{dist-C2o0r0se.js → dist-Biz3NhE4.js} +4 -4
- package/ui-dist/assets/{ebnfDiagram-PWID7BFC-C20WACav.js → ebnfDiagram-PWID7BFC-sN1WpIzH.js} +1 -1
- package/ui-dist/assets/{el-GR-BZB4AONW-FSgeiYUW.js → el-GR-BZB4AONW-BMi-5oTn.js} +1 -1
- package/ui-dist/assets/{en-B4ZKOASM-BAWBMIE-.js → en-B4ZKOASM-DTTcVPyw.js} +1 -1
- package/ui-dist/assets/{erDiagram-SSCWMZ5O-DU4Qz6qu.js → erDiagram-SSCWMZ5O-qLib13wp.js} +1 -1
- package/ui-dist/assets/{es-ES-U4NZUMDT-CZ9XqqCk.js → es-ES-U4NZUMDT-DSk-whe2.js} +1 -1
- package/ui-dist/assets/{eu-ES-A7QVB2H4-CNagAo_o.js → eu-ES-A7QVB2H4-Dlhf1HMz.js} +1 -1
- package/ui-dist/assets/eventmodeling-NTZA5JFV-BN91GLT5.js +1 -0
- package/ui-dist/assets/{fa-IR-HGAKTJCU-CGpX3K56.js → fa-IR-HGAKTJCU-C4NL1SUQ.js} +1 -1
- package/ui-dist/assets/{fi-FI-Z5N7JZ37-D8ErPXQZ.js → fi-FI-Z5N7JZ37-BPDGFbjy.js} +1 -1
- package/ui-dist/assets/flowDiagram-A5DVABFB-DBrXJ-Jf.js +1 -0
- package/ui-dist/assets/{fr-FR-RHASNOE6-CgP9qmF-.js → fr-FR-RHASNOE6-BKM44_qc.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-EL5Y4UJY-CNqGfKGy.js → ganttDiagram-EL5Y4UJY-Cm_9m3AA.js} +1 -1
- package/ui-dist/assets/{gitGraph-4MIJSDKK-Cjg2l4tr.js → gitGraph-4MIJSDKK-B53Ccobw.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-WWUBYQGX-C1RblGyv.js → gitGraphDiagram-WWUBYQGX-CshbIfrd.js} +1 -1
- package/ui-dist/assets/{gl-ES-HMX3MZ6V-D64w31ga.js → gl-ES-HMX3MZ6V-CYq-Wgeo.js} +1 -1
- package/ui-dist/assets/{he-IL-6SHJWFNN-prTy1rRE.js → he-IL-6SHJWFNN-CejOCh7c.js} +1 -1
- package/ui-dist/assets/{hi-IN-IWLTKZ5I-uvdg8ovV.js → hi-IN-IWLTKZ5I-DdZM6com.js} +1 -1
- package/ui-dist/assets/{hu-HU-A5ZG7DT2-OIhzhh7g.js → hu-HU-A5ZG7DT2-DcLFRMuO.js} +1 -1
- package/ui-dist/assets/{id-ID-SAP4L64H-Bs8DbFR5.js → id-ID-SAP4L64H-1x9JAf0A.js} +1 -1
- package/ui-dist/assets/image-GAAHSSAO-BgehxCDd.js +1 -0
- package/ui-dist/assets/{index-CknJbzCM.js → index-CzWe1zeF.js} +8 -8
- package/ui-dist/assets/{info-A6RAGUB7-DdLeprH9.js → info-A6RAGUB7-Cge9ecX_.js} +1 -1
- package/ui-dist/assets/{infoDiagram-RXCK75RN-B1aPG_BB.js → infoDiagram-RXCK75RN-VS1BTI_H.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-5VMMS53U-ChG5EVuT.js → ishikawaDiagram-5VMMS53U-Cbf1xbxj.js} +1 -1
- package/ui-dist/assets/{it-IT-JPQ66NNP-CVy3c_Ht.js → it-IT-JPQ66NNP-DgmQi0B_.js} +1 -1
- package/ui-dist/assets/{ja-JP-DBVTYXUO-EcX4mq4z.js → ja-JP-DBVTYXUO-BpmMfXE3.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-EYS64GPL-BZ4Ytc1U.js → journeyDiagram-EYS64GPL-C8RWIfHV.js} +1 -1
- package/ui-dist/assets/{kaa-6HZHGXH3-BwP9az-p.js → kaa-6HZHGXH3-CczLR43o.js} +1 -1
- package/ui-dist/assets/{kab-KAB-ZGHBKWFO-By-AIEWs.js → kab-KAB-ZGHBKWFO-Cx74DVre.js} +1 -1
- package/ui-dist/assets/{kanban-definition-3QL26DDD-Dm8bYrkM.js → kanban-definition-3QL26DDD-R8ng9q7k.js} +1 -1
- package/ui-dist/assets/{kk-KZ-P5N5QNE5-DYNjxBd-.js → kk-KZ-P5N5QNE5-BPvg9KTT.js} +1 -1
- package/ui-dist/assets/{km-KH-HSX4SM5Z-DS2ZYG-3.js → km-KH-HSX4SM5Z-Blgo7Zit.js} +1 -1
- package/ui-dist/assets/{ko-KR-MTYHY66A-DOz4vl1z.js → ko-KR-MTYHY66A-DZdo-KOi.js} +1 -1
- package/ui-dist/assets/{ku-TR-6OUDTVRD-CxEEWxJq.js → ku-TR-6OUDTVRD-CTpgWpW_.js} +1 -1
- package/ui-dist/assets/{line-B65qaCJb.js → line-Baf15v0x.js} +1 -1
- package/ui-dist/assets/{lt-LT-XHIRWOB4-CkgB2O8i.js → lt-LT-XHIRWOB4-DKNkbcsj.js} +1 -1
- package/ui-dist/assets/{lv-LV-5QDEKY6T-BUDeq4Hb.js → lv-LV-5QDEKY6T-DwnZRxkH.js} +1 -1
- package/ui-dist/assets/{mermaid-parser.core-C60rNywA.js → mermaid-parser.core-0V2gZHuN.js} +3 -3
- package/ui-dist/assets/{mindmap-definition-FBJOCRG2-DAu41qFN.js → mindmap-definition-FBJOCRG2-7hOTFX4B.js} +1 -1
- package/ui-dist/assets/{mr-IN-CRQNXWMA-DtuuryqC.js → mr-IN-CRQNXWMA-C-BFvdUk.js} +1 -1
- package/ui-dist/assets/{my-MM-5M5IBNSE-CC79-XBH.js → my-MM-5M5IBNSE-BFs64Lrm.js} +1 -1
- package/ui-dist/assets/{nb-NO-T6EIAALU-CKNIbK-0.js → nb-NO-T6EIAALU-CHGzOQzI.js} +1 -1
- package/ui-dist/assets/{nl-NL-IS3SIHDZ-B3dYZhvS.js → nl-NL-IS3SIHDZ-CmrNJ43t.js} +1 -1
- package/ui-dist/assets/{nn-NO-6E72VCQL-CdPrOnP4.js → nn-NO-6E72VCQL-Cmx8XlD1.js} +1 -1
- package/ui-dist/assets/{oc-FR-POXYY2M6-DUmzGjKc.js → oc-FR-POXYY2M6-D6ZK0W24.js} +1 -1
- package/ui-dist/assets/{pa-IN-N4M65BXN-DH39ZTHj.js → pa-IN-N4M65BXN-CoFjVv1P.js} +1 -1
- package/ui-dist/assets/{packet-AYTQ26CC-DdR4jEOZ.js → packet-AYTQ26CC-auec35xT.js} +1 -1
- package/ui-dist/assets/{pegDiagram-XKGWAZYB-Dx1lj8MV.js → pegDiagram-XKGWAZYB-NMMkeAIs.js} +1 -1
- package/ui-dist/assets/percentages-BXMCSKIN-BBuUnwM-.js +1 -0
- package/ui-dist/assets/{pie-WAS4IAKB-cVrV21tR.js → pie-WAS4IAKB-Brhoju7F.js} +1 -1
- package/ui-dist/assets/{pieDiagram-E7YTZNPT-CcvgLYQz.js → pieDiagram-E7YTZNPT-CbaXV2ep.js} +1 -1
- package/ui-dist/assets/{pl-PL-T2D74RX3-BNYpL8df.js → pl-PL-T2D74RX3-CtZh2-fJ.js} +1 -1
- package/ui-dist/assets/{pt-BR-5N22H2LF-RWmGHl_8.js → pt-BR-5N22H2LF-Dwnm2Lle.js} +1 -1
- package/ui-dist/assets/{pt-PT-UZXXM6DQ-smq6YmTY.js → pt-PT-UZXXM6DQ-Cb08TgqC.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-AXDQQJYC-C4xDsL0E.js → quadrantDiagram-AXDQQJYC-CXEPKL_-.js} +1 -1
- package/ui-dist/assets/{radar-RG4KPBEZ-DYaemlGZ.js → radar-RG4KPBEZ-CTDsgRBl.js} +1 -1
- package/ui-dist/assets/{railroad-74A4TZTK-BbRg5RPZ.js → railroad-74A4TZTK-Bad-j95k.js} +1 -1
- package/ui-dist/assets/railroad-abnf-HS5TGJTU-CbvNSNpm.js +1 -0
- package/ui-dist/assets/railroad-ebnf-LZEXJU2U-DdltjnE0.js +1 -0
- package/ui-dist/assets/railroad-peg-WCYAUIDC-CgbxToYh.js +1 -0
- package/ui-dist/assets/{railroadDiagram-O6MQD6OU-CR1fbGhX.js → railroadDiagram-O6MQD6OU-CJiZ6mmg.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-EFPCY7ZU-CFp52i96.js → requirementDiagram-EFPCY7ZU-T8QMEZu6.js} +1 -1
- package/ui-dist/assets/{ro-RO-JPDTUUEW-BOjKaxCz.js → ro-RO-JPDTUUEW-D6H165NT.js} +1 -1
- package/ui-dist/assets/{ru-RU-B4JR7IUQ-DOK2ZlyX.js → ru-RU-B4JR7IUQ-CBp0xVXG.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-P5KCCOFB-CZWdGNnS.js → sankeyDiagram-P5KCCOFB-Z9s0vmSt.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-WJ2MYXX4-D4X03yFA.js → sequenceDiagram-WJ2MYXX4-BulR70nw.js} +1 -1
- package/ui-dist/assets/{si-LK-N5RQ5JYF-BtKkEPfN.js → si-LK-N5RQ5JYF-10AxMH9e.js} +1 -1
- package/ui-dist/assets/{sk-SK-C5VTKIMK-DehBWGkI.js → sk-SK-C5VTKIMK-BXvCxb46.js} +1 -1
- package/ui-dist/assets/{sl-SI-NN7IZMDC-ClR46UYx.js → sl-SI-NN7IZMDC-BI5_PFXZ.js} +1 -1
- package/ui-dist/assets/{stateDiagram-HBIQ2CUA-Bg1Uy2K-.js → stateDiagram-HBIQ2CUA-Dam0DwKS.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-4QOOHH4V-CSjCWsxW.js +1 -0
- package/ui-dist/assets/subset-shared.chunk-Du7WrYQy.js +1 -0
- package/ui-dist/assets/{subset-worker.chunk-BLppPGco.js → subset-worker.chunk-BaDYCnkg.js} +1 -1
- package/ui-dist/assets/{sv-SE-XGPEYMSR-Cq54FLpH.js → sv-SE-XGPEYMSR-dVM3morJ.js} +1 -1
- package/ui-dist/assets/{swimlanes-XN3QIQJK-Ca4vLBMp.js → swimlanes-XN3QIQJK-txWA6rWV.js} +1 -1
- package/ui-dist/assets/swimlanesDiagram-VK2B7HYN-CU4h0g7a.js +8 -0
- package/ui-dist/assets/{ta-IN-2NMHFXQM-SCh3n0lB.js → ta-IN-2NMHFXQM-CWJY03pN.js} +1 -1
- package/ui-dist/assets/{th-TH-HPSO5L25-BotlAjVv.js → th-TH-HPSO5L25-CR6GhLgj.js} +1 -1
- package/ui-dist/assets/{timeline-definition-24CTP7MA-CjHCKN4P.js → timeline-definition-24CTP7MA-D8m_1UrT.js} +1 -1
- package/ui-dist/assets/{tr-TR-DEFEU3FU-B4u6Au2y.js → tr-TR-DEFEU3FU-BI8tDJSm.js} +1 -1
- package/ui-dist/assets/{treeView-Q6P3EWNA-CKMtikLc.js → treeView-Q6P3EWNA-CWJmpg6A.js} +1 -1
- package/ui-dist/assets/{treemap-WGGIJYW6-B51xYeX7.js → treemap-WGGIJYW6-CvClsvN5.js} +1 -1
- package/ui-dist/assets/{uk-UA-QMV73CPH-CtQkKgv_.js → uk-UA-QMV73CPH-D3Uc38wP.js} +1 -1
- package/ui-dist/assets/{vennDiagram-4TSXK5OY-CSH3IvAD.js → vennDiagram-4TSXK5OY-C5iS8F8o.js} +1 -1
- package/ui-dist/assets/{vi-VN-M7AON7JQ-CjZyv0HH.js → vi-VN-M7AON7JQ-B6BZpyS4.js} +1 -1
- package/ui-dist/assets/{wardley-WFR3VGLG-wnJkewtF.js → wardley-WFR3VGLG-CdqB7_9-.js} +1 -1
- package/ui-dist/assets/{wardleyDiagram-VM6X3IG4-BJuisjH-.js → wardleyDiagram-VM6X3IG4-DAHyWwbW.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-S5SC5T6Z-hiDu0XBA.js → xychartDiagram-S5SC5T6Z-ilyFTLQ_.js} +1 -1
- package/ui-dist/assets/{zh-CN-LNUGB5OW-DyyyDDxj.js → zh-CN-LNUGB5OW-B0PN355q.js} +1 -1
- package/ui-dist/assets/{zh-HK-E62DVLB3-Ch2pxiFR.js → zh-HK-E62DVLB3-DUEHDaPB.js} +1 -1
- package/ui-dist/assets/{zh-TW-RAJ6MFWO-CSf1_B6H.js → zh-TW-RAJ6MFWO-Ci4YMClQ.js} +1 -1
- package/ui-dist/index.html +1 -1
- package/ui-dist/assets/architecture-7GRP2DOG-8nO9N-PA.js +0 -1
- package/ui-dist/assets/channel-uzdT5KPV.js +0 -1
- package/ui-dist/assets/classDiagram-DTDB5LWJ-CodHh4yt.js +0 -1
- package/ui-dist/assets/classDiagram-v2-JRS7N3AN-CodHh4yt.js +0 -1
- package/ui-dist/assets/eventmodeling-NTZA5JFV-CLxW34Y6.js +0 -1
- package/ui-dist/assets/flowDiagram-A5DVABFB-mMONVpxe.js +0 -1
- package/ui-dist/assets/image-GAAHSSAO-D1P4Y62B.js +0 -1
- package/ui-dist/assets/percentages-BXMCSKIN-d5p7s-wT.js +0 -1
- package/ui-dist/assets/railroad-abnf-HS5TGJTU-BoiCOpxv.js +0 -1
- package/ui-dist/assets/railroad-ebnf-LZEXJU2U-ArFqgLSZ.js +0 -1
- package/ui-dist/assets/railroad-peg-WCYAUIDC-BAks8GCx.js +0 -1
- package/ui-dist/assets/stateDiagram-v2-4QOOHH4V-Ci4MD4Pt.js +0 -1
- package/ui-dist/assets/subset-shared.chunk-DQ-JqEaX.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-VK2B7HYN-BKiafpMh.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# chalkbridge
|
|
2
2
|
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
**An upgrade now actually arrives, a bridge can be stopped, and it ends when you are
|
|
6
|
+
done with it.**
|
|
7
|
+
|
|
8
|
+
(1.0.2 was built and verified but never published — everything below shipped as 1.0.3.)
|
|
9
|
+
|
|
10
|
+
The bridge is spawned detached and outlives the session that started it — deliberately,
|
|
11
|
+
because writes have to succeed with no browser connected. But `ensureBridge` reused
|
|
12
|
+
whatever was already listening without ever checking its version, so `npx -y chalkbridge
|
|
13
|
+
mcp` would fetch a new package, find the **old** bridge still answering, and reuse it.
|
|
14
|
+
Every fix would ship and none would arrive, silently. If 1.0.1 seemed not to change
|
|
15
|
+
anything for you, that is why.
|
|
16
|
+
|
|
17
|
+
- **A bridge from another build is replaced.** It is asked to stop first, so its pending
|
|
18
|
+
`.excalidraw` write still reaches the disk.
|
|
19
|
+
- **`chalkbridge stop`** ends the bridge for the current repo, flushing anything unsaved.
|
|
20
|
+
Until now the only options were a reboot or hunting the pid.
|
|
21
|
+
- **`POST /api/shutdown`** is what both use — a request rather than a signal, because on
|
|
22
|
+
Windows a signal from another process terminates outright and the flush never happens.
|
|
23
|
+
- **A pid fallback for bridges built before this release.** 1.0.0 and 1.0.1 have no
|
|
24
|
+
shutdown endpoint, so the polite path is unavailable for exactly the bridges an upgrade
|
|
25
|
+
has to replace. Without it, upgrading from either would leave the new build unable to
|
|
26
|
+
start at all. Found by running the published 1.0.1 against a local build.
|
|
27
|
+
|
|
28
|
+
**And it ends when you are done with it.** Until now a bridge ran until the machine
|
|
29
|
+
restarted — one per repo, forever — which is not what anybody expects after closing a chat
|
|
30
|
+
and a tab. It now exits when nothing is watching *and* nothing is asking, for 90 seconds:
|
|
31
|
+
|
|
32
|
+
| | |
|
|
33
|
+
|---|---|
|
|
34
|
+
| chat closed, tab closed | exits |
|
|
35
|
+
| tab refreshed | reconnects in about a second, so it stays |
|
|
36
|
+
| chat closed, tab still open | stays — somebody is looking at the canvas |
|
|
37
|
+
| Claude drawing with no tab open | every tool call counts, so it stays |
|
|
38
|
+
| two chats on one repo | activity keeps it alive |
|
|
39
|
+
|
|
40
|
+
One rule, no session counting. `CHALK_IDLE_TIMEOUT` tunes it and `0` restores the old
|
|
41
|
+
behaviour.
|
|
42
|
+
|
|
43
|
+
**A tool call now survives its own bridge.** That is what makes the above invisible: if a
|
|
44
|
+
bridge has given up, the next call re-runs the bootstrap — spawning one and reopening the
|
|
45
|
+
canvas — instead of failing. Previously a bridge lost mid-session meant every call failed
|
|
46
|
+
until Claude Code was restarted.
|
|
47
|
+
|
|
48
|
+
After this release, updating really is just restarting Claude Code.
|
|
49
|
+
|
|
3
50
|
## 1.0.1
|
|
4
51
|
|
|
5
52
|
**Arrows are drawn where they belong, the first time.**
|
package/README.md
CHANGED
|
@@ -53,10 +53,26 @@ reach loopback. Do not work around it by binding a wider address.
|
|
|
53
53
|
```bash
|
|
54
54
|
chalkbridge health # what is running for this repository
|
|
55
55
|
chalkbridge serve # start the bridge by hand
|
|
56
|
+
chalkbridge stop # end it, flushing anything unsaved
|
|
56
57
|
chalkbridge icons list # what is in the machine-wide icon catalog
|
|
57
58
|
chalkbridge icons install devicon
|
|
58
59
|
```
|
|
59
60
|
|
|
61
|
+
**The bridge is spawned detached and outlives your session** — deliberately, because
|
|
62
|
+
writes have to succeed with no browser connected. It ends when nothing is watching *and*
|
|
63
|
+
nothing is asking:
|
|
64
|
+
|
|
65
|
+
| | |
|
|
66
|
+
|---|---|
|
|
67
|
+
| chat closed, tab closed | exits after 90 seconds |
|
|
68
|
+
| tab refreshed | reconnects in about a second, so it stays |
|
|
69
|
+
| chat closed, tab still open | stays — you are still looking at the canvas |
|
|
70
|
+
| Claude drawing with no tab | every tool call counts, so it stays |
|
|
71
|
+
|
|
72
|
+
If it has already given up, the next tool call brings it back and reopens the canvas, so
|
|
73
|
+
you never have to think about it. `chalkbridge stop` ends one now; `CHALK_IDLE_TIMEOUT`
|
|
74
|
+
tunes the ninety seconds, and `0` keeps it up forever.
|
|
75
|
+
|
|
60
76
|
`CHALK_NO_AUTOSTART=1` and `CHALK_NO_OPEN=1` turn off the two automatic behaviours;
|
|
61
77
|
`CHALK_PORT` pins the port; `CHALK_DATA_DIR` moves the icon catalog.
|
|
62
78
|
|
|
@@ -223,10 +223,16 @@ var BINDING_FIELDS = [
|
|
|
223
223
|
"startBinding",
|
|
224
224
|
"endBinding"
|
|
225
225
|
];
|
|
226
|
+
var DataUrl = z.custom(isNonEmptyString, {
|
|
227
|
+
message: "dataURL must be a non-empty string"
|
|
228
|
+
});
|
|
229
|
+
var FileMimeType = z.custom(isNonEmptyString, {
|
|
230
|
+
message: "mimeType must be a non-empty string"
|
|
231
|
+
});
|
|
226
232
|
var SceneFile = z.object({
|
|
227
233
|
id: FileId,
|
|
228
|
-
mimeType:
|
|
229
|
-
dataURL:
|
|
234
|
+
mimeType: FileMimeType,
|
|
235
|
+
dataURL: DataUrl,
|
|
230
236
|
created: z.number(),
|
|
231
237
|
lastRetrieved: z.number().optional()
|
|
232
238
|
});
|
|
@@ -1248,6 +1254,14 @@ var bridgeUnreachable = (port) => port === null ? err("BRIDGE_UNREACHABLE", "no
|
|
|
1248
1254
|
hint: "the bridge may have exited \u2014 `chalkbridge health` reports what is running",
|
|
1249
1255
|
detail: { port }
|
|
1250
1256
|
});
|
|
1257
|
+
var bridgeVersionMismatch = (running, ours, port) => err(
|
|
1258
|
+
"BRIDGE_VERSION_MISMATCH",
|
|
1259
|
+
`a Chalkbridge ${running} bridge is running on 127.0.0.1:${port} and this is ${ours}`,
|
|
1260
|
+
{
|
|
1261
|
+
hint: "it did not stop when asked \u2014 run `chalkbridge stop` in this repo, or end that process, and try again",
|
|
1262
|
+
detail: { running, ours, port }
|
|
1263
|
+
}
|
|
1264
|
+
);
|
|
1251
1265
|
var portUnavailable = (from, tried) => err("PORT_UNAVAILABLE", `no free port between ${from} and ${from + tried - 1}`, {
|
|
1252
1266
|
hint: "something is occupying the whole range \u2014 set CHALK_PORT to pick a different one",
|
|
1253
1267
|
detail: { from, tried }
|
|
@@ -1449,6 +1463,8 @@ async function loadConverter() {
|
|
|
1449
1463
|
uninstall();
|
|
1450
1464
|
}
|
|
1451
1465
|
}
|
|
1466
|
+
var NEEDS_STAND_IN = /* @__PURE__ */ new Set(["image", "frame", "embeddable"]);
|
|
1467
|
+
var standIn = (element) => NEEDS_STAND_IN.has(element.type) ? { ...element, type: "rectangle" } : element;
|
|
1452
1468
|
function createNodeSkeletonExpander() {
|
|
1453
1469
|
return {
|
|
1454
1470
|
async expand(skeletons, context) {
|
|
@@ -1458,7 +1474,7 @@ function createNodeSkeletonExpander() {
|
|
|
1458
1474
|
if (!loaded.ok) return loaded;
|
|
1459
1475
|
let raw;
|
|
1460
1476
|
try {
|
|
1461
|
-
const convertible = (context ?? []).
|
|
1477
|
+
const convertible = (context ?? []).map(standIn);
|
|
1462
1478
|
raw = loaded.value([...convertible, ...skeletons], { regenerateIds: false });
|
|
1463
1479
|
} catch (thrown) {
|
|
1464
1480
|
return fail(expansionFailed(describeThrown(thrown)));
|
|
@@ -1495,6 +1511,6 @@ var stable = (element) => {
|
|
|
1495
1511
|
return rest;
|
|
1496
1512
|
};
|
|
1497
1513
|
|
|
1498
|
-
export { AnnotateInput, AnnotateOutput, ApiError, ArrangeOutput, ArrangeToolInput, BINDING_FIELDS, ClientMessage, ConnectOutput, ConnectToolInput, CreateElementsInput, CreateElementsOutput, DebugElementRequest, DeleteElementsInput, DeleteElementsOutput, DescribeSceneInput, DescribeSceneOutput, DetailLevel, EXCALIDRAW_FILE_TYPE, EXCALIDRAW_FILE_VERSION, ElementId, EmbedInput, EmbedOutput, ExcalidrawFile, ExportImageInput, ExportImageOutput, ExportSceneInput, ExportSceneOutput, FLAG_GLYPH, FileId, FocusInput, FocusOutput, FrameId, FrameInput, FrameOutput, GUIDE_TOPICS, GetElementsInput, GetElementsOutput, GetSelectionInput, GetSelectionOutput, GroupId, GroupInput, GroupOutput, GuideTopic, HOUSE, HealthResponse, IconId, IconItem, ImportSceneInput, ImportSceneOutput, Index, InstallPackInput, InstallPackOutput, KIND_ABBREVIATION, ListPacksInput, ListPacksOutput, ListScenesInput, ListScenesOutput, PROTOCOL_VERSION, PackKind, PackName, PackRecipe, PlaceIconInput, PlaceIconOutput, ROUNDNESS, RawElementsInput, RawElementsOutput, ReadMeInput, ReadMeOutput, RemovePackInput, RemovePackOutput, RestoreSnapshotInput, RestoreSnapshotOutput, SERVER_MANAGED_FIELDS, STALE_SELECTION_MS, Scene, SceneElement, SceneId, SceneSettingsInput, SceneSettingsOutput, ScreenshotInput, ScreenshotOutput, ScreenshotResponse, SearchIconsInput, SearchIconsOutput, SnapshotId, SnapshotInput, SnapshotOutput, UngroupInput, UngroupOutput, UpdateElementsInput, UpdateElementsOutput, assertNever, bridgeSpawnFailed, bridgeUnreachable, catalogUnavailable, createNodeSkeletonExpander, deepEqual, describeThrown, diskConflict, emptySelection, expansionFailed, exportFailed, exportTimedOut, fail, frameIdOf, iconIdOf, idCollision, isFail, isOk, noBoundLabel, noBrowser, noScenes, notAPack, notARepo, ok, packInstallFailed, partition, pathOutsideRepo, point, portUnavailable, refusedFieldMessage, sceneFileMissing, staleVersion, storeUnavailable, unknownElement, unknownIcon, unknownScene, unknownSnapshot, unreadableSceneFile };
|
|
1499
|
-
//# sourceMappingURL=chunk-
|
|
1500
|
-
//# sourceMappingURL=chunk-
|
|
1514
|
+
export { AnnotateInput, AnnotateOutput, ApiError, ArrangeOutput, ArrangeToolInput, BINDING_FIELDS, ClientMessage, ConnectOutput, ConnectToolInput, CreateElementsInput, CreateElementsOutput, DataUrl, DebugElementRequest, DeleteElementsInput, DeleteElementsOutput, DescribeSceneInput, DescribeSceneOutput, DetailLevel, EXCALIDRAW_FILE_TYPE, EXCALIDRAW_FILE_VERSION, ElementId, EmbedInput, EmbedOutput, ExcalidrawFile, ExportImageInput, ExportImageOutput, ExportSceneInput, ExportSceneOutput, FLAG_GLYPH, FileId, FocusInput, FocusOutput, FrameId, FrameInput, FrameOutput, GUIDE_TOPICS, GetElementsInput, GetElementsOutput, GetSelectionInput, GetSelectionOutput, GroupId, GroupInput, GroupOutput, GuideTopic, HOUSE, HealthResponse, IconId, IconItem, ImportSceneInput, ImportSceneOutput, Index, InstallPackInput, InstallPackOutput, KIND_ABBREVIATION, ListPacksInput, ListPacksOutput, ListScenesInput, ListScenesOutput, PROTOCOL_VERSION, PackKind, PackName, PackRecipe, PlaceIconInput, PlaceIconOutput, ROUNDNESS, RawElementsInput, RawElementsOutput, ReadMeInput, ReadMeOutput, RemovePackInput, RemovePackOutput, RestoreSnapshotInput, RestoreSnapshotOutput, SERVER_MANAGED_FIELDS, STALE_SELECTION_MS, Scene, SceneElement, SceneId, SceneSettingsInput, SceneSettingsOutput, ScreenshotInput, ScreenshotOutput, ScreenshotResponse, SearchIconsInput, SearchIconsOutput, SnapshotId, SnapshotInput, SnapshotOutput, UngroupInput, UngroupOutput, UpdateElementsInput, UpdateElementsOutput, assertNever, bridgeSpawnFailed, bridgeUnreachable, bridgeVersionMismatch, catalogUnavailable, createNodeSkeletonExpander, deepEqual, describeThrown, diskConflict, emptySelection, expansionFailed, exportFailed, exportTimedOut, fail, frameIdOf, iconIdOf, idCollision, isFail, isOk, noBoundLabel, noBrowser, noScenes, notAPack, notARepo, ok, packInstallFailed, partition, pathOutsideRepo, point, portUnavailable, refusedFieldMessage, sceneFileMissing, staleVersion, storeUnavailable, unknownElement, unknownIcon, unknownScene, unknownSnapshot, unreadableSceneFile };
|
|
1515
|
+
//# sourceMappingURL=chunk-U2ZMSGNS.js.map
|
|
1516
|
+
//# sourceMappingURL=chunk-U2ZMSGNS.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { SceneElement, PackName, PackKind, IconId, SceneId, Scene, SnapshotId, SERVER_MANAGED_FIELDS, BINDING_FIELDS, GUIDE_TOPICS, DetailLevel, createNodeSkeletonExpander, ok, fail, bridgeSpawnFailed, bridgeUnreachable, GuideTopic, storeUnavailable, describeThrown, unreadableSceneFile, pathOutsideRepo, packInstallFailed, sceneFileMissing, notAPack, PackRecipe, portUnavailable, DescribeSceneOutput, DescribeSceneInput, GetSelectionOutput, GetSelectionInput, GetElementsOutput, GetElementsInput, ListScenesOutput, ListScenesInput, SceneSettingsOutput, SceneSettingsInput, SearchIconsOutput, SearchIconsInput, ScreenshotOutput, ScreenshotInput, ReadMeOutput, ReadMeInput, PlaceIconOutput, PlaceIconInput, SnapshotOutput, SnapshotInput, RestoreSnapshotOutput, RestoreSnapshotInput, ExportSceneOutput, ExportSceneInput, ImportSceneOutput, ImportSceneInput, ExportImageOutput, ExportImageInput, InstallPackOutput, InstallPackInput, notARepo, ScreenshotResponse, RemovePackOutput, ListPacksOutput, RawElementsOutput, FocusOutput, EmbedOutput, AnnotateOutput, FrameOutput, UngroupOutput, GroupOutput, ArrangeOutput, DeleteElementsOutput, UpdateElementsOutput, ConnectOutput, CreateElementsOutput, HealthResponse, iconIdOf, unknownScene, unknownSnapshot, exportFailed, unknownIcon, HOUSE, FileId, ElementId, diskConflict, refusedFieldMessage, idCollision, expansionFailed, emptySelection, unknownElement, frameIdOf, GroupId, staleVersion, noBoundLabel, deepEqual, exportTimedOut, noBrowser, DebugElementRequest, CreateElementsInput, ConnectToolInput, UpdateElementsInput, DeleteElementsInput, ArrangeToolInput, GroupInput, UngroupInput, FrameInput, AnnotateInput, EmbedInput, FocusInput, RawElementsInput, ListPacksInput, RemovePackInput, Index, ROUNDNESS, STALE_SELECTION_MS, noScenes, ClientMessage, assertNever, PROTOCOL_VERSION, ApiError, EXCALIDRAW_FILE_VERSION, EXCALIDRAW_FILE_TYPE, point, FLAG_GLYPH, KIND_ABBREVIATION, catalogUnavailable, FrameId, IconItem, ExcalidrawFile } from './chunk-
|
|
2
|
+
import { SceneElement, PackName, PackKind, IconId, SceneId, Scene, SnapshotId, SERVER_MANAGED_FIELDS, BINDING_FIELDS, GUIDE_TOPICS, DetailLevel, createNodeSkeletonExpander, ok, fail, bridgeSpawnFailed, bridgeVersionMismatch, bridgeUnreachable, GuideTopic, storeUnavailable, describeThrown, unreadableSceneFile, pathOutsideRepo, packInstallFailed, sceneFileMissing, notAPack, PackRecipe, portUnavailable, DescribeSceneOutput, DescribeSceneInput, GetSelectionOutput, GetSelectionInput, GetElementsOutput, GetElementsInput, ListScenesOutput, ListScenesInput, SceneSettingsOutput, SceneSettingsInput, SearchIconsOutput, SearchIconsInput, ScreenshotOutput, ScreenshotInput, ReadMeOutput, ReadMeInput, PlaceIconOutput, PlaceIconInput, SnapshotOutput, SnapshotInput, RestoreSnapshotOutput, RestoreSnapshotInput, ExportSceneOutput, ExportSceneInput, ImportSceneOutput, ImportSceneInput, ExportImageOutput, ExportImageInput, InstallPackOutput, InstallPackInput, notARepo, ScreenshotResponse, RemovePackOutput, ListPacksOutput, RawElementsOutput, FocusOutput, EmbedOutput, AnnotateOutput, FrameOutput, UngroupOutput, GroupOutput, ArrangeOutput, DeleteElementsOutput, UpdateElementsOutput, ConnectOutput, CreateElementsOutput, HealthResponse, iconIdOf, unknownScene, unknownSnapshot, exportFailed, unknownIcon, HOUSE, FileId, ElementId, diskConflict, refusedFieldMessage, idCollision, expansionFailed, emptySelection, unknownElement, frameIdOf, GroupId, staleVersion, noBoundLabel, deepEqual, exportTimedOut, noBrowser, DebugElementRequest, CreateElementsInput, ConnectToolInput, UpdateElementsInput, DeleteElementsInput, ArrangeToolInput, GroupInput, UngroupInput, FrameInput, AnnotateInput, EmbedInput, FocusInput, RawElementsInput, ListPacksInput, RemovePackInput, DataUrl, Index, ROUNDNESS, STALE_SELECTION_MS, noScenes, ClientMessage, assertNever, PROTOCOL_VERSION, ApiError, EXCALIDRAW_FILE_VERSION, EXCALIDRAW_FILE_TYPE, point, FLAG_GLYPH, KIND_ABBREVIATION, catalogUnavailable, FrameId, IconItem, ExcalidrawFile } from './chunk-U2ZMSGNS.js';
|
|
3
3
|
import './chunk-7D4SUZUM.js';
|
|
4
4
|
import { appendFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
@@ -1046,6 +1046,7 @@ var KNOWN_CODES = /* @__PURE__ */ new Set([
|
|
|
1046
1046
|
"BRIDGE_SPAWN_FAILED",
|
|
1047
1047
|
"BRIDGE_UNREACHABLE",
|
|
1048
1048
|
"PORT_UNAVAILABLE",
|
|
1049
|
+
"BRIDGE_VERSION_MISMATCH",
|
|
1049
1050
|
"STALE_VERSION",
|
|
1050
1051
|
"ID_COLLISION",
|
|
1051
1052
|
"UNKNOWN_ELEMENT",
|
|
@@ -1099,23 +1100,48 @@ function createBridgeClient() {
|
|
|
1099
1100
|
return null;
|
|
1100
1101
|
}
|
|
1101
1102
|
},
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1103
|
+
async shutdown(port, timeoutMs = DEFAULT_HEALTH_TIMEOUT_MS) {
|
|
1104
|
+
try {
|
|
1105
|
+
await fetch(`http://127.0.0.1:${port}/api/shutdown`, {
|
|
1106
|
+
method: "POST",
|
|
1107
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
1108
|
+
});
|
|
1109
|
+
} catch {
|
|
1110
|
+
}
|
|
1111
|
+
const deadline = Date.now() + timeoutMs * 4;
|
|
1112
|
+
while (Date.now() < deadline) {
|
|
1113
|
+
if (await this.health(port, timeoutMs) === null) return true;
|
|
1114
|
+
await new Promise((resolve6) => setTimeout(resolve6, 100));
|
|
1115
|
+
}
|
|
1116
|
+
return false;
|
|
1117
|
+
},
|
|
1118
|
+
connect(port, reconnect) {
|
|
1119
|
+
let current = port;
|
|
1120
|
+
async function attempt(path, init, timeoutMs) {
|
|
1106
1121
|
try {
|
|
1107
|
-
|
|
1122
|
+
return await fetch(`http://127.0.0.1:${current}${path}`, {
|
|
1108
1123
|
...init,
|
|
1109
1124
|
signal: AbortSignal.timeout(timeoutMs)
|
|
1110
1125
|
});
|
|
1111
1126
|
} catch {
|
|
1112
|
-
return
|
|
1127
|
+
return null;
|
|
1113
1128
|
}
|
|
1129
|
+
}
|
|
1130
|
+
async function call(path, schema, init, timeoutMs = DEFAULT_API_TIMEOUT_MS) {
|
|
1131
|
+
let response = await attempt(path, init, timeoutMs);
|
|
1132
|
+
if (response === null && reconnect !== void 0) {
|
|
1133
|
+
const revived = await reconnect();
|
|
1134
|
+
if (revived !== null) {
|
|
1135
|
+
current = revived;
|
|
1136
|
+
response = await attempt(path, init, timeoutMs);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
if (response === null) return fail(bridgeUnreachable(current));
|
|
1114
1140
|
const body = await response.json().catch(() => null);
|
|
1115
|
-
if (!response.ok) return fail(toChalkError(body,
|
|
1141
|
+
if (!response.ok) return fail(toChalkError(body, current));
|
|
1116
1142
|
const parsed = schema.safeParse(body);
|
|
1117
1143
|
if (!parsed.success) {
|
|
1118
|
-
return fail(bridgeUnreachable(
|
|
1144
|
+
return fail(bridgeUnreachable(current));
|
|
1119
1145
|
}
|
|
1120
1146
|
return ok(parsed.data);
|
|
1121
1147
|
}
|
|
@@ -1726,6 +1752,24 @@ function createBridgeLauncher(options, deps) {
|
|
|
1726
1752
|
await sleep(pollIntervalMs);
|
|
1727
1753
|
}
|
|
1728
1754
|
return fail(bridgeSpawnFailed(`it did not start listening within ${readyTimeoutMs}ms`));
|
|
1755
|
+
},
|
|
1756
|
+
async stop(pid) {
|
|
1757
|
+
try {
|
|
1758
|
+
process.kill(pid, "SIGTERM");
|
|
1759
|
+
} catch {
|
|
1760
|
+
return false;
|
|
1761
|
+
}
|
|
1762
|
+
const deadline = Date.now() + 5e3;
|
|
1763
|
+
while (Date.now() < deadline) {
|
|
1764
|
+
try {
|
|
1765
|
+
process.kill(pid, 0);
|
|
1766
|
+
} catch {
|
|
1767
|
+
return true;
|
|
1768
|
+
}
|
|
1769
|
+
await sleep(pollIntervalMs);
|
|
1770
|
+
}
|
|
1771
|
+
deps.logger.warn("a bridge did not exit after being signalled", { pid });
|
|
1772
|
+
return false;
|
|
1729
1773
|
}
|
|
1730
1774
|
};
|
|
1731
1775
|
}
|
|
@@ -1734,6 +1778,48 @@ function createBridgeLauncher(options, deps) {
|
|
|
1734
1778
|
function createClock() {
|
|
1735
1779
|
return { now: () => Date.now() };
|
|
1736
1780
|
}
|
|
1781
|
+
|
|
1782
|
+
// src/adapters/system/idle-watch.ts
|
|
1783
|
+
var intervalFor = (timeoutMs) => Math.max(1e3, Math.min(1e4, Math.floor(timeoutMs / 3)));
|
|
1784
|
+
function createIdleWatch(options, deps) {
|
|
1785
|
+
let lastActivity = deps.clock.now();
|
|
1786
|
+
let timer = null;
|
|
1787
|
+
let fired = false;
|
|
1788
|
+
return {
|
|
1789
|
+
touch() {
|
|
1790
|
+
lastActivity = deps.clock.now();
|
|
1791
|
+
},
|
|
1792
|
+
start({ isWatched, onIdle }) {
|
|
1793
|
+
const timeoutMs = options.timeoutMs;
|
|
1794
|
+
if (timeoutMs === null) {
|
|
1795
|
+
deps.logger.debug("idle shutdown is disabled", { reason: "CHALK_IDLE_TIMEOUT=0" });
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
if (timer !== null) return;
|
|
1799
|
+
const every = options.checkIntervalMs ?? intervalFor(timeoutMs);
|
|
1800
|
+
timer = setInterval(() => {
|
|
1801
|
+
if (fired) return;
|
|
1802
|
+
if (isWatched()) {
|
|
1803
|
+
lastActivity = deps.clock.now();
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
if (deps.clock.now() - lastActivity < timeoutMs) return;
|
|
1807
|
+
fired = true;
|
|
1808
|
+
deps.logger.info("idle \u2014 nothing watching and nothing asking", {
|
|
1809
|
+
idleMs: deps.clock.now() - lastActivity
|
|
1810
|
+
});
|
|
1811
|
+
onIdle();
|
|
1812
|
+
}, every);
|
|
1813
|
+
timer.unref?.();
|
|
1814
|
+
deps.logger.debug("watching for idle", { timeoutMs, every });
|
|
1815
|
+
},
|
|
1816
|
+
stop() {
|
|
1817
|
+
if (timer === null) return;
|
|
1818
|
+
clearInterval(timer);
|
|
1819
|
+
timer = null;
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1737
1823
|
var ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1738
1824
|
var shortId = (length) => {
|
|
1739
1825
|
let out = "";
|
|
@@ -2427,7 +2513,20 @@ function ensureBridge(deps) {
|
|
|
2427
2513
|
const repoRoot = await deps.projectDir.findRepoRoot(options.cwd);
|
|
2428
2514
|
if (!repoRoot.ok) return repoRoot;
|
|
2429
2515
|
const existingPort = await deps.projectDir.readPort(repoRoot.value);
|
|
2430
|
-
|
|
2516
|
+
let existing = existingPort === null ? null : await deps.client.health(existingPort);
|
|
2517
|
+
if (existing !== null && existingPort !== null && existing.version !== deps.version) {
|
|
2518
|
+
deps.logger.info("replacing a bridge from another build", {
|
|
2519
|
+
running: existing.version,
|
|
2520
|
+
ours: deps.version,
|
|
2521
|
+
port: existingPort
|
|
2522
|
+
});
|
|
2523
|
+
const stopped = await deps.client.shutdown(existingPort) || await deps.launcher.stop(existing.pid);
|
|
2524
|
+
if (!stopped) {
|
|
2525
|
+
return fail(bridgeVersionMismatch(existing.version, deps.version, existingPort));
|
|
2526
|
+
}
|
|
2527
|
+
await deps.projectDir.clearPort(repoRoot.value);
|
|
2528
|
+
existing = null;
|
|
2529
|
+
}
|
|
2431
2530
|
let port = existing === null ? null : existingPort;
|
|
2432
2531
|
let health = existing;
|
|
2433
2532
|
let spawned = false;
|
|
@@ -3926,7 +4025,7 @@ var iconBox = (art, size) => {
|
|
|
3926
4025
|
height: Math.round(art.height * scale)
|
|
3927
4026
|
};
|
|
3928
4027
|
};
|
|
3929
|
-
var svgDataUrl = (svg) => `data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}
|
|
4028
|
+
var svgDataUrl = (svg) => DataUrl.parse(`data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}`);
|
|
3930
4029
|
function placeIcon(deps) {
|
|
3931
4030
|
return async (input) => {
|
|
3932
4031
|
const opened = await deps.icons();
|
|
@@ -4028,12 +4127,13 @@ var toRejection = (id, error) => ({
|
|
|
4028
4127
|
});
|
|
4029
4128
|
function writeContext(deps) {
|
|
4030
4129
|
const resolveScene2 = getScene({ store: deps.store });
|
|
4031
|
-
const broadcast = (scene, sceneVersion, elements) => deps.broadcaster.broadcastToScene(scene.id, {
|
|
4130
|
+
const broadcast = (scene, sceneVersion, elements, files) => deps.broadcaster.broadcastToScene(scene.id, {
|
|
4032
4131
|
t: "scene_patch",
|
|
4033
4132
|
sceneId: scene.id,
|
|
4034
4133
|
origin: "claude",
|
|
4035
4134
|
sceneVersion,
|
|
4036
|
-
elements: [...elements]
|
|
4135
|
+
elements: [...elements],
|
|
4136
|
+
...files === void 0 ? {} : { files }
|
|
4037
4137
|
});
|
|
4038
4138
|
return {
|
|
4039
4139
|
resolve(sceneId) {
|
|
@@ -4085,7 +4185,7 @@ function writeContext(deps) {
|
|
|
4085
4185
|
return ok({
|
|
4086
4186
|
sceneId: scene.id,
|
|
4087
4187
|
sceneVersion: updated.sceneVersion,
|
|
4088
|
-
broadcastTo: broadcast(scene, updated.sceneVersion, pushed)
|
|
4188
|
+
broadcastTo: broadcast(scene, updated.sceneVersion, pushed, patch?.files)
|
|
4089
4189
|
});
|
|
4090
4190
|
},
|
|
4091
4191
|
apply(scene, changed, options) {
|
|
@@ -4371,6 +4471,7 @@ function printLine(line) {
|
|
|
4371
4471
|
}
|
|
4372
4472
|
var DEFAULT_PORT = 7180;
|
|
4373
4473
|
var PORT_SCAN_RANGE = 32;
|
|
4474
|
+
var DEFAULT_IDLE_SECONDS = 90;
|
|
4374
4475
|
var truthy = (value) => value !== void 0 && value !== "" && value !== "0" && value.toLowerCase() !== "false";
|
|
4375
4476
|
var EnvSchema = z.object({
|
|
4376
4477
|
CHALK_PORT: z.coerce.number().int().min(1).max(65535).optional(),
|
|
@@ -4383,12 +4484,18 @@ var EnvSchema = z.object({
|
|
|
4383
4484
|
* icon pack into the developer real data directory would be a test that changed the
|
|
4384
4485
|
* machine it ran on.
|
|
4385
4486
|
*/
|
|
4386
|
-
CHALK_DATA_DIR: z.string().min(1).optional()
|
|
4487
|
+
CHALK_DATA_DIR: z.string().min(1).optional(),
|
|
4488
|
+
/**
|
|
4489
|
+
* Seconds a bridge may sit with no browser client and no tool call before it exits.
|
|
4490
|
+
* `0` keeps it up forever, which is what every version before v1.0.2 did.
|
|
4491
|
+
*/
|
|
4492
|
+
CHALK_IDLE_TIMEOUT: z.coerce.number().int().min(0).max(86400).optional()
|
|
4387
4493
|
});
|
|
4388
4494
|
function readEnv(source) {
|
|
4389
4495
|
const parsed = EnvSchema.safeParse(source);
|
|
4390
4496
|
const env = parsed.success ? parsed.data : {};
|
|
4391
4497
|
const explicit2 = env.CHALK_PORT ?? null;
|
|
4498
|
+
const idleSeconds = env.CHALK_IDLE_TIMEOUT ?? DEFAULT_IDLE_SECONDS;
|
|
4392
4499
|
return {
|
|
4393
4500
|
listenFrom: explicit2 ?? DEFAULT_PORT,
|
|
4394
4501
|
listenTries: explicit2 === null ? PORT_SCAN_RANGE : 1,
|
|
@@ -4396,12 +4503,13 @@ function readEnv(source) {
|
|
|
4396
4503
|
autoStart: !truthy(env.CHALK_NO_AUTOSTART),
|
|
4397
4504
|
autoOpen: !truthy(env.CHALK_NO_OPEN),
|
|
4398
4505
|
dataDir: env.CHALK_DATA_DIR ?? null,
|
|
4506
|
+
idleTimeoutMs: idleSeconds === 0 ? null : idleSeconds * 1e3,
|
|
4399
4507
|
logLevel: env.CHALK_LOG_LEVEL ?? "info"
|
|
4400
4508
|
};
|
|
4401
4509
|
}
|
|
4402
4510
|
|
|
4403
4511
|
// src/composition/container.ts
|
|
4404
|
-
var PACKAGE_VERSION = "1.0.
|
|
4512
|
+
var PACKAGE_VERSION = "1.0.4";
|
|
4405
4513
|
function readRuntime() {
|
|
4406
4514
|
return {
|
|
4407
4515
|
env: process.env,
|
|
@@ -4465,6 +4573,7 @@ function buildCommandContext(runtime = readRuntime()) {
|
|
|
4465
4573
|
if (!opened.ok) return opened;
|
|
4466
4574
|
const store = opened.value;
|
|
4467
4575
|
const broadcaster = createBroadcaster(idGen, logger);
|
|
4576
|
+
const idleWatch = createIdleWatch({ timeoutMs: config.idleTimeoutMs }, { clock, logger });
|
|
4468
4577
|
const presenceTracker = createPresenceTracker();
|
|
4469
4578
|
const expander = createNodeSkeletonExpander();
|
|
4470
4579
|
const repoWriter = createRepoWriter({ repoRoot }, { store, logger });
|
|
@@ -4472,6 +4581,7 @@ function buildCommandContext(runtime = readRuntime()) {
|
|
|
4472
4581
|
const diskWatcher = createDiskWatcher({ logger });
|
|
4473
4582
|
const commit = commitScene({ store, repoWriter });
|
|
4474
4583
|
const repoFiles = createRepoFiles({ repoRoot });
|
|
4584
|
+
let onShutdown = null;
|
|
4475
4585
|
const exportBroker = createExportBroker({}, { broadcaster, idGen, logger });
|
|
4476
4586
|
const globalPaths = globalPathsOf(runtime, config);
|
|
4477
4587
|
let catalog = null;
|
|
@@ -4635,6 +4745,10 @@ function buildCommandContext(runtime = readRuntime()) {
|
|
|
4635
4745
|
// logic in `app/`, and a lifecycle command has no more business holding a store
|
|
4636
4746
|
// than a route does.
|
|
4637
4747
|
sceneFilePaths: () => store.list().map((scene) => scene.repoPath).filter((path) => path !== null).map((path) => resolve(repoRoot, path)),
|
|
4748
|
+
idleWatch,
|
|
4749
|
+
onShutdownRequest: (handler) => {
|
|
4750
|
+
onShutdown = handler;
|
|
4751
|
+
},
|
|
4638
4752
|
close: () => {
|
|
4639
4753
|
repoWriter.cancel();
|
|
4640
4754
|
exportBroker.abandon();
|
|
@@ -4675,6 +4789,7 @@ function buildCommandContext(runtime = readRuntime()) {
|
|
|
4675
4789
|
importScene: usecases.importScene,
|
|
4676
4790
|
broadcaster,
|
|
4677
4791
|
identity,
|
|
4792
|
+
requestShutdown: () => onShutdown?.(),
|
|
4678
4793
|
logger
|
|
4679
4794
|
},
|
|
4680
4795
|
ws: {
|
|
@@ -4698,24 +4813,42 @@ function buildCommandContext(runtime = readRuntime()) {
|
|
|
4698
4813
|
{ cliEntry: runtime.entryPath, execPath: runtime.execPath, env: runtime.env },
|
|
4699
4814
|
{ projectDir, client, logger }
|
|
4700
4815
|
);
|
|
4816
|
+
const bootstrap = ensureBridge({
|
|
4817
|
+
// Compared against whatever is already listening: an upgrade that reused an
|
|
4818
|
+
// older detached bridge would ship every fix and deliver none of them.
|
|
4819
|
+
version: runtime.version,
|
|
4820
|
+
projectDir,
|
|
4821
|
+
client,
|
|
4822
|
+
launcher,
|
|
4823
|
+
opener: createBrowserOpener(logger),
|
|
4824
|
+
logger
|
|
4825
|
+
});
|
|
4701
4826
|
return {
|
|
4702
4827
|
logger,
|
|
4703
4828
|
projectDir,
|
|
4704
4829
|
client,
|
|
4830
|
+
launcher,
|
|
4705
4831
|
// A7 — the tool handlers never see a port, a URL, or a `fetch`. They see the
|
|
4706
4832
|
// bridge's read surface and a shelf of markdown, and nothing else exists to
|
|
4707
4833
|
// tempt them into caching a scene (invariant 1).
|
|
4834
|
+
//
|
|
4835
|
+
// The `reconnect` argument is what makes a session survive its own bridge. One
|
|
4836
|
+
// now exits when nothing is watching and nothing is asking, so "the port this
|
|
4837
|
+
// session started with" stops being true the moment the user closes the tab and
|
|
4838
|
+
// walks away. Re-running the bootstrap puts a bridge *and a tab* back, which is
|
|
4839
|
+
// what the session's first call did, so a tool call after a break just works.
|
|
4708
4840
|
createToolDeps: (port) => ({
|
|
4709
|
-
bridge: client.connect(port)
|
|
4841
|
+
bridge: client.connect(port, async () => {
|
|
4842
|
+
const revived = await bootstrap({
|
|
4843
|
+
cwd: runtime.cwd,
|
|
4844
|
+
autoStart: config.autoStart,
|
|
4845
|
+
autoOpen: config.autoOpen
|
|
4846
|
+
});
|
|
4847
|
+
return revived.ok ? revived.value.port : null;
|
|
4848
|
+
}),
|
|
4710
4849
|
guides: createGuideLibrary({ dir: resolveGuidesDir() }, { logger })
|
|
4711
4850
|
}),
|
|
4712
|
-
ensureBridge:
|
|
4713
|
-
projectDir,
|
|
4714
|
-
client,
|
|
4715
|
-
launcher,
|
|
4716
|
-
opener: createBrowserOpener(logger),
|
|
4717
|
-
logger
|
|
4718
|
-
})
|
|
4851
|
+
ensureBridge: bootstrap
|
|
4719
4852
|
};
|
|
4720
4853
|
}
|
|
4721
4854
|
};
|
|
@@ -5702,6 +5835,8 @@ var STATUS = {
|
|
|
5702
5835
|
BRIDGE_SPAWN_FAILED: 500,
|
|
5703
5836
|
BRIDGE_UNREACHABLE: 503,
|
|
5704
5837
|
PORT_UNAVAILABLE: 500,
|
|
5838
|
+
// 409: something is there, it is simply not the build this process belongs to.
|
|
5839
|
+
BRIDGE_VERSION_MISMATCH: 409,
|
|
5705
5840
|
// 409 for both: a stale version and a file that changed underneath us are the same
|
|
5706
5841
|
// shape of problem — the caller's view of the world is out of date, and re-reading is
|
|
5707
5842
|
// the way forward.
|
|
@@ -5960,6 +6095,20 @@ var sessionRoutes = [
|
|
|
5960
6095
|
})
|
|
5961
6096
|
];
|
|
5962
6097
|
|
|
6098
|
+
// src/interfaces/http/routes/shutdown.ts
|
|
6099
|
+
var shutdownRoute = {
|
|
6100
|
+
name: "shutdown",
|
|
6101
|
+
register(app, deps) {
|
|
6102
|
+
app.post("/api/shutdown", async (_request, reply) => {
|
|
6103
|
+
const identity = deps.identity();
|
|
6104
|
+
deps.logger.info("shutdown requested over the API", { pid: identity.pid });
|
|
6105
|
+
await reply.send({ stopping: true, pid: identity.pid, version: identity.version });
|
|
6106
|
+
setTimeout(() => deps.requestShutdown(), 0);
|
|
6107
|
+
return reply;
|
|
6108
|
+
});
|
|
6109
|
+
}
|
|
6110
|
+
};
|
|
6111
|
+
|
|
5963
6112
|
// src/interfaces/http/routes/write.ts
|
|
5964
6113
|
var writeRoutes = [
|
|
5965
6114
|
postRoute({
|
|
@@ -6045,6 +6194,7 @@ var ROUTES = [
|
|
|
6045
6194
|
elementsRoute,
|
|
6046
6195
|
settingsRoute,
|
|
6047
6196
|
debugElementRoute,
|
|
6197
|
+
shutdownRoute,
|
|
6048
6198
|
...writeRoutes,
|
|
6049
6199
|
...sessionRoutes
|
|
6050
6200
|
];
|
|
@@ -6058,6 +6208,9 @@ async function createHttpServer(deps) {
|
|
|
6058
6208
|
bodyLimit: 32 * 1024 * 1024
|
|
6059
6209
|
});
|
|
6060
6210
|
await app.register(websocket);
|
|
6211
|
+
app.addHook("onRequest", async () => {
|
|
6212
|
+
deps.touch();
|
|
6213
|
+
});
|
|
6061
6214
|
for (const route of ROUTES) {
|
|
6062
6215
|
route.register(app, deps.routes);
|
|
6063
6216
|
deps.logger.debug("registered route", { route: route.name });
|
|
@@ -6067,6 +6220,7 @@ async function createHttpServer(deps) {
|
|
|
6067
6220
|
const send = (message) => {
|
|
6068
6221
|
socket.send(JSON.stringify(message));
|
|
6069
6222
|
};
|
|
6223
|
+
deps.touch();
|
|
6070
6224
|
const handle = deps.broadcaster.register(send);
|
|
6071
6225
|
const session = { handle, send };
|
|
6072
6226
|
socket.on("message", (data) => {
|
|
@@ -6147,7 +6301,8 @@ ${built.error.hint ?? ""}
|
|
|
6147
6301
|
ws: services.ws,
|
|
6148
6302
|
broadcaster: services.broadcaster,
|
|
6149
6303
|
logger: services.logger,
|
|
6150
|
-
uiDistPath: services.uiDistPath
|
|
6304
|
+
uiDistPath: services.uiDistPath,
|
|
6305
|
+
touch: () => services.idleWatch.touch()
|
|
6151
6306
|
});
|
|
6152
6307
|
const listening = await listenOnFirstFreePort(app, {
|
|
6153
6308
|
host: "127.0.0.1",
|
|
@@ -6174,6 +6329,7 @@ ${built.error.hint ?? ""}
|
|
|
6174
6329
|
await new Promise((resolve6) => {
|
|
6175
6330
|
const shutdown = async (signal) => {
|
|
6176
6331
|
services.logger.info("shutting down", { signal });
|
|
6332
|
+
services.idleWatch.stop();
|
|
6177
6333
|
await services.diskWatcher.stop();
|
|
6178
6334
|
const flushed = await services.repoWriter.flushAll();
|
|
6179
6335
|
if (flushed.length > 0) {
|
|
@@ -6184,18 +6340,75 @@ ${built.error.hint ?? ""}
|
|
|
6184
6340
|
services.close();
|
|
6185
6341
|
resolve6();
|
|
6186
6342
|
};
|
|
6343
|
+
services.idleWatch.start({
|
|
6344
|
+
isWatched: () => services.broadcaster.clientCount() > 0,
|
|
6345
|
+
onIdle: () => void shutdown("idle")
|
|
6346
|
+
});
|
|
6187
6347
|
process.once("SIGINT", () => void shutdown("SIGINT"));
|
|
6188
6348
|
process.once("SIGTERM", () => void shutdown("SIGTERM"));
|
|
6349
|
+
services.onShutdownRequest(() => void shutdown("api"));
|
|
6189
6350
|
});
|
|
6190
6351
|
return 0;
|
|
6191
6352
|
}
|
|
6192
6353
|
};
|
|
6193
6354
|
|
|
6355
|
+
// src/interfaces/cli/commands/stop.ts
|
|
6356
|
+
var stopCommand = {
|
|
6357
|
+
name: "stop",
|
|
6358
|
+
summary: "stop the bridge running for this repo, flushing anything unsaved",
|
|
6359
|
+
detail: [
|
|
6360
|
+
"Ends the bridge for the repository containing the working directory.",
|
|
6361
|
+
"",
|
|
6362
|
+
"The bridge flushes every pending .excalidraw write, stops watching the repo, and",
|
|
6363
|
+
"clears its port file on the way out \u2014 so nothing drawn in the last two seconds is",
|
|
6364
|
+
"lost. Nothing is started; the next Claude Code session starts a fresh one."
|
|
6365
|
+
].join("\n"),
|
|
6366
|
+
async run(context) {
|
|
6367
|
+
const services = context.createClientServices({ prefix: "[stop]" });
|
|
6368
|
+
const repoRoot = await services.projectDir.findRepoRoot(context.runtime.cwd);
|
|
6369
|
+
if (!repoRoot.ok) {
|
|
6370
|
+
context.print(repoRoot.error.message);
|
|
6371
|
+
if (repoRoot.error.hint !== void 0) context.print(` ${repoRoot.error.hint}`);
|
|
6372
|
+
return 1;
|
|
6373
|
+
}
|
|
6374
|
+
const port = await services.projectDir.readPort(repoRoot.value);
|
|
6375
|
+
if (port === null) {
|
|
6376
|
+
context.print(`no bridge is running for ${repoRoot.value}`);
|
|
6377
|
+
return 0;
|
|
6378
|
+
}
|
|
6379
|
+
const health = await services.client.health(port);
|
|
6380
|
+
if (health === null) {
|
|
6381
|
+
await services.projectDir.clearPort(repoRoot.value);
|
|
6382
|
+
context.print(`nothing was listening on 127.0.0.1:${port} \u2014 cleared the stale port file`);
|
|
6383
|
+
return 0;
|
|
6384
|
+
}
|
|
6385
|
+
context.print(
|
|
6386
|
+
`stopping chalkbridge ${health.version} on 127.0.0.1:${port} (pid ${health.pid})`
|
|
6387
|
+
);
|
|
6388
|
+
if (await services.client.shutdown(port)) {
|
|
6389
|
+
context.print(" stopped \u2014 pending scene writes were flushed");
|
|
6390
|
+
return 0;
|
|
6391
|
+
}
|
|
6392
|
+
context.print(" it has no shutdown endpoint (built before v1.0.2) \u2014 ending it by pid");
|
|
6393
|
+
if (await services.launcher.stop(health.pid)) {
|
|
6394
|
+
await services.projectDir.clearPort(repoRoot.value);
|
|
6395
|
+
context.print(` stopped pid ${health.pid}`);
|
|
6396
|
+
return 0;
|
|
6397
|
+
}
|
|
6398
|
+
context.print(" it would not stop \u2014 end it yourself:");
|
|
6399
|
+
context.print(
|
|
6400
|
+
context.runtime.platform === "win32" ? ` taskkill /PID ${health.pid} /F` : ` kill ${health.pid}`
|
|
6401
|
+
);
|
|
6402
|
+
return 1;
|
|
6403
|
+
}
|
|
6404
|
+
};
|
|
6405
|
+
|
|
6194
6406
|
// src/interfaces/cli/registry.ts
|
|
6195
6407
|
var COMMANDS = [
|
|
6196
6408
|
serveCommand,
|
|
6197
6409
|
mcpCommand,
|
|
6198
6410
|
healthCommand,
|
|
6411
|
+
stopCommand,
|
|
6199
6412
|
iconsCommand
|
|
6200
6413
|
];
|
|
6201
6414
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createNodeSkeletonExpander, fail, isFail, isOk, ok, partition } from './chunk-
|
|
1
|
+
export { createNodeSkeletonExpander, fail, isFail, isOk, ok, partition } from './chunk-U2ZMSGNS.js';
|
|
2
2
|
import './chunk-7D4SUZUM.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
package/ui-dist/assets/{abnfDiagram-VCTEODGH-BJtEDuNS.js → abnfDiagram-VCTEODGH-C_cqCKun.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as t}from"./src-oBChb5qS.js";import"./chunk-DU6HZSFF-
|
|
1
|
+
import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as t}from"./src-oBChb5qS.js";import"./chunk-DU6HZSFF-_YwywVCK.js";import"./dist-Biz3NhE4.js";import{m as n,t as r}from"./mermaid-parser.core-0V2gZHuN.js";import{n as i,r as a,t as o}from"./chunk-SVP7TREG-DCss0vmb.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";var c=n().RailroadAbnf.parser.LangiumParser,l=e(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=e(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=e(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=e(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=e(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=e(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=e(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:e(e=>{o.clear(),t.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new r(n);let i=n.value;t.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),t.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
|