excalidrop 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/cli.d.ts +1 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +143 -50
  4. package/dist/cli.js.map +1 -1
  5. package/dist/frontend/assets/{advancedFormat-D_hAUGHx.js → advancedFormat-BI2QsyKs.js} +1 -1
  6. package/dist/frontend/assets/{ar-SA-G6X2FPQ2-C0cHHnYG.js → ar-SA-G6X2FPQ2-CaxtlU6V.js} +1 -1
  7. package/dist/frontend/assets/{arc-voAwz44g.js → arc-C4XPGgh1.js} +1 -1
  8. package/dist/frontend/assets/{az-AZ-76LH7QW2-Cjxzg4vI.js → az-AZ-76LH7QW2-DONe7hWP.js} +1 -1
  9. package/dist/frontend/assets/{bg-BG-XCXSNQG7-CE2Qd7cU.js → bg-BG-XCXSNQG7-C9Evwejq.js} +1 -1
  10. package/dist/frontend/assets/{blockDiagram-38ab4fdb-Bm_YLm4c.js → blockDiagram-38ab4fdb-CeGBx2IG.js} +1 -1
  11. package/dist/frontend/assets/{blockDiagram-68f4deed-BYexJ9l5.js → blockDiagram-68f4deed-BuFU62c1.js} +1 -1
  12. package/dist/frontend/assets/{bn-BD-2XOGV67Q-C3hztSh7.js → bn-BD-2XOGV67Q-A2u0B_YK.js} +1 -1
  13. package/dist/frontend/assets/{c4Diagram-15b5d702-DpvGNdb1.js → c4Diagram-15b5d702-BZOyxrhW.js} +1 -1
  14. package/dist/frontend/assets/{c4Diagram-3d4e48cf-Cex_37iq.js → c4Diagram-3d4e48cf-CtNeMwMI.js} +1 -1
  15. package/dist/frontend/assets/{ca-ES-6MX7JW3Y-DK0cMPVf.js → ca-ES-6MX7JW3Y-BJ2cOzQv.js} +1 -1
  16. package/dist/frontend/assets/channel-Bt1V_DY2.js +1 -0
  17. package/dist/frontend/assets/{classDiagram-70f12bd4-C-bM5szZ.js → classDiagram-70f12bd4-ffvmJhkT.js} +1 -1
  18. package/dist/frontend/assets/{classDiagram-d40c83e7-CNWHkFWX.js → classDiagram-d40c83e7-BKAqbPiT.js} +1 -1
  19. package/dist/frontend/assets/{classDiagram-v2-d5a6b087-CnoZ7UrM.js → classDiagram-v2-d5a6b087-B3I9-f1h.js} +1 -1
  20. package/dist/frontend/assets/{classDiagram-v2-f2320105-NEl1a8DW.js → classDiagram-v2-f2320105-ApA5rBIt.js} +1 -1
  21. package/dist/frontend/assets/clone-CverySyw.js +1 -0
  22. package/dist/frontend/assets/{createText-2e5e7dd3-CmOdNLlQ.js → createText-2e5e7dd3-Dz5JTn8-.js} +1 -1
  23. package/dist/frontend/assets/{createText-d213de94-BjNTFE-8.js → createText-d213de94-pvwHhTBT.js} +1 -1
  24. package/dist/frontend/assets/{cs-CZ-2BRQDIVT-DtnD7eNT.js → cs-CZ-2BRQDIVT-C1R2nrlZ.js} +1 -1
  25. package/dist/frontend/assets/{cytoscape-cose-bilkent-BrMrzgmp.js → cytoscape-cose-bilkent-HJBsCRy0.js} +1 -1
  26. package/dist/frontend/assets/{da-DK-5WZEPLOC-CQxH9pPs.js → da-DK-5WZEPLOC-uwpRmCSQ.js} +1 -1
  27. package/dist/frontend/assets/{de-DE-XR44H4JA--uxdtPKd.js → de-DE-XR44H4JA-DqNQykXn.js} +1 -1
  28. package/dist/frontend/assets/{edges-332bd1c7-CNic_93o.js → edges-332bd1c7-Dg01WbV7.js} +1 -1
  29. package/dist/frontend/assets/{edges-e0da2a9e-CDLrMOf-.js → edges-e0da2a9e-DrH5I7lw.js} +1 -1
  30. package/dist/frontend/assets/{el-GR-BZB4AONW-C0n5lsCo.js → el-GR-BZB4AONW-Fcd_Oynx.js} +1 -1
  31. package/dist/frontend/assets/{elk.bundled-BItCL1sO.js → elk.bundled-CCB9WSod.js} +1 -1
  32. package/dist/frontend/assets/{erDiagram-880f2ed8-DQ9hgik4.js → erDiagram-880f2ed8-DFHvELXS.js} +1 -1
  33. package/dist/frontend/assets/{erDiagram-9861fffd-16-nrx_I.js → erDiagram-9861fffd-BVYpHhLd.js} +1 -1
  34. package/dist/frontend/assets/{es-ES-U4NZUMDT-DR884pTc.js → es-ES-U4NZUMDT-dLw4wp8P.js} +1 -1
  35. package/dist/frontend/assets/{eu-ES-A7QVB2H4-CwGzoAb_.js → eu-ES-A7QVB2H4-OFvgphe5.js} +1 -1
  36. package/dist/frontend/assets/{fa-IR-HGAKTJCU-STUZS8sk.js → fa-IR-HGAKTJCU-DVwXzh2v.js} +1 -1
  37. package/dist/frontend/assets/{fi-FI-Z5N7JZ37-woRdrfKl.js → fi-FI-Z5N7JZ37-Munvd1SA.js} +1 -1
  38. package/dist/frontend/assets/{flowDb-7c981674-B4jwhc_8.js → flowDb-7c981674-Cgju3yay.js} +1 -1
  39. package/dist/frontend/assets/{flowDb-956e92f1-BMD1bhuC.js → flowDb-956e92f1-DmvPlEfa.js} +1 -1
  40. package/dist/frontend/assets/{flowDiagram-66a62f08-JlSVzRU0.js → flowDiagram-66a62f08-CXRe71xE.js} +1 -1
  41. package/dist/frontend/assets/{flowDiagram-cbd28bf7-i3WrrODz.js → flowDiagram-cbd28bf7-BpskBBZf.js} +1 -1
  42. package/dist/frontend/assets/flowDiagram-v2-96b9c2cf-QcN14kBk.js +1 -0
  43. package/dist/frontend/assets/flowDiagram-v2-ffc7f31a-DzLwKpgk.js +1 -0
  44. package/dist/frontend/assets/{flowchart-elk-definition-36e2d292-S2mocwzS.js → flowchart-elk-definition-36e2d292-CS7pfG05.js} +1 -1
  45. package/dist/frontend/assets/{flowchart-elk-definition-4a651766-CzLVoMj3.js → flowchart-elk-definition-4a651766-Cx-hM3BH.js} +1 -1
  46. package/dist/frontend/assets/{fr-FR-RHASNOE6-DEb_Iax4.js → fr-FR-RHASNOE6-B7uBhME6.js} +1 -1
  47. package/dist/frontend/assets/{ganttDiagram-04f9e578-VkIDQA63.js → ganttDiagram-04f9e578-BRI0m3iQ.js} +1 -1
  48. package/dist/frontend/assets/{ganttDiagram-c361ad54-GEDjodY6.js → ganttDiagram-c361ad54-DUIBD4rF.js} +1 -1
  49. package/dist/frontend/assets/{gitGraphDiagram-21fc4d3e-B4kyX168.js → gitGraphDiagram-21fc4d3e-BjD943_N.js} +1 -1
  50. package/dist/frontend/assets/{gitGraphDiagram-72cf32ee-BfZt9Uzr.js → gitGraphDiagram-72cf32ee-BPS4b8NG.js} +1 -1
  51. package/dist/frontend/assets/{gl-ES-HMX3MZ6V-DyLoL109.js → gl-ES-HMX3MZ6V-Divkg6yM.js} +1 -1
  52. package/dist/frontend/assets/{graph-5xNnc_2T.js → graph-Ye5fu1Py.js} +1 -1
  53. package/dist/frontend/assets/{graph-CJ5DL8Lf.js → graph-bxFPq5mp.js} +1 -1
  54. package/dist/frontend/assets/{he-IL-6SHJWFNN-B64T5I63.js → he-IL-6SHJWFNN-BHAX0Gxf.js} +1 -1
  55. package/dist/frontend/assets/{hi-IN-IWLTKZ5I-tu5bb-U9.js → hi-IN-IWLTKZ5I-BS5KD0eR.js} +1 -1
  56. package/dist/frontend/assets/{hu-HU-A5ZG7DT2-CbgcLTiz.js → hu-HU-A5ZG7DT2-BTZGcO35.js} +1 -1
  57. package/dist/frontend/assets/{id-ID-SAP4L64H-e2p7Zb_E.js → id-ID-SAP4L64H-D7X-a_Xl.js} +1 -1
  58. package/dist/frontend/assets/{index-3862675e-Bmm4Fc9s.js → index-3862675e--eWXWZQF.js} +1 -1
  59. package/dist/frontend/assets/{index-6079d271-CUioOh7n.js → index-6079d271-MAxNAr8f.js} +1 -1
  60. package/dist/frontend/assets/index-BVWcEKOQ.js +349 -0
  61. package/dist/frontend/assets/{index-Dkn7NkQE.js → index-BuQ5hb2w.js} +4 -4
  62. package/dist/frontend/assets/{infoDiagram-4a4f5b27-BhNHOwZA.js → infoDiagram-4a4f5b27-D0Gnhf0x.js} +1 -1
  63. package/dist/frontend/assets/{infoDiagram-f8f76790-BiNVg3cP.js → infoDiagram-f8f76790-CJcfYXU-.js} +1 -1
  64. package/dist/frontend/assets/{it-IT-JPQ66NNP-BZbWAY73.js → it-IT-JPQ66NNP-B7iPxEBG.js} +1 -1
  65. package/dist/frontend/assets/{ja-JP-DBVTYXUO-BTRvkLHp.js → ja-JP-DBVTYXUO-BE0v8MzJ.js} +1 -1
  66. package/dist/frontend/assets/{journeyDiagram-29694f62-Bh6lLjz4.js → journeyDiagram-29694f62-BJwkeuWK.js} +1 -1
  67. package/dist/frontend/assets/{journeyDiagram-49397b02-BS6zYMvG.js → journeyDiagram-49397b02-JC9lXhGe.js} +1 -1
  68. package/dist/frontend/assets/{kaa-6HZHGXH3-DVgbCgaP.js → kaa-6HZHGXH3-DFz38Q6C.js} +1 -1
  69. package/dist/frontend/assets/{kab-KAB-ZGHBKWFO-BjAPMX8e.js → kab-KAB-ZGHBKWFO-D-00Mjtt.js} +1 -1
  70. package/dist/frontend/assets/{kk-KZ-P5N5QNE5-CzxQzok2.js → kk-KZ-P5N5QNE5-Dm5igMCn.js} +1 -1
  71. package/dist/frontend/assets/{km-KH-HSX4SM5Z-Cp6ccIfb.js → km-KH-HSX4SM5Z-DpZYZnqU.js} +1 -1
  72. package/dist/frontend/assets/{ko-KR-MTYHY66A-F3PDpwD9.js → ko-KR-MTYHY66A-x7JVdXGx.js} +1 -1
  73. package/dist/frontend/assets/{ku-TR-6OUDTVRD-DqXhgZl-.js → ku-TR-6OUDTVRD-B7ow782Q.js} +1 -1
  74. package/dist/frontend/assets/{layout-DEauq2-V.js → layout-BtzmFPIx.js} +1 -1
  75. package/dist/frontend/assets/{layout-0oV3gk2v.js → layout-DHGBOueG.js} +1 -1
  76. package/dist/frontend/assets/{line-De4TmFEB.js → line-MN52CDfx.js} +1 -1
  77. package/dist/frontend/assets/{linear-B4mjEkfY.js → linear-Uzo-IsR2.js} +1 -1
  78. package/dist/frontend/assets/{lt-LT-XHIRWOB4-1eCe67Bl.js → lt-LT-XHIRWOB4-hNmxWFbJ.js} +1 -1
  79. package/dist/frontend/assets/{lv-LV-5QDEKY6T-CAsgjtjW.js → lv-LV-5QDEKY6T-Cudz98Yj.js} +1 -1
  80. package/dist/frontend/assets/{mindmap-definition-ac74a2e8-BqOdiX5M.js → mindmap-definition-ac74a2e8-z4UezY2y.js} +1 -1
  81. package/dist/frontend/assets/{mindmap-definition-fc14e90a-B8Rxhfa7.js → mindmap-definition-fc14e90a-4hiL1CmF.js} +1 -1
  82. package/dist/frontend/assets/{mr-IN-CRQNXWMA-DM2GvLsC.js → mr-IN-CRQNXWMA-CUblVYcb.js} +1 -1
  83. package/dist/frontend/assets/{my-MM-5M5IBNSE-Dz0p0cZk.js → my-MM-5M5IBNSE-Bf96t_sG.js} +1 -1
  84. package/dist/frontend/assets/{nb-NO-T6EIAALU-DJTgfL8G.js → nb-NO-T6EIAALU-BAa5-M-j.js} +1 -1
  85. package/dist/frontend/assets/{nl-NL-IS3SIHDZ-QXFgpjik.js → nl-NL-IS3SIHDZ-bgrTOFXJ.js} +1 -1
  86. package/dist/frontend/assets/{nn-NO-6E72VCQL-CupEMZo5.js → nn-NO-6E72VCQL-sKg1DMPp.js} +1 -1
  87. package/dist/frontend/assets/{oc-FR-POXYY2M6-DM3mK7_w.js → oc-FR-POXYY2M6-YnFHq8Ry.js} +1 -1
  88. package/dist/frontend/assets/{pa-IN-N4M65BXN-39D7GgUd.js → pa-IN-N4M65BXN-Cqsg9m3b.js} +1 -1
  89. package/dist/frontend/assets/{pica-BYbIcfPn.js → pica-cE5KMNox.js} +1 -1
  90. package/dist/frontend/assets/{pie-B1U0OQ26.js → pie-cQT28yIQ.js} +1 -1
  91. package/dist/frontend/assets/{pieDiagram-421022e6-BvT5PUN-.js → pieDiagram-421022e6-Dj1z_wDD.js} +1 -1
  92. package/dist/frontend/assets/{pieDiagram-8a3498a8-BVAWtEPp.js → pieDiagram-8a3498a8-Bjaxvjyi.js} +1 -1
  93. package/dist/frontend/assets/{pl-PL-T2D74RX3-BBmu2SjR.js → pl-PL-T2D74RX3-DcB1SCjx.js} +1 -1
  94. package/dist/frontend/assets/{pt-BR-5N22H2LF-BHGnlXVQ.js → pt-BR-5N22H2LF-CuXpjbkS.js} +1 -1
  95. package/dist/frontend/assets/{pt-PT-UZXXM6DQ-Bs9CAKkb.js → pt-PT-UZXXM6DQ-tHNUpzQf.js} +1 -1
  96. package/dist/frontend/assets/{quadrantDiagram-0957ecba-DEeyKHE8.js → quadrantDiagram-0957ecba-CFMyQ0mP.js} +1 -1
  97. package/dist/frontend/assets/{quadrantDiagram-120e2f19-DcJBH6EB.js → quadrantDiagram-120e2f19-1SJE472b.js} +1 -1
  98. package/dist/frontend/assets/{relay-DDrathjM.js → relay-1sEnjBCn.js} +2 -2
  99. package/dist/frontend/assets/{requirementDiagram-23d650b8-CVQ2ZP6m.js → requirementDiagram-23d650b8-JQ5Er2kb.js} +1 -1
  100. package/dist/frontend/assets/{requirementDiagram-deff3bca-hhOSwcyj.js → requirementDiagram-deff3bca-BpRNAAqo.js} +1 -1
  101. package/dist/frontend/assets/{ro-RO-JPDTUUEW-5j9Qcvxw.js → ro-RO-JPDTUUEW-BI7B7oOe.js} +1 -1
  102. package/dist/frontend/assets/{ru-RU-B4JR7IUQ-DicRcrKQ.js → ru-RU-B4JR7IUQ-zconPLrO.js} +1 -1
  103. package/dist/frontend/assets/{sankeyDiagram-04a897e0-BTt5fO25.js → sankeyDiagram-04a897e0-D31Or3lC.js} +1 -1
  104. package/dist/frontend/assets/{sankeyDiagram-23345273-CqrhI2Nl.js → sankeyDiagram-23345273-OXnSG5On.js} +1 -1
  105. package/dist/frontend/assets/{selectAll-qOHydfRB.js → selectAll-Bbco7MHs.js} +1 -1
  106. package/dist/frontend/assets/{sequenceDiagram-17ac3bff-Dioe6R0p.js → sequenceDiagram-17ac3bff-D44sltda.js} +1 -1
  107. package/dist/frontend/assets/{sequenceDiagram-704730f1-CwAM-8xD.js → sequenceDiagram-704730f1-SNpJuTGo.js} +1 -1
  108. package/dist/frontend/assets/{si-LK-N5RQ5JYF-Cvyi5caX.js → si-LK-N5RQ5JYF-GXylzPyi.js} +1 -1
  109. package/dist/frontend/assets/{sk-SK-C5VTKIMK-CVF6jp0N.js → sk-SK-C5VTKIMK-ByE-Je_t.js} +1 -1
  110. package/dist/frontend/assets/{sl-SI-NN7IZMDC-BUEZxlx3.js → sl-SI-NN7IZMDC-CkPRwE28.js} +1 -1
  111. package/dist/frontend/assets/{stateDiagram-587899a1-BScbzVlp.js → stateDiagram-587899a1-DilqgCTY.js} +1 -1
  112. package/dist/frontend/assets/{stateDiagram-9c5f0230-BRyfqsP4.js → stateDiagram-9c5f0230-CqJITn5b.js} +1 -1
  113. package/dist/frontend/assets/{stateDiagram-v2-51a3dcff-C_46txUS.js → stateDiagram-v2-51a3dcff-eBMZVGNY.js} +1 -1
  114. package/dist/frontend/assets/{stateDiagram-v2-d93cdb3a-fE8T9scw.js → stateDiagram-v2-d93cdb3a-BaylKhDX.js} +1 -1
  115. package/dist/frontend/assets/{styles-2ab5d517-BjYPsJFb.js → styles-2ab5d517-BIGHfmZe.js} +1 -1
  116. package/dist/frontend/assets/{styles-5f03d8d2-BxGvIUMy.js → styles-5f03d8d2-Dw55Rbpd.js} +1 -1
  117. package/dist/frontend/assets/{styles-6aaf32cf-C6EV3LU1.js → styles-6aaf32cf-BXUnVQLh.js} +1 -1
  118. package/dist/frontend/assets/{styles-9a916d00-D-fHYofd.js → styles-9a916d00-BYq8kLgA.js} +1 -1
  119. package/dist/frontend/assets/{styles-c10674c1-DJPAyH2i.js → styles-c10674c1-CIZGAqw9.js} +1 -1
  120. package/dist/frontend/assets/{styles-edf9a4b0-xaIyorjl.js → styles-edf9a4b0-JKycmYZL.js} +1 -1
  121. package/dist/frontend/assets/subset-shared.chunk.js +1 -1
  122. package/dist/frontend/assets/subset-worker.chunk.js +1 -1
  123. package/dist/frontend/assets/{sv-SE-XGPEYMSR-D9N-82r3.js → sv-SE-XGPEYMSR-zSyT8j9A.js} +1 -1
  124. package/dist/frontend/assets/{svgDrawCommon-08f97a94-lJ3gP-XD.js → svgDrawCommon-08f97a94-Cb5i4omb.js} +1 -1
  125. package/dist/frontend/assets/{svgDrawCommon-3ba9043b-BRyUvN8a.js → svgDrawCommon-3ba9043b-D-rnBjeC.js} +1 -1
  126. package/dist/frontend/assets/{ta-IN-2NMHFXQM-uCND4pry.js → ta-IN-2NMHFXQM-CkFuHV3V.js} +1 -1
  127. package/dist/frontend/assets/{th-TH-HPSO5L25-ZovlT-xD.js → th-TH-HPSO5L25-QIx9Ya2v.js} +1 -1
  128. package/dist/frontend/assets/{timeline-definition-7e6b55e7--QFtbYaW.js → timeline-definition-7e6b55e7-Cgy_R8Xc.js} +1 -1
  129. package/dist/frontend/assets/{timeline-definition-85554ec2-B3E_Lcbb.js → timeline-definition-85554ec2-27azWgNk.js} +1 -1
  130. package/dist/frontend/assets/{tr-TR-DEFEU3FU-DoPB0JUv.js → tr-TR-DEFEU3FU-B6BhZE1y.js} +1 -1
  131. package/dist/frontend/assets/{uk-UA-QMV73CPH-CFwy-mfZ.js → uk-UA-QMV73CPH-HB1GcgFG.js} +1 -1
  132. package/dist/frontend/assets/{union-DVy4cDRi.js → union-ClsoZ0JD.js} +1 -1
  133. package/dist/frontend/assets/{vi-VN-M7AON7JQ-CqHLJYoP.js → vi-VN-M7AON7JQ-2HLiH-NR.js} +1 -1
  134. package/dist/frontend/assets/{xychartDiagram-b6496bcd-DhEWj72p.js → xychartDiagram-b6496bcd-Dexwv94Q.js} +1 -1
  135. package/dist/frontend/assets/{xychartDiagram-e933f94c-DMJdoP4V.js → xychartDiagram-e933f94c-B1Ihwsmh.js} +1 -1
  136. package/dist/frontend/assets/{zh-CN-LNUGB5OW-CTW1RjkW.js → zh-CN-LNUGB5OW-XUBwWymm.js} +1 -1
  137. package/dist/frontend/assets/{zh-HK-E62DVLB3-CRHRMlEl.js → zh-HK-E62DVLB3-O0sNr9xc.js} +1 -1
  138. package/dist/frontend/assets/{zh-TW-RAJ6MFWO-D7-lWxxC.js → zh-TW-RAJ6MFWO-kz6UjkWj.js} +1 -1
  139. package/dist/frontend/assets/{zipObject-C2E0t_xQ.js → zipObject-BTD_n5-E.js} +1 -1
  140. package/dist/frontend/index.html +1 -1
  141. package/dist/mcp.d.ts.map +1 -1
  142. package/dist/mcp.js +61 -2
  143. package/dist/mcp.js.map +1 -1
  144. package/package.json +1 -1
  145. package/dist/frontend/assets/channel-C3hXDCqP.js +0 -1
  146. package/dist/frontend/assets/clone-B5s05voD.js +0 -1
  147. package/dist/frontend/assets/flowDiagram-v2-96b9c2cf-DXJYhZPJ.js +0 -1
  148. package/dist/frontend/assets/flowDiagram-v2-ffc7f31a-Dt9-YCmt.js +0 -1
  149. package/dist/frontend/assets/index-Dtc2YcdT.js +0 -349
package/dist/cli.d.ts CHANGED
@@ -8,5 +8,6 @@ export type EditorStatus = {
8
8
  repo: string | null;
9
9
  where: string;
10
10
  outdatedForm?: boolean;
11
+ pinned?: boolean;
11
12
  };
12
13
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AA8QA,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ5E;AA4JD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASvD;AAwJD,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AA8QA,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ5E;AAuKD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASvD;AAqKD,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC"}
package/dist/cli.js CHANGED
@@ -345,13 +345,25 @@ function wranglerAccount() {
345
345
  const m = r.out.match(/[\w.+-]+@[\w-]+\.[\w.]+/);
346
346
  return { ok: true, display: m?.[0] ?? 'logged in' };
347
347
  }
348
+ /** Create a Pages project (idempotent). 'taken' = global subdomain collision
349
+ * owned by someone else; 'ok' = created or already owned by this account. */
350
+ function createCfProject(project) {
351
+ const create = spawnSync('npx', [...WRANGLER, 'pages', 'project', 'create', project, '--force', '--production-branch=main'], { stdio: 'pipe', encoding: 'utf8', env: wranglerEnv() });
352
+ const createOut = (create.stdout || '') + (create.stderr || '');
353
+ if (create.status === 0 || /already exists/i.test(createOut))
354
+ return 'ok';
355
+ if (/taken|already in use|not available|conflict|8007|8008/i.test(createOut))
356
+ return 'taken';
357
+ throw new Error(`wrangler pages project create failed:\n${createOut.slice(-800)}\nRun \`wrangler login\` first (or set CLOUDFLARE_API_TOKEN).`);
358
+ }
348
359
  function deployToCloudflarePages(project, dir) {
349
360
  // wrangler 4 doesn't auto-create Pages projects and its Workers delegation
350
361
  // misfires on explicit asset dirs — create once, then deploy classic with --force.
351
- const create = spawnSync('npx', [...WRANGLER, 'pages', 'project', 'create', project, '--force', '--production-branch=main'], { stdio: 'pipe', encoding: 'utf8', env: wranglerEnv() });
352
- const createOut = (create.stdout || '') + (create.stderr || '');
353
- if (create.status !== 0 && !/already exists/i.test(createOut)) {
354
- throw new Error(`wrangler pages project create failed:\n${createOut.slice(-800)}\nRun \`wrangler login\` first (or set CLOUDFLARE_API_TOKEN).`);
362
+ // The TUI pre-flights this; headless runs land here (create is idempotent).
363
+ const st = createCfProject(project);
364
+ if (st === 'taken') {
365
+ const [o] = project.split('-');
366
+ throw new Error(`The project name "${project}" is already taken on Cloudflare Pages (${project}.pages.dev is global, owned by someone else). Choose another name and re-run with --project-name <name> (e.g. --project-name "${project}-${o || 'app'}").`);
355
367
  }
356
368
  const r = spawnSync('npx', [...WRANGLER, 'pages', 'deploy', dir || viewerDir(), '--project-name', project, '--force'], { stdio: 'inherit', env: wranglerEnv() });
357
369
  if (r.status !== 0)
@@ -498,13 +510,21 @@ function ensureNpxPrefix() {
498
510
  }
499
511
  catch { /* spawn will surface real errors */ }
500
512
  }
513
+ // User-scope (global) entries are repo-less: the server resolves the canvas
514
+ // at spawn time (--repo flag → $EXCALIDROP_REPO → .excalidrop.json → git
515
+ // origin → last-used repo) and remembers the last repo. Pinning --repo in a
516
+ // global entry would freeze every editor on one canvas and force a "repoint"
517
+ // on every setup. Project-scope entries keep their --repo pin (per-project).
518
+ // Pass repo=null for user-scope, the slug for project-scope.
501
519
  function mcpArgs(repo) {
502
520
  // --prefix isolates the npx install from the caller's project: when an
503
521
  // editor spawns this from inside a checkout whose package.json is ALSO
504
522
  // named excalidrop at a satisfying version, bare `npx -y excalidrop@latest`
505
523
  // resolves to the local (possibly bin-less/stale) tree and dies with
506
524
  // "command not found". A neutral prefix forces the registry fetch.
507
- return ['--prefix', NPX_PREFIX, '-y', 'excalidrop@latest', 'mcp', '--repo', repo];
525
+ return repo
526
+ ? ['--prefix', NPX_PREFIX, '-y', 'excalidrop@latest', 'mcp', '--repo', repo]
527
+ : ['--prefix', NPX_PREFIX, '-y', 'excalidrop@latest', 'mcp'];
508
528
  }
509
529
  // Quote one argv element for display/manual-run strings (arrays stay raw).
510
530
  function shellQuote(a) {
@@ -513,18 +533,22 @@ function shellQuote(a) {
513
533
  function mcpArgsDisplay(repo) {
514
534
  return mcpArgs(repo).map(shellQuote).join(' ');
515
535
  }
536
+ /** Repo arg for an editor install: null (dynamic) for user-scope, slug for project-scope. */
537
+ function installRepo(id, repo) {
538
+ return editorScope(id) === 'user' ? null : repo;
539
+ }
516
540
  const EDITOR_IDS = ['claude-project', 'claude-user', 'codex', 'cursor', 'cursor-user', 'desktop', 'opencode', 'opencode-user'];
517
541
  function editorCommand(id, repo) {
518
- const a = mcpArgsDisplay(repo);
542
+ const a = mcpArgsDisplay(installRepo(id, repo));
519
543
  switch (id) {
520
544
  case 'claude-project': return `claude mcp add excalidrop --scope project -- npx ${a}`;
521
545
  case 'claude-user': return `claude mcp add excalidrop --scope user -- npx ${a}`;
522
546
  case 'codex': return `codex mcp add excalidrop -- npx ${a}`;
523
547
  case 'cursor':
524
548
  case 'cursor-user':
525
- case 'desktop': return JSON.stringify({ mcpServers: { excalidrop: { command: 'npx', args: mcpArgs(repo) } } }, null, 2);
549
+ case 'desktop': return JSON.stringify({ mcpServers: { excalidrop: { command: 'npx', args: mcpArgs(installRepo(id, repo)) } } }, null, 2);
526
550
  case 'opencode':
527
- case 'opencode-user': return JSON.stringify({ $schema: 'https://opencode.ai/config.json', mcp: { excalidrop: { type: 'local', command: ['npx', ...mcpArgs(repo)], enabled: true } } }, null, 2);
551
+ case 'opencode-user': return JSON.stringify({ $schema: 'https://opencode.ai/config.json', mcp: { excalidrop: { type: 'local', command: ['npx', ...mcpArgs(installRepo(id, repo))], enabled: true } } }, null, 2);
528
552
  }
529
553
  }
530
554
  function editorScope(id) {
@@ -614,22 +638,49 @@ function codexMcpRepo() {
614
638
  }
615
639
  function detectEditorState(id, repo, root) {
616
640
  const want = repo.toLowerCase();
641
+ // User-scope (global) entries must stay repo-less — the server remembers
642
+ // the last/current canvas at runtime. A legacy --repo pin is stale (migrate
643
+ // once to dynamic, then it stays current forever). Project-scope entries
644
+ // keep the pinned-repo comparison.
645
+ const dynamic = editorScope(id) === 'user';
617
646
  if (id === 'codex') {
618
647
  const s = codexMcpRepo();
619
648
  if (!s.present)
620
649
  return { status: 'missing', repo: null, where: '~/.codex/config.toml' };
621
- if (s.repo === want && s.modern)
650
+ if (!s.modern)
651
+ return { status: 'stale', repo: s.repo, where: '~/.codex/config.toml', outdatedForm: true, pinned: !!s.repo };
652
+ if (dynamic)
653
+ return s.repo
654
+ ? { status: 'stale', repo: s.repo, where: '~/.codex/config.toml', pinned: true }
655
+ : { status: 'current', repo: null, where: '~/.codex/config.toml' };
656
+ if (s.repo === want)
622
657
  return { status: 'current', repo: s.repo, where: '~/.codex/config.toml' };
623
- return { status: 'stale', repo: s.repo, where: '~/.codex/config.toml', outdatedForm: s.repo === want && !s.modern };
658
+ return { status: 'stale', repo: s.repo, where: '~/.codex/config.toml' };
624
659
  }
625
660
  const f = editorFile(id, root);
626
661
  const where = shortenHome(f.path);
627
662
  const s = jsonMcpRepo(f.path, f.key);
628
663
  if (!s.present)
629
664
  return { status: 'missing', repo: null, where };
630
- if (s.repo === want && s.modern)
665
+ if (!s.modern)
666
+ return { status: 'stale', repo: s.repo, where, outdatedForm: true, pinned: !!s.repo };
667
+ if (dynamic)
668
+ return s.repo
669
+ ? { status: 'stale', repo: s.repo, where, pinned: true }
670
+ : { status: 'current', repo: null, where };
671
+ if (s.repo === want)
631
672
  return { status: 'current', repo: s.repo, where };
632
- return { status: 'stale', repo: s.repo, where, outdatedForm: s.repo === want && !s.modern };
673
+ return { status: 'stale', repo: s.repo, where };
674
+ }
675
+ /** Human-readable reason a stale entry needs rewriting. */
676
+ function staleWhy(st) {
677
+ if (st.outdatedForm && st.pinned)
678
+ return `pinned to ${st.repo} with outdated npx form — unpin to dynamic (remembers last repo)`;
679
+ if (st.outdatedForm)
680
+ return 'outdated npx form (missing --prefix)';
681
+ if (st.pinned)
682
+ return `pinned to ${st.repo} — global entry must stay repo-less (remembers last repo)`;
683
+ return `points at ${st.repo ?? 'unknown'}`;
633
684
  }
634
685
  function updateCommand(id, repo) {
635
686
  if (id === 'claude-project' || id === 'claude-user') {
@@ -697,23 +748,23 @@ function opencodeEntry(repo) {
697
748
  }
698
749
  function installEditor(id, repo, root) {
699
750
  const fail = (detail) => ({ id, outcome: 'failed', detail });
751
+ const want = installRepo(id, repo);
752
+ const at = (r) => (r ?? 'dynamic (remembers last repo)');
700
753
  // Idempotent first: never reinstall over an identical entry, never silently
701
754
  // leave a stale one — report it with the exact update command.
702
755
  const st = detectEditorState(id, repo, root);
703
756
  if (st.status === 'current')
704
- return { id, outcome: 'already-current', detail: `${st.where} already points at ${repo}` };
705
- const staleNote = st.status === 'stale'
706
- ? (st.outdatedForm ? ' (outdated npx form — needs --prefix)' : ` (currently → ${st.repo ?? 'unknown'})`)
707
- : '';
757
+ return { id, outcome: 'already-current', detail: `${st.where} already → ${at(st.repo)}` };
758
+ const staleNote = st.status === 'stale' ? ` (${staleWhy(st)})` : '';
708
759
  if (id === 'claude-project' || id === 'claude-user' || id === 'codex') {
709
760
  const bin = id === 'codex' ? 'codex' : 'claude';
710
761
  if (!commandExists(bin))
711
762
  return fail(`${bin} CLI not found — run manually:\n${editorCommand(id, repo)}`);
712
763
  const cargs = id === 'claude-project'
713
- ? ['mcp', 'add', 'excalidrop', '--scope', 'project', '--', 'npx', ...mcpArgs(repo)]
764
+ ? ['mcp', 'add', 'excalidrop', '--scope', 'project', '--', 'npx', ...mcpArgs(want)]
714
765
  : id === 'claude-user'
715
- ? ['mcp', 'add', 'excalidrop', '--scope', 'user', '--', 'npx', ...mcpArgs(repo)]
716
- : ['mcp', 'add', 'excalidrop', '--', 'npx', ...mcpArgs(repo)];
766
+ ? ['mcp', 'add', 'excalidrop', '--scope', 'user', '--', 'npx', ...mcpArgs(want)]
767
+ : ['mcp', 'add', 'excalidrop', '--', 'npx', ...mcpArgs(want)];
717
768
  const r = runCapture(bin, cargs);
718
769
  if (r.status === 0 && !/already exists/i.test(r.out)) {
719
770
  // detail must NOT repeat the command — callers already print editorCommand.
@@ -724,17 +775,16 @@ function installEditor(id, repo, root) {
724
775
  // honestly whether the existing entry is current or stale.
725
776
  const now = detectEditorState(id, repo, root);
726
777
  if (now.status === 'current')
727
- return { id, outcome: 'already-current', detail: `${now.where} already points at ${repo}` };
728
- const why = now.outdatedForm ? 'outdated npx form (missing --prefix)' : `→ ${now.repo ?? 'unknown'}`;
729
- return { id, outcome: 'stale', detail: `already exists (${why}) — not updated. Run:\n${updateCommand(id, repo)}` };
778
+ return { id, outcome: 'already-current', detail: `${now.where} already → ${at(now.repo)}` };
779
+ return { id, outcome: 'stale', detail: `already exists (${staleWhy(now)}) — not updated. Run:\n${updateCommand(id, repo)}` };
730
780
  }
731
781
  return fail((r.out.trim() || `${bin} exited ${r.status}`).slice(0, 300));
732
782
  }
733
783
  // File-based harnesses: JSON merge is safe to write for both add and update.
734
784
  const f = editorFile(id, root);
735
- const entry = id === 'cursor' || id === 'cursor-user' || id === 'desktop' ? cursorEntry(repo) : opencodeEntry(repo);
785
+ const entry = id === 'cursor' || id === 'cursor-user' || id === 'desktop' ? cursorEntry(want) : opencodeEntry(want);
736
786
  if (upsertJsonMcp(f.path, f.key, entry)) {
737
- return { id, outcome: 'added', detail: `wrote ${shortenHome(f.path)}${staleNote} → ${repo}` };
787
+ return { id, outcome: 'added', detail: `wrote ${shortenHome(f.path)}${staleNote} → ${at(want)}` };
738
788
  }
739
789
  return fail(`${shortenHome(f.path)} is not valid JSON — leaving it untouched. Add manually:\n${editorCommand(id, repo)}`);
740
790
  }
@@ -774,6 +824,8 @@ function stateHint(st) {
774
824
  return 'installed';
775
825
  if (st.status !== 'stale')
776
826
  return undefined;
827
+ if (st.pinned)
828
+ return `pinned → ${st.repo}`;
777
829
  if (st.outdatedForm)
778
830
  return 'outdated entry (old npx form)';
779
831
  return `installed → ${st.repo ?? 'unknown'}`;
@@ -783,7 +835,7 @@ function harnessSummary(h, slug, root) {
783
835
  const parts = ids.map((id) => {
784
836
  const st = detectEditorState(id, slug, root);
785
837
  const cur = st.status === 'current' ? 'installed' : st.status === 'stale'
786
- ? (st.outdatedForm ? 'outdated entry' : `installed → ${st.repo ?? 'unknown'}`)
838
+ ? (st.pinned ? `pinned → ${st.repo}` : st.outdatedForm ? 'outdated entry' : `installed → ${st.repo ?? 'unknown'}`)
787
839
  : '—';
788
840
  return ids.length > 1 ? `${editorScope(id)}: ${cur}` : cur;
789
841
  });
@@ -869,12 +921,29 @@ async function cmdSetup(args, editorOverride, opts = {}) {
869
921
  await ghGet(`/repos/${slug}`);
870
922
  }
871
923
  catch (e) {
872
- if (String(e.message).includes('→ 404')) {
924
+ const msg = String(e.message || '');
925
+ if (msg.includes('→ 404')) {
873
926
  console.error(`Repo "${slug}" not found (404). Check the slug for typos, or create it:\n\n gh repo create ${slug} --private # or --public\n`);
874
927
  process.exit(1);
875
928
  }
929
+ if (/installations and requests .* disabled|oauth .* restricted|organization .* blocked|access restricted by/i.test(msg)) {
930
+ const [owner, name] = slug.split('/');
931
+ console.error([
932
+ `Organization "${owner}" disables OAuth/GitHub-App installs and requests ("Installations and requests are disabled").`,
933
+ `OAuth login cannot unlock this canvas. Use a fine-grained PAT instead:`,
934
+ ``,
935
+ ` 1. Create: https://github.com/settings/personal-access-tokens/new?name=excalidrop-${owner}-${name}&resource_owner=${owner}`,
936
+ ` Scope: ONLY repository ${slug} → Contents: Read & write. Tokens for other repos or classic ghp_ are rejected.`,
937
+ ` 2. Export it for this command: GITHUB_TOKEN=github_pat_... npx excalidrop setup ${slug}`,
938
+ ` 3. In the viewer, open "Use PAT" and paste the same token.`,
939
+ ].join('\n'));
940
+ process.exit(1);
941
+ }
876
942
  throw e;
877
943
  }
944
+ if (/^ghp_/i.test(process.env.GITHUB_TOKEN || '')) {
945
+ console.warn('Warning: GITHUB_TOKEN looks like a classic PAT (ghp_) with broad access. Prefer a fine-grained PAT (github_pat_) scoped to this repo only with Contents: Read & write.');
946
+ }
878
947
  const explicitTarget = parseFlag(args, 'target');
879
948
  const target = await resolveTarget(slug, explicitTarget);
880
949
  console.log(`Repo: ${slug}\nHost: ${target}${explicitTarget ? (opts.fromTui ? ' (selected)' : ' (explicit)') : ' (auto: private→cloudflare, public→pages)'}\n`);
@@ -1151,26 +1220,46 @@ async function runTui() {
1151
1220
  process.exit(0);
1152
1221
  }
1153
1222
  const target = hostAnswer;
1154
- // Cloudflare project name = the *.pages.dev subdomain. Offer the choice
1155
- // up front so the URL is predictable (and re-runnable without surprises).
1156
- // Suggest the simplest free name (bare repo first, availability-checked
1157
- // against this account); republish keeps the current project for URL stability.
1223
+ // Cloudflare project name = the GLOBAL *.pages.dev subdomain. Offer the
1224
+ // choice up front so the URL is predictable (and re-runnable without
1225
+ // surprises). suggestProjectName only checks THIS account's project list —
1226
+ // a short name like `test` can still be taken globally, so the message
1227
+ // must not promise "free" and the create step retries on taken names.
1228
+ // Republish keeps the current project for URL stability.
1158
1229
  let project = projectNameForRepo(slug);
1159
1230
  if (target === 'cloudflare') {
1160
1231
  const suggested = suggestProjectName(slug, findProjectRoot(process.cwd()));
1161
1232
  if (suggested !== project)
1162
- clack.log.info(`Shortest free project name: ${suggested} (default was ${project}).`);
1163
- const nameAnswer = await clack.text({
1164
- message: 'Cloudflare project name (viewer host)?',
1165
- placeholder: suggested,
1166
- initialValue: suggested,
1167
- validate: (v) => (normalizeProjectName(v, '') ? undefined : 'Lowercase letters, numbers, hyphens.'),
1168
- });
1169
- if (clack.isCancel(nameAnswer)) {
1170
- clack.cancel('Aborted.');
1171
- process.exit(0);
1233
+ clack.log.info(`Shortest available name in your account: ${suggested}. Note: *.pages.dev is global — a short name may still be taken; you'll be asked again if so.`);
1234
+ const askProject = async (initial) => {
1235
+ const nameAnswer = await clack.text({
1236
+ message: 'Cloudflare project name (viewer host)?',
1237
+ placeholder: initial,
1238
+ initialValue: initial,
1239
+ validate: (v) => (normalizeProjectName(v, '') ? undefined : 'Lowercase letters, numbers, hyphens.'),
1240
+ });
1241
+ if (clack.isCancel(nameAnswer)) {
1242
+ clack.cancel('Aborted.');
1243
+ process.exit(0);
1244
+ }
1245
+ return normalizeProjectName(nameAnswer, project);
1246
+ };
1247
+ project = await askProject(suggested);
1248
+ // Pre-flight: `project create` fails when the subdomain is taken globally
1249
+ // (even if absent from this account). Retry in the prompt instead of
1250
+ // dying mid-deploy. `createCfProject` returns 'taken' for a global
1251
+ // collision, 'ok' when created or already owned by this account.
1252
+ for (let attempt = 0; attempt < 3; attempt++) {
1253
+ const st = createCfProject(project);
1254
+ if (st === 'ok')
1255
+ break;
1256
+ const [owner, name] = slug.split('/');
1257
+ const alts = [`${owner}-${name}`, projectNameForRepo(slug), `${project}-${owner}`]
1258
+ .map((s) => normalizeProjectName(s, '')).filter(Boolean)
1259
+ .filter((s, i, a) => a.indexOf(s) === i && s !== project);
1260
+ clack.log.warn(`The name "${project}" is already taken on Cloudflare Pages (${project}.pages.dev is global, owned by someone else)${alts.length > 0 ? `. Try: ${alts.slice(0, 3).join(', ')}` : ''}.`);
1261
+ project = await askProject(alts[0] || `${project}-2`);
1172
1262
  }
1173
- project = normalizeProjectName(nameAnswer, project);
1174
1263
  }
1175
1264
  // Cloudflare deploys run under the USER's own wrangler identity and quota.
1176
1265
  // Verify login up front (with an offer to log in now) instead of failing
@@ -1241,19 +1330,21 @@ async function runTui() {
1241
1330
  editors.push(scopeAnswer);
1242
1331
  }
1243
1332
  // Stale Claude entries can't be overwritten by `add` (it exits 0 with
1244
- // "already exists" and changes nothing) — offer an explicit repoint before
1245
- // the deploy phase so the install below actually lands. Same-repo entries
1246
- // in the old npx form count as stale too (they break when spawned from
1247
- // inside an excalidrop checkout).
1333
+ // "already exists" and changes nothing) — offer an explicit rewrite before
1334
+ // the deploy phase so the install below actually lands. That covers the old
1335
+ // npx form, legacy --repo pins on user-scope entries (global entries stay
1336
+ // repo-less), and project-scope entries pointing at another repo.
1248
1337
  for (const id of editors) {
1249
1338
  if (id !== 'claude-user' && id !== 'claude-project')
1250
1339
  continue;
1251
1340
  const st = detectEditorState(id, slug, projectRoot);
1252
1341
  if (st.status !== 'stale')
1253
1342
  continue;
1254
- const what = st.outdatedForm
1255
- ? `${EDITOR_LABELS[id]} uses the old npx form (breaks inside excalidrop checkouts) — rewrite it for ${slug}?`
1256
- : `${EDITOR_LABELS[id]} points at ${st.repo ?? 'unknown'} — repoint to ${slug}?`;
1343
+ const what = st.pinned && editorScope(id) === 'user'
1344
+ ? `${EDITOR_LABELS[id]} is pinned to ${st.repo} — make it dynamic (remember last repo)?`
1345
+ : st.outdatedForm
1346
+ ? `${EDITOR_LABELS[id]} uses the old npx form (breaks inside excalidrop checkouts) — rewrite it${editorScope(id) === 'user' ? ' (dynamic, no repo pin)' : ` for ${slug}`}?`
1347
+ : `${EDITOR_LABELS[id]} points at ${st.repo ?? 'unknown'} — repoint to ${slug}?`;
1257
1348
  const ok = await clack.confirm({ message: what });
1258
1349
  if (clack.isCancel(ok)) {
1259
1350
  clack.cancel('Aborted.');
@@ -1324,7 +1415,7 @@ function printHelp() {
1324
1415
  Usage:
1325
1416
  npx excalidrop interactive setup TUI
1326
1417
  npx excalidrop setup owner/repo [--target pages|cloudflare] [--relay shared|self] [--editor claude-project,claude-user,codex,cursor,cursor-user,desktop,opencode,opencode-user] [--no-prompt]
1327
- npx --prefix ~/.excalidrop-npx -y excalidrop@latest mcp --repo owner/repo run MCP stdio server (editors use this)
1418
+ npx --prefix ~/.excalidrop-npx -y excalidrop@latest mcp run MCP stdio server, repo auto-resolved (--repo owner/repo overrides)
1328
1419
  npx excalidrop login [--repo owner/repo] GitHub device-flow login
1329
1420
  npx excalidrop publish owner/repo [--target ..] redeploy viewer only
1330
1421
  npx excalidrop status show repo + auth + scene
@@ -1366,7 +1457,9 @@ async function main() {
1366
1457
  console.log('Add excalidrop to your AI agent (no install, always latest):\n');
1367
1458
  for (const id of ids) {
1368
1459
  const st = repo.includes('/') ? detectEditorState(id, repo, root) : null;
1369
- const mark = st?.status === 'current' ? ' (installed)' : st?.status === 'stale' ? (st.outdatedForm ? ' (outdated npx form)' : ` (installed → ${st.repo ?? 'unknown'})`) : '';
1460
+ const mark = st?.status === 'current'
1461
+ ? (editorScope(id) === 'user' ? ' (installed, dynamic)' : ' (installed)')
1462
+ : st?.status === 'stale' ? (st.pinned ? ` (pinned → ${st.repo})` : st.outdatedForm ? ' (outdated npx form)' : ` (installed → ${st.repo ?? 'unknown'})`) : '';
1370
1463
  console.log(`## ${EDITOR_LABELS[id]} → ${editorTarget(id, root)}${mark}\n${editorCommand(id, repo)}\n`);
1371
1464
  }
1372
1465
  break;