@dsh-sup/dsh-core-linux-x64 0.1.6-BETA.6 → 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.6");
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 {
@@ -1207,7 +1207,7 @@ var require_main_store = __commonJS({
1207
1207
  if (!live) live = readDshMainFile();
1208
1208
  if (corrupt && !(typeof m.remoteToken === "string" && m.remoteToken)) {
1209
1209
  const l = logger();
1210
- if (l && l.warn) l.warn("_writeDshMain: \u6587\u4EF6\u635F\u574F\u6001\uFF0C\u62D2\u7EDD\u4EE5\u9ED8\u8BA4\u503C\u8986\u76D6\u5199\u56DE");
1210
+ if (l && l.warn) l.warn("writeDshMain: \u6587\u4EF6\u635F\u574F\u6001\uFF0C\u62D2\u7EDD\u4EE5\u9ED8\u8BA4\u503C\u8986\u76D6\u5199\u56DE");
1211
1211
  return;
1212
1212
  }
1213
1213
  corrupt = false;
@@ -1227,7 +1227,7 @@ var require_main_store = __commonJS({
1227
1227
  writeAtomic(f, body, { mode: 384 });
1228
1228
  } catch (e) {
1229
1229
  const l = logger();
1230
- if (l && l.warn) l.warn("_writeDshMain: " + (e && e.message || e));
1230
+ if (l && l.warn) l.warn("writeDshMain: " + (e && e.message || e));
1231
1231
  }
1232
1232
  }
1233
1233
  return { dshMainFile, registryFileName, readDshMain, readDshMainFile, writeDshMain };
@@ -3020,10 +3020,6 @@ var require_facades = __commonJS({
3020
3020
  _makeRouterFacade() {
3021
3021
  const client = createCtlClient({ getConfig: () => this.config });
3022
3022
  return createRouterCtlFacade({ getRouterPort: client.routerCtlPort, ctlCall: client.ctlCall });
3023
- },
3024
- _makeCtlFacade(port) {
3025
- const client = createCtlClient({ getConfig: () => this.config });
3026
- return createCtlFacade({ port, ctlCall: client.ctlCall });
3027
3023
  }
3028
3024
  };
3029
3025
  module2.exports = { createCtlFacade, createRouterCtlFacade, methods };
@@ -4006,27 +4002,7 @@ var require_orphan_scan = __commonJS({
4006
4002
  logger && logger.warn && logger.warn("[orphan] \u81EA\u68C0\u5F02\u5E38: " + (e && e.message || e));
4007
4003
  }
4008
4004
  }
4009
- function hostOrphanAudit() {
4010
- return orphanAudit({
4011
- getConfig: () => this.config,
4012
- getLogger: () => this.logger,
4013
- getEvents: () => this.events,
4014
- getInstances: () => this.instances,
4015
- getManagedObjects: () => this.managedObjects,
4016
- getCtl: () => this.ctl,
4017
- getDaemons: () => this.daemons,
4018
- getStopping: () => this._stopping,
4019
- getLastKey: () => this._lastOrphanKey,
4020
- setLastKey: (v) => {
4021
- this._lastOrphanKey = v;
4022
- },
4023
- getLastAt: () => this._lastOrphanAt,
4024
- setLastAt: (v) => {
4025
- this._lastOrphanAt = v;
4026
- }
4027
- });
4028
- }
4029
- module2.exports = { methods: { _orphanAudit: hostOrphanAudit }, orphanAudit };
4005
+ module2.exports = { orphanAudit };
4030
4006
  }
4031
4007
  });
4032
4008
 
@@ -4132,7 +4108,6 @@ var require_collaborators = __commonJS({
4132
4108
  routerStatus: "routerStatus",
4133
4109
  status: "statusSummary"
4134
4110
  },
4135
- audit: { orphan: "_orphanAudit" },
4136
4111
  ui: { notify: "notify" }
4137
4112
  };
4138
4113
  var THIN_NAMES = Object.keys(THIN_SPEC);
@@ -4227,7 +4202,6 @@ var require_collaborators = __commonJS({
4227
4202
  host2._registryFileName = () => state.registryFileName();
4228
4203
  host2._readDshMain = () => state.readMainMeta();
4229
4204
  host2._readDshMainFile = () => state.readMainMetaFile();
4230
- host2._writeDshMain = (meta) => state.writeMainMeta(meta);
4231
4205
  host2.writeState = (force) => state.write(force);
4232
4206
  host2.loadState = () => state.loadState();
4233
4207
  host2._migrateMainRecord = () => state.migrateMainRecord();
@@ -6535,44 +6509,183 @@ var require_ip = __commonJS({
6535
6509
  }
6536
6510
  });
6537
6511
 
6538
- // src/platform/distribution/policies.js
6539
- var require_policies = __commonJS({
6540
- "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) {
6541
6515
  "use strict";
6542
6516
  var { isPrivateHostLiteral } = require_ip();
6543
- var FALLBACK_REGISTRIES = [
6544
- "https://registry.npmjs.org",
6545
- "https://registry.npmmirror.com"
6546
- ];
6547
- function normalizeOrigin(origin) {
6548
- 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(/\/+$/, "");
6522
+ }
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;
6549
6528
  }
6550
- function isValidOrigin(origin) {
6551
- const s = normalizeOrigin(origin);
6552
- if (!/^https?:\/\/(\[[0-9A-Fa-f:]+\]|[A-Za-z0-9.\-_]+)(:\d+)?$/.test(s)) return false;
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");
6553
6534
  let u;
6554
6535
  try {
6555
- u = new URL(s);
6536
+ u = new URL(base);
6556
6537
  } catch {
6557
- return false;
6538
+ return bad("\u955C\u50CF\u6E90\u65E0\u6CD5\u89E3\u6790: " + base);
6558
6539
  }
6559
- if (u.protocol !== "http:" && u.protocol !== "https:") return false;
6560
- if (u.username || u.password) return false;
6561
- if (u.hash) return false;
6562
- if (!u.hostname) return false;
6563
- 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 };
6564
6546
  }
6565
- function registryOriginViolation(origin) {
6566
- const o = normalizeOrigin(origin);
6567
- 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) {
6568
6548
  let u;
6569
6549
  try {
6570
- u = new URL(o);
6550
+ u = new URL(String(rawUrl || ""));
6571
6551
  } catch {
6572
- return "\u955C\u50CF\u6E90\u65E0\u6CD5\u89E3\u6790: " + o;
6552
+ return "\u8DF3\u8F6C\u76EE\u6807\u65E0\u6CD5\u89E3\u6790";
6573
6553
  }
6574
- 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;
6575
- 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);
6576
6689
  }
6577
6690
  function effectiveOrigins(registryConfig, defaultRegistries) {
6578
6691
  const o = registryConfig && registryConfig.origins || [];
@@ -6590,32 +6703,27 @@ var require_policies = __commonJS({
6590
6703
  };
6591
6704
  }
6592
6705
  function resolveProbe(origin, spec, platformTag) {
6593
- 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 };
6594
6709
  if (spec && spec.kind === "package-metadata" && spec.pathTemplate && platformTag) {
6595
6710
  return {
6596
- url: base + "/" + spec.pathTemplate.replace("{platform}", platformTag),
6711
+ url: registryRef.registryUrl(parsed.base, spec.pathTemplate.replace("{platform}", platformTag)),
6597
6712
  kind: spec.kind,
6598
- timeoutMs: spec.timeoutMs || 4e3
6713
+ timeoutMs
6599
6714
  };
6600
6715
  }
6601
- return { url: base + "/-/ping", kind: "ping", timeoutMs: spec && spec.timeoutMs || 4e3 };
6602
- }
6603
- function pickFastestReachable(results) {
6604
- const reachable = results.filter((r) => r.ok).sort((a, b) => a.latencyMs - b.latencyMs);
6605
- return reachable.length ? reachable[0] : null;
6716
+ return { url: registryRef.registryUrl(parsed.base, "/-/ping"), kind: "ping", timeoutMs };
6606
6717
  }
6607
6718
  function isInCanaryList(state) {
6608
6719
  return state.canary === true;
6609
6720
  }
6610
6721
  module2.exports = {
6611
6722
  FALLBACK_REGISTRIES,
6612
- normalizeOrigin,
6613
- isValidOrigin,
6614
6723
  registryOriginViolation,
6615
6724
  effectiveOrigins,
6616
6725
  rebuildRegistryConfig,
6617
6726
  resolveProbe,
6618
- pickFastestReachable,
6619
6727
  isInCanaryList
6620
6728
  };
6621
6729
  }
@@ -6731,64 +6839,6 @@ var require_release = __commonJS({
6731
6839
  }
6732
6840
  });
6733
6841
 
6734
- // src/platform/contract/matrix.js
6735
- var require_matrix = __commonJS({
6736
- "src/platform/contract/matrix.js"(exports2, module2) {
6737
- "use strict";
6738
- var SUPPORTED = [
6739
- { platform: "linux", arch: "x64", osTag: "linux", npmTag: "linux-x64" },
6740
- { platform: "darwin", arch: "arm64", osTag: "darwin", npmTag: "darwin-arm64" },
6741
- { platform: "darwin", arch: "x64", osTag: "darwin", npmTag: "darwin-x64" },
6742
- { platform: "win32", arch: "x64", osTag: "win", npmTag: "win-x64" }
6743
- ];
6744
- var OS_TAG = { linux: "linux", darwin: "darwin", win32: "win" };
6745
- var FRP_OS = { linux: "linux", darwin: "darwin", win32: "windows" };
6746
- var FRP_ARCH = { x64: "amd64", arm64: "arm64" };
6747
- function osTag(platform) {
6748
- return OS_TAG[platform || process.platform] || null;
6749
- }
6750
- function current(platform, arch) {
6751
- const p = platform || process.platform;
6752
- const a = arch || process.arch;
6753
- return { platform: p, arch: a, osTag: OS_TAG[p] || null, npmTag: npmTag(p, a) };
6754
- }
6755
- function npmTag(platform, arch) {
6756
- const p = platform || process.platform;
6757
- const a = arch || process.arch;
6758
- const os2 = OS_TAG[p];
6759
- if (!os2 || a !== "x64" && a !== "arm64") {
6760
- throw new Error("\u4E0D\u652F\u6301\u7684\u5E73\u53F0\u7EC4\u5408: " + p + "/" + a + "\uFF08\u4EC5 linux/darwin/win32 \xD7 x64/arm64\uFF09");
6761
- }
6762
- return os2 + "-" + a;
6763
- }
6764
- function isSupported(platform, arch) {
6765
- const p = platform || process.platform;
6766
- const a = arch || process.arch;
6767
- return SUPPORTED.some((x) => x.platform === p && x.arch === a);
6768
- }
6769
- function frpTag(platform, arch) {
6770
- const p = platform || process.platform;
6771
- const a = arch || process.arch;
6772
- const os2 = FRP_OS[p];
6773
- const am = FRP_ARCH[a];
6774
- if (!os2 || !am) return null;
6775
- return { os: os2, arch: am, tag: os2 + "_" + am, exe: p === "win32" };
6776
- }
6777
- function supportsProcessGroup(platform) {
6778
- return (platform || process.platform) !== "win32";
6779
- }
6780
- module2.exports = {
6781
- SUPPORTED,
6782
- osTag,
6783
- current,
6784
- npmTag,
6785
- isSupported,
6786
- frpTag,
6787
- supportsProcessGroup
6788
- };
6789
- }
6790
- });
6791
-
6792
6842
  // src/platform/contract/registry.js
6793
6843
  var require_registry = __commonJS({
6794
6844
  "src/platform/contract/registry.js"(exports2, module2) {
@@ -6890,26 +6940,16 @@ var require_registry = __commonJS({
6890
6940
  }
6891
6941
  });
6892
6942
 
6893
- // src/platform/distribution/registry.js
6894
- var require_registry2 = __commonJS({
6895
- "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) {
6896
6946
  "use strict";
6897
6947
  var fs2 = require("node:fs");
6898
6948
  var path2 = require("node:path");
6899
- var matrix = require_matrix();
6900
6949
  var registryContract = require_registry();
6901
6950
  var { writeAtomic } = require_fs();
6902
6951
  var policies = require_policies();
6903
6952
  var CONTRACT_TTL_MS = 60 * 1e3;
6904
- function platformTag() {
6905
- return matrix.npmTag();
6906
- }
6907
- function reloadContractIfStale(state) {
6908
- const now = Date.now();
6909
- if (state._contractLoadedAt && now - state._contractLoadedAt < CONTRACT_TTL_MS) return;
6910
- loadRegistryConfig(state);
6911
- state._contractLoadedAt = now;
6912
- }
6913
6953
  function loadRegistryConfig(state) {
6914
6954
  state.contract = registryContract.read(state.registryFile);
6915
6955
  if (!state.contract.ok) {
@@ -6936,6 +6976,12 @@ var require_registry2 = __commonJS({
6936
6976
  state.logger.warn && state.logger.warn("dist: registry config load failed: " + e.message);
6937
6977
  }
6938
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
+ }
6939
6985
  function saveRegistryConfig(state) {
6940
6986
  if (!state.registryFile) return;
6941
6987
  try {
@@ -6966,6 +7012,85 @@ var require_registry2 = __commonJS({
6966
7012
  doc.manualOrigin = rc.manualOrigin;
6967
7013
  writeAtomic(f, JSON.stringify(doc, null, 2) + "\n", { mode: 384 });
6968
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
+ }
6969
7094
  async function probeRegistry(state, origin) {
6970
7095
  const spec = state.contract && state.contract.ok && state.contract.probe || null;
6971
7096
  let tag = null;
@@ -6975,106 +7100,154 @@ var require_registry2 = __commonJS({
6975
7100
  tag = null;
6976
7101
  }
6977
7102
  const target = policies.resolveProbe(origin, spec, tag);
6978
- const start = Date.now();
6979
- try {
6980
- const res = await fetch(target.url, { signal: AbortSignal.timeout(target.timeoutMs), redirect: "manual" });
6981
- const ok = res.status >= 200 && res.status < 300;
6982
- return { ok, latencyMs: Date.now() - start, probe: target.kind };
6983
- } catch (e) {
6984
- 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" };
6985
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 };
6986
7113
  }
6987
7114
  async function probeOrigin(state, origin) {
6988
- const o = policies.normalizeOrigin(origin);
6989
- if (!policies.isValidOrigin(o)) return { origin: o, ok: false, latencyMs: null, error: "\u975E\u6CD5 origin" };
6990
- const p = await probeRegistry(state, o);
6991
- 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 };
6992
7119
  }
6993
7120
  function registryOrigins(state) {
6994
- 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;
6995
7149
  }
6996
7150
  async function selectRegistry(state, force) {
6997
- reloadContractIfStale(state);
7151
+ config.reloadContractIfStale(state);
6998
7152
  const rc = state.registryConfig || {};
6999
- if (rc.mode === "manual" && rc.manualOrigin) {
7000
- const origin = policies.normalizeOrigin(rc.manualOrigin);
7001
- state.selectedRegistry = { origin, latencyMs: null, checkedAt: Date.now(), manual: true, probes: [] };
7002
- return origin;
7003
- }
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;
7004
7157
  const now = Date.now();
7005
- if (!force && state.selectedRegistry && !state.selectedRegistry.manual && state.selectedRegistry.checkedAt && now - state.selectedRegistry.checkedAt < 30 * 60 * 1e3) {
7006
- return state.selectedRegistry.origin;
7158
+ const cached = state.selectedRegistry;
7159
+ if (!force && cached && cached.checkedAt && now - cached.checkedAt < 30 * 60 * 1e3) {
7160
+ return cached;
7007
7161
  }
7008
7162
  const c = state.contract;
7009
- if (!force && c && c.ok && c.selected) {
7163
+ if (!force && !manual && c && c.ok && c.selected) {
7010
7164
  const age = Math.floor(Date.now() / 1e3) - c.selected.checkedAt;
7011
- 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;
7012
7168
  state.selectedRegistry = {
7013
- origin: c.selected.origin,
7014
- latencyMs: c.selected.latencyMs,
7015
- checkedAt: Date.now(),
7016
- manual: false,
7169
+ origin,
7170
+ ordered: orderFor(origin, origins, null),
7017
7171
  source: "shell",
7018
- 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" }]
7019
7176
  };
7020
7177
  if (state.events) {
7021
7178
  try {
7022
- state.events.append("dist_registry_selected", { origin: c.selected.origin, source: "shell-contract" });
7179
+ state.events.append("dist_registry_selected", { origin, source: "shell-contract" });
7023
7180
  } catch {
7024
7181
  }
7025
7182
  }
7026
- return c.selected.origin;
7183
+ return state.selectedRegistry;
7027
7184
  }
7028
- }
7029
- const origins = registryOrigins(state);
7030
- const results = await Promise.all(origins.map(async (origin) => {
7031
- const p = await probeRegistry(state, origin);
7032
- return { origin, ok: p.ok, latencyMs: p.latencyMs };
7033
- }));
7034
- const picked = policies.pickFastestReachable(results);
7035
- if (!picked) {
7036
- state.selectedRegistry = { origin: null, latencyMs: null, checkedAt: null, manual: false, probes: results };
7037
- if (state.events) {
7038
- state.events.append("dist_registry_unreachable", {
7039
- candidates: results.map((r) => r.origin + ":" + r.latencyMs + "ms")
7040
- });
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");
7041
7187
  }
7042
- return null;
7043
7188
  }
7044
- state.selectedRegistry = {
7045
- origin: picked.origin,
7046
- latencyMs: picked.latencyMs,
7047
- checkedAt: Date.now(),
7048
- 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,
7049
7200
  probes: results
7050
7201
  };
7202
+ state.selectedRegistry = selected;
7051
7203
  if (state.events) {
7052
- state.events.append("dist_registry_selected", {
7053
- origin: picked.origin,
7054
- latencyMs: picked.latencyMs,
7055
- candidates: results.map((r) => r.origin + ":" + r.latencyMs + "ms")
7056
- });
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
+ }
7057
7212
  }
7058
- 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;
7059
7218
  }
7060
7219
  async function registryInfo(state) {
7061
- reloadContractIfStale(state);
7062
- const origin = await selectRegistry(state, false);
7220
+ config.reloadContractIfStale(state);
7221
+ const sel = await selectRegistry(state, false) || {};
7063
7222
  const rc = state.registryConfig || {};
7064
7223
  const c = state.contract;
7065
- const sel = state.selectedRegistry;
7224
+ const verdictOf = (origin) => (sel.probes || []).find((p) => p.origin === origin) || null;
7066
7225
  return {
7067
- origin,
7226
+ origin: sel.origin || null,
7227
+ ordered: sel.ordered || [],
7228
+ source: sel.source || null,
7068
7229
  mode: rc.mode || "auto",
7069
7230
  manualOrigin: rc.manualOrigin || "",
7070
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
+ }),
7071
7244
  // 预设 = 壳投放的目录;契约不可用时为空数组,UI 应展示 candidates。
7072
7245
  presets: c && c.ok ? c.catalog : [],
7073
7246
  catalogSource: c && c.ok ? c.writtenBy || "shell" : "fallback",
7074
- latencyMs: sel && sel.latencyMs || null,
7075
- checkedAt: sel && sel.checkedAt || null,
7076
- manual: !!(sel && sel.manual),
7077
- probes: sel && sel.probes || []
7247
+ latencyMs: sel.latencyMs || null,
7248
+ checkedAt: sel.checkedAt || null,
7249
+ manual: !!sel.manual,
7250
+ probes: sel.probes || []
7078
7251
  };
7079
7252
  }
7080
7253
  async function setRegistryConfig(state, cfg) {
@@ -7111,7 +7284,7 @@ var require_registry2 = __commonJS({
7111
7284
  }
7112
7285
  }
7113
7286
  state.registryConfig = rc;
7114
- saveRegistryConfig(state);
7287
+ config.saveRegistryConfig(state);
7115
7288
  state.selectedRegistry = null;
7116
7289
  const info = await registryInfo(state);
7117
7290
  if (rejected.length) {
@@ -7123,21 +7296,117 @@ var require_registry2 = __commonJS({
7123
7296
  return info;
7124
7297
  }
7125
7298
  module2.exports = {
7126
- CONTRACT_TTL_MS,
7127
7299
  platformTag,
7128
- reloadContractIfStale,
7129
- loadRegistryConfig,
7130
- saveRegistryConfig,
7131
7300
  probeRegistry,
7132
7301
  probeOrigin,
7302
+ probeAllOrigins,
7133
7303
  registryOrigins,
7304
+ orderFor,
7134
7305
  selectRegistry,
7306
+ registryOrigin,
7135
7307
  registryInfo,
7136
7308
  setRegistryConfig
7137
7309
  };
7138
7310
  }
7139
7311
  });
7140
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
+
7141
7410
  // src/platform/contract/runtime.js
7142
7411
  var require_runtime = __commonJS({
7143
7412
  "src/platform/contract/runtime.js"(exports2, module2) {
@@ -7215,72 +7484,11 @@ var require_install = __commonJS({
7215
7484
  var runtimeContract = require_runtime();
7216
7485
  var service = require_service().current();
7217
7486
  var { VERSION_RE } = require_version2();
7218
- var release = require_release();
7219
- var registry = require_registry2();
7220
- var policies = require_policies();
7487
+ var ref = require_registry_ref();
7221
7488
  var input = require_input();
7222
7489
  var PKG_NAME_RE = input.PKG_NAME_RE;
7223
7490
  var BAD_ARGV_CHAR_RE = input.ARGV_UNSAFE_RE;
7224
7491
  var WIN_DRIVE_ABS_RE = input.WIN_ABS_PATH_RE;
7225
- async function fetchNpmLatest(state, pkg, opts) {
7226
- if (!pkg) return null;
7227
- const o = opts || {};
7228
- let origin = null;
7229
- if (o.authoritative) {
7230
- const list = registry.registryOrigins(state);
7231
- origin = list.find((x) => /registry\.npmjs\.org/.test(x)) || list[0] || "https://registry.npmjs.org";
7232
- } else {
7233
- origin = await registry.selectRegistry(state, false);
7234
- }
7235
- if (!origin) return null;
7236
- const base = policies.normalizeOrigin(origin);
7237
- if (!policies.isValidOrigin(base)) return null;
7238
- if (!PKG_NAME_RE.test(pkg)) return null;
7239
- try {
7240
- const res = await fetch(base + "/" + encodeURIComponent(pkg), { signal: AbortSignal.timeout(1e4) });
7241
- if (!res.ok) return null;
7242
- const j = await res.json();
7243
- const picked = release.pickReleaseVersion(j, {
7244
- isOurs: release.isOurReleasePackage(pkg),
7245
- canary: policies.isInCanaryList(state),
7246
- // 仅 isOurs 分支消费
7247
- isValid: (v) => typeof v === "string" && VERSION_RE.test(v)
7248
- });
7249
- if (picked) return picked;
7250
- const lr = await fetch(base + "/" + encodeURIComponent(pkg) + "/latest", { signal: AbortSignal.timeout(8e3) });
7251
- if (!lr.ok) return null;
7252
- const lj = await lr.json();
7253
- return lj && typeof lj.version === "string" && VERSION_RE.test(lj.version) ? lj.version : null;
7254
- } catch (e) {
7255
- return null;
7256
- }
7257
- }
7258
- async function fetchGithubLatest(owner, repo) {
7259
- if (!owner || !repo) return null;
7260
- try {
7261
- const res = await fetch(
7262
- "https://api.github.com/repos/" + encodeURIComponent(owner) + "/" + encodeURIComponent(repo) + "/releases/latest",
7263
- { signal: AbortSignal.timeout(1e4), headers: { "User-Agent": "dsh-supervisor" } }
7264
- );
7265
- if (!res.ok) return null;
7266
- const j = await res.json();
7267
- const tag = j && typeof j.tag_name === "string" ? j.tag_name : j && typeof j.name === "string" ? j.name : null;
7268
- if (!tag) return null;
7269
- return String(tag).replace(/^v/, "");
7270
- } catch (e) {
7271
- return null;
7272
- }
7273
- }
7274
- async function fetchLatestVersion(state, pkg, channel, opts) {
7275
- const ch = channel || "npm";
7276
- const o = opts || {};
7277
- if (ch === "github") {
7278
- const slash = String(pkg).split("/");
7279
- if (slash.length >= 2) return fetchGithubLatest(slash[0], slash.slice(1).join("/"));
7280
- return null;
7281
- }
7282
- return fetchNpmLatest(state, pkg, { authoritative: o.authoritative === true });
7283
- }
7284
7492
  var INFLIGHT_NPM = /* @__PURE__ */ new Set();
7285
7493
  function inflightNpmCount() {
7286
7494
  return INFLIGHT_NPM.size;
@@ -7329,11 +7537,12 @@ var require_install = __commonJS({
7329
7537
  }
7330
7538
  const envVars = runtimeContract.withPath(process.env);
7331
7539
  if (o.registry) {
7332
- if (!policies.isValidOrigin(o.registry)) {
7333
- 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: [] });
7334
7543
  }
7335
- envVars.npm_config_registry = o.registry;
7336
- envVars.NPM_CONFIG_REGISTRY = o.registry;
7544
+ envVars.npm_config_registry = rv.base;
7545
+ envVars.NPM_CONFIG_REGISTRY = rv.base;
7337
7546
  }
7338
7547
  return new Promise((resolve) => {
7339
7548
  let child;
@@ -7443,9 +7652,6 @@ var require_install = __commonJS({
7443
7652
  PKG_NAME_RE,
7444
7653
  BAD_ARGV_CHAR_RE,
7445
7654
  WIN_DRIVE_ABS_RE,
7446
- fetchNpmLatest,
7447
- fetchGithubLatest,
7448
- fetchLatestVersion,
7449
7655
  runNpmInstall,
7450
7656
  waitPortHealthy,
7451
7657
  // 在途 npm 的记账/中止出口(关停路径经 platform/distribution 门面 re-export)
@@ -7461,7 +7667,9 @@ var require_distribution = __commonJS({
7461
7667
  "use strict";
7462
7668
  var policies = require_policies();
7463
7669
  var release = require_release();
7670
+ var registryConfig = require_registry_config();
7464
7671
  var registry = require_registry2();
7672
+ var versionCheck = require_version_check();
7465
7673
  var install = require_install();
7466
7674
  var { semverCompare, VERSION_RE } = require_version2();
7467
7675
  var DistributionManager = class {
@@ -7475,18 +7683,18 @@ var require_distribution = __commonJS({
7475
7683
  this.registryConfig = { mode: "auto", origins: [...this.defaultRegistries], manualOrigin: this.defaultRegistries[0] || "" };
7476
7684
  this.canary = opts.canary === true;
7477
7685
  this.selectedRegistry = null;
7478
- registry.loadRegistryConfig(this);
7686
+ registryConfig.loadRegistryConfig(this);
7479
7687
  this._contractLoadedAt = Date.now();
7480
7688
  }
7481
- // ---- 镜像源(registry.js)----
7689
+ // ---- 镜像源(registry-config.js 载入/落盘,registry.js 探测/选源)----
7482
7690
  _reloadContractIfStale() {
7483
- registry.reloadContractIfStale(this);
7691
+ registryConfig.reloadContractIfStale(this);
7484
7692
  }
7485
7693
  _loadRegistryConfig() {
7486
- registry.loadRegistryConfig(this);
7694
+ registryConfig.loadRegistryConfig(this);
7487
7695
  }
7488
7696
  _saveRegistryConfig() {
7489
- registry.saveRegistryConfig(this);
7697
+ registryConfig.saveRegistryConfig(this);
7490
7698
  }
7491
7699
  _platformTag() {
7492
7700
  return registry.platformTag();
@@ -7503,6 +7711,9 @@ var require_distribution = __commonJS({
7503
7711
  selectRegistry(force) {
7504
7712
  return registry.selectRegistry(this, force);
7505
7713
  }
7714
+ registryOrigin(force) {
7715
+ return registry.registryOrigin(this, force);
7716
+ }
7506
7717
  registryInfo() {
7507
7718
  return registry.registryInfo(this);
7508
7719
  }
@@ -7512,15 +7723,13 @@ var require_distribution = __commonJS({
7512
7723
  _inCanaryList() {
7513
7724
  return policies.isInCanaryList(this);
7514
7725
  }
7515
- // ---- 版本检查 / 安装 / 健康(install.js)----
7726
+ // ---- 版本检查 / 安装 / 健康(version-check.js + install.js)----
7727
+ // fetchNpmLatest 回结构化结果(含实际给出该版本的 origin 与逐源原因);fetchLatestVersion 只回版本字符串。
7516
7728
  fetchNpmLatest(pkg, opts) {
7517
- return install.fetchNpmLatest(this, pkg, opts);
7518
- }
7519
- fetchGithubLatest(owner, repo) {
7520
- return install.fetchGithubLatest(owner, repo);
7729
+ return versionCheck.fetchNpmLatest(this, pkg, opts);
7521
7730
  }
7522
7731
  fetchLatestVersion(pkg, channel, opts) {
7523
- return install.fetchLatestVersion(this, pkg, channel, opts);
7732
+ return versionCheck.fetchLatestVersion(this, pkg, channel, opts);
7524
7733
  }
7525
7734
  runNpmInstall(opts) {
7526
7735
  return install.runNpmInstall(opts);
@@ -12150,7 +12359,8 @@ var require_facets = __commonJS({
12150
12359
  { name: "domain-actions/router", mod: require_router2(), factory: "createRouterActions" },
12151
12360
  { name: "domain-actions/lan", mod: require_lan2(), factory: "createLanActions" },
12152
12361
  { name: "domain-actions/main", mod: require_main2(), factory: "createMainActions" },
12153
- { name: "audit/orphan-scan", mod: require_orphan_scan() },
12362
+ // audit/orphan-scan 不在本清单:它是真 ctor 工厂(assembly/collaborators.js 的 installAuditFactory
12363
+ // 构造 host.audit),实现体本身只是纯函数,不再需要 host 兼容外壳切面。
12154
12364
  { name: "settings/env", mod: require_env() },
12155
12365
  { name: "settings/node-lts", mod: require_node_lts() },
12156
12366
  { name: "settings/versions", mod: require_versions() },
@@ -13944,7 +14154,7 @@ var require_model = __commonJS({
13944
14154
  adapter: p.adapter || null,
13945
14155
  proxyAppId: p.proxyAppId || null,
13946
14156
  proxyRunning: p.proxyRunning || false,
13947
- selectedAccountKeyId: p.selectedAccountKeyId || p.selectedProxyKeyId || null,
14157
+ selectedAccountKeyId: p.selectedAccountKeyId || null,
13948
14158
  activeAccountKeyId: p.activeAccount && p.activeAccount.keyId || null,
13949
14159
  accounts: (p.accounts || []).map((a) => {
13950
14160
  p._normalizeConsistency(a);
@@ -14356,7 +14566,6 @@ var require_freeze = __commonJS({
14356
14566
  const usable = !!acc && acc.status === "ready" && (typeof provider.isAccountUsable !== "function" || provider.isAccountUsable(acc));
14357
14567
  if (!usable) {
14358
14568
  provider.selectedAccountKeyId = null;
14359
- if (provider.selectedProxyKeyId === lockedId) provider.selectedProxyKeyId = null;
14360
14569
  }
14361
14570
  }
14362
14571
  module2.exports = { setStatus, ensureLimit, previewLimit, setLimit, freezeLimited, markCreditsExhausted, markQuotaExhausted, markBanned, applyDetection, normalizeConsistency, reconcileLock };
@@ -15284,7 +15493,7 @@ var require_pkg_cache = __commonJS({
15284
15493
  if (!app || !app.pkg) return { ok: true };
15285
15494
  if (cachedPkgBin(app.pkg)) return { ok: true, cached: true };
15286
15495
  try {
15287
- 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;
15288
15497
  const env = Object.assign({}, process.env);
15289
15498
  if (regOrigin) {
15290
15499
  env.npm_config_registry = regOrigin;
@@ -15981,7 +16190,7 @@ var require_proxy = __commonJS({
15981
16190
  }
15982
16191
  /** 解析启动命令(缓存优先 + fallback npx):拼装委托 command.js;凭证剔除留在本层(纪律)。 */
15983
16192
  async _resolveLaunchCommand(app, port, key) {
15984
- 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;
15985
16194
  const cachedBin = this._cachedPkgBin(app.pkg);
15986
16195
  const launch = buildCommand({ app, port, cachedBin, registry, launcher: npxLauncher(), execPath: process.execPath });
15987
16196
  if (!launch || !launch.ok) return launch || { ok: false, error: "\u547D\u4EE4\u62FC\u88C5\u5931\u8D25" };
@@ -17616,12 +17825,18 @@ var require_apps_registry = __commonJS({
17616
17825
  continue;
17617
17826
  }
17618
17827
  let ver = null;
17828
+ let why = "\u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
17619
17829
  try {
17620
- if (dist) ver = await dist.fetchNpmLatest(a.registry);
17621
- } 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);
17622
17837
  }
17623
17838
  const prev = c.latest || null;
17624
- 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" };
17625
17840
  if (ver && prev && ver !== prev && events) events.append("proxy_update_available", { appId: a.id, pkg: a.registry, from: prev, to: ver });
17626
17841
  results[a.id] = ver;
17627
17842
  }
@@ -19996,8 +20211,7 @@ var require_dsh_install = __commonJS({
19996
20211
  function createDshInstall(deps) {
19997
20212
  const { store, dist, tasks, logger, instancesRoot } = deps;
19998
20213
  const save = () => store.save();
19999
- let _latestDshVer = null;
20000
- let _latestDshVerAt = 0;
20214
+ let _latestDsh = null;
20001
20215
  function installTimeoutWatchdog(inst, task) {
20002
20216
  try {
20003
20217
  if (inst.state && inst.state.phase === "INSTALLING") {
@@ -20062,49 +20276,38 @@ var require_dsh_install = __commonJS({
20062
20276
  } catch {
20063
20277
  }
20064
20278
  }
20065
- const env = Object.assign({}, process.env);
20066
- let reg = null;
20067
- if (dist) {
20068
- try {
20069
- reg = await dist.selectRegistry(false);
20070
- if (reg) {
20071
- env.npm_config_registry = reg;
20072
- env.NPM_CONFIG_REGISTRY = reg;
20073
- }
20074
- } catch (e) {
20075
- logger.warn && logger.warn("sandbox registry select failed: " + e.message);
20076
- }
20077
- }
20078
- const latestVer = await latestDshVersion();
20079
- pushLog("\u5B89\u88C5\u76EE\u6807\u7248\u672C\uFF1A" + (latestVer || "latest tag"));
20080
- if (!latestVer) {
20279
+ if (!dist) {
20081
20280
  inst.state.installOk = false;
20082
- inst.state.installError = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C";
20281
+ inst.state.installError = "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
20083
20282
  save();
20084
20283
  if (task) {
20085
20284
  try {
20086
- 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");
20087
20286
  } catch {
20088
20287
  }
20089
20288
  }
20090
- 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" };
20091
20290
  }
20092
- 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");
20093
20295
  inst.state.installOk = false;
20094
- inst.state.installError = "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528";
20296
+ inst.state.installError = why;
20095
20297
  save();
20096
20298
  if (task) {
20097
20299
  try {
20098
- tasks.fail(task.id, "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528");
20300
+ tasks.fail(task.id, why);
20099
20301
  } catch {
20100
20302
  }
20101
20303
  }
20102
- return { ok: false, error: "dist \u5206\u53D1\u670D\u52A1\u4E0D\u53EF\u7528" };
20304
+ return { ok: false, error: why };
20103
20305
  }
20306
+ const latestVer = pick.version;
20104
20307
  const watchdog = setTimeout(() => installTimeoutWatchdog(inst, task), 10 * 60 * 1e3);
20105
20308
  let res;
20106
20309
  try {
20107
- 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 });
20108
20311
  } finally {
20109
20312
  clearTimeout(watchdog);
20110
20313
  }
@@ -20150,18 +20353,24 @@ var require_dsh_install = __commonJS({
20150
20353
  return null;
20151
20354
  }
20152
20355
  }
20153
- async function latestDshVersion() {
20154
- if (_latestDshVer && Date.now() - _latestDshVerAt < 3e4) return _latestDshVer;
20155
- let v = null;
20156
- try {
20157
- if (dist) v = await dist.fetchNpmLatest("@deepseek-ai/dsh");
20158
- } 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
+ }
20159
20365
  }
20160
- _latestDshVer = v;
20161
- _latestDshVerAt = Date.now();
20162
- return v;
20366
+ if (r.ok && r.version) _latestDsh = Object.assign({ at: Date.now() }, r);
20367
+ return r;
20163
20368
  }
20164
- return { installSandbox, readInstalledVersion, latestDshVersion };
20369
+ async function latestDshVersion() {
20370
+ const r = await latestDsh();
20371
+ return r.version;
20372
+ }
20373
+ return { installSandbox, readInstalledVersion, latestDsh, latestDshVersion };
20165
20374
  }
20166
20375
  module2.exports = { createDshInstall };
20167
20376
  }
@@ -20209,6 +20418,9 @@ var require_upgrade = __commonJS({
20209
20418
  function readInstalledVersion(inst) {
20210
20419
  return install.readInstalledVersion(inst);
20211
20420
  }
20421
+ async function latestDsh() {
20422
+ return install.latestDsh();
20423
+ }
20212
20424
  async function latestDshVersion() {
20213
20425
  return install.latestDshVersion();
20214
20426
  }
@@ -20239,8 +20451,9 @@ var require_upgrade = __commonJS({
20239
20451
  let latest = cached && cached.latest || null;
20240
20452
  if (!latest || !cached || Date.now() - cached.checkedAt > _updTTL) {
20241
20453
  try {
20242
- latest = await dist.fetchNpmLatest("@deepseek-ai/dsh");
20243
- _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" };
20244
20457
  } catch (e) {
20245
20458
  latest = null;
20246
20459
  _updCache[id] = { latest: null, checkedAt: Date.now(), error: e.message };
@@ -20267,16 +20480,6 @@ var require_upgrade = __commonJS({
20267
20480
  _updJobs[id] = nj;
20268
20481
  (async () => {
20269
20482
  const installDir = sandbox.installDir(instancesRoot, inst);
20270
- const env = Object.assign({}, process.env);
20271
- let reg = null;
20272
- try {
20273
- reg = await dist.selectRegistry(false);
20274
- if (reg) {
20275
- env.npm_config_registry = reg;
20276
- env.NPM_CONFIG_REGISTRY = reg;
20277
- }
20278
- } catch {
20279
- }
20280
20483
  let wasRunning = false;
20281
20484
  try {
20282
20485
  wasRunning = lifecycle.probe(inst).running;
@@ -20303,12 +20506,15 @@ var require_upgrade = __commonJS({
20303
20506
  const s = tasks.step(task.id, "\u5B89\u88C5\u6700\u65B0\u7248");
20304
20507
  tasks.stepState(task.id, tasks.get(task.id).steps.indexOf(s), "running");
20305
20508
  }
20306
- const targetVer = await latestDshVersion();
20307
- 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" : ""));
20308
20513
  if (!targetVer) {
20514
+ const why = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\uFF1A" + (pick.error || "\u672A\u77E5\u539F\u56E0");
20309
20515
  nj.errors++;
20310
- nj.error = "\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C";
20311
- 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);
20312
20518
  } else {
20313
20519
  if (!dist) {
20314
20520
  nj.errors++;
@@ -21074,6 +21280,7 @@ var require_market_sources = __commonJS({
21074
21280
  "src/domains/plugin/market-sources.js"(exports2, module2) {
21075
21281
  "use strict";
21076
21282
  var { getJson, getText } = require_market_net();
21283
+ var ref = require_registry_ref();
21077
21284
  var RAW_MIRRORS = ["https://gh-proxy.com/", "https://ghproxy.net/"];
21078
21285
  async function rawGet(pathPart, isJson, timeoutMs = 15e3) {
21079
21286
  const direct = "https://raw.githubusercontent.com/" + pathPart;
@@ -21087,12 +21294,10 @@ var require_market_sources = __commonJS({
21087
21294
  throw new Error("raw fetch failed for " + pathPart);
21088
21295
  }
21089
21296
  async function fetchLatest(origin, name) {
21090
- try {
21091
- const base = String(origin || "").replace(/\/+$/, "");
21092
- return await getJson(base + "/" + encodeURIComponent(name) + "/latest", 8e3);
21093
- } catch {
21094
- return null;
21095
- }
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;
21096
21301
  }
21097
21302
  async function repoPkg(fullName) {
21098
21303
  for (const branch of ["master", "main"]) {
@@ -21407,16 +21612,16 @@ var require_market = __commonJS({
21407
21612
  }
21408
21613
  return out;
21409
21614
  }
21410
- /** npm 镜像源 origin(经 dist 统一选择;dist 不可达降级官方源)。 */
21615
+ /** npm 镜像源基址(经 dist 统一选择;dist 不可达降级官方源)。尾斜杠归一交给 registry-ref。 */
21411
21616
  async _npmOrigin() {
21412
21617
  let origin = null;
21413
21618
  if (this.dist) {
21414
21619
  try {
21415
- origin = await this.dist.selectRegistry(false);
21620
+ origin = await this.dist.registryOrigin(false);
21416
21621
  } catch {
21417
21622
  }
21418
21623
  }
21419
- return (origin || REGISTRY).replace(/\/+$/, "");
21624
+ return origin || REGISTRY;
21420
21625
  }
21421
21626
  /** npm 最新版元数据查询(镜像源选择见 _npmOrigin)。 */
21422
21627
  async safeFetchLatest(name) {
@@ -21872,7 +22077,7 @@ var require_cli = __commonJS({
21872
22077
  async function registryOrigin(dist) {
21873
22078
  if (dist) {
21874
22079
  try {
21875
- return dist.selectRegistry(false);
22080
+ return await dist.registryOrigin(false);
21876
22081
  } catch {
21877
22082
  }
21878
22083
  }
@@ -22443,6 +22648,23 @@ var require_updater = __commonJS({
22443
22648
  "src/domains/plugin/updater.js"(exports2, module2) {
22444
22649
  "use strict";
22445
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
+ }
22446
22668
  async function checkUpdates(ctx, force) {
22447
22669
  const targets = [ctx._nativeTarget(), ...ctx._allSandboxTargets()];
22448
22670
  const meta = /* @__PURE__ */ new Map();
@@ -22451,17 +22673,7 @@ var require_updater = __commonJS({
22451
22673
  if (meta.has(p.name)) continue;
22452
22674
  const st = specType(p.source);
22453
22675
  let latest = null;
22454
- const c = ctx._updCache[p.name];
22455
- if (c && !force && Date.now() - c.at < ctx._updTTL) latest = c.latest;
22456
- else {
22457
- if (st === "npm" && ctx.dist) {
22458
- try {
22459
- latest = await ctx.dist.fetchNpmLatest(p.name);
22460
- } catch {
22461
- }
22462
- }
22463
- if (latest !== null) ctx._updCache[p.name] = { latest, at: Date.now() };
22464
- }
22676
+ if (st === "npm" && ctx.dist) latest = (await latestCached(ctx, p.name, force)).latest;
22465
22677
  meta.set(p.name, { specType: st, latest });
22466
22678
  }
22467
22679
  }
@@ -22494,19 +22706,9 @@ var require_updater = __commonJS({
22494
22706
  const desc = targetStr === "all" ? "\u4EFB\u4F55\u76EE\u6807" : "\u76EE\u6807\u300C" + (targetStr || "native") + "\u300D";
22495
22707
  return { ok: false, error: desc + " \u672A\u5B89\u88C5\u63D2\u4EF6 " + name };
22496
22708
  }
22497
- let latest = null;
22498
- const c = ctx._updCache[name];
22499
- if (c && Date.now() - c.at < ctx._updTTL) latest = c.latest;
22500
- else {
22501
- if (ctx.dist) {
22502
- try {
22503
- latest = await ctx.dist.fetchNpmLatest(name);
22504
- } catch {
22505
- }
22506
- }
22507
- if (latest !== null) ctx._updCache[name] = { latest, at: Date.now() };
22508
- }
22509
- 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" };
22510
22712
  const job = ctx.jobs.createJob("update", name, targetStr || "native", targets);
22511
22713
  if (ctx.events) ctx.events.append("plugin_update_started", { name, jobId: job.id, target: job.target, targets: targets.map((t) => t.name) });
22512
22714
  let idx = 0;
@@ -23438,7 +23640,7 @@ var require_npm = __commonJS({
23438
23640
  async function selectRegistry(host2) {
23439
23641
  if (!host2.dist) return null;
23440
23642
  try {
23441
- return await host2.dist.selectRegistry(true);
23643
+ return await host2.dist.registryOrigin(true);
23442
23644
  } catch {
23443
23645
  return null;
23444
23646
  }
@@ -26911,10 +27113,7 @@ var require_managed = __commonJS({
26911
27113
  const main = typeof mainOf === "function" ? mainOf() : null;
26912
27114
  return main ? [...sandboxes, main] : sandboxes;
26913
27115
  }
26914
- function findManaged(list, id) {
26915
- return (list || []).find((x) => x.id === id) || null;
26916
- }
26917
- module2.exports = { localAddresses, allManaged, findManaged };
27116
+ module2.exports = { localAddresses, allManaged };
26918
27117
  }
26919
27118
  });
26920
27119
 
@@ -27620,7 +27819,6 @@ var require_ops5 = __commonJS({
27620
27819
  this.instances = opts.instances;
27621
27820
  this.configPath = opts.configPath || "";
27622
27821
  this.mainOf = opts.mainOf || null;
27623
- this.persist = opts.persist || null;
27624
27822
  this.frp = opts.frp || new FrpManager({ dir: opts.stateDir, logger: this.logger, events: this.events });
27625
27823
  this.lanInstances = [];
27626
27824
  this._reconcileInFlight = null;
@@ -27631,31 +27829,10 @@ var require_ops5 = __commonJS({
27631
27829
  localAddresses() {
27632
27830
  return managed.localAddresses();
27633
27831
  }
27634
- /** 持久化:优先注入的 persist 路由,否则回退沙箱 instances.save()。 */
27635
- _saveAll() {
27636
- if (typeof this.persist === "function") {
27637
- try {
27638
- this.persist();
27639
- } catch (e) {
27640
- this.logger && this.logger.warn && this.logger.warn("lan persist: " + (e && e.message));
27641
- }
27642
- return;
27643
- }
27644
- if (this.instances && typeof this.instances.save === "function") {
27645
- try {
27646
- this.instances.save();
27647
- } catch {
27648
- }
27649
- }
27650
- }
27651
27832
  /** 受管 DSH 合成清单(沙箱 + 原生主干 main)。 */
27652
27833
  _allManaged() {
27653
27834
  return managed.allManaged({ instances: this.instances, mainOf: this.mainOf });
27654
27835
  }
27655
- /** 合成查找:按 id 取首个匹配。 */
27656
- _findManaged(id) {
27657
- return managed.findManaged(this._allManaged(), id);
27658
- }
27659
27836
  /** frpc 子进程句柄只读访问器:不暴露 frp 私有对象,供 daemon 优雅停机等待其退出。 */
27660
27837
  frpChild() {
27661
27838
  return this.frp && this.frp.child || null;
@@ -27935,13 +28112,6 @@ var require_supervisor = __commonJS({
27935
28112
  m.kind = "native";
27936
28113
  return m;
27937
28114
  },
27938
- persist: () => {
27939
- try {
27940
- if (this.instances && this.instances.save) this.instances.save();
27941
- } catch {
27942
- }
27943
- this._writeDshMain({});
27944
- },
27945
28115
  tokenOf: (id) => this.tokenService.get(id)
27946
28116
  });
27947
28117
  }