chainlesschain 0.161.11 → 0.162.0

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 (184) hide show
  1. package/package.json +4 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-Cv7DnNSv.js → AIOps-Dn8q-Cu4.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-B1m9njbz.js → ActionButton-BePEVs4O.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CU5lrpIq.js → Analytics-CKp-5Gi0.js} +1 -1
  6. package/src/assets/web-panel/assets/AppLayout-BSudqld0.js +3 -0
  7. package/src/assets/web-panel/assets/{AppLayout-BpbfrB7k.css → AppLayout-DBgtkmP7.css} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-DUkzhAbX.js → Audit-iefpSeRG.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-L1i5rG4e.js → Backup-Ce43ZIhD.js} +1 -1
  10. package/src/assets/web-panel/assets/BaseInput-BvGiwRav.js +1 -0
  11. package/src/assets/web-panel/assets/{Chat-ySuja9_N.js → Chat-BAaQg-Oc.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-5jHkbotn.js → Checkbox-Dvn8uxKO.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-CpTSti2I.js → Codegen-CTcZCayj.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-C5SJSGcO.js → Col-CBFpGgb5.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-0PMz9hPX.js → Community-DmCYaV9M.js} +1 -1
  16. package/src/assets/web-panel/assets/Compact-DnOD5uMF.js +1 -0
  17. package/src/assets/web-panel/assets/{Compliance-BEVqh-i7.js → Compliance-u53e9lg-.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-C_UEYiR5.js → Cowork-CL5ohuXH.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cron-B4f0_E2W.js → Cron-DubcmRgt.js} +1 -1
  20. package/src/assets/web-panel/assets/{Crosschain-CZT6FKhl.js → Crosschain-BWXcUXc3.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-LDSJdg_E.js → DID-Cw0i8WjE.js} +1 -1
  22. package/src/assets/web-panel/assets/{Dashboard-CczHBzZy.js → Dashboard-BbofvIWH.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-KJXQPCdN.js → Dropdown-DN6ur5xV.js} +1 -1
  24. package/src/assets/web-panel/assets/Federation-CA-rIdkY.js +1 -0
  25. package/src/assets/web-panel/assets/{FormItemContext-CenKDKRv.js → FormItemContext-D_HGU4aA.js} +1 -1
  26. package/src/assets/web-panel/assets/{Git-Ck3yvIOj.js → Git-CBWFs6Uk.js} +1 -1
  27. package/src/assets/web-panel/assets/{Governance-C-Wqvp5q.js → Governance-Cx6PTC43.js} +1 -1
  28. package/src/assets/web-panel/assets/{Inference-D1Q4GQsE.js → Inference-Ubk1VstS.js} +1 -1
  29. package/src/assets/web-panel/assets/{KnowledgeGraph-6-id5kqA.js → KnowledgeGraph-DTB10MYO.js} +1 -1
  30. package/src/assets/web-panel/assets/{Logs-BIrBldyi.js → Logs-Tfk4FBVC.js} +1 -1
  31. package/src/assets/web-panel/assets/{Marketplace-DuEYH2k1.js → Marketplace-BAsztG4O.js} +1 -1
  32. package/src/assets/web-panel/assets/{McpTools-CJyrjpOa.js → McpTools-DliPfvuK.js} +1 -1
  33. package/src/assets/web-panel/assets/{Memory-25VBuGGA.js → Memory-hkw6Xwyv.js} +1 -1
  34. package/src/assets/web-panel/assets/{MobileBridge-DDepR_yK.js → MobileBridge-eeNMFGj6.js} +1 -1
  35. package/src/assets/web-panel/assets/{Mtc-B52jkX63.js → Mtc-BP3Riowm.js} +1 -1
  36. package/src/assets/web-panel/assets/{MtcAudit-BimrvH_0.js → MtcAudit-DvD7pE7V.js} +6 -6
  37. package/src/assets/web-panel/assets/Multisig-CPtc-fVL.js +7 -0
  38. package/src/assets/web-panel/assets/Multisig-kwPDnXnl.css +1 -0
  39. package/src/assets/web-panel/assets/{NLProgramming-D9sqtzgg.js → NLProgramming-1y__Epjg.js} +1 -1
  40. package/src/assets/web-panel/assets/{Notes-BtaoLR6l.js → Notes-CEvJqMP8.js} +1 -1
  41. package/src/assets/web-panel/assets/{NotificationSettings-DGc4Pnhc.js → NotificationSettings-wmCYm99r.js} +1 -1
  42. package/src/assets/web-panel/assets/{Organization-CH8YH1WC.js → Organization-CSoz8gGr.js} +1 -1
  43. package/src/assets/web-panel/assets/{Overflow-BEfCQNlN.js → Overflow-kf1mnFrM.js} +1 -1
  44. package/src/assets/web-panel/assets/{OverrideContext-DYxbd09I.js → OverrideContext-x9ZzjLwk.js} +1 -1
  45. package/src/assets/web-panel/assets/{P2P-Bp_HTJ00.js → P2P-C4GfXJ8Z.js} +1 -1
  46. package/src/assets/web-panel/assets/{Permissions-UHQF_4gL.js → Permissions-CW1Mn95X.js} +1 -1
  47. package/src/assets/web-panel/assets/{Pipeline-yCVADMbj.js → Pipeline-CM1ppddn.js} +1 -1
  48. package/src/assets/web-panel/assets/{Privacy-C1oNG_1P.js → Privacy-DuAY5fEm.js} +1 -1
  49. package/src/assets/web-panel/assets/{ProjectInit-DMW2d6Cb.js → ProjectInit-C72779b6.js} +2 -2
  50. package/src/assets/web-panel/assets/{ProjectSettings-5G8pJeC_.js → ProjectSettings-CAilXWam.js} +1 -1
  51. package/src/assets/web-panel/assets/Projects-0OrfK90x.css +1 -0
  52. package/src/assets/web-panel/assets/Projects-DTIlVTkF.js +1 -0
  53. package/src/assets/web-panel/assets/{Providers-CL_oE5tl.js → Providers-Cf6Yv8bu.js} +1 -1
  54. package/src/assets/web-panel/assets/{QuickAsk-BV38kJpn.js → QuickAsk-CK1_VVzw.js} +1 -1
  55. package/src/assets/web-panel/assets/{Recommend-SAj9Q6gO.js → Recommend-QBC7KgvR.js} +1 -1
  56. package/src/assets/web-panel/assets/{Reputation-1kCD0gaB.js → Reputation-ju6lWzMM.js} +1 -1
  57. package/src/assets/web-panel/assets/Row-DQwipGEm.js +1 -0
  58. package/src/assets/web-panel/assets/{RssFeed-CAJCjHjh.js → RssFeed-DkLGmeLW.js} +1 -1
  59. package/src/assets/web-panel/assets/{Search-cvcqK6k5.js → Search-YYhitzkt.js} +1 -1
  60. package/src/assets/web-panel/assets/{Security-CQg7wTKN.js → Security-DEllaBqe.js} +1 -1
  61. package/src/assets/web-panel/assets/{Services-CsUFvNqx.js → Services-BgPHBq9S.js} +2 -2
  62. package/src/assets/web-panel/assets/{Skeleton-xBd6cpeg.js → Skeleton-DHEyJI7c.js} +1 -1
  63. package/src/assets/web-panel/assets/{Skills-CaroVcXP.js → Skills-c212vgf3.js} +1 -1
  64. package/src/assets/web-panel/assets/{Sla-BtpCM7Ko.js → Sla-COqhw_no.js} +1 -1
  65. package/src/assets/web-panel/assets/{SpeechSettings-BqMJfygi.js → SpeechSettings-Bmds06su.js} +1 -1
  66. package/src/assets/web-panel/assets/{SyncSettings-CZouEnTT.js → SyncSettings-Bx1_A34Y.js} +1 -1
  67. package/src/assets/web-panel/assets/{Tasks-CXRSaKbt.js → Tasks-B0Lo_9aN.js} +1 -1
  68. package/src/assets/web-panel/assets/{Templates-DJY8TQ5i.js → Templates-D0RcpfuW.js} +1 -1
  69. package/src/assets/web-panel/assets/{Tenant-BvR-WVDe.js → Tenant-G0yVctLy.js} +1 -1
  70. package/src/assets/web-panel/assets/Terminal-DqgLtK3c.js +3 -0
  71. package/src/assets/web-panel/assets/Terminal-G1DrFtKr.css +1 -0
  72. package/src/assets/web-panel/assets/{Tokens-BvsTsita.js → Tokens-Cdt0aqCc.js} +1 -1
  73. package/src/assets/web-panel/assets/{Trigger-BpAXwpX5.js → Trigger-DFbfZFuJ.js} +1 -1
  74. package/src/assets/web-panel/assets/{Trust-CQn3-pr1.js → Trust-BQXsWPz6.js} +1 -1
  75. package/src/assets/web-panel/assets/{UkeySign-mdcVVgmW.js → UkeySign-DBem5Xkj.js} +1 -1
  76. package/src/assets/web-panel/assets/{VideoEditing-B64a6mxs.js → VideoEditing-B1yipKKv.js} +1 -1
  77. package/src/assets/web-panel/assets/{Wallet-CD6sh797.js → Wallet-iPJtU5QZ.js} +4 -4
  78. package/src/assets/web-panel/assets/{WebAuthn-CBMAhuJk.js → WebAuthn-HLb9srUL.js} +1 -1
  79. package/src/assets/web-panel/assets/{WorkflowEditor-BL2e4pEf.js → WorkflowEditor-BSqXL8GD.js} +1 -1
  80. package/src/assets/web-panel/assets/addon-fit-CK6X9sAG.js +1 -0
  81. package/src/assets/web-panel/assets/{chat-D0R75-Vf.js → chat-D_J-ZVBh.js} +1 -1
  82. package/src/assets/web-panel/assets/{collapseMotion-CZQhO80h.js → collapseMotion-CjFH_Jop.js} +1 -1
  83. package/src/assets/web-panel/assets/{colors-Z5R3KUYW.js → colors-B126JcB4.js} +1 -1
  84. package/src/assets/web-panel/assets/{compact-item-Buyen0aR.js → compact-item-Bw5EEKw4.js} +1 -1
  85. package/src/assets/web-panel/assets/{createContext-D9l1X-OX.js → createContext-xLJXI46O.js} +1 -1
  86. package/src/assets/web-panel/assets/{echarts-TwhxblyG.js → echarts-Bq-n0MtJ.js} +1 -1
  87. package/src/assets/web-panel/assets/{hasIn-DV4wtumO.js → hasIn-K8QCNlyy.js} +1 -1
  88. package/src/assets/web-panel/assets/{icons-Q99MnhG8.js → icons-NT6gy8Ee.js} +2 -2
  89. package/src/assets/web-panel/assets/{index--pPzkOu2.js → index-85lab9HJ.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-BSXvEQFS.js → index-B9ztiTnX.js} +1 -1
  91. package/src/assets/web-panel/assets/index-BEYypR_d.js +1 -0
  92. package/src/assets/web-panel/assets/{index-C4m8PjHn.js → index-BQ_NIMQS.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BAf0-ayI.js → index-BSgvvXgq.js} +2 -2
  94. package/src/assets/web-panel/assets/{index-RpJYGfg0.js → index-BWUG9yVI.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Cs7GKmFk.js → index-B_PqXUkT.js} +6 -6
  96. package/src/assets/web-panel/assets/index-BaXXyyT0.js +21 -0
  97. package/src/assets/web-panel/assets/index-Bptjq-wQ.js +1 -0
  98. package/src/assets/web-panel/assets/{index-CpemtT_B.js → index-BsbKjK1o.js} +2 -2
  99. package/src/assets/web-panel/assets/{index-Cs2QeQFi.js → index-Bv9odL87.js} +2 -2
  100. package/src/assets/web-panel/assets/{index-0P8ZPtKp.js → index-C2CgD7TN.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CprQ5h5e.js → index-COCq6xuZ.js} +1 -1
  102. package/src/assets/web-panel/assets/index-CVeuzjxG.js +55 -0
  103. package/src/assets/web-panel/assets/index-CWBajOcE.js +3 -0
  104. package/src/assets/web-panel/assets/{index-CT46jhtC.js → index-CvAey6iD.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Z-i_sfIN.js → index-DFPVNSby.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CoV9UGnc.js → index-DFwF_JeQ.js} +2 -2
  107. package/src/assets/web-panel/assets/{index-DO9gd9wz.js → index-DLZZi1Km.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BRWO_MUe.js → index-DY5Oc3z6.js} +4 -4
  109. package/src/assets/web-panel/assets/index-DZWfmuM2.js +1 -0
  110. package/src/assets/web-panel/assets/{index-CRvOaSuy.js → index-DZcij18m.js} +2 -2
  111. package/src/assets/web-panel/assets/{index-BLDanIEV.js → index-Da7bZewp.js} +1 -1
  112. package/src/assets/web-panel/assets/index-DdMzLeDn.js +1 -0
  113. package/src/assets/web-panel/assets/index-Dj8BNg-z.js +1 -0
  114. package/src/assets/web-panel/assets/index-DlX09aXr.js +1 -0
  115. package/src/assets/web-panel/assets/{index-CHs1Rtgi.js → index-DrfiELFa.js} +2 -2
  116. package/src/assets/web-panel/assets/{index-DMcK4Son.js → index-Dt0Tp8TS.js} +1 -1
  117. package/src/assets/web-panel/assets/index-DvNCyE3A.js +13 -0
  118. package/src/assets/web-panel/assets/{index-vSjbNv8F.js → index-LZYGhjVr.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-AXmFZTsT.js → index-fMwtau_-.js} +2 -2
  120. package/src/assets/web-panel/assets/{index-D_g5wyjB.js → index-mqHxeING.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DBBX0xZN.js → index-mzNWO8Yy.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-UAkLBWLE.js → index-p3d5_s7V.js} +2 -2
  123. package/src/assets/web-panel/assets/{index-BBFrPlY4.js → index-qJbfToeQ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DtRv6Tqv.js → index-sAfwWh0R.js} +8 -8
  125. package/src/assets/web-panel/assets/index-xJkPbv0L.js +12 -0
  126. package/src/assets/web-panel/assets/index-yhA-qP4Y.js +1 -0
  127. package/src/assets/web-panel/assets/index-zEr6BW9X.js +1 -0
  128. package/src/assets/web-panel/assets/{initDefaultProps-C5tyEoyp.js → initDefaultProps-CacwmJft.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-By5VpSMZ.js → motion-BWrP7Lz6.js} +2 -2
  130. package/src/assets/web-panel/assets/{move-CNRFLi9k.js → move-imnbiy1n.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-DYc7DRhT.js → omit-BlaOv91I.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-D667btUF.js → pickAttrs-DUGKp0ro.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-Ce-Y2-Qq.js → placementArrow-P0ZA4yAK.js} +1 -1
  134. package/src/assets/web-panel/assets/responsiveObserve-CZz-M9cI.js +1 -0
  135. package/src/assets/web-panel/assets/{slide-CyKGKfJ8.js → slide-BEnICwoX.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-DffXAKmJ.js → statusUtils-DdYKRSiH.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-CeeSLisW.js → styleChecker-DgUxvOQt.js} +1 -1
  138. package/src/assets/web-panel/assets/useFlexGapSupport-BUEmeWdR.js +1 -0
  139. package/src/assets/web-panel/assets/{useFs--Vkrwu51.js → useFs-BXsj6Z5e.js} +1 -1
  140. package/src/assets/web-panel/assets/{useMergedState-D3PX36GT.js → useMergedState-O7QXt4P5.js} +1 -1
  141. package/src/assets/web-panel/assets/{useRefs-opfcK7Pm.js → useRefs-0J6m8UWN.js} +1 -1
  142. package/src/assets/web-panel/assets/{useState-Cp5WlLTS.js → useState-CSzR8F8O.js} +1 -1
  143. package/src/assets/web-panel/assets/{vendor-BVLz_z7V.js → vendor-M5lGV-wr.js} +1 -1
  144. package/src/assets/web-panel/assets/{vnode-ChnNrJNw.js → vnode-B3Pp583L.js} +1 -1
  145. package/src/assets/web-panel/assets/xterm-BZcWGsqw.js +9 -0
  146. package/src/assets/web-panel/assets/xterm-DFuMZ0ql.css +1 -0
  147. package/src/assets/web-panel/assets/{zoom-DE1Teifl.js → zoom-D-LYfiQh.js} +1 -1
  148. package/src/assets/web-panel/index.html +3 -3
  149. package/src/commands/crosschain.js +403 -1
  150. package/src/commands/pair.js +291 -0
  151. package/src/gateways/terminal/PtyManager.js +248 -0
  152. package/src/gateways/terminal/RingBuffer.js +61 -0
  153. package/src/gateways/terminal/terminal-handlers.js +121 -0
  154. package/src/gateways/ws/topic-handler-attachment.js +211 -0
  155. package/src/index.js +2 -0
  156. package/src/lib/cross-chain-mtc.js +275 -6
  157. package/src/lib/cross-chain.js +48 -2
  158. package/src/lib/lan-pairing-preflight.js +425 -0
  159. package/src/lib/lan-pairing-tokens.js +264 -0
  160. package/src/runtime/agent-runtime.js +33 -0
  161. package/src/assets/web-panel/assets/AppLayout-CrQBcjC1.js +0 -3
  162. package/src/assets/web-panel/assets/BaseInput-CQSPRZVh.js +0 -1
  163. package/src/assets/web-panel/assets/Compact-CwrJK_94.js +0 -1
  164. package/src/assets/web-panel/assets/Federation-Bu085RVF.js +0 -1
  165. package/src/assets/web-panel/assets/Multisig-D-IuEDLa.css +0 -1
  166. package/src/assets/web-panel/assets/Multisig-DWsGuuyz.js +0 -1
  167. package/src/assets/web-panel/assets/Projects-BpLpgCga.js +0 -1
  168. package/src/assets/web-panel/assets/Projects-C34BWmmy.css +0 -1
  169. package/src/assets/web-panel/assets/Row-CUF6ofec.js +0 -1
  170. package/src/assets/web-panel/assets/index-BBvRNeKy.js +0 -1
  171. package/src/assets/web-panel/assets/index-BJzerWCW.js +0 -1
  172. package/src/assets/web-panel/assets/index-BbZ_pXN3.js +0 -1
  173. package/src/assets/web-panel/assets/index-BloaIh8i.js +0 -1
  174. package/src/assets/web-panel/assets/index-C1u_F_WR.js +0 -12
  175. package/src/assets/web-panel/assets/index-CHPsWSeL.js +0 -1
  176. package/src/assets/web-panel/assets/index-CLk9-Adx.js +0 -13
  177. package/src/assets/web-panel/assets/index-Cyal1Os0.js +0 -1
  178. package/src/assets/web-panel/assets/index-DYq0yh8a.js +0 -1
  179. package/src/assets/web-panel/assets/index-KvlSpGws.js +0 -21
  180. package/src/assets/web-panel/assets/index-WbY1RGjg.js +0 -3
  181. package/src/assets/web-panel/assets/index-cTf60nCj.js +0 -1
  182. package/src/assets/web-panel/assets/index-ry4j00pG.js +0 -55
  183. package/src/assets/web-panel/assets/responsiveObserve-BzzJzAds.js +0 -1
  184. package/src/assets/web-panel/assets/useFlexGapSupport-CCzODKgI.js +0 -1
@@ -0,0 +1 @@
1
+ .xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;inset:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;inset:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}
@@ -1,4 +1,4 @@
1
- import{K as o}from"./index-BRWO_MUe.js";import{i as f}from"./motion-By5VpSMZ.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
1
+ import{K as o}from"./index-DY5Oc3z6.js";import{i as f}from"./motion-BWrP7Lz6.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
2
2
  ${t}-enter,
3
3
  ${t}-appear
4
4
  `]:{transform:"scale(0)",opacity:0,animationTimingFunction:n.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${t}-leave`]:{animationTimingFunction:n.motionEaseInOutCirc}}]};export{h as i,c as z};
@@ -8,9 +8,9 @@
8
8
  // Injected by web-ui-server.js at serve time
9
9
  window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
10
10
  </script>
11
- <script type="module" crossorigin src="./assets/index-BRWO_MUe.js"></script>
12
- <link rel="modulepreload" crossorigin href="./assets/vendor-BVLz_z7V.js">
13
- <link rel="modulepreload" crossorigin href="./assets/icons-Q99MnhG8.js">
11
+ <script type="module" crossorigin src="./assets/index-DY5Oc3z6.js"></script>
12
+ <link rel="modulepreload" crossorigin href="./assets/vendor-M5lGV-wr.js">
13
+ <link rel="modulepreload" crossorigin href="./assets/icons-NT6gy8Ee.js">
14
14
  <link rel="stylesheet" crossorigin href="./assets/index-CfX1DEtk.css">
15
15
  </head>
16
16
  <body>
@@ -1,5 +1,10 @@
1
1
  /**
2
2
  * `cc crosschain` — CLI surface for Phase 89 Cross-Chain Interoperability.
3
+ *
4
+ * #21 B.5 Layer 1 PR1 (2026-05-15): `cc crosschain bridge --require-multisig`
5
+ * opt-in routes outbound bridge through m-of-n multisig (domain
6
+ * `crosschain.bridge.outbound`); `cc crosschain bridge-consume <proposalId>`
7
+ * finalizes after threshold is reached. Mirrors marketplace purchase/consume.
3
8
  */
4
9
 
5
10
  import fs from "node:fs";
@@ -8,6 +13,14 @@ import { Command } from "commander";
8
13
 
9
14
  import { bootstrap } from "../runtime/bootstrap.js";
10
15
  import { getHomeDir } from "../lib/paths.js";
16
+ import {
17
+ openMultisigManager,
18
+ defaultMultisigDbPath,
19
+ defaultMultisigLogPath,
20
+ readSecretKey,
21
+ } from "../lib/multisig-runtime.js";
22
+
23
+ const MULTISIG_BRIDGE_OUTBOUND_DOMAIN = "crosschain.bridge.outbound";
11
24
  import {
12
25
  getCrossChainMtcDir,
13
26
  getBridgeMtcStatus,
@@ -111,6 +124,299 @@ function _maybeStageMtc(opts, opBuilder) {
111
124
  }
112
125
  }
113
126
 
127
+ /**
128
+ * #21 B.5 Layer 1 — open a multisig proposal for an outbound bridge.
129
+ * Does NOT insert into cc_bridges yet; bridge-consume does that after
130
+ * the proposal reaches threshold. Mirrors marketplace.purchase.
131
+ */
132
+ async function _bridgePropose({
133
+ fromChain,
134
+ toChain,
135
+ amount,
136
+ asset,
137
+ sender,
138
+ recipient,
139
+ initiator,
140
+ alg,
141
+ key,
142
+ multisigDb,
143
+ multisigLog,
144
+ json,
145
+ }) {
146
+ if (!initiator) {
147
+ const out = {
148
+ status: "blocked",
149
+ reason: "missing_initiator",
150
+ path: "multisig",
151
+ };
152
+ if (json) console.log(JSON.stringify(out, null, 2));
153
+ else
154
+ console.error(
155
+ "✗ --initiator <did> required when --require-multisig is set",
156
+ );
157
+ process.exitCode = 2;
158
+ return out;
159
+ }
160
+ if (!key) {
161
+ const out = {
162
+ status: "blocked",
163
+ reason: "missing_key",
164
+ path: "multisig",
165
+ };
166
+ if (json) console.log(JSON.stringify(out, null, 2));
167
+ else
168
+ console.error(
169
+ "✗ --key <hex|path> required when --require-multisig is set",
170
+ );
171
+ process.exitCode = 2;
172
+ return out;
173
+ }
174
+
175
+ const { store, mgr, close } = await openMultisigManager(
176
+ multisigDb,
177
+ multisigLog,
178
+ );
179
+ try {
180
+ const policy = store.getPolicy(MULTISIG_BRIDGE_OUTBOUND_DOMAIN);
181
+ if (!policy) {
182
+ const out = {
183
+ status: "blocked",
184
+ reason: "no_policy",
185
+ path: "multisig",
186
+ domain: MULTISIG_BRIDGE_OUTBOUND_DOMAIN,
187
+ };
188
+ if (json) console.log(JSON.stringify(out, null, 2));
189
+ else
190
+ console.error(
191
+ `✗ No multisig policy for domain "${MULTISIG_BRIDGE_OUTBOUND_DOMAIN}". Run: cc multisig policy set ${MULTISIG_BRIDGE_OUTBOUND_DOMAIN} --m <M> --members <json>`,
192
+ );
193
+ process.exitCode = 2;
194
+ return out;
195
+ }
196
+
197
+ const secretKey = readSecretKey(key);
198
+ const payload = {
199
+ fromChain,
200
+ toChain,
201
+ asset: asset || "native",
202
+ amount,
203
+ sender: sender || null,
204
+ recipient: recipient || null,
205
+ };
206
+ const result = mgr.propose({
207
+ domain: MULTISIG_BRIDGE_OUTBOUND_DOMAIN,
208
+ payload,
209
+ policy,
210
+ initiator: { did: initiator, alg: alg || "Ed25519", secretKey },
211
+ });
212
+ const out = {
213
+ status: "needs_co_sign",
214
+ path: "multisig",
215
+ proposalId: result.proposal.id,
216
+ reachedThreshold: result.reachedThreshold,
217
+ requiredSigs: policy.m,
218
+ memberCount: policy.members.length,
219
+ payload,
220
+ };
221
+ if (json) {
222
+ console.log(JSON.stringify(out, null, 2));
223
+ } else {
224
+ console.log(
225
+ `↪ Routed through multisig (domain ${MULTISIG_BRIDGE_OUTBOUND_DOMAIN})`,
226
+ );
227
+ console.log(` proposalId: ${result.proposal.id}`);
228
+ console.log(` needs ${policy.m} of ${policy.members.length} signatures`);
229
+ if (result.reachedThreshold)
230
+ console.log(
231
+ ` ✓ threshold reached on first signature — run: cc crosschain bridge-consume ${result.proposal.id}`,
232
+ );
233
+ }
234
+ return out;
235
+ } finally {
236
+ close();
237
+ }
238
+ }
239
+
240
+ /**
241
+ * #21 B.5 Layer 1 — finalize an outbound bridge after multisig threshold.
242
+ * Reads the proposal's payload, executes the actual bridgeAsset() insert,
243
+ * then marks the proposal consumed. Mirrors marketplace.consume.
244
+ *
245
+ * PR4 — when `mtc=true`, additionally stage the bridge op with multisig
246
+ * provenance via `_maybeStageMtc` so closeBatch carries it into the MTC
247
+ * envelope leaf (and downstream wrapper attachment / Layer 3 broadcast).
248
+ */
249
+ async function _bridgeConsume({
250
+ db,
251
+ proposalId,
252
+ multisigDb,
253
+ multisigLog,
254
+ json,
255
+ mtc,
256
+ mtcConfigDir,
257
+ }) {
258
+ const { mgr, close } = await openMultisigManager(multisigDb, multisigLog);
259
+ try {
260
+ const got = mgr.get(proposalId);
261
+ if (!got) {
262
+ const out = { status: "error", reason: "proposal_not_found" };
263
+ if (json) console.log(JSON.stringify(out, null, 2));
264
+ else console.error(`✗ No proposal: ${proposalId}`);
265
+ process.exitCode = 2;
266
+ return out;
267
+ }
268
+ if (got.proposal.domain !== MULTISIG_BRIDGE_OUTBOUND_DOMAIN) {
269
+ const out = {
270
+ status: "error",
271
+ reason: "wrong_domain",
272
+ expected: MULTISIG_BRIDGE_OUTBOUND_DOMAIN,
273
+ actual: got.proposal.domain,
274
+ };
275
+ if (json) console.log(JSON.stringify(out, null, 2));
276
+ else
277
+ console.error(
278
+ `✗ Proposal domain "${got.proposal.domain}" is not "${MULTISIG_BRIDGE_OUTBOUND_DOMAIN}" — use the matching consume command for that domain instead.`,
279
+ );
280
+ process.exitCode = 2;
281
+ return out;
282
+ }
283
+ if (got.proposal.state !== "reached") {
284
+ const out = {
285
+ status: "error",
286
+ reason: `proposal_state_${got.proposal.state}`,
287
+ };
288
+ if (json) console.log(JSON.stringify(out, null, 2));
289
+ else
290
+ console.error(
291
+ `✗ Proposal state is "${got.proposal.state}", need "reached" — sign more before consume.`,
292
+ );
293
+ process.exitCode = 2;
294
+ return out;
295
+ }
296
+
297
+ const payload = JSON.parse(got.proposal.payloadJcs);
298
+
299
+ // #21 B.5 Layer 2 PR1 — extract m-of-n provenance from the reached
300
+ // proposal and persist it alongside the bridge row. signatures are
301
+ // returned sorted by signer_did ASC (store.getSignatures), so the array
302
+ // ordering is canonical for any downstream onchain verifier.
303
+ const signatures = got.signatures || [];
304
+ // PR4 adds thresholdM + memberCountN so the carry-forward MTC staging
305
+ // can build the canonical multisig_provenance shape required by
306
+ // attachMultisigProvenance / verifyMultisigProvenance.
307
+ const multisigContext = {
308
+ proposalId: got.proposal.id,
309
+ thresholdM: got.proposal.thresholdM,
310
+ memberCountN: Array.isArray(got.proposal.memberSet)
311
+ ? got.proposal.memberSet.length
312
+ : signatures.length,
313
+ signers: signatures.map((s) => s.signerDid),
314
+ partialSigs: signatures.map((s) => ({
315
+ did: s.signerDid,
316
+ alg: s.alg,
317
+ sig: Buffer.isBuffer(s.sig) ? s.sig.toString("hex") : String(s.sig),
318
+ })),
319
+ };
320
+
321
+ const bridgeResult = bridgeAsset(
322
+ db,
323
+ {
324
+ fromChain: payload.fromChain,
325
+ toChain: payload.toChain,
326
+ asset: payload.asset,
327
+ amount: payload.amount,
328
+ senderAddress: payload.sender,
329
+ recipientAddress: payload.recipient,
330
+ },
331
+ multisigContext,
332
+ );
333
+ if (!bridgeResult.bridgeId) {
334
+ const out = {
335
+ status: "error",
336
+ reason: `bridge_insert_failed_${bridgeResult.reason}`,
337
+ proposalId,
338
+ };
339
+ if (json) console.log(JSON.stringify(out, null, 2));
340
+ else
341
+ console.error(
342
+ `✗ Bridge insert failed: ${bridgeResult.reason} — proposal left in "reached" state`,
343
+ );
344
+ process.exitCode = 1;
345
+ return out;
346
+ }
347
+ const finalizeRes = mgr.finalize(proposalId);
348
+ if (!finalizeRes.ok) {
349
+ const out = {
350
+ status: "error",
351
+ reason: finalizeRes.reason,
352
+ proposalId,
353
+ bridgeId: bridgeResult.bridgeId,
354
+ };
355
+ if (json) console.log(JSON.stringify(out, null, 2));
356
+ else
357
+ console.error(
358
+ `✗ Finalize failed: ${finalizeRes.reason} (bridge row ${bridgeResult.bridgeId} already inserted)`,
359
+ );
360
+ process.exitCode = 1;
361
+ return out;
362
+ }
363
+
364
+ // PR4 — opt-in MTC staging carries the multisig provenance forward into
365
+ // closeBatch / wrapper envelope. Same `_maybeStageMtc` helper as the
366
+ // legacy direct-bridge path, just with an enriched op shape including
367
+ // the canonical `multisig_provenance` field.
368
+ const mtcStaged = _maybeStageMtc({ mtc, mtcConfigDir }, () => ({
369
+ bridge_op: "lock",
370
+ src_chain: payload.fromChain,
371
+ dst_chain: payload.toChain,
372
+ src_tx_hash: bridgeResult.bridgeId,
373
+ amount: String(payload.amount),
374
+ asset: payload.asset || "native",
375
+ src_did: payload.sender || null,
376
+ dst_did: payload.recipient || null,
377
+ issued_at: new Date().toISOString(),
378
+ multisig_provenance: {
379
+ proposal_id: multisigContext.proposalId,
380
+ threshold_m: multisigContext.thresholdM,
381
+ member_count_n: multisigContext.memberCountN,
382
+ signers: multisigContext.signers,
383
+ partial_sigs: multisigContext.partialSigs,
384
+ },
385
+ }));
386
+
387
+ const out = {
388
+ status: "consumed",
389
+ proposalId,
390
+ bridgeId: bridgeResult.bridgeId,
391
+ fee: bridgeResult.fee,
392
+ payload,
393
+ // Layer 2 provenance — surface what was persisted on the bridge row.
394
+ signers: multisigContext.signers,
395
+ partialSigCount: multisigContext.partialSigs.length,
396
+ // PR4 — surface MTC staging result when --mtc was passed.
397
+ mtc: mtcStaged,
398
+ };
399
+ if (json) {
400
+ console.log(JSON.stringify(out, null, 2));
401
+ } else {
402
+ console.log(
403
+ `✓ Bridge consumed — ${payload.fromChain} → ${payload.toChain}, amount ${payload.amount} ${payload.asset}`,
404
+ );
405
+ console.log(
406
+ ` bridgeId: ${bridgeResult.bridgeId} (fee ${bridgeResult.fee})`,
407
+ );
408
+ console.log(` proposalId: ${proposalId}`);
409
+ if (mtcStaged?.staged)
410
+ console.log(` MTC envelope staged: ${mtcStaged.path}`);
411
+ else if (mtcStaged && !mtcStaged.staged)
412
+ console.log(` MTC stage skipped: ${mtcStaged.reason}`);
413
+ }
414
+ return out;
415
+ } finally {
416
+ close();
417
+ }
418
+ }
419
+
114
420
  export function registerCrossChainCommand(program) {
115
421
  const cc = new Command("crosschain")
116
422
  .description("Cross-chain interoperability (Phase 89)")
@@ -174,9 +480,49 @@ export function registerCrossChainCommand(program) {
174
480
  "On success, stage an MTC bridge envelope (requires cc crosschain mtc-batch to close)",
175
481
  )
176
482
  .option("--mtc-config-dir <dir>", "Override MTC config root")
483
+ .option(
484
+ "--require-multisig",
485
+ "Route through m-of-n multisig (domain crosschain.bridge.outbound). Requires --initiator + --key + policy set.",
486
+ )
487
+ .option(
488
+ "--initiator <did>",
489
+ "Initiator DID for multisig proposal (required when --require-multisig)",
490
+ )
491
+ .option("--alg <alg>", "Initiator signing alg", "Ed25519")
492
+ .option(
493
+ "--key <hex|path>",
494
+ "Initiator secret key hex or path to hex file (required when --require-multisig)",
495
+ )
496
+ .option(
497
+ "--multisig-db <path>",
498
+ "Multisig SQLite DB path (default ~/.chainlesschain/multisig.db)",
499
+ )
500
+ .option(
501
+ "--multisig-log <path>",
502
+ "Multisig governance log path (default ~/.chainlesschain/multisig.governance.log)",
503
+ )
177
504
  .option("--json", "JSON output")
178
- .action((fromChain, toChain, amount, opts) => {
505
+ .action(async (fromChain, toChain, amount, opts) => {
179
506
  const db = _dbFromCtx(cc);
507
+
508
+ if (opts.requireMultisig) {
509
+ return _bridgePropose({
510
+ db,
511
+ fromChain,
512
+ toChain,
513
+ amount: parseFloat(amount),
514
+ asset: opts.asset,
515
+ sender: opts.sender,
516
+ recipient: opts.recipient,
517
+ initiator: opts.initiator,
518
+ alg: opts.alg,
519
+ key: opts.key,
520
+ multisigDb: opts.multisigDb || defaultMultisigDbPath(),
521
+ multisigLog: opts.multisigLog || defaultMultisigLogPath(),
522
+ json: opts.json,
523
+ });
524
+ }
525
+
180
526
  const result = bridgeAsset(db, {
181
527
  fromChain,
182
528
  toChain,
@@ -208,6 +554,37 @@ export function registerCrossChainCommand(program) {
208
554
  console.log(`MTC stage skipped: ${mtc.reason}`);
209
555
  });
210
556
 
557
+ cc.command("bridge-consume <proposalId>")
558
+ .description(
559
+ "Finalize a multisig-gated bridge after threshold reached — performs the SQLite insert and marks proposal consumed",
560
+ )
561
+ .option(
562
+ "--multisig-db <path>",
563
+ "Multisig SQLite DB path (default ~/.chainlesschain/multisig.db)",
564
+ )
565
+ .option(
566
+ "--multisig-log <path>",
567
+ "Multisig governance log path (default ~/.chainlesschain/multisig.governance.log)",
568
+ )
569
+ .option(
570
+ "--mtc",
571
+ "On success, stage an MTC bridge envelope carrying the multisig provenance (requires cc crosschain mtc-batch to close)",
572
+ )
573
+ .option("--mtc-config-dir <dir>", "Override MTC config root")
574
+ .option("--json", "JSON output")
575
+ .action(async (proposalId, opts) => {
576
+ const db = _dbFromCtx(cc);
577
+ return _bridgeConsume({
578
+ db,
579
+ proposalId,
580
+ multisigDb: opts.multisigDb || defaultMultisigDbPath(),
581
+ multisigLog: opts.multisigLog || defaultMultisigLogPath(),
582
+ json: opts.json,
583
+ mtc: opts.mtc,
584
+ mtcConfigDir: opts.mtcConfigDir,
585
+ });
586
+ });
587
+
211
588
  cc.command("bridge-status <bridge-id> <status>")
212
589
  .description("Update bridge status")
213
590
  .option("-t, --tx-hash <hash>", "Transaction hash")
@@ -242,6 +619,31 @@ export function registerCrossChainCommand(program) {
242
619
  if (b.lock_tx_hash) console.log(`Lock TX: ${b.lock_tx_hash}`);
243
620
  if (b.mint_tx_hash) console.log(`Mint TX: ${b.mint_tx_hash}`);
244
621
  if (b.error_message) console.log(`Error: ${b.error_message}`);
622
+ // #21 B.5 Layer 2 PR1 — surface m-of-n provenance when present.
623
+ if (b.multisig_proposal_id) {
624
+ console.log(`Multisig: ${b.multisig_proposal_id}`);
625
+ try {
626
+ const signers = b.signers_did_json
627
+ ? JSON.parse(b.signers_did_json)
628
+ : [];
629
+ const sigs = b.partial_sigs_json
630
+ ? JSON.parse(b.partial_sigs_json)
631
+ : [];
632
+ console.log(
633
+ `Signers: ${signers.length} — ${signers.join(", ") || "(none)"}`,
634
+ );
635
+ if (sigs.length) {
636
+ const algs = [...new Set(sigs.map((s) => s.alg))].join("+");
637
+ console.log(`Sigs: ${sigs.length} partial (${algs})`);
638
+ }
639
+ } catch (_err) {
640
+ /* malformed provenance JSON — show raw cell content */
641
+ if (b.signers_did_json)
642
+ console.log(`Signers: ${b.signers_did_json}`);
643
+ if (b.partial_sigs_json)
644
+ console.log(`Sigs: ${b.partial_sigs_json}`);
645
+ }
646
+ }
245
647
  });
246
648
 
247
649
  cc.command("bridges")