chainlesschain 0.162.150 → 0.162.151

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 (164) hide show
  1. package/README.md +1 -1
  2. package/package.json +3 -2
  3. package/src/assets/web-panel/assets/{AIOps-CBLvrjeG.js → AIOps-DuEOzebi.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DYv2GtE0.js → ActionButton-C6GiJa5H.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CL6PZ-Ww.js → Analytics-BBIiL_pO.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-xuyHt4uA.js → AppLayout-CuI2gZRy.js} +3 -3
  7. package/src/assets/web-panel/assets/{Audit-DOvSVycq.js → Audit-CbUjfr-K.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-DMhfTswr.js → Backup-CsSW9ljf.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-CQxDdm63.js → BaseInput-kM3rLe7F.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-BEeNhK2a.js → Chat-kfE51YN3.js} +5 -5
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-8nul8eTq.js → ChatBubbleRenderer-Bg2FTW6A.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-CL04O-ER.js → Checkbox-jYb1uj-M.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-C50o-n7x.js → Codegen-X9XiD5Lj.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-CH-bDkzs.js → Col-BfbHu1xI.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-DqAIMvSe.js → Community-c4oJMFS-.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-C43fo_my.js → Compact-BFmnZpH7.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-BERnMrdP.js → Compliance-s9shVHBS.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-Baw3w1gp.js → Cowork-C5da--TC.js} +4 -4
  19. package/src/assets/web-panel/assets/{Cron-BEqAHF1-.js → Cron-9kNbyNE4.js} +2 -2
  20. package/src/assets/web-panel/assets/{Crosschain-CvnmKwK4.js → Crosschain-C1k3NJD4.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-iMPxgVdt.js → DID-DkheEvNK.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dashboard--4SJX3YR.js → Dashboard-C3FuSGmJ.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-BgLV6xgz.js → Dropdown-CAV6FMFD.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-Bvb8oUD8.js → EmailListRenderer-Cc-Ulc4l.js} +1 -1
  25. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DpXPjJB5.js → FamilyGuardDashboard-8CitHEtv.js} +1 -1
  26. package/src/assets/web-panel/assets/{Federation-BbFfJ1Xi.js → Federation-DFSZ5KDt.js} +1 -1
  27. package/src/assets/web-panel/assets/{FormItemContext-DeGq1B-q.js → FormItemContext-CEWCtnG2.js} +1 -1
  28. package/src/assets/web-panel/assets/{GenericCardRenderer-CNW7s9zM.js → GenericCardRenderer-CwRzNzmX.js} +1 -1
  29. package/src/assets/web-panel/assets/{Git-L1PjW-lT.js → Git-0rgDM7cJ.js} +2 -2
  30. package/src/assets/web-panel/assets/{Governance-PK-X58to.js → Governance-CfBKtK9F.js} +1 -1
  31. package/src/assets/web-panel/assets/{Inference-BePWEH-d.js → Inference-CzcUVvud.js} +1 -1
  32. package/src/assets/web-panel/assets/{KnowledgeGraph-LF_sBvdL.js → KnowledgeGraph-Dwc4YL4A.js} +1 -1
  33. package/src/assets/web-panel/assets/{Logs-BKkfk9hy.js → Logs-DgFPwR2F.js} +2 -2
  34. package/src/assets/web-panel/assets/{Marketplace-BNMqUDla.js → Marketplace-DnpPTbGU.js} +1 -1
  35. package/src/assets/web-panel/assets/{McpTools-w4WPiyz2.js → McpTools-DRxxINyW.js} +5 -5
  36. package/src/assets/web-panel/assets/{Memory-DUKMVGNi.js → Memory-OhmW_6Z3.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileBridge-BWhiEyTJ.js → MobileBridge-DkTW-RK5.js} +1 -1
  38. package/src/assets/web-panel/assets/{MobileProjects-Ocf5JEkX.js → MobileProjects-DpCGV_lI.js} +1 -1
  39. package/src/assets/web-panel/assets/{Mtc-D2B6MMhU.js → Mtc--vmkL0AS.js} +4 -4
  40. package/src/assets/web-panel/assets/{MtcAudit-DdYjCq1O.js → MtcAudit-DGoFWjD4.js} +4 -4
  41. package/src/assets/web-panel/assets/{Multisig-Cb1hfuUZ.js → Multisig-B4kWgq95.js} +3 -3
  42. package/src/assets/web-panel/assets/{NLProgramming-CTeImGp7.js → NLProgramming-YQwvommE.js} +1 -1
  43. package/src/assets/web-panel/assets/{Notes-BjYNc7eQ.js → Notes-CgjtUADJ.js} +4 -4
  44. package/src/assets/web-panel/assets/{NotificationSettings-Dn_NtRXQ.js → NotificationSettings-6JDrpBG5.js} +1 -1
  45. package/src/assets/web-panel/assets/{OrderTableRenderer-DVYYIizh.js → OrderTableRenderer-PM6IlxjO.js} +1 -1
  46. package/src/assets/web-panel/assets/{Organization-Be2Kmr5j.js → Organization-8McOT_OF.js} +4 -4
  47. package/src/assets/web-panel/assets/{Overflow-Cu_-qRlR.js → Overflow-DAZpSCGc.js} +1 -1
  48. package/src/assets/web-panel/assets/{P2P-DD2HoGzE.js → P2P-B7l2ZWLy.js} +2 -2
  49. package/src/assets/web-panel/assets/{PdhVaultBrowser-BRI7DVth.js → PdhVaultBrowser-W1Ud-NAL.js} +3 -3
  50. package/src/assets/web-panel/assets/{Permissions-C9Srcs2M.js → Permissions-Czm_w9u_.js} +4 -4
  51. package/src/assets/web-panel/assets/{PersonalDataHub-CUqcMgo1.js → PersonalDataHub-B4F0_ZVM.js} +3 -3
  52. package/src/assets/web-panel/assets/{Pipeline-HBrQGLXt.js → Pipeline-B37aFiWv.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-D-B0vjwh.js → Privacy-94KBnRrD.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-eTeLIu9e.js → ProjectInit-B5h8_dlh.js} +2 -2
  55. package/src/assets/web-panel/assets/{ProjectSettings-DrRqCsC6.js → ProjectSettings-lmeI3Lpm.js} +2 -2
  56. package/src/assets/web-panel/assets/{Projects-1G9DNOhI.js → Projects-D5AYOasl.js} +1 -1
  57. package/src/assets/web-panel/assets/{Providers-RkTZzpxP.js → Providers-B3cNWwJg.js} +1 -1
  58. package/src/assets/web-panel/assets/{QrScannerModal-BSCUgsgC.js → QrScannerModal-CHRvOw1R.js} +1 -1
  59. package/src/assets/web-panel/assets/{QuickAsk-CHgyM3Bz.js → QuickAsk-D1JMgFEd.js} +1 -1
  60. package/src/assets/web-panel/assets/{Recommend-0lry4OZq.js → Recommend-EYWGR79p.js} +1 -1
  61. package/src/assets/web-panel/assets/{RemoteSession-Cn45UroZ.js → RemoteSession-BAMC2pJt.js} +2 -2
  62. package/src/assets/web-panel/assets/{Reputation-Q-Zjb707.js → Reputation-X2Hk1XG_.js} +1 -1
  63. package/src/assets/web-panel/assets/{Row-BdM70oda.js → Row-Eq98LRtU.js} +1 -1
  64. package/src/assets/web-panel/assets/{RssFeed-DmOAKKap.js → RssFeed-i76s6z_o.js} +2 -2
  65. package/src/assets/web-panel/assets/{Search-Dwavbm07.js → Search-D_Es7CAI.js} +1 -1
  66. package/src/assets/web-panel/assets/{Security-DukXFCnk.js → Security-kayD2e94.js} +3 -3
  67. package/src/assets/web-panel/assets/{Services-BIlRnITu.js → Services-Ctsm6ul8.js} +2 -2
  68. package/src/assets/web-panel/assets/{Skeleton-YYVQdhhQ.js → Skeleton-CRNYlfdf.js} +1 -1
  69. package/src/assets/web-panel/assets/{Skills-B8_iYHz2.js → Skills-DkZYpF4-.js} +1 -1
  70. package/src/assets/web-panel/assets/{Sla-BdVrhT31.js → Sla-DXkoBcOP.js} +1 -1
  71. package/src/assets/web-panel/assets/{SpeechSettings-CD3ggRx7.js → SpeechSettings-DXi_GI1d.js} +1 -1
  72. package/src/assets/web-panel/assets/{SyncSettings-Bp02VZFH.js → SyncSettings-rNKpfomn.js} +2 -2
  73. package/src/assets/web-panel/assets/{Tasks-DEVmCEsr.js → Tasks-XF4uPtG-.js} +1 -1
  74. package/src/assets/web-panel/assets/{Templates-B6czWc4N.js → Templates-i0Hzfeyu.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tenant-BCJLv17r.js → Tenant-sMpHAi27.js} +1 -1
  76. package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +3 -0
  77. package/src/assets/web-panel/assets/{TimelineRenderer-ZB-CvkZl.js → TimelineRenderer-yuC6K7Rf.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tokens-BnSY0S-s.js → Tokens-B8O8i0s6.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trigger-VZw9Oy2w.js → Trigger-Bv6yrlCr.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trust-pZq7Hjd2.js → Trust-C4mW95Ev.js} +1 -1
  81. package/src/assets/web-panel/assets/{UkeySign-DnQaqk4q.js → UkeySign-DV6yKaHn.js} +1 -1
  82. package/src/assets/web-panel/assets/{VideoEditing-BEUfmvJV.js → VideoEditing-UI479-sD.js} +1 -1
  83. package/src/assets/web-panel/assets/{Wallet-CoZKMXJ2.js → Wallet-M5oV9EVP.js} +4 -4
  84. package/src/assets/web-panel/assets/{WebAuthn-CBOGVx1I.js → WebAuthn-DDyDHPDR.js} +5 -5
  85. package/src/assets/web-panel/assets/{WorkflowEditor-huSKn7TT.js → WorkflowEditor-RoBv4rqk.js} +1 -1
  86. package/src/assets/web-panel/assets/{chat-A_3w6FBO.js → chat-Cw1mE5LS.js} +1 -1
  87. package/src/assets/web-panel/assets/{colors-D1Bem9Oy.js → colors-BFP62Gwf.js} +1 -1
  88. package/src/assets/web-panel/assets/{compact-item-CJYJj0oO.js → compact-item-17HL6pyC.js} +1 -1
  89. package/src/assets/web-panel/assets/{createContext-BkbFiKT4.js → createContext-D55X4fZX.js} +1 -1
  90. package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +1 -0
  91. package/src/assets/web-panel/assets/{hasIn-CKvUafVY.js → hasIn-D3E5mNsP.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-CVS8Ymuq.js → index--44J50mc.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-qNTtOVi_.js → index-ASPYTzMK.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DpW9cf3e.js → index-BC6zxOlU.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BSgWxAOG.js → index-BEa1RW4c.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DjYrecNb.js → index-BQmZg5si.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-B8i0lViZ.js → index-BY_xZ2jy.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DfgCdFrN.js → index-BgN5G5vF.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-ChkXUj3f.js → index-BnGpft-Z.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BHdHSX06.js → index-Bq83UBDr.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C9bWmTcO.js → index-Bzpp2z2S.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-ttDQVhZy.js → index-CFYGn88j.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-C37f6iey.js → index-CGyTos4p.js} +1 -1
  104. package/src/assets/web-panel/assets/index-CKBI1U5K.js +1 -0
  105. package/src/assets/web-panel/assets/{index-By5a0T_W.js → index-CLEzsZ8A.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CBlBVJ_m.js → index-CR9rNUvi.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BiDWxzbn.js → index-CW6LLoJO.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Cj0OZ-37.js → index-C_MfcrLf.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-JEAGMii9.js → index-Cdvk2_2q.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-F--HuPG1.js → index-CjCwi7we.js} +1 -1
  111. package/src/assets/web-panel/assets/index-CkLp6DTO.js +1 -0
  112. package/src/assets/web-panel/assets/{index-CUj-l7GM.js → index-CvCFKojj.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Crp8CbRg.js → index-D4LHSde4.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Co3OFL0t.js → index-DCLu84x-.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-tgO8iza6.js → index-DD_qGBrt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Fuk6t_3K.js → index-DIRvdwBX.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-B9Svn0zc.js → index-DOjA8bvj.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BOoAQjJz.js → index-Da27u6j0.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CBaosWRO.js → index-DkBVYlE4.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D22zNXiS.js → index-DtAnPBWP.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-C-WIY-FQ.js → index-DzG7mkgW.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BJwlEnYo.js → index-H9_X1Cg_.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-pyvMVX8r.js → index-ITeEHb8L.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BHdailyo.js → index-KtLJXn4s.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BdutMsne.js → index-RYZgFIwo.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DTs_D1OL.js → index-gAVxDiTZ.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-b-sbVdjQ.js → index-paVubXzn.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CD62EEGo.js → index-tUH_6bdJ.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-PF-mpv8K.js → index-tVRPgYGr.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-AjrSPnvv.js → index-uSsiwgZ2.js} +1 -1
  131. package/src/assets/web-panel/assets/{initDefaultProps-DtrnfsZH.js → initDefaultProps-Ckp7xVZS.js} +1 -1
  132. package/src/assets/web-panel/assets/{motion-D4zqSaX3.js → motion-DUZgCpn6.js} +1 -1
  133. package/src/assets/web-panel/assets/{move-CGFGOUQj.js → move-B2rttglH.js} +1 -1
  134. package/src/assets/web-panel/assets/{mtc-parser-DH2HvkJl.js → mtc-parser-BYWcLTuN.js} +1 -1
  135. package/src/assets/web-panel/assets/{omit-jJ2at5HX.js → omit-DhHqKeFx.js} +1 -1
  136. package/src/assets/web-panel/assets/{pickAttrs-CRyMT1Fv.js → pickAttrs-ANpJaWMO.js} +1 -1
  137. package/src/assets/web-panel/assets/{placementArrow-DZ_CX0Pt.js → placementArrow-CfZWe7CA.js} +1 -1
  138. package/src/assets/web-panel/assets/{responsiveObserve-wruHk-h5.js → responsiveObserve-D7Xz2y-R.js} +1 -1
  139. package/src/assets/web-panel/assets/{slide-BGgx8q67.js → slide-DekqCBY9.js} +1 -1
  140. package/src/assets/web-panel/assets/{statusUtils-Do5M7gKm.js → statusUtils-BET6XU7h.js} +1 -1
  141. package/src/assets/web-panel/assets/{styleChecker-CRa-GZpX.js → styleChecker-qHmJjV62.js} +1 -1
  142. package/src/assets/web-panel/assets/{useFlexGapSupport-BxPcq6pj.js → useFlexGapSupport-BoMCTNyu.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFs-v5O2ZcJm.js → useFs-TdW-NgFC.js} +1 -1
  144. package/src/assets/web-panel/assets/{usePersonalDataHub--z2FU0Px.js → usePersonalDataHub-Dyox7wCu.js} +1 -1
  145. package/src/assets/web-panel/assets/{vnode-1emidVKd.js → vnode-XUn5S8CP.js} +1 -1
  146. package/src/assets/web-panel/assets/{zoom-CcJaRyHs.js → zoom-Ls77i8hn.js} +1 -1
  147. package/src/assets/web-panel/index.html +1 -1
  148. package/src/command-manifest.json +8 -1
  149. package/src/commands/changelog.js +148 -0
  150. package/src/data/changelog.json +189 -0
  151. package/src/gateways/ws/remote-session-protocol.js +9 -2
  152. package/src/index.js +2 -0
  153. package/src/lib/changelog.js +252 -0
  154. package/src/lib/lsp/lsp-server-registry.js +15 -4
  155. package/src/lib/plugin-runtime/hooks.js +20 -4
  156. package/src/lib/plugin-runtime/monitors.js +20 -4
  157. package/src/lib/plugin-runtime/signature.js +16 -0
  158. package/src/lib/sandbox-egress-proxy.js +38 -2
  159. package/src/lib/sandbox-network-policy.js +26 -4
  160. package/src/lib/telemetry/span-recorder.js +12 -1
  161. package/src/assets/web-panel/assets/Terminal-CD132d2Y.js +0 -3
  162. package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +0 -1
  163. package/src/assets/web-panel/assets/index-Dwix3p4g.js +0 -1
  164. package/src/assets/web-panel/assets/index-SHaoZ0CA.js +0 -1
@@ -77,6 +77,22 @@ export function verifyInstalledSignature(plugin, opts = {}) {
77
77
  return { signed: false, reason: "lock is not signature-verified" };
78
78
  }
79
79
  const manifestFile = path.join(plugin.root, lock.manifest || "plugin.json");
80
+ // `lock.manifest` is untrusted — it lives in the (writable) plugin dir. A lock
81
+ // pointing OUTSIDE the plugin root (`manifest: "../../secret"`) would make us
82
+ // re-hash an arbitrary file and, with a matching locked sha256, forge
83
+ // signed:true — which gates load-time requireSignedPlugins. A plugin's manifest
84
+ // is ALWAYS inside its own root, so reject any path that escapes it (boundary
85
+ // via path.relative, not startsWith — the sandbox-fs-policy pattern).
86
+ const rel = path.relative(
87
+ path.resolve(plugin.root),
88
+ path.resolve(manifestFile),
89
+ );
90
+ if (!rel || rel.startsWith("..") || path.isAbsolute(rel)) {
91
+ return {
92
+ signed: false,
93
+ reason: "lock manifest path escapes the plugin root",
94
+ };
95
+ }
80
96
  if (!_deps.existsSync(manifestFile)) {
81
97
  return { signed: false, reason: "locked manifest file is missing" };
82
98
  }
@@ -72,6 +72,42 @@ async function guardResolvedTarget(host, policy, lookup) {
72
72
  return { ok: true, ip: typeof first === "string" ? first : first.address };
73
73
  }
74
74
 
75
+ /**
76
+ * Parse a CONNECT request target ("host:port") into `{ host, port }`. A naive
77
+ * `split(":")` mangles IPv6 literals — `[2001:db8::1]:8443` would yield host
78
+ * `"[2001"` and a NaN port that silently defaults to 443, so even an IP-pinned
79
+ * tunnel connects to the WRONG port (and, when unpinned, the wrong host). Handle
80
+ * the bracketed-IPv6, bare-IPv6, and `name[:port]` forms explicitly. Port
81
+ * defaults to 443 (the CONNECT/HTTPS default).
82
+ */
83
+ export function parseConnectTarget(target) {
84
+ const s = String(target == null ? "" : target).trim();
85
+ const toPort = (v) => {
86
+ const n = parseInt(v, 10);
87
+ return Number.isInteger(n) && n > 0 && n <= 65535 ? n : 443;
88
+ };
89
+ // Bracketed IPv6: "[::1]" or "[::1]:8443"
90
+ if (s.startsWith("[")) {
91
+ const end = s.indexOf("]");
92
+ if (end > 0) {
93
+ const host = s.slice(1, end);
94
+ const rest = s.slice(end + 1); // "" or ":8443"
95
+ return { host, port: rest.startsWith(":") ? toPort(rest.slice(1)) : 443 };
96
+ }
97
+ // malformed bracket — fall through to the generic handling
98
+ }
99
+ // Bare IPv6 literal (2+ colons, no brackets) → no port component to split off.
100
+ if ((s.match(/:/g) || []).length > 1) {
101
+ return { host: s, port: 443 };
102
+ }
103
+ // "name:port" (rsplit on the single colon) or bare "name".
104
+ const idx = s.lastIndexOf(":");
105
+ if (idx > 0) {
106
+ return { host: s.slice(0, idx), port: toPort(s.slice(idx + 1)) };
107
+ }
108
+ return { host: s, port: 443 };
109
+ }
110
+
75
111
  /**
76
112
  * Build the proxy env vars a child process needs to route through the proxy.
77
113
  * `NO_PROXY` is intentionally empty so nothing bypasses the filter.
@@ -204,8 +240,8 @@ export function createEgressProxy(policy = {}, opts = {}) {
204
240
  clientSocket.end();
205
241
  return;
206
242
  }
207
- const [host, portStr] = req.url.split(":");
208
- const port = parseInt(portStr, 10) || 443;
243
+ // Parse host:port properly (IPv6 literals break a naive split).
244
+ const { host, port } = parseConnectTarget(req.url);
209
245
  // Connect to the pinned validated IP so a rebind at connect time can't
210
246
  // swap in a private address between our check and the socket.
211
247
  const upstream = net.connect(port, ip || host, () => {
@@ -60,6 +60,24 @@ function anyMatch(host, patterns) {
60
60
  return (patterns || []).some((p) => matchesDomain(host, p));
61
61
  }
62
62
 
63
+ /**
64
+ * If `h` is an IPv4-mapped IPv6 address, return the embedded IPv4 in dotted
65
+ * form; else null. Handles both the dotted tail ("::ffff:127.0.0.1", how a user
66
+ * might type it) and the compressed-hex tail ("::ffff:7f00:1", how Node's URL
67
+ * parser serializes it). The hex tail is two 16-bit groups = the 32-bit IPv4.
68
+ */
69
+ function mappedIpv4Tail(h) {
70
+ const dotted = h.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i);
71
+ if (dotted) return dotted[1];
72
+ const hex = h.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
73
+ if (hex) {
74
+ const high = parseInt(hex[1], 16);
75
+ const low = parseInt(hex[2], 16);
76
+ return `${(high >> 8) & 0xff}.${high & 0xff}.${(low >> 8) & 0xff}.${low & 0xff}`;
77
+ }
78
+ return null;
79
+ }
80
+
63
81
  /** Private / loopback / link-local / cloud-metadata target? (SSRF guard) */
64
82
  export function isPrivateHost(host) {
65
83
  if (!host) return false;
@@ -70,10 +88,14 @@ export function isPrivateHost(host) {
70
88
  // IPv6 loopback / unique-local / link-local.
71
89
  if (h === "::1" || h === "::") return true;
72
90
  if (/^f[cd][0-9a-f]{2}:/i.test(h)) return true; // fc00::/7 unique-local
73
- if (/^fe80:/i.test(h)) return true; // link-local
74
- // IPv4-mapped IPv6 (::ffff:127.0.0.1) — check the tail.
75
- const mapped = h.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);
76
- const ipv4 = mapped ? mapped[1] : h;
91
+ if (/^fe[89ab][0-9a-f]:/i.test(h)) return true; // fe80::/10 link-local (fe80–febf)
92
+ // IPv4-mapped IPv6 — check the embedded IPv4 tail. Node's WHATWG URL parser
93
+ // serializes "[::ffff:127.0.0.1]" as COMPRESSED HEX ("::ffff:7f00:1"), never
94
+ // dotted-decimal, so we must decode BOTH forms or the guard is dead code for
95
+ // any URL/bracketed input (loopback, private ranges, AND 169.254.169.254 all
96
+ // sail through — confirmed SSRF bypass). Bare non-URL hosts may still arrive
97
+ // dotted, so keep that form too.
98
+ const ipv4 = mappedIpv4Tail(h) || h;
77
99
  const m = ipv4.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
78
100
  if (m) {
79
101
  const [a, b] = [Number(m[1]), Number(m[2])];
@@ -20,6 +20,16 @@ function spanId() {
20
20
  return _seq.toString(16).padStart(16, "0");
21
21
  }
22
22
 
23
+ // One trace per recorder (a "run"). The OTLP/OTel spec treats an ALL-ZERO
24
+ // traceId as INVALID, so a strict collector would drop every span exported with
25
+ // `"0".repeat(32)` — defeating toOtlp()'s purpose. Derive a non-zero, monotonic
26
+ // (RNG-free, snapshot-replayable) 32-hex traceId per recorder instead.
27
+ let _traceSeq = 0;
28
+ function newTraceId() {
29
+ _traceSeq = (_traceSeq + 1) % Number.MAX_SAFE_INTEGER;
30
+ return _traceSeq.toString(16).padStart(32, "0"); // never all-zero (starts at 1)
31
+ }
32
+
23
33
  export class TelemetryRecorder {
24
34
  constructor({
25
35
  now = () => Date.now(),
@@ -27,6 +37,7 @@ export class TelemetryRecorder {
27
37
  } = {}) {
28
38
  this._now = typeof now === "function" ? now : () => now;
29
39
  this.serviceName = serviceName;
40
+ this.traceId = newTraceId(); // one trace per recorder (valid non-zero id)
30
41
  this._spans = []; // completed spans
31
42
  this._counters = new Map(); // name → { total, byAttr }
32
43
  this._failures = new Map(); // category → count
@@ -171,7 +182,7 @@ export class TelemetryRecorder {
171
182
  {
172
183
  scope: { name: "chainlesschain.cli" },
173
184
  spans: this._spans.map((s) => ({
174
- traceId: "0".repeat(32),
185
+ traceId: this.traceId,
175
186
  spanId: s.id,
176
187
  parentSpanId: s.parentId || "",
177
188
  name: s.name,
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
2
- import{u as fe,_ as me,d as B,e as U}from"./index-DfgCdFrN.js";import{I as z,J as x,U as _,Q as D,S as K,K as T,V as R,c as A,F as Q,Z,R as E,o as G,f as H,w as $,n as V,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-BMxUs6UX.js";import{R as ye,b as pe,as as ge}from"./icons-BsDmGpcT.js";const k=new Map,C=new Map,N=new Set,F=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),N.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),F.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(L=>({seq:L.seq,data:ae(L.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(N.add(a),()=>N.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(F.add(a),()=>F.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function L(t){return t?t.slice(0,8):""}let O=null,M=null;async function I(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await U(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await U(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await U(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function q(t){await V();const{xtermMod:l,fitAddonMod:p}=await I(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?B.warning("该命令被桌面端拦截(高危关键字)"):B.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
3
- \x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const J of v)m.write(J.data),t.lastSeq=J.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const j=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});j.observe(b);const ue=t.offs;t.offs=()=>{try{j.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await q(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,V(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function X(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await q(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}G(async()=>{await X()}),H(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{V(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const Y={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:I,mountXterm:q,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:G,onBeforeUnmount:H,nextTick:V,watch:$,get message(){return B},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(Y,"__isScriptSetup",{enumerable:!1,value:!0}),Y}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={key:1,class:"terminal-footer"},Ve={key:0,class:"footer-exit"};function qe(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=D(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Z(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Z(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",Ve,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",qe],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-1VVfY7/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-DfgCdFrN.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-BdM70oda.js";import{a0 as t}from"./index-DfgCdFrN.js";import"./vendor-BMxUs6UX.js";import"./responsiveObserve-wruHk-h5.js";import"./useFlexGapSupport-BxPcq6pj.js";import"./styleChecker-CRa-GZpX.js";import"./index-Cj0OZ-37.js";import"./icons-BsDmGpcT.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-CH-bDkzs.js";import{a0 as t}from"./index-DfgCdFrN.js";import"./vendor-BMxUs6UX.js";import"./index-Cj0OZ-37.js";import"./icons-BsDmGpcT.js";const s=t(o);export{s as default};