@dsh-sup/dsh-core-linux-x64 0.1.6-BETA.7 → 0.1.6-BETA.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core.cjs CHANGED
@@ -947,7 +947,7 @@ var require_version = __commonJS({
947
947
  var fs2 = require("node:fs");
948
948
  var path2 = require("node:path");
949
949
  function guardVersion() {
950
- if (true) return String("0.1.6-BETA.7");
950
+ if (true) return String("0.1.6-BETA.8");
951
951
  try {
952
952
  return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version || "unknown";
953
953
  } catch {
@@ -6509,44 +6509,183 @@ var require_ip = __commonJS({
6509
6509
  }
6510
6510
  });
6511
6511
 
6512
- // src/platform/distribution/policies.js
6513
- var require_policies = __commonJS({
6514
- "src/platform/distribution/policies.js"(exports2, module2) {
6512
+ // src/platform/distribution/registry-ref.js
6513
+ var require_registry_ref = __commonJS({
6514
+ "src/platform/distribution/registry-ref.js"(exports2, module2) {
6515
6515
  "use strict";
6516
6516
  var { isPrivateHostLiteral } = require_ip();
6517
- var FALLBACK_REGISTRIES = [
6518
- "https://registry.npmjs.org",
6519
- "https://registry.npmmirror.com"
6520
- ];
6521
- function normalizeOrigin(origin) {
6522
- return String(origin || "").trim().replace(/\/+$/, "");
6517
+ var REDIRECT_MAX_HOPS = 3;
6518
+ var MAX_BODY_BYTES = 32 * 1024 * 1024;
6519
+ var DEFAULT_TIMEOUT_MS = 1e4;
6520
+ function normalizeBase(raw) {
6521
+ return String(raw == null ? "" : raw).trim().replace(/\/+$/, "");
6523
6522
  }
6524
- function isValidOrigin(origin) {
6525
- const s = normalizeOrigin(origin);
6526
- if (!/^https?:\/\/(\[[0-9A-Fa-f:]+\]|[A-Za-z0-9.\-_]+)(:\d+)?$/.test(s)) return false;
6523
+ function hostViolation(host2) {
6524
+ const h = String(host2 || "").toLowerCase().replace(/^\[|\]$/g, "");
6525
+ if (!h) return "\u955C\u50CF\u6E90\u7F3A\u5C11\u4E3B\u673A\u540D";
6526
+ if (isPrivateHostLiteral(h)) return "\u955C\u50CF\u6E90\u4E3B\u673A\u4E0D\u5F97\u4E3A\u56DE\u73AF/\u79C1\u7F51/\u94FE\u8DEF\u672C\u5730/\u4FDD\u7559\u6BB5\u5B57\u9762\u91CF: " + h;
6527
+ return null;
6528
+ }
6529
+ function parseRegistryBase(raw) {
6530
+ const base = normalizeBase(raw);
6531
+ const bad = (violation) => ({ ok: false, base, protocol: "", host: "", violation });
6532
+ if (!base) return bad("\u955C\u50CF\u6E90\u4E3A\u7A7A");
6533
+ if (/[\s]/.test(base)) return bad("\u955C\u50CF\u6E90\u4E0D\u5F97\u542B\u7A7A\u767D\u5B57\u7B26");
6527
6534
  let u;
6528
6535
  try {
6529
- u = new URL(s);
6536
+ u = new URL(base);
6530
6537
  } catch {
6531
- return false;
6538
+ return bad("\u955C\u50CF\u6E90\u65E0\u6CD5\u89E3\u6790: " + base);
6532
6539
  }
6533
- if (u.protocol !== "http:" && u.protocol !== "https:") return false;
6534
- if (u.username || u.password) return false;
6535
- if (u.hash) return false;
6536
- if (!u.hostname) return false;
6537
- return u.pathname === "" || u.pathname === "/" || u.pathname === "//";
6540
+ if (u.protocol !== "http:" && u.protocol !== "https:") return bad("\u955C\u50CF\u6E90\u5FC5\u987B\u662F http(s) \u534F\u8BAE: " + base);
6541
+ if (u.username || u.password) return bad("\u955C\u50CF\u6E90\u4E0D\u5F97\u643A\u5E26\u7528\u6237\u540D\u6216\u5BC6\u7801: " + base);
6542
+ if (u.search) return bad("\u955C\u50CF\u6E90\u4E0D\u5F97\u643A\u5E26\u67E5\u8BE2\u4E32: " + base);
6543
+ if (u.hash) return bad("\u955C\u50CF\u6E90\u4E0D\u5F97\u643A\u5E26\u7247\u6BB5: " + base);
6544
+ if (!u.hostname) return bad("\u955C\u50CF\u6E90\u7F3A\u5C11\u4E3B\u673A\u540D: " + base);
6545
+ return { ok: true, base, protocol: u.protocol.replace(/:$/, ""), host: u.hostname, violation: null };
6538
6546
  }
6539
- function registryOriginViolation(origin) {
6540
- const o = normalizeOrigin(origin);
6541
- if (!isValidOrigin(o)) return "\u955C\u50CF\u6E90\u5FC5\u987B\u662F http(s) \u7EAF origin\uFF08\u65E0\u8DEF\u5F84/\u67E5\u8BE2/\u51ED\u8BC1\uFF09: " + o;
6547
+ function targetHostViolation(rawUrl, fromUrl) {
6542
6548
  let u;
6543
6549
  try {
6544
- u = new URL(o);
6550
+ u = new URL(String(rawUrl || ""));
6545
6551
  } catch {
6546
- return "\u955C\u50CF\u6E90\u65E0\u6CD5\u89E3\u6790: " + o;
6552
+ return "\u8DF3\u8F6C\u76EE\u6807\u65E0\u6CD5\u89E3\u6790";
6547
6553
  }
6548
- if (isPrivateHostLiteral(u.hostname)) return "\u955C\u50CF\u6E90\u4E3B\u673A\u4E0D\u5F97\u4E3A\u56DE\u73AF/\u79C1\u7F51/\u94FE\u8DEF\u672C\u5730/\u4FDD\u7559\u6BB5\u5B57\u9762\u91CF: " + o;
6549
- return null;
6554
+ if (u.protocol !== "http:" && u.protocol !== "https:") return "\u8DF3\u8F6C\u76EE\u6807\u534F\u8BAE\u975E\u6CD5: " + u.protocol;
6555
+ if (u.username || u.password) return "\u8DF3\u8F6C\u76EE\u6807\u4E0D\u5F97\u643A\u5E26\u51ED\u8BC1";
6556
+ let from;
6557
+ try {
6558
+ from = new URL(String(fromUrl || ""));
6559
+ } catch {
6560
+ from = null;
6561
+ }
6562
+ if (from && from.hostname.toLowerCase() === u.hostname.toLowerCase()) return null;
6563
+ return hostViolation(u.hostname);
6564
+ }
6565
+ function registryPackagePath(pkg) {
6566
+ return encodeURIComponent(String(pkg || ""));
6567
+ }
6568
+ function registryUrl(base, ...segments) {
6569
+ const parsed = parseRegistryBase(base);
6570
+ if (!parsed.ok) return null;
6571
+ const tail = segments.filter((s) => s !== "" && s != null).map((s) => String(s).replace(/^\/+/, "").replace(/\/+$/, "")).filter(Boolean).join("/");
6572
+ return tail ? parsed.base + "/" + tail : parsed.base;
6573
+ }
6574
+ async function readCapped(res, maxBytes) {
6575
+ const cl = Number(res.headers && res.headers.get("content-length")) || 0;
6576
+ if (cl > maxBytes) return null;
6577
+ const reader = res.body && typeof res.body.getReader === "function" ? res.body.getReader() : null;
6578
+ if (!reader) {
6579
+ const text = await res.text();
6580
+ return text.length > maxBytes ? null : text;
6581
+ }
6582
+ const chunks = [];
6583
+ let total = 0;
6584
+ for (; ; ) {
6585
+ const { done, value } = await reader.read();
6586
+ if (done) break;
6587
+ if (!value) continue;
6588
+ total += value.byteLength || value.length || 0;
6589
+ if (total > maxBytes) {
6590
+ try {
6591
+ await reader.cancel();
6592
+ } catch {
6593
+ }
6594
+ return null;
6595
+ }
6596
+ chunks.push(value);
6597
+ }
6598
+ const buf = Buffer.concat(chunks.map((c) => Buffer.from(c.buffer, c.byteOffset, c.byteLength)));
6599
+ return buf.toString("utf8");
6600
+ }
6601
+ async function fetchRegistry(startUrl, opts) {
6602
+ const o = opts || {};
6603
+ const timeoutMs = Number.isFinite(o.timeoutMs) && o.timeoutMs > 0 ? o.timeoutMs : DEFAULT_TIMEOUT_MS;
6604
+ const maxBytes = Number.isFinite(o.maxBytes) && o.maxBytes > 0 ? o.maxBytes : MAX_BODY_BYTES;
6605
+ const maxHops = Number.isFinite(o.maxHops) ? o.maxHops : REDIRECT_MAX_HOPS;
6606
+ let url = String(startUrl || "");
6607
+ const hops = [];
6608
+ const fail = (status, error) => ({ ok: false, status, json: null, error, url, hops });
6609
+ for (let hop = 0; ; hop++) {
6610
+ let res;
6611
+ try {
6612
+ res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs), redirect: "manual" });
6613
+ } catch (e) {
6614
+ return fail(null, e && (e.name === "TimeoutError" ? "\u8D85\u65F6" : e.message) || String(e));
6615
+ }
6616
+ hops.push({ url, status: res.status });
6617
+ if (res.status >= 300 && res.status < 400) {
6618
+ try {
6619
+ if (res.body) await res.body.cancel();
6620
+ } catch {
6621
+ }
6622
+ if (hop >= maxHops) return fail(res.status, "\u8DF3\u8F6C\u6B21\u6570\u8D85\u8FC7\u4E0A\u9650");
6623
+ const loc = res.headers.get("location");
6624
+ if (!loc) return fail(res.status, "\u8DF3\u8F6C\u7F3A\u5C11 Location");
6625
+ let next;
6626
+ try {
6627
+ next = new URL(loc, url).toString();
6628
+ } catch {
6629
+ return fail(res.status, "\u8DF3\u8F6C\u76EE\u6807\u65E0\u6CD5\u89E3\u6790");
6630
+ }
6631
+ const tv = targetHostViolation(next, url);
6632
+ url = next;
6633
+ if (tv) return fail(res.status, tv);
6634
+ continue;
6635
+ }
6636
+ if (res.status < 200 || res.status >= 300) {
6637
+ try {
6638
+ if (res.body) await res.body.cancel();
6639
+ } catch {
6640
+ }
6641
+ return fail(res.status, "HTTP " + res.status);
6642
+ }
6643
+ if (o.expect === "none") {
6644
+ try {
6645
+ if (res.body) await res.body.cancel();
6646
+ } catch {
6647
+ }
6648
+ return { ok: true, status: res.status, json: null, error: null, url, hops };
6649
+ }
6650
+ let text;
6651
+ try {
6652
+ text = await readCapped(res, maxBytes);
6653
+ } catch (e) {
6654
+ return fail(res.status, "\u8BFB\u53D6\u54CD\u5E94\u4F53\u4E2D\u65AD\uFF1A" + (e && e.message || String(e)));
6655
+ }
6656
+ if (text === null) return fail(res.status, "\u54CD\u5E94\u4F53\u8D85\u8FC7\u4E0A\u9650");
6657
+ if (o.expect !== "json") return { ok: true, status: res.status, json: null, text, error: null, url, hops };
6658
+ try {
6659
+ return { ok: true, status: res.status, json: JSON.parse(text), error: null, url, hops };
6660
+ } catch {
6661
+ return fail(res.status, "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON");
6662
+ }
6663
+ }
6664
+ }
6665
+ module2.exports = {
6666
+ normalizeBase,
6667
+ hostViolation,
6668
+ parseRegistryBase,
6669
+ registryPackagePath,
6670
+ registryUrl,
6671
+ fetchRegistry
6672
+ };
6673
+ }
6674
+ });
6675
+
6676
+ // src/platform/distribution/policies.js
6677
+ var require_policies = __commonJS({
6678
+ "src/platform/distribution/policies.js"(exports2, module2) {
6679
+ "use strict";
6680
+ var registryRef = require_registry_ref();
6681
+ var FALLBACK_REGISTRIES = [
6682
+ "https://registry.npmjs.org",
6683
+ "https://registry.npmmirror.com"
6684
+ ];
6685
+ function registryOriginViolation(origin) {
6686
+ const parsed = registryRef.parseRegistryBase(origin);
6687
+ if (!parsed.ok) return parsed.violation;
6688
+ return registryRef.hostViolation(parsed.host);
6550
6689
  }
6551
6690
  function effectiveOrigins(registryConfig, defaultRegistries) {
6552
6691
  const o = registryConfig && registryConfig.origins || [];
@@ -6564,32 +6703,27 @@ var require_policies = __commonJS({
6564
6703
  };
6565
6704
  }
6566
6705
  function resolveProbe(origin, spec, platformTag) {
6567
- const base = normalizeOrigin(origin);
6706
+ const timeoutMs = spec && Number.isFinite(spec.timeoutMs) && spec.timeoutMs > 0 ? spec.timeoutMs : 4e3;
6707
+ const parsed = registryRef.parseRegistryBase(origin);
6708
+ if (!parsed.ok) return { url: null, kind: "invalid", timeoutMs, violation: parsed.violation };
6568
6709
  if (spec && spec.kind === "package-metadata" && spec.pathTemplate && platformTag) {
6569
6710
  return {
6570
- url: base + "/" + spec.pathTemplate.replace("{platform}", platformTag),
6711
+ url: registryRef.registryUrl(parsed.base, spec.pathTemplate.replace("{platform}", platformTag)),
6571
6712
  kind: spec.kind,
6572
- timeoutMs: spec.timeoutMs || 4e3
6713
+ timeoutMs
6573
6714
  };
6574
6715
  }
6575
- return { url: base + "/-/ping", kind: "ping", timeoutMs: spec && spec.timeoutMs || 4e3 };
6576
- }
6577
- function pickFastestReachable(results) {
6578
- const reachable = results.filter((r) => r.ok).sort((a, b) => a.latencyMs - b.latencyMs);
6579
- return reachable.length ? reachable[0] : null;
6716
+ return { url: registryRef.registryUrl(parsed.base, "/-/ping"), kind: "ping", timeoutMs };
6580
6717
  }
6581
6718
  function isInCanaryList(state) {
6582
6719
  return state.canary === true;
6583
6720
  }
6584
6721
  module2.exports = {
6585
6722
  FALLBACK_REGISTRIES,
6586
- normalizeOrigin,
6587
- isValidOrigin,
6588
6723
  registryOriginViolation,
6589
6724
  effectiveOrigins,
6590
6725
  rebuildRegistryConfig,
6591
6726
  resolveProbe,
6592
- pickFastestReachable,
6593
6727
  isInCanaryList
6594
6728
  };
6595
6729
  }
@@ -6705,64 +6839,6 @@ var require_release = __commonJS({
6705
6839
  }
6706
6840
  });
6707
6841
 
6708
- // src/platform/contract/matrix.js
6709
- var require_matrix = __commonJS({
6710
- "src/platform/contract/matrix.js"(exports2, module2) {
6711
- "use strict";
6712
- var SUPPORTED = [
6713
- { platform: "linux", arch: "x64", osTag: "linux", npmTag: "linux-x64" },
6714
- { platform: "darwin", arch: "arm64", osTag: "darwin", npmTag: "darwin-arm64" },
6715
- { platform: "darwin", arch: "x64", osTag: "darwin", npmTag: "darwin-x64" },
6716
- { platform: "win32", arch: "x64", osTag: "win", npmTag: "win-x64" }
6717
- ];
6718
- var OS_TAG = { linux: "linux", darwin: "darwin", win32: "win" };
6719
- var FRP_OS = { linux: "linux", darwin: "darwin", win32: "windows" };
6720
- var FRP_ARCH = { x64: "amd64", arm64: "arm64" };
6721
- function osTag(platform) {
6722
- return OS_TAG[platform || process.platform] || null;
6723
- }
6724
- function current(platform, arch) {
6725
- const p = platform || process.platform;
6726
- const a = arch || process.arch;
6727
- return { platform: p, arch: a, osTag: OS_TAG[p] || null, npmTag: npmTag(p, a) };
6728
- }
6729
- function npmTag(platform, arch) {
6730
- const p = platform || process.platform;
6731
- const a = arch || process.arch;
6732
- const os2 = OS_TAG[p];
6733
- if (!os2 || a !== "x64" && a !== "arm64") {
6734
- throw new Error("\u4E0D\u652F\u6301\u7684\u5E73\u53F0\u7EC4\u5408: " + p + "/" + a + "\uFF08\u4EC5 linux/darwin/win32 \xD7 x64/arm64\uFF09");
6735
- }
6736
- return os2 + "-" + a;
6737
- }
6738
- function isSupported(platform, arch) {
6739
- const p = platform || process.platform;
6740
- const a = arch || process.arch;
6741
- return SUPPORTED.some((x) => x.platform === p && x.arch === a);
6742
- }
6743
- function frpTag(platform, arch) {
6744
- const p = platform || process.platform;
6745
- const a = arch || process.arch;
6746
- const os2 = FRP_OS[p];
6747
- const am = FRP_ARCH[a];
6748
- if (!os2 || !am) return null;
6749
- return { os: os2, arch: am, tag: os2 + "_" + am, exe: p === "win32" };
6750
- }
6751
- function supportsProcessGroup(platform) {
6752
- return (platform || process.platform) !== "win32";
6753
- }
6754
- module2.exports = {
6755
- SUPPORTED,
6756
- osTag,
6757
- current,
6758
- npmTag,
6759
- isSupported,
6760
- frpTag,
6761
- supportsProcessGroup
6762
- };
6763
- }
6764
- });
6765
-
6766
6842
  // src/platform/contract/registry.js
6767
6843
  var require_registry = __commonJS({
6768
6844
  "src/platform/contract/registry.js"(exports2, module2) {
@@ -6864,26 +6940,16 @@ var require_registry = __commonJS({
6864
6940
  }
6865
6941
  });
6866
6942
 
6867
- // src/platform/distribution/registry.js
6868
- var require_registry2 = __commonJS({
6869
- "src/platform/distribution/registry.js"(exports2, module2) {
6943
+ // src/platform/distribution/registry-config.js
6944
+ var require_registry_config = __commonJS({
6945
+ "src/platform/distribution/registry-config.js"(exports2, module2) {
6870
6946
  "use strict";
6871
6947
  var fs2 = require("node:fs");
6872
6948
  var path2 = require("node:path");
6873
- var matrix = require_matrix();
6874
6949
  var registryContract = require_registry();
6875
6950
  var { writeAtomic } = require_fs();
6876
6951
  var policies = require_policies();
6877
6952
  var CONTRACT_TTL_MS = 60 * 1e3;
6878
- function platformTag() {
6879
- return matrix.npmTag();
6880
- }
6881
- function reloadContractIfStale(state) {
6882
- const now = Date.now();
6883
- if (state._contractLoadedAt && now - state._contractLoadedAt < CONTRACT_TTL_MS) return;
6884
- loadRegistryConfig(state);
6885
- state._contractLoadedAt = now;
6886
- }
6887
6953
  function loadRegistryConfig(state) {
6888
6954
  state.contract = registryContract.read(state.registryFile);
6889
6955
  if (!state.contract.ok) {
@@ -6910,6 +6976,12 @@ var require_registry2 = __commonJS({
6910
6976
  state.logger.warn && state.logger.warn("dist: registry config load failed: " + e.message);
6911
6977
  }
6912
6978
  }
6979
+ function reloadContractIfStale(state) {
6980
+ const now = Date.now();
6981
+ if (state._contractLoadedAt && now - state._contractLoadedAt < CONTRACT_TTL_MS) return;
6982
+ loadRegistryConfig(state);
6983
+ state._contractLoadedAt = now;
6984
+ }
6913
6985
  function saveRegistryConfig(state) {
6914
6986
  if (!state.registryFile) return;
6915
6987
  try {
@@ -6940,6 +7012,85 @@ var require_registry2 = __commonJS({
6940
7012
  doc.manualOrigin = rc.manualOrigin;
6941
7013
  writeAtomic(f, JSON.stringify(doc, null, 2) + "\n", { mode: 384 });
6942
7014
  }
7015
+ module2.exports = {
7016
+ CONTRACT_TTL_MS,
7017
+ loadRegistryConfig,
7018
+ reloadContractIfStale,
7019
+ saveRegistryConfig
7020
+ };
7021
+ }
7022
+ });
7023
+
7024
+ // src/platform/contract/matrix.js
7025
+ var require_matrix = __commonJS({
7026
+ "src/platform/contract/matrix.js"(exports2, module2) {
7027
+ "use strict";
7028
+ var SUPPORTED = [
7029
+ { platform: "linux", arch: "x64", osTag: "linux", npmTag: "linux-x64" },
7030
+ { platform: "darwin", arch: "arm64", osTag: "darwin", npmTag: "darwin-arm64" },
7031
+ { platform: "darwin", arch: "x64", osTag: "darwin", npmTag: "darwin-x64" },
7032
+ { platform: "win32", arch: "x64", osTag: "win", npmTag: "win-x64" }
7033
+ ];
7034
+ var OS_TAG = { linux: "linux", darwin: "darwin", win32: "win" };
7035
+ var FRP_OS = { linux: "linux", darwin: "darwin", win32: "windows" };
7036
+ var FRP_ARCH = { x64: "amd64", arm64: "arm64" };
7037
+ function osTag(platform) {
7038
+ return OS_TAG[platform || process.platform] || null;
7039
+ }
7040
+ function current(platform, arch) {
7041
+ const p = platform || process.platform;
7042
+ const a = arch || process.arch;
7043
+ return { platform: p, arch: a, osTag: OS_TAG[p] || null, npmTag: npmTag(p, a) };
7044
+ }
7045
+ function npmTag(platform, arch) {
7046
+ const p = platform || process.platform;
7047
+ const a = arch || process.arch;
7048
+ const os2 = OS_TAG[p];
7049
+ if (!os2 || a !== "x64" && a !== "arm64") {
7050
+ throw new Error("\u4E0D\u652F\u6301\u7684\u5E73\u53F0\u7EC4\u5408: " + p + "/" + a + "\uFF08\u4EC5 linux/darwin/win32 \xD7 x64/arm64\uFF09");
7051
+ }
7052
+ return os2 + "-" + a;
7053
+ }
7054
+ function isSupported(platform, arch) {
7055
+ const p = platform || process.platform;
7056
+ const a = arch || process.arch;
7057
+ return SUPPORTED.some((x) => x.platform === p && x.arch === a);
7058
+ }
7059
+ function frpTag(platform, arch) {
7060
+ const p = platform || process.platform;
7061
+ const a = arch || process.arch;
7062
+ const os2 = FRP_OS[p];
7063
+ const am = FRP_ARCH[a];
7064
+ if (!os2 || !am) return null;
7065
+ return { os: os2, arch: am, tag: os2 + "_" + am, exe: p === "win32" };
7066
+ }
7067
+ function supportsProcessGroup(platform) {
7068
+ return (platform || process.platform) !== "win32";
7069
+ }
7070
+ module2.exports = {
7071
+ SUPPORTED,
7072
+ osTag,
7073
+ current,
7074
+ npmTag,
7075
+ isSupported,
7076
+ frpTag,
7077
+ supportsProcessGroup
7078
+ };
7079
+ }
7080
+ });
7081
+
7082
+ // src/platform/distribution/registry.js
7083
+ var require_registry2 = __commonJS({
7084
+ "src/platform/distribution/registry.js"(exports2, module2) {
7085
+ "use strict";
7086
+ var matrix = require_matrix();
7087
+ var policies = require_policies();
7088
+ var ref = require_registry_ref();
7089
+ var config = require_registry_config();
7090
+ var PROBE_MAX_BODY_BYTES = 8 * 1024 * 1024;
7091
+ function platformTag() {
7092
+ return matrix.npmTag();
7093
+ }
6943
7094
  async function probeRegistry(state, origin) {
6944
7095
  const spec = state.contract && state.contract.ok && state.contract.probe || null;
6945
7096
  let tag = null;
@@ -6949,106 +7100,154 @@ var require_registry2 = __commonJS({
6949
7100
  tag = null;
6950
7101
  }
6951
7102
  const target = policies.resolveProbe(origin, spec, tag);
6952
- const start = Date.now();
6953
- try {
6954
- const res = await fetch(target.url, { signal: AbortSignal.timeout(target.timeoutMs), redirect: "manual" });
6955
- const ok = res.status >= 200 && res.status < 300;
6956
- return { ok, latencyMs: Date.now() - start, probe: target.kind };
6957
- } catch (e) {
6958
- return { ok: false, latencyMs: Date.now() - start, probe: target.kind };
7103
+ if (!target.url) {
7104
+ return { ok: false, latencyMs: 0, probe: target.kind, error: target.violation || "\u955C\u50CF\u57FA\u5740\u975E\u6CD5" };
6959
7105
  }
7106
+ const start = Date.now();
7107
+ const r = await ref.fetchRegistry(target.url, {
7108
+ timeoutMs: target.timeoutMs,
7109
+ expect: "text",
7110
+ maxBytes: PROBE_MAX_BODY_BYTES
7111
+ });
7112
+ return { ok: !!r.ok, latencyMs: Date.now() - start, probe: target.kind, error: r.error || null };
6960
7113
  }
6961
7114
  async function probeOrigin(state, origin) {
6962
- const o = policies.normalizeOrigin(origin);
6963
- if (!policies.isValidOrigin(o)) return { origin: o, ok: false, latencyMs: null, error: "\u975E\u6CD5 origin" };
6964
- const p = await probeRegistry(state, o);
6965
- return { origin: o, ok: !!p.ok, latencyMs: p.latencyMs, probe: p.probe };
7115
+ const parsed = ref.parseRegistryBase(origin);
7116
+ if (!parsed.ok) return { origin: ref.normalizeBase(origin), ok: false, latencyMs: null, error: parsed.violation };
7117
+ const p = await probeRegistry(state, parsed.base);
7118
+ return { origin: parsed.base, ok: !!p.ok, latencyMs: p.latencyMs, probe: p.probe, error: p.error || null };
6966
7119
  }
6967
7120
  function registryOrigins(state) {
6968
- return policies.effectiveOrigins(state.registryConfig, state.defaultRegistries);
7121
+ const seen = /* @__PURE__ */ new Set();
7122
+ const out = [];
7123
+ for (const raw of policies.effectiveOrigins(state.registryConfig, state.defaultRegistries)) {
7124
+ const parsed = ref.parseRegistryBase(raw);
7125
+ const base = parsed.ok ? parsed.base : ref.normalizeBase(raw);
7126
+ if (seen.has(base)) continue;
7127
+ seen.add(base);
7128
+ out.push(base);
7129
+ }
7130
+ return out;
7131
+ }
7132
+ async function probeAllOrigins(state, origins) {
7133
+ const results = await Promise.all(origins.map(async (origin) => {
7134
+ const p = await probeRegistry(state, origin);
7135
+ return { origin, ok: !!p.ok, latencyMs: p.latencyMs, error: p.error || null };
7136
+ }));
7137
+ results.sort((a, b) => a.ok === b.ok ? a.latencyMs - b.latencyMs : a.ok ? -1 : 1);
7138
+ return results;
7139
+ }
7140
+ function orderFor(primary, origins, results) {
7141
+ const usable = (o) => ref.parseRegistryBase(o).ok;
7142
+ const ranked = (results || []).filter((r) => r.ok).map((r) => r.origin);
7143
+ const ordered = [];
7144
+ for (const o of [primary, ...ranked, ...origins]) {
7145
+ if (!o || !usable(o)) continue;
7146
+ if (!ordered.includes(o)) ordered.push(o);
7147
+ }
7148
+ return ordered;
6969
7149
  }
6970
7150
  async function selectRegistry(state, force) {
6971
- reloadContractIfStale(state);
7151
+ config.reloadContractIfStale(state);
6972
7152
  const rc = state.registryConfig || {};
6973
- if (rc.mode === "manual" && rc.manualOrigin) {
6974
- const origin = policies.normalizeOrigin(rc.manualOrigin);
6975
- state.selectedRegistry = { origin, latencyMs: null, checkedAt: Date.now(), manual: true, probes: [] };
6976
- return origin;
6977
- }
7153
+ const origins = registryOrigins(state);
7154
+ const manualParsed = ref.parseRegistryBase(rc.manualOrigin);
7155
+ const manualBase = manualParsed.ok ? manualParsed.base : "";
7156
+ const manual = rc.mode === "manual" && !!manualBase;
6978
7157
  const now = Date.now();
6979
- if (!force && state.selectedRegistry && !state.selectedRegistry.manual && state.selectedRegistry.checkedAt && now - state.selectedRegistry.checkedAt < 30 * 60 * 1e3) {
6980
- return state.selectedRegistry.origin;
7158
+ const cached = state.selectedRegistry;
7159
+ if (!force && cached && cached.checkedAt && now - cached.checkedAt < 30 * 60 * 1e3) {
7160
+ return cached;
6981
7161
  }
6982
7162
  const c = state.contract;
6983
- if (!force && c && c.ok && c.selected) {
7163
+ if (!force && !manual && c && c.ok && c.selected) {
6984
7164
  const age = Math.floor(Date.now() / 1e3) - c.selected.checkedAt;
6985
- if (age >= 0 && age < 30 * 60) {
7165
+ const adopted = ref.parseRegistryBase(c.selected.origin);
7166
+ if (age >= 0 && age < 30 * 60 && adopted.ok) {
7167
+ const origin = adopted.base;
6986
7168
  state.selectedRegistry = {
6987
- origin: c.selected.origin,
6988
- latencyMs: c.selected.latencyMs,
6989
- checkedAt: Date.now(),
6990
- manual: false,
7169
+ origin,
7170
+ ordered: orderFor(origin, origins, null),
6991
7171
  source: "shell",
6992
- probes: []
7172
+ manual: false,
7173
+ checkedAt: now,
7174
+ latencyMs: Number.isFinite(c.selected.latencyMs) ? c.selected.latencyMs : null,
7175
+ probes: [{ origin, ok: true, latencyMs: c.selected.latencyMs, error: null, from: "shell-contract" }]
6993
7176
  };
6994
7177
  if (state.events) {
6995
7178
  try {
6996
- state.events.append("dist_registry_selected", { origin: c.selected.origin, source: "shell-contract" });
7179
+ state.events.append("dist_registry_selected", { origin, source: "shell-contract" });
6997
7180
  } catch {
6998
7181
  }
6999
7182
  }
7000
- return c.selected.origin;
7183
+ return state.selectedRegistry;
7001
7184
  }
7002
- }
7003
- const origins = registryOrigins(state);
7004
- const results = await Promise.all(origins.map(async (origin) => {
7005
- const p = await probeRegistry(state, origin);
7006
- return { origin, ok: p.ok, latencyMs: p.latencyMs };
7007
- }));
7008
- const picked = policies.pickFastestReachable(results);
7009
- if (!picked) {
7010
- state.selectedRegistry = { origin: null, latencyMs: null, checkedAt: null, manual: false, probes: results };
7011
- if (state.events) {
7012
- state.events.append("dist_registry_unreachable", {
7013
- candidates: results.map((r) => r.origin + ":" + r.latencyMs + "ms")
7014
- });
7185
+ if (!adopted.ok && state.logger && state.logger.warn) {
7186
+ state.logger.warn("dist: \u5951\u7EA6 selected \u57FA\u5740\u975E\u6CD5\uFF0C\u6539\u4E3A\u81EA\u884C\u6D4B\u901F\uFF08" + adopted.violation + "\uFF09");
7015
7187
  }
7016
- return null;
7017
7188
  }
7018
- state.selectedRegistry = {
7019
- origin: picked.origin,
7020
- latencyMs: picked.latencyMs,
7021
- checkedAt: Date.now(),
7022
- manual: false,
7189
+ const results = await probeAllOrigins(state, origins);
7190
+ const firstReachable = results.find((r) => r.ok);
7191
+ const primary = manual ? manualBase : firstReachable && firstReachable.origin || null;
7192
+ const selected = {
7193
+ origin: primary,
7194
+ ordered: orderFor(primary, origins, results),
7195
+ source: manual ? "manual" : firstReachable ? "probe" : "unreachable",
7196
+ manual,
7197
+ checkedAt: firstReachable || manual ? now : null,
7198
+ // 全不可达不缓存坏选择:下次调用仍会重测
7199
+ latencyMs: firstReachable && firstReachable.origin === primary ? firstReachable.latencyMs : null,
7023
7200
  probes: results
7024
7201
  };
7202
+ state.selectedRegistry = selected;
7025
7203
  if (state.events) {
7026
- state.events.append("dist_registry_selected", {
7027
- origin: picked.origin,
7028
- latencyMs: picked.latencyMs,
7029
- candidates: results.map((r) => r.origin + ":" + r.latencyMs + "ms")
7030
- });
7204
+ try {
7205
+ state.events.append(firstReachable || manual ? "dist_registry_selected" : "dist_registry_unreachable", {
7206
+ origin: primary,
7207
+ source: selected.source,
7208
+ candidates: results.map((r) => r.origin + ":" + (r.ok ? r.latencyMs + "ms" : r.error || "\u4E0D\u53EF\u8FBE"))
7209
+ });
7210
+ } catch {
7211
+ }
7031
7212
  }
7032
- return picked.origin;
7213
+ return selected;
7214
+ }
7215
+ async function registryOrigin(state, force) {
7216
+ const sel = await selectRegistry(state, force);
7217
+ return sel && sel.origin || null;
7033
7218
  }
7034
7219
  async function registryInfo(state) {
7035
- reloadContractIfStale(state);
7036
- const origin = await selectRegistry(state, false);
7220
+ config.reloadContractIfStale(state);
7221
+ const sel = await selectRegistry(state, false) || {};
7037
7222
  const rc = state.registryConfig || {};
7038
7223
  const c = state.contract;
7039
- const sel = state.selectedRegistry;
7224
+ const verdictOf = (origin) => (sel.probes || []).find((p) => p.origin === origin) || null;
7040
7225
  return {
7041
- origin,
7226
+ origin: sel.origin || null,
7227
+ ordered: sel.ordered || [],
7228
+ source: sel.source || null,
7042
7229
  mode: rc.mode || "auto",
7043
7230
  manualOrigin: rc.manualOrigin || "",
7044
7231
  candidates: registryOrigins(state).map((o) => ({ origin: o })),
7232
+ registries: registryOrigins(state).map((o) => {
7233
+ const parsed = ref.parseRegistryBase(o);
7234
+ const v = verdictOf(o);
7235
+ return {
7236
+ base: parsed.base,
7237
+ usable: parsed.ok,
7238
+ violation: parsed.violation,
7239
+ reachable: v ? v.ok : null,
7240
+ latencyMs: v ? v.latencyMs : null,
7241
+ error: v ? v.error || null : null
7242
+ };
7243
+ }),
7045
7244
  // 预设 = 壳投放的目录;契约不可用时为空数组,UI 应展示 candidates。
7046
7245
  presets: c && c.ok ? c.catalog : [],
7047
7246
  catalogSource: c && c.ok ? c.writtenBy || "shell" : "fallback",
7048
- latencyMs: sel && sel.latencyMs || null,
7049
- checkedAt: sel && sel.checkedAt || null,
7050
- manual: !!(sel && sel.manual),
7051
- probes: sel && sel.probes || []
7247
+ latencyMs: sel.latencyMs || null,
7248
+ checkedAt: sel.checkedAt || null,
7249
+ manual: !!sel.manual,
7250
+ probes: sel.probes || []
7052
7251
  };
7053
7252
  }
7054
7253
  async function setRegistryConfig(state, cfg) {
@@ -7085,7 +7284,7 @@ var require_registry2 = __commonJS({
7085
7284
  }
7086
7285
  }
7087
7286
  state.registryConfig = rc;
7088
- saveRegistryConfig(state);
7287
+ config.saveRegistryConfig(state);
7089
7288
  state.selectedRegistry = null;
7090
7289
  const info = await registryInfo(state);
7091
7290
  if (rejected.length) {
@@ -7097,21 +7296,117 @@ var require_registry2 = __commonJS({
7097
7296
  return info;
7098
7297
  }
7099
7298
  module2.exports = {
7100
- CONTRACT_TTL_MS,
7101
7299
  platformTag,
7102
- reloadContractIfStale,
7103
- loadRegistryConfig,
7104
- saveRegistryConfig,
7105
7300
  probeRegistry,
7106
7301
  probeOrigin,
7302
+ probeAllOrigins,
7107
7303
  registryOrigins,
7304
+ orderFor,
7108
7305
  selectRegistry,
7306
+ registryOrigin,
7109
7307
  registryInfo,
7110
7308
  setRegistryConfig
7111
7309
  };
7112
7310
  }
7113
7311
  });
7114
7312
 
7313
+ // src/platform/distribution/version-check.js
7314
+ var require_version_check = __commonJS({
7315
+ "src/platform/distribution/version-check.js"(exports2, module2) {
7316
+ "use strict";
7317
+ var { VERSION_RE } = require_version2();
7318
+ var input = require_input();
7319
+ var policies = require_policies();
7320
+ var registry = require_registry2();
7321
+ var ref = require_registry_ref();
7322
+ var release = require_release();
7323
+ var PKG_NAME_RE = input.PKG_NAME_RE;
7324
+ var METADATA_TIMEOUT_MS = 8e3;
7325
+ var FETCH_BUDGET_MS = 25e3;
7326
+ async function versionFromOrigin(state, base, pkg) {
7327
+ const url = ref.registryUrl(base, ref.registryPackagePath(pkg));
7328
+ const res = await ref.fetchRegistry(url, { timeoutMs: METADATA_TIMEOUT_MS, expect: "json" });
7329
+ if (!res.ok) return { version: null, error: res.error || "HTTP " + res.status };
7330
+ const picked = release.pickReleaseVersion(res.json, {
7331
+ isOurs: release.isOurReleasePackage(pkg),
7332
+ canary: policies.isInCanaryList(state),
7333
+ // 仅 isOurs 分支消费
7334
+ isValid: (v2) => typeof v2 === "string" && VERSION_RE.test(v2)
7335
+ });
7336
+ if (picked) return { version: picked, error: null };
7337
+ const lr = await ref.fetchRegistry(
7338
+ ref.registryUrl(base, ref.registryPackagePath(pkg), "latest"),
7339
+ { timeoutMs: METADATA_TIMEOUT_MS, expect: "json" }
7340
+ );
7341
+ if (!lr.ok) return { version: null, error: lr.error || "HTTP " + lr.status };
7342
+ const v = lr.json && typeof lr.json.version === "string" && VERSION_RE.test(lr.json.version) ? lr.json.version : null;
7343
+ return { version: v, error: v ? null : "\u5143\u6570\u636E\u65E0\u53EF\u7528\u7248\u672C" };
7344
+ }
7345
+ async function fetchNpmLatest(state, pkg, opts) {
7346
+ const o = opts || {};
7347
+ const fail = (error, attempts2) => ({ ok: false, version: null, origin: null, attempts: attempts2 || [], error });
7348
+ if (!pkg) return fail("\u7F3A\u5C11\u5305\u540D");
7349
+ if (!PKG_NAME_RE.test(pkg)) return fail("\u975E\u6CD5\u5305\u540D\uFF08\u5B57\u7B26\u96C6\u767D\u540D\u5355\u4E0D\u901A\u8FC7\uFF09: " + String(pkg).slice(0, 80));
7350
+ let candidates = [];
7351
+ if (o.authoritative) {
7352
+ const list = registry.registryOrigins(state).filter((x) => ref.parseRegistryBase(x).ok);
7353
+ candidates = list.filter((x) => /registry\.npmjs\.org/.test(x));
7354
+ if (!candidates.length && list.length) candidates = [list[0]];
7355
+ } else {
7356
+ const sel = await registry.selectRegistry(state, false);
7357
+ candidates = sel && sel.ordered || [];
7358
+ }
7359
+ if (!candidates.length) return fail("\u65E0\u53EF\u7528\u7684\u955C\u50CF\u6E90\u5019\u9009\uFF08\u5168\u90E8\u57FA\u5740\u975E\u6CD5\u6216\u5217\u8868\u4E3A\u7A7A\uFF09");
7360
+ const attempts = [];
7361
+ const deadline = Date.now() + FETCH_BUDGET_MS;
7362
+ for (let i = 0; i < candidates.length; i++) {
7363
+ if (i && Date.now() >= deadline) {
7364
+ attempts.push({ origin: candidates.slice(i).join(","), error: "\u672A\u5C1D\u8BD5\uFF08\u8D85\u51FA " + Math.round(FETCH_BUDGET_MS / 1e3) + "s \u603B\u9884\u7B97\uFF09" });
7365
+ break;
7366
+ }
7367
+ const base = candidates[i];
7368
+ const r = await versionFromOrigin(state, base, pkg);
7369
+ if (r.version) return { ok: true, version: r.version, origin: base, attempts, error: null };
7370
+ attempts.push({ origin: base, error: r.error || "\u672A\u53D6\u5230\u7248\u672C" });
7371
+ }
7372
+ return fail("\u5168\u90E8\u955C\u50CF\u672A\u53D6\u5230 " + pkg + " \u7684\u7248\u672C\uFF1A" + attempts.map((a) => a.origin + "=" + a.error).join("; "), attempts);
7373
+ }
7374
+ async function fetchGithubLatest(owner, repo) {
7375
+ if (!owner || !repo) return null;
7376
+ try {
7377
+ const res = await fetch(
7378
+ "https://api.github.com/repos/" + encodeURIComponent(owner) + "/" + encodeURIComponent(repo) + "/releases/latest",
7379
+ { signal: AbortSignal.timeout(1e4), headers: { "User-Agent": "dsh-supervisor" } }
7380
+ );
7381
+ if (!res.ok) return null;
7382
+ const j = await res.json();
7383
+ const tag = j && typeof j.tag_name === "string" ? j.tag_name : j && typeof j.name === "string" ? j.name : null;
7384
+ if (!tag) return null;
7385
+ return String(tag).replace(/^v/, "");
7386
+ } catch (e) {
7387
+ return null;
7388
+ }
7389
+ }
7390
+ async function fetchLatestVersion(state, pkg, channel, opts) {
7391
+ const ch = channel || "npm";
7392
+ const o = opts || {};
7393
+ if (ch === "github") {
7394
+ const slash = String(pkg).split("/");
7395
+ if (slash.length >= 2) return fetchGithubLatest(slash[0], slash.slice(1).join("/"));
7396
+ return null;
7397
+ }
7398
+ const r = await fetchNpmLatest(state, pkg, { authoritative: o.authoritative === true });
7399
+ return r.ok ? r.version : null;
7400
+ }
7401
+ module2.exports = {
7402
+ METADATA_TIMEOUT_MS,
7403
+ FETCH_BUDGET_MS,
7404
+ fetchNpmLatest,
7405
+ fetchLatestVersion
7406
+ };
7407
+ }
7408
+ });
7409
+
7115
7410
  // src/platform/contract/runtime.js
7116
7411
  var require_runtime = __commonJS({
7117
7412
  "src/platform/contract/runtime.js"(exports2, module2) {
@@ -7189,72 +7484,11 @@ var require_install = __commonJS({
7189
7484
  var runtimeContract = require_runtime();
7190
7485
  var service = require_service().current();
7191
7486
  var { VERSION_RE } = require_version2();
7192
- var release = require_release();
7193
- var registry = require_registry2();
7194
- var policies = require_policies();
7487
+ var ref = require_registry_ref();
7195
7488
  var input = require_input();
7196
7489
  var PKG_NAME_RE = input.PKG_NAME_RE;
7197
7490
  var BAD_ARGV_CHAR_RE = input.ARGV_UNSAFE_RE;
7198
7491
  var WIN_DRIVE_ABS_RE = input.WIN_ABS_PATH_RE;
7199
- async function fetchNpmLatest(state, pkg, opts) {
7200
- if (!pkg) return null;
7201
- const o = opts || {};
7202
- let origin = null;
7203
- if (o.authoritative) {
7204
- const list = registry.registryOrigins(state);
7205
- origin = list.find((x) => /registry\.npmjs\.org/.test(x)) || list[0] || "https://registry.npmjs.org";
7206
- } else {
7207
- origin = await registry.selectRegistry(state, false);
7208
- }
7209
- if (!origin) return null;
7210
- const base = policies.normalizeOrigin(origin);
7211
- if (!policies.isValidOrigin(base)) return null;
7212
- if (!PKG_NAME_RE.test(pkg)) return null;
7213
- try {
7214
- const res = await fetch(base + "/" + encodeURIComponent(pkg), { signal: AbortSignal.timeout(1e4) });
7215
- if (!res.ok) return null;
7216
- const j = await res.json();
7217
- const picked = release.pickReleaseVersion(j, {
7218
- isOurs: release.isOurReleasePackage(pkg),
7219
- canary: policies.isInCanaryList(state),
7220
- // 仅 isOurs 分支消费
7221
- isValid: (v) => typeof v === "string" && VERSION_RE.test(v)
7222
- });
7223
- if (picked) return picked;
7224
- const lr = await fetch(base + "/" + encodeURIComponent(pkg) + "/latest", { signal: AbortSignal.timeout(8e3) });
7225
- if (!lr.ok) return null;
7226
- const lj = await lr.json();
7227
- return lj && typeof lj.version === "string" && VERSION_RE.test(lj.version) ? lj.version : null;
7228
- } catch (e) {
7229
- return null;
7230
- }
7231
- }
7232
- async function fetchGithubLatest(owner, repo) {
7233
- if (!owner || !repo) return null;
7234
- try {
7235
- const res = await fetch(
7236
- "https://api.github.com/repos/" + encodeURIComponent(owner) + "/" + encodeURIComponent(repo) + "/releases/latest",
7237
- { signal: AbortSignal.timeout(1e4), headers: { "User-Agent": "dsh-supervisor" } }
7238
- );
7239
- if (!res.ok) return null;
7240
- const j = await res.json();
7241
- const tag = j && typeof j.tag_name === "string" ? j.tag_name : j && typeof j.name === "string" ? j.name : null;
7242
- if (!tag) return null;
7243
- return String(tag).replace(/^v/, "");
7244
- } catch (e) {
7245
- return null;
7246
- }
7247
- }
7248
- async function fetchLatestVersion(state, pkg, channel, opts) {
7249
- const ch = channel || "npm";
7250
- const o = opts || {};
7251
- if (ch === "github") {
7252
- const slash = String(pkg).split("/");
7253
- if (slash.length >= 2) return fetchGithubLatest(slash[0], slash.slice(1).join("/"));
7254
- return null;
7255
- }
7256
- return fetchNpmLatest(state, pkg, { authoritative: o.authoritative === true });
7257
- }
7258
7492
  var INFLIGHT_NPM = /* @__PURE__ */ new Set();
7259
7493
  function inflightNpmCount() {
7260
7494
  return INFLIGHT_NPM.size;
@@ -7303,11 +7537,12 @@ var require_install = __commonJS({
7303
7537
  }
7304
7538
  const envVars = runtimeContract.withPath(process.env);
7305
7539
  if (o.registry) {
7306
- if (!policies.isValidOrigin(o.registry)) {
7307
- return Promise.resolve({ ok: false, error: "runNpmInstall: \u975E\u6CD5 registry origin\uFF08\u987B\u4E3A\u7EAF http(s) origin\uFF09: " + String(o.registry).slice(0, 80), output: [] });
7540
+ const rv = ref.parseRegistryBase(o.registry);
7541
+ if (!rv.ok) {
7542
+ return Promise.resolve({ ok: false, error: "runNpmInstall: \u975E\u6CD5 registry \u57FA\u5740\uFF08" + rv.violation + "\uFF09: " + String(o.registry).slice(0, 80), output: [] });
7308
7543
  }
7309
- envVars.npm_config_registry = o.registry;
7310
- envVars.NPM_CONFIG_REGISTRY = o.registry;
7544
+ envVars.npm_config_registry = rv.base;
7545
+ envVars.NPM_CONFIG_REGISTRY = rv.base;
7311
7546
  }
7312
7547
  return new Promise((resolve) => {
7313
7548
  let child;
@@ -7417,9 +7652,6 @@ var require_install = __commonJS({
7417
7652
  PKG_NAME_RE,
7418
7653
  BAD_ARGV_CHAR_RE,
7419
7654
  WIN_DRIVE_ABS_RE,
7420
- fetchNpmLatest,
7421
- fetchGithubLatest,
7422
- fetchLatestVersion,
7423
7655
  runNpmInstall,
7424
7656
  waitPortHealthy,
7425
7657
  // 在途 npm 的记账/中止出口(关停路径经 platform/distribution 门面 re-export)
@@ -7435,7 +7667,9 @@ var require_distribution = __commonJS({
7435
7667
  "use strict";
7436
7668
  var policies = require_policies();
7437
7669
  var release = require_release();
7670
+ var registryConfig = require_registry_config();
7438
7671
  var registry = require_registry2();
7672
+ var versionCheck = require_version_check();
7439
7673
  var install = require_install();
7440
7674
  var { semverCompare, VERSION_RE } = require_version2();
7441
7675
  var DistributionManager = class {
@@ -7449,18 +7683,18 @@ var require_distribution = __commonJS({
7449
7683
  this.registryConfig = { mode: "auto", origins: [...this.defaultRegistries], manualOrigin: this.defaultRegistries[0] || "" };
7450
7684
  this.canary = opts.canary === true;
7451
7685
  this.selectedRegistry = null;
7452
- registry.loadRegistryConfig(this);
7686
+ registryConfig.loadRegistryConfig(this);
7453
7687
  this._contractLoadedAt = Date.now();
7454
7688
  }
7455
- // ---- 镜像源(registry.js)----
7689
+ // ---- 镜像源(registry-config.js 载入/落盘,registry.js 探测/选源)----
7456
7690
  _reloadContractIfStale() {
7457
- registry.reloadContractIfStale(this);
7691
+ registryConfig.reloadContractIfStale(this);
7458
7692
  }
7459
7693
  _loadRegistryConfig() {
7460
- registry.loadRegistryConfig(this);
7694
+ registryConfig.loadRegistryConfig(this);
7461
7695
  }
7462
7696
  _saveRegistryConfig() {
7463
- registry.saveRegistryConfig(this);
7697
+ registryConfig.saveRegistryConfig(this);
7464
7698
  }
7465
7699
  _platformTag() {
7466
7700
  return registry.platformTag();
@@ -7477,6 +7711,9 @@ var require_distribution = __commonJS({
7477
7711
  selectRegistry(force) {
7478
7712
  return registry.selectRegistry(this, force);
7479
7713
  }
7714
+ registryOrigin(force) {
7715
+ return registry.registryOrigin(this, force);
7716
+ }
7480
7717
  registryInfo() {
7481
7718
  return registry.registryInfo(this);
7482
7719
  }
@@ -7486,15 +7723,13 @@ var require_distribution = __commonJS({
7486
7723
  _inCanaryList() {
7487
7724
  return policies.isInCanaryList(this);
7488
7725
  }
7489
- // ---- 版本检查 / 安装 / 健康(install.js)----
7726
+ // ---- 版本检查 / 安装 / 健康(version-check.js + install.js)----
7727
+ // fetchNpmLatest 回结构化结果(含实际给出该版本的 origin 与逐源原因);fetchLatestVersion 只回版本字符串。
7490
7728
  fetchNpmLatest(pkg, opts) {
7491
- return install.fetchNpmLatest(this, pkg, opts);
7492
- }
7493
- fetchGithubLatest(owner, repo) {
7494
- return install.fetchGithubLatest(owner, repo);
7729
+ return versionCheck.fetchNpmLatest(this, pkg, opts);
7495
7730
  }
7496
7731
  fetchLatestVersion(pkg, channel, opts) {
7497
- return install.fetchLatestVersion(this, pkg, channel, opts);
7732
+ return versionCheck.fetchLatestVersion(this, pkg, channel, opts);
7498
7733
  }
7499
7734
  runNpmInstall(opts) {
7500
7735
  return install.runNpmInstall(opts);
@@ -15258,7 +15493,7 @@ var require_pkg_cache = __commonJS({
15258
15493
  if (!app || !app.pkg) return { ok: true };
15259
15494
  if (cachedPkgBin(app.pkg)) return { ok: true, cached: true };
15260
15495
  try {
15261
- const regOrigin = provider.dist ? await provider.dist.selectRegistry(false).catch(() => null) : null;
15496
+ const regOrigin = provider.dist ? await provider.dist.registryOrigin(false).catch(() => null) : null;
15262
15497
  const env = Object.assign({}, process.env);
15263
15498
  if (regOrigin) {
15264
15499
  env.npm_config_registry = regOrigin;
@@ -15955,7 +16190,7 @@ var require_proxy = __commonJS({
15955
16190
  }
15956
16191
  /** 解析启动命令(缓存优先 + fallback npx):拼装委托 command.js;凭证剔除留在本层(纪律)。 */
15957
16192
  async _resolveLaunchCommand(app, port, key) {
15958
- const registry = this.dist ? await this.dist.selectRegistry(false).catch(() => null) : null;
16193
+ const registry = this.dist ? await this.dist.registryOrigin(false).catch(() => null) : null;
15959
16194
  const cachedBin = this._cachedPkgBin(app.pkg);
15960
16195
  const launch = buildCommand({ app, port, cachedBin, registry, launcher: npxLauncher(), execPath: process.execPath });
15961
16196
  if (!launch || !launch.ok) return launch || { ok: false, error: "\u547D\u4EE4\u62FC\u88C5\u5931\u8D25" };
@@ -17590,12 +17825,18 @@ var require_apps_registry = __commonJS({
17590
17825
  continue;
17591
17826
  }
17592
17827
  let ver = null;
17828
+ let why = "\u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
17593
17829
  try {
17594
- if (dist) ver = await dist.fetchNpmLatest(a.registry);
17595
- } catch {
17830
+ if (dist) {
17831
+ const r = await dist.fetchNpmLatest(a.registry);
17832
+ ver = r && r.ok ? r.version : null;
17833
+ why = r && r.ok ? null : r && r.error || "\u672A\u53D6\u5230\u7248\u672C";
17834
+ }
17835
+ } catch (e) {
17836
+ why = e && e.message || String(e);
17596
17837
  }
17597
17838
  const prev = c.latest || null;
17598
- cache[a.id] = { pkg: a.registry, latest: ver, checkedAt: Date.now(), error: ver ? null : "query failed" };
17839
+ cache[a.id] = { pkg: a.registry, latest: ver, checkedAt: Date.now(), error: ver ? null : why || "query failed" };
17599
17840
  if (ver && prev && ver !== prev && events) events.append("proxy_update_available", { appId: a.id, pkg: a.registry, from: prev, to: ver });
17600
17841
  results[a.id] = ver;
17601
17842
  }
@@ -19970,8 +20211,7 @@ var require_dsh_install = __commonJS({
19970
20211
  function createDshInstall(deps) {
19971
20212
  const { store, dist, tasks, logger, instancesRoot } = deps;
19972
20213
  const save = () => store.save();
19973
- let _latestDshVer = null;
19974
- let _latestDshVerAt = 0;
20214
+ let _latestDsh = null;
19975
20215
  function installTimeoutWatchdog(inst, task) {
19976
20216
  try {
19977
20217
  if (inst.state && inst.state.phase === "INSTALLING") {
@@ -20036,49 +20276,38 @@ var require_dsh_install = __commonJS({
20036
20276
  } catch {
20037
20277
  }
20038
20278
  }
20039
- const env = Object.assign({}, process.env);
20040
- let reg = null;
20041
- if (dist) {
20042
- try {
20043
- reg = await dist.selectRegistry(false);
20044
- if (reg) {
20045
- env.npm_config_registry = reg;
20046
- env.NPM_CONFIG_REGISTRY = reg;
20047
- }
20048
- } catch (e) {
20049
- logger.warn && logger.warn("sandbox registry select failed: " + e.message);
20050
- }
20051
- }
20052
- const latestVer = await latestDshVersion();
20053
- pushLog("\u5B89\u88C5\u76EE\u6807\u7248\u672C\uFF1A" + (latestVer || "latest tag"));
20054
- if (!latestVer) {
20279
+ if (!dist) {
20055
20280
  inst.state.installOk = false;
20056
- inst.state.installError = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C";
20281
+ inst.state.installError = "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
20057
20282
  save();
20058
20283
  if (task) {
20059
20284
  try {
20060
- tasks.fail(task.id, "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C");
20285
+ tasks.fail(task.id, "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528");
20061
20286
  } catch {
20062
20287
  }
20063
20288
  }
20064
- return { ok: false, error: "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C" };
20289
+ return { ok: false, error: "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528" };
20065
20290
  }
20066
- if (!dist) {
20291
+ const pick = await latestDsh();
20292
+ pushLog("\u5B89\u88C5\u76EE\u6807\u7248\u672C\uFF1A" + (pick.version || "\u672A\u77E5") + (pick.origin ? "\uFF08\u6E90 " + pick.origin + "\uFF09" : ""));
20293
+ if (!pick.version) {
20294
+ const why = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\uFF1A" + (pick.error || "\u672A\u77E5\u539F\u56E0");
20067
20295
  inst.state.installOk = false;
20068
- inst.state.installError = "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
20296
+ inst.state.installError = why;
20069
20297
  save();
20070
20298
  if (task) {
20071
20299
  try {
20072
- tasks.fail(task.id, "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528");
20300
+ tasks.fail(task.id, why);
20073
20301
  } catch {
20074
20302
  }
20075
20303
  }
20076
- return { ok: false, error: "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528" };
20304
+ return { ok: false, error: why };
20077
20305
  }
20306
+ const latestVer = pick.version;
20078
20307
  const watchdog = setTimeout(() => installTimeoutWatchdog(inst, task), 10 * 60 * 1e3);
20079
20308
  let res;
20080
20309
  try {
20081
- res = await dist.runNpmInstall({ pkg: "@deepseek-ai/dsh", version: latestVer, prefix: installDir, registry: reg, onLine: pushLog });
20310
+ res = await dist.runNpmInstall({ pkg: "@deepseek-ai/dsh", version: latestVer, prefix: installDir, registry: pick.origin, onLine: pushLog });
20082
20311
  } finally {
20083
20312
  clearTimeout(watchdog);
20084
20313
  }
@@ -20124,18 +20353,24 @@ var require_dsh_install = __commonJS({
20124
20353
  return null;
20125
20354
  }
20126
20355
  }
20127
- async function latestDshVersion() {
20128
- if (_latestDshVer && Date.now() - _latestDshVerAt < 3e4) return _latestDshVer;
20129
- let v = null;
20130
- try {
20131
- if (dist) v = await dist.fetchNpmLatest("@deepseek-ai/dsh");
20132
- } catch {
20356
+ async function latestDsh() {
20357
+ if (_latestDsh && Date.now() - _latestDsh.at < 3e4) return _latestDsh;
20358
+ let r = { ok: false, version: null, origin: null, attempts: [], error: "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528" };
20359
+ if (dist) {
20360
+ try {
20361
+ r = await dist.fetchNpmLatest("@deepseek-ai/dsh");
20362
+ } catch (e) {
20363
+ r = { ok: false, version: null, origin: null, attempts: [], error: e && e.message || String(e) };
20364
+ }
20133
20365
  }
20134
- _latestDshVer = v;
20135
- _latestDshVerAt = Date.now();
20136
- return v;
20366
+ if (r.ok && r.version) _latestDsh = Object.assign({ at: Date.now() }, r);
20367
+ return r;
20137
20368
  }
20138
- return { installSandbox, readInstalledVersion, latestDshVersion };
20369
+ async function latestDshVersion() {
20370
+ const r = await latestDsh();
20371
+ return r.version;
20372
+ }
20373
+ return { installSandbox, readInstalledVersion, latestDsh, latestDshVersion };
20139
20374
  }
20140
20375
  module2.exports = { createDshInstall };
20141
20376
  }
@@ -20183,6 +20418,9 @@ var require_upgrade = __commonJS({
20183
20418
  function readInstalledVersion(inst) {
20184
20419
  return install.readInstalledVersion(inst);
20185
20420
  }
20421
+ async function latestDsh() {
20422
+ return install.latestDsh();
20423
+ }
20186
20424
  async function latestDshVersion() {
20187
20425
  return install.latestDshVersion();
20188
20426
  }
@@ -20213,8 +20451,9 @@ var require_upgrade = __commonJS({
20213
20451
  let latest = cached && cached.latest || null;
20214
20452
  if (!latest || !cached || Date.now() - cached.checkedAt > _updTTL) {
20215
20453
  try {
20216
- latest = await dist.fetchNpmLatest("@deepseek-ai/dsh");
20217
- _updCache[id] = { latest, checkedAt: Date.now(), error: latest ? null : "\u67E5\u8BE2\u5931\u8D25" };
20454
+ const pick = await dist.fetchNpmLatest("@deepseek-ai/dsh");
20455
+ latest = pick.ok ? pick.version : null;
20456
+ _updCache[id] = { latest, checkedAt: Date.now(), error: pick.ok ? null : pick.error || "\u67E5\u8BE2\u5931\u8D25" };
20218
20457
  } catch (e) {
20219
20458
  latest = null;
20220
20459
  _updCache[id] = { latest: null, checkedAt: Date.now(), error: e.message };
@@ -20241,16 +20480,6 @@ var require_upgrade = __commonJS({
20241
20480
  _updJobs[id] = nj;
20242
20481
  (async () => {
20243
20482
  const installDir = sandbox.installDir(instancesRoot, inst);
20244
- const env = Object.assign({}, process.env);
20245
- let reg = null;
20246
- try {
20247
- reg = await dist.selectRegistry(false);
20248
- if (reg) {
20249
- env.npm_config_registry = reg;
20250
- env.NPM_CONFIG_REGISTRY = reg;
20251
- }
20252
- } catch {
20253
- }
20254
20483
  let wasRunning = false;
20255
20484
  try {
20256
20485
  wasRunning = lifecycle.probe(inst).running;
@@ -20277,12 +20506,15 @@ var require_upgrade = __commonJS({
20277
20506
  const s = tasks.step(task.id, "\u5B89\u88C5\u6700\u65B0\u7248");
20278
20507
  tasks.stepState(task.id, tasks.get(task.id).steps.indexOf(s), "running");
20279
20508
  }
20280
- const targetVer = await latestDshVersion();
20281
- if (task) tasks.log(task.id, "\u76EE\u6807\u7248\u672C\uFF1A" + (targetVer || "latest tag"));
20509
+ const pick = await latestDsh();
20510
+ const targetVer = pick.version;
20511
+ const reg = pick.origin;
20512
+ if (task) tasks.log(task.id, "\u76EE\u6807\u7248\u672C\uFF1A" + (targetVer || "\u672A\u77E5") + (reg ? "\uFF08\u6E90 " + reg + "\uFF09" : ""));
20282
20513
  if (!targetVer) {
20514
+ const why = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\uFF1A" + (pick.error || "\u672A\u77E5\u539F\u56E0");
20283
20515
  nj.errors++;
20284
- nj.error = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C";
20285
- if (task) tasks.log(task.id, "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C");
20516
+ nj.error = why;
20517
+ if (task) tasks.log(task.id, why);
20286
20518
  } else {
20287
20519
  if (!dist) {
20288
20520
  nj.errors++;
@@ -21048,6 +21280,7 @@ var require_market_sources = __commonJS({
21048
21280
  "src/domains/plugin/market-sources.js"(exports2, module2) {
21049
21281
  "use strict";
21050
21282
  var { getJson, getText } = require_market_net();
21283
+ var ref = require_registry_ref();
21051
21284
  var RAW_MIRRORS = ["https://gh-proxy.com/", "https://ghproxy.net/"];
21052
21285
  async function rawGet(pathPart, isJson, timeoutMs = 15e3) {
21053
21286
  const direct = "https://raw.githubusercontent.com/" + pathPart;
@@ -21061,12 +21294,10 @@ var require_market_sources = __commonJS({
21061
21294
  throw new Error("raw fetch failed for " + pathPart);
21062
21295
  }
21063
21296
  async function fetchLatest(origin, name) {
21064
- try {
21065
- const base = String(origin || "").replace(/\/+$/, "");
21066
- return await getJson(base + "/" + encodeURIComponent(name) + "/latest", 8e3);
21067
- } catch {
21068
- return null;
21069
- }
21297
+ const url = ref.registryUrl(origin, ref.registryPackagePath(name), "latest");
21298
+ if (!url) return null;
21299
+ const r = await ref.fetchRegistry(url, { timeoutMs: 8e3, expect: "json" });
21300
+ return r.ok ? r.json : null;
21070
21301
  }
21071
21302
  async function repoPkg(fullName) {
21072
21303
  for (const branch of ["master", "main"]) {
@@ -21381,16 +21612,16 @@ var require_market = __commonJS({
21381
21612
  }
21382
21613
  return out;
21383
21614
  }
21384
- /** npm 镜像源 origin(经 dist 统一选择;dist 不可达降级官方源)。 */
21615
+ /** npm 镜像源基址(经 dist 统一选择;dist 不可达降级官方源)。尾斜杠归一交给 registry-ref。 */
21385
21616
  async _npmOrigin() {
21386
21617
  let origin = null;
21387
21618
  if (this.dist) {
21388
21619
  try {
21389
- origin = await this.dist.selectRegistry(false);
21620
+ origin = await this.dist.registryOrigin(false);
21390
21621
  } catch {
21391
21622
  }
21392
21623
  }
21393
- return (origin || REGISTRY).replace(/\/+$/, "");
21624
+ return origin || REGISTRY;
21394
21625
  }
21395
21626
  /** npm 最新版元数据查询(镜像源选择见 _npmOrigin)。 */
21396
21627
  async safeFetchLatest(name) {
@@ -21846,7 +22077,7 @@ var require_cli = __commonJS({
21846
22077
  async function registryOrigin(dist) {
21847
22078
  if (dist) {
21848
22079
  try {
21849
- return dist.selectRegistry(false);
22080
+ return await dist.registryOrigin(false);
21850
22081
  } catch {
21851
22082
  }
21852
22083
  }
@@ -22417,6 +22648,23 @@ var require_updater = __commonJS({
22417
22648
  "src/domains/plugin/updater.js"(exports2, module2) {
22418
22649
  "use strict";
22419
22650
  var { specType, isUpdateAvailable } = require_policies2();
22651
+ async function latestCached(ctx, name, force) {
22652
+ const c = ctx._updCache[name];
22653
+ if (c && !force && Date.now() - c.at < ctx._updTTL) return { latest: c.latest, error: null };
22654
+ let latest = null;
22655
+ let error = "\u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
22656
+ if (ctx.dist) {
22657
+ try {
22658
+ const r = await ctx.dist.fetchNpmLatest(name);
22659
+ latest = r && r.ok ? r.version : null;
22660
+ error = r && r.ok ? null : r && r.error || "\u672A\u53D6\u5230\u7248\u672C";
22661
+ } catch (e) {
22662
+ error = e && e.message || String(e);
22663
+ }
22664
+ }
22665
+ if (latest !== null) ctx._updCache[name] = { latest, at: Date.now() };
22666
+ return { latest, error };
22667
+ }
22420
22668
  async function checkUpdates(ctx, force) {
22421
22669
  const targets = [ctx._nativeTarget(), ...ctx._allSandboxTargets()];
22422
22670
  const meta = /* @__PURE__ */ new Map();
@@ -22425,17 +22673,7 @@ var require_updater = __commonJS({
22425
22673
  if (meta.has(p.name)) continue;
22426
22674
  const st = specType(p.source);
22427
22675
  let latest = null;
22428
- const c = ctx._updCache[p.name];
22429
- if (c && !force && Date.now() - c.at < ctx._updTTL) latest = c.latest;
22430
- else {
22431
- if (st === "npm" && ctx.dist) {
22432
- try {
22433
- latest = await ctx.dist.fetchNpmLatest(p.name);
22434
- } catch {
22435
- }
22436
- }
22437
- if (latest !== null) ctx._updCache[p.name] = { latest, at: Date.now() };
22438
- }
22676
+ if (st === "npm" && ctx.dist) latest = (await latestCached(ctx, p.name, force)).latest;
22439
22677
  meta.set(p.name, { specType: st, latest });
22440
22678
  }
22441
22679
  }
@@ -22468,19 +22706,9 @@ var require_updater = __commonJS({
22468
22706
  const desc = targetStr === "all" ? "\u4EFB\u4F55\u76EE\u6807" : "\u76EE\u6807\u300C" + (targetStr || "native") + "\u300D";
22469
22707
  return { ok: false, error: desc + " \u672A\u5B89\u88C5\u63D2\u4EF6 " + name };
22470
22708
  }
22471
- let latest = null;
22472
- const c = ctx._updCache[name];
22473
- if (c && Date.now() - c.at < ctx._updTTL) latest = c.latest;
22474
- else {
22475
- if (ctx.dist) {
22476
- try {
22477
- latest = await ctx.dist.fetchNpmLatest(name);
22478
- } catch {
22479
- }
22480
- }
22481
- if (latest !== null) ctx._updCache[name] = { latest, at: Date.now() };
22482
- }
22483
- if (!latest) return { ok: false, error: "\u65E0\u6CD5\u83B7\u53D6 " + name + " \u7684\u6700\u65B0\u7248\u672C\uFF08registry \u4E0D\u53EF\u8FBE\uFF09\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5" };
22709
+ const pick = await latestCached(ctx, name, false);
22710
+ const latest = pick.latest;
22711
+ if (!latest) return { ok: false, error: "\u65E0\u6CD5\u83B7\u53D6 " + name + " \u7684\u6700\u65B0\u7248\u672C\uFF08" + (pick.error || "registry \u4E0D\u53EF\u8FBE") + "\uFF09\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5" };
22484
22712
  const job = ctx.jobs.createJob("update", name, targetStr || "native", targets);
22485
22713
  if (ctx.events) ctx.events.append("plugin_update_started", { name, jobId: job.id, target: job.target, targets: targets.map((t) => t.name) });
22486
22714
  let idx = 0;
@@ -23412,7 +23640,7 @@ var require_npm = __commonJS({
23412
23640
  async function selectRegistry(host2) {
23413
23641
  if (!host2.dist) return null;
23414
23642
  try {
23415
- return await host2.dist.selectRegistry(true);
23643
+ return await host2.dist.registryOrigin(true);
23416
23644
  } catch {
23417
23645
  return null;
23418
23646
  }