@dsh-sup/dsh-core-linux-x64 0.1.5-BETA.5 → 0.1.5-BETA.7
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 +228 -112
- package/package.json +1 -1
package/core.cjs
CHANGED
|
@@ -80,6 +80,71 @@ var require_exec = __commonJS({
|
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
+
// src/platform/state-root.js
|
|
84
|
+
var require_state_root = __commonJS({
|
|
85
|
+
"src/platform/state-root.js"(exports2, module2) {
|
|
86
|
+
"use strict";
|
|
87
|
+
var fs2 = require("node:fs");
|
|
88
|
+
var os2 = require("node:os");
|
|
89
|
+
var path2 = require("node:path");
|
|
90
|
+
var SCHEMA = 1;
|
|
91
|
+
function root() {
|
|
92
|
+
const override = process.env.DSH_SUPERVISOR_HOME;
|
|
93
|
+
if (override && String(override).trim()) return path2.resolve(String(override).trim());
|
|
94
|
+
if (process.platform === "win32") {
|
|
95
|
+
const local = process.env.LOCALAPPDATA || path2.join(os2.homedir(), "AppData", "Local");
|
|
96
|
+
return path2.join(local, "dsh-supervisor");
|
|
97
|
+
}
|
|
98
|
+
if (process.platform === "darwin") {
|
|
99
|
+
return path2.join(os2.homedir(), "Library", "Application Support", "dsh-supervisor");
|
|
100
|
+
}
|
|
101
|
+
const xdg = process.env.XDG_STATE_HOME;
|
|
102
|
+
return xdg && String(xdg).trim() ? path2.join(String(xdg).trim(), "dsh-supervisor") : path2.join(os2.homedir(), ".local", "state", "dsh-supervisor");
|
|
103
|
+
}
|
|
104
|
+
function supervisorDir() {
|
|
105
|
+
return path2.join(root(), "supervisor");
|
|
106
|
+
}
|
|
107
|
+
function shellDir() {
|
|
108
|
+
return path2.join(root(), "shell");
|
|
109
|
+
}
|
|
110
|
+
function legacySupervisorDir() {
|
|
111
|
+
return path2.join(os2.homedir(), ".dsh", "supervisor");
|
|
112
|
+
}
|
|
113
|
+
function legacyShellDir() {
|
|
114
|
+
return path2.join(os2.homedir(), ".dsh", "shell");
|
|
115
|
+
}
|
|
116
|
+
function migrateLegacy() {
|
|
117
|
+
const moved = [];
|
|
118
|
+
for (const [from, to] of [
|
|
119
|
+
[legacySupervisorDir(), supervisorDir()],
|
|
120
|
+
[legacyShellDir(), shellDir()]
|
|
121
|
+
]) {
|
|
122
|
+
try {
|
|
123
|
+
if (!fs2.existsSync(from)) continue;
|
|
124
|
+
fs2.mkdirSync(to, { recursive: true });
|
|
125
|
+
for (const name of fs2.readdirSync(from)) {
|
|
126
|
+
const src = path2.join(from, name);
|
|
127
|
+
const dst = path2.join(to, name);
|
|
128
|
+
if (fs2.existsSync(dst)) continue;
|
|
129
|
+
try {
|
|
130
|
+
fs2.renameSync(src, dst);
|
|
131
|
+
moved.push(src + " -> " + dst);
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
if (fs2.readdirSync(from).length === 0) fs2.rmdirSync(from);
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return moved;
|
|
143
|
+
}
|
|
144
|
+
module2.exports = { SCHEMA, root, supervisorDir, shellDir, legacySupervisorDir, legacyShellDir, migrateLegacy };
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
83
148
|
// src/platform/config.js
|
|
84
149
|
var require_config = __commonJS({
|
|
85
150
|
"src/platform/config.js"(exports2, module2) {
|
|
@@ -92,6 +157,7 @@ var require_config = __commonJS({
|
|
|
92
157
|
if (p.startsWith("~/")) return path2.join(os2.homedir(), p.slice(2));
|
|
93
158
|
return p;
|
|
94
159
|
}
|
|
160
|
+
var SUP = require_state_root().supervisorDir();
|
|
95
161
|
var DEFAULTS = {
|
|
96
162
|
probeIntervalMs: 5e3,
|
|
97
163
|
// 健康探测(三层):L0 进程存活 + L1 端口监听 + L2 HTTP GET healthUrl。
|
|
@@ -117,15 +183,15 @@ var require_config = __commonJS({
|
|
|
117
183
|
// managed = relay/proxyInstance/oauthCallback 共享池(K8s 单一范围思想,杜绝段碎片化);
|
|
118
184
|
// providerApi = 智能路由供应商独立端点池(按供应商规模调大)。null = 用内置默认池。
|
|
119
185
|
portPools: null,
|
|
120
|
-
stateFile: "
|
|
186
|
+
stateFile: path2.join(SUP, "state.json"),
|
|
121
187
|
// 系统日志框架目录布局:log/ 与 events/ 分目录;
|
|
122
188
|
// 守卫(guard) 事件在 events/guard.events.log、分级日志在 log/guard.log(daemon 用 router/lan 同构文件)。
|
|
123
189
|
// 显式配置(既有生产 config.json / 测试)仍尊重用户给定路径——不强行改写。
|
|
124
|
-
logFile: "
|
|
190
|
+
logFile: path2.join(SUP, "events", "guard.events.log"),
|
|
125
191
|
eventsMaxBytes: 5 * 1024 * 1024,
|
|
126
|
-
supervisorLogFile: "
|
|
127
|
-
dshLogFile: "
|
|
128
|
-
upgradeLogFile: "
|
|
192
|
+
supervisorLogFile: path2.join(SUP, "log", "guard.log"),
|
|
193
|
+
dshLogFile: path2.join(SUP, "log", "dsh.log"),
|
|
194
|
+
upgradeLogFile: path2.join(SUP, "log", "upgrade.log"),
|
|
129
195
|
logLevel: "info",
|
|
130
196
|
logMaxBytes: 5 * 1024 * 1024,
|
|
131
197
|
notifyEnabled: true,
|
|
@@ -223,7 +289,7 @@ var require_version = __commonJS({
|
|
|
223
289
|
var fs2 = require("node:fs");
|
|
224
290
|
var path2 = require("node:path");
|
|
225
291
|
function guardVersion() {
|
|
226
|
-
if (true) return String("0.1.5-BETA.
|
|
292
|
+
if (true) return String("0.1.5-BETA.7");
|
|
227
293
|
try {
|
|
228
294
|
return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version || "unknown";
|
|
229
295
|
} catch {
|
|
@@ -1033,7 +1099,48 @@ var require_exec_path = __commonJS({
|
|
|
1033
1099
|
if (resolved) return resolved;
|
|
1034
1100
|
return "npm.cmd";
|
|
1035
1101
|
}
|
|
1036
|
-
|
|
1102
|
+
var DSH_PKG = ["@deepseek-ai", "dsh"];
|
|
1103
|
+
function dshJsIn(prefix) {
|
|
1104
|
+
return path2.join(prefix, "node_modules", ...DSH_PKG, "lib", "bin.js");
|
|
1105
|
+
}
|
|
1106
|
+
function resolveDsh(opts) {
|
|
1107
|
+
const o = opts || {};
|
|
1108
|
+
const pl = o.platform || process.platform;
|
|
1109
|
+
const env = o.env || process.env;
|
|
1110
|
+
const isFile = (p) => {
|
|
1111
|
+
try {
|
|
1112
|
+
return fs2.statSync(p).isFile();
|
|
1113
|
+
} catch {
|
|
1114
|
+
return false;
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
const asJs = (bin, launcher) => ({ runtime: process.execPath, bin, isJs: true, launcher: launcher || null });
|
|
1118
|
+
if (env.DSH_BIN) {
|
|
1119
|
+
try {
|
|
1120
|
+
const r = fs2.realpathSync(env.DSH_BIN);
|
|
1121
|
+
if (isFile(r)) return asJs(r, env.DSH_BIN);
|
|
1122
|
+
} catch {
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
const hit = resolveExecutable("dsh", { platform: pl, env });
|
|
1126
|
+
if (hit) {
|
|
1127
|
+
try {
|
|
1128
|
+
const real = fs2.realpathSync(hit);
|
|
1129
|
+
if (isFile(real) && /\.(js|cjs|mjs)$/i.test(real)) return asJs(real, hit);
|
|
1130
|
+
} catch {
|
|
1131
|
+
}
|
|
1132
|
+
const js = dshJsIn(path2.dirname(hit));
|
|
1133
|
+
if (isFile(js)) return asJs(js, hit);
|
|
1134
|
+
if (isFile(hit) && !/\.(cmd|bat|exe)$/i.test(hit)) return asJs(hit, hit);
|
|
1135
|
+
return { runtime: null, bin: hit, isJs: false, launcher: hit };
|
|
1136
|
+
}
|
|
1137
|
+
if (o.npmRoot) {
|
|
1138
|
+
const js = dshJsIn(o.npmRoot);
|
|
1139
|
+
if (isFile(js)) return asJs(js, null);
|
|
1140
|
+
}
|
|
1141
|
+
return null;
|
|
1142
|
+
}
|
|
1143
|
+
module2.exports = { resolveExecutable, candidateNames, standardDirs, firstExecutable, npmBin, npxBin, resolveDsh, dshJsIn };
|
|
1037
1144
|
}
|
|
1038
1145
|
});
|
|
1039
1146
|
|
|
@@ -1551,7 +1658,7 @@ var require_autostart = __commonJS({
|
|
|
1551
1658
|
return String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1552
1659
|
}
|
|
1553
1660
|
function macGuiPlist(guiExe) {
|
|
1554
|
-
const log = path2.join(
|
|
1661
|
+
const log = path2.join(require_state_root().shellDir(), "gui-stdio.log");
|
|
1555
1662
|
return '<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0"><dict>\n <key>Label</key><string>' + xmlEscape(GUI_LABEL) + "</string>\n <key>ProgramArguments</key>\n <array><string>" + xmlEscape(guiExe) + "</string></array>\n <key>RunAtLoad</key><true/>\n <key>LimitLoadToSessionType</key><string>Aqua</string>\n <key>ProcessType</key><string>Interactive</string>\n <key>StandardOutPath</key><string>" + xmlEscape(log) + "</string>\n <key>StandardErrorPath</key><string>" + xmlEscape(log) + "</string>\n</dict></plist>\n";
|
|
1556
1663
|
}
|
|
1557
1664
|
function guiFile() {
|
|
@@ -1605,54 +1712,14 @@ var require_autostart = __commonJS({
|
|
|
1605
1712
|
const errors = [];
|
|
1606
1713
|
if (isWindows) {
|
|
1607
1714
|
try {
|
|
1608
|
-
const watchdogPs1 = path2.join(os2.homedir(), ".dsh", "supervisor", "watchdog.ps1");
|
|
1609
1715
|
if (on) {
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
const guiPath = guiCommand();
|
|
1613
|
-
const ps = [
|
|
1614
|
-
'$ErrorActionPreference = "SilentlyContinue"',
|
|
1615
|
-
"$port = " + JSON.stringify(String(apiPort)),
|
|
1616
|
-
"$daemon = " + JSON.stringify(String(daemon)),
|
|
1617
|
-
"$gui = " + JSON.stringify(String(guiPath)),
|
|
1618
|
-
"$up = Test-NetConnection -ComputerName 127.0.0.1 -Port $port -InformationLevel Quiet -WarningAction SilentlyContinue",
|
|
1619
|
-
"# \u2500\u2500 \u5B88\u536B\u4FDD\u6D3B\uFF08\u4EC5\u5728\u5B88\u536B\u4E0D\u53EF\u8FBE\u65F6\uFF09\u2500\u2500",
|
|
1620
|
-
"if (-not $up) {",
|
|
1621
|
-
" $p = @(Get-Process -Name dsh-supervisor -ErrorAction SilentlyContinue)",
|
|
1622
|
-
" if (-not $p) { Start-Process -FilePath $daemon -ArgumentList 'daemon' -WindowStyle Hidden }",
|
|
1623
|
-
"}",
|
|
1624
|
-
"# \u2500\u2500 \u58F3\u4FDD\u6D3B\uFF08\u26A0 \u5FC5\u987B**\u72EC\u7ACB\u4E8E\u5B88\u536B\u72B6\u6001**\uFF09\u2500\u2500",
|
|
1625
|
-
"# 2026-09-11 \u5BA1\u8BA1\u4FEE\u590D\uFF1A\u65E7\u5B9E\u73B0\u628A\u58F3\u68C0\u67E5\u5D4C\u5728\u4E0A\u9762\u7684 if (-not $up) \u5185\uFF0C",
|
|
1626
|
-
"# \u4E8E\u662F\u300C\u58F3\u5D29\u3001\u5B88\u536B\u6D3B\u300D\u65F6 $up \u4E3A\u771F \u2192 \u6574\u5757\u8DF3\u8FC7 \u2192 **\u58F3\u6C38\u8FDC\u4E0D\u4F1A\u88AB\u62C9\u8D77**\u3002",
|
|
1627
|
-
"# \u800C\u90A3\u6070\u662F\u58F3\u81EA\u6108\u552F\u4E00\u9700\u8981\u751F\u6548\u7684\u573A\u666F\uFF08\u5B88\u536B\u7531\u670D\u52A1\u7BA1\u7406\u5668\u4FDD\u6D3B\uFF0C\u58F3\u65E0\u4EBA\u7BA1\uFF09\u3002",
|
|
1628
|
-
"$g = @(Get-Process -Name dsh-supervisor-gui -ErrorAction SilentlyContinue)",
|
|
1629
|
-
"if (-not $g -and (Test-Path $gui)) { Start-Process -FilePath $gui -WindowStyle Hidden }",
|
|
1630
|
-
"exit 0"
|
|
1631
|
-
].join(String.fromCharCode(13, 10));
|
|
1632
|
-
fs2.mkdirSync(path2.dirname(watchdogPs1), { recursive: true });
|
|
1633
|
-
const atmp = watchdogPs1 + ".tmp";
|
|
1634
|
-
fs2.writeFileSync(atmp, ps);
|
|
1635
|
-
fs2.renameSync(atmp, watchdogPs1);
|
|
1636
|
-
{
|
|
1637
|
-
const r = ex2.runDetail("schtasks", ["/Create", "/TN", "DSH-Supervisor-GUI", "/SC", "ONLOGON", "/RL", "HIGHEST", "/F", "/TR", '"' + guiCommand() + '"']);
|
|
1638
|
-
if (!r.ok) errors.push("schtasks gui: " + (r.error || "\u6267\u884C\u5931\u8D25"));
|
|
1639
|
-
}
|
|
1640
|
-
ex2.run("schtasks", ["/Change", "/TN", "DSH-Supervisor", "/ENABLE"]);
|
|
1641
|
-
{
|
|
1642
|
-
const r = ex2.runDetail("schtasks", ["/Create", "/TN", "DSH-Supervisor-Watchdog", "/SC", "MINUTE", "/MO", "5", "/RL", "HIGHEST", "/F", "/TR", 'powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "' + watchdogPs1 + '"']);
|
|
1643
|
-
if (!r.ok) errors.push("schtasks watchdog: " + (r.error || "\u6267\u884C\u5931\u8D25"));
|
|
1644
|
-
}
|
|
1716
|
+
const r = ex2.runDetail("schtasks", ["/Create", "/TN", "DSH-Supervisor-GUI", "/SC", "ONLOGON", "/RL", "HIGHEST", "/F", "/TR", '"' + guiCommand() + '"']);
|
|
1717
|
+
if (!r.ok) errors.push("schtasks gui: " + (r.error || "\u6267\u884C\u5931\u8D25"));
|
|
1645
1718
|
} else {
|
|
1646
|
-
ex2.run("schtasks", ["/Delete", "/TN", "DSH-Supervisor-Watchdog", "/F"]);
|
|
1647
1719
|
ex2.run("schtasks", ["/Delete", "/TN", "DSH-Supervisor-GUI", "/F"]);
|
|
1648
|
-
ex2.run("schtasks", ["/Change", "/TN", "DSH-Supervisor", "/DISABLE"]);
|
|
1649
|
-
try {
|
|
1650
|
-
fs2.unlinkSync(watchdogPs1);
|
|
1651
|
-
} catch {
|
|
1652
|
-
}
|
|
1653
1720
|
}
|
|
1654
1721
|
} catch (e) {
|
|
1655
|
-
errors.push("
|
|
1722
|
+
errors.push("gui autostart: " + e.message);
|
|
1656
1723
|
}
|
|
1657
1724
|
return { ok: errors.length === 0, errors, ...status() };
|
|
1658
1725
|
}
|
|
@@ -1834,7 +1901,7 @@ var require_os = __commonJS({
|
|
|
1834
1901
|
return path2.join(os2.homedir(), ".dsh");
|
|
1835
1902
|
}
|
|
1836
1903
|
function supervisorDir() {
|
|
1837
|
-
return
|
|
1904
|
+
return require_state_root().supervisorDir();
|
|
1838
1905
|
}
|
|
1839
1906
|
function capabilityProfile(platform, arch) {
|
|
1840
1907
|
const pl = platform || PLATFORM;
|
|
@@ -2067,7 +2134,7 @@ var require_ports = __commonJS({
|
|
|
2067
2134
|
};
|
|
2068
2135
|
var PortRegistry = class {
|
|
2069
2136
|
constructor(opts) {
|
|
2070
|
-
this._file = opts && opts.file || path2.join(
|
|
2137
|
+
this._file = opts && opts.file || path2.join(require_state_root().supervisorDir(), "ports.json");
|
|
2071
2138
|
this._records = /* @__PURE__ */ new Map();
|
|
2072
2139
|
this._allocLock = false;
|
|
2073
2140
|
this._pools = Object.assign({}, DEFAULT_POOLS, opts && opts.pools || {});
|
|
@@ -3391,6 +3458,7 @@ var require_proxy = __commonJS({
|
|
|
3391
3458
|
this.kind = "proxy";
|
|
3392
3459
|
this.proxyAppId = opts.proxyAppId;
|
|
3393
3460
|
this.app = opts.app || null;
|
|
3461
|
+
this.stateDir = opts.stateDir || null;
|
|
3394
3462
|
this.proxyRunning = false;
|
|
3395
3463
|
this.instances = [];
|
|
3396
3464
|
this.selectedAccountKeyId = null;
|
|
@@ -3624,7 +3692,8 @@ var require_proxy = __commonJS({
|
|
|
3624
3692
|
const logFilter = /error|streaming|idle|timeout|ECONN|abort|socket|finish|truncat/i;
|
|
3625
3693
|
let logStream = null;
|
|
3626
3694
|
try {
|
|
3627
|
-
const
|
|
3695
|
+
const baseDir = this.stateDir || require("../../platform/state-root").supervisorDir();
|
|
3696
|
+
const logDir = require("node:path").join(baseDir, "logs");
|
|
3628
3697
|
require("node:fs").mkdirSync(logDir, { recursive: true });
|
|
3629
3698
|
logStream = require("node:fs").createWriteStream(require("node:path").join(logDir, "proxy-instance-" + this.proxyAppId + "-" + port + ".log"), { flags: "a" });
|
|
3630
3699
|
} catch {
|
|
@@ -4728,7 +4797,7 @@ var require_runtime_contract = __commonJS({
|
|
|
4728
4797
|
var path2 = require("node:path");
|
|
4729
4798
|
var SUPPORTED_SCHEMA = 2;
|
|
4730
4799
|
function file() {
|
|
4731
|
-
return path2.join(
|
|
4800
|
+
return path2.join(require_state_root().supervisorDir(), "runtime.json");
|
|
4732
4801
|
}
|
|
4733
4802
|
function read() {
|
|
4734
4803
|
let j;
|
|
@@ -4745,6 +4814,8 @@ var require_runtime_contract = __commonJS({
|
|
|
4745
4814
|
nodePath: j.nodePath || node.path || null,
|
|
4746
4815
|
nodeBinDir: j.nodeBinDir || node.binDir || null,
|
|
4747
4816
|
npmPath: j.npmPath || npm.path || null,
|
|
4817
|
+
// 外壳可只提供包内 JS(npmPath=node,npmArgs=[npm-cli.js])——消费者必须带上 args。
|
|
4818
|
+
npmArgs: Array.isArray(j.npmArgs) ? j.npmArgs : Array.isArray(npm.args) ? npm.args : [],
|
|
4748
4819
|
minNode: j.minNode || null,
|
|
4749
4820
|
writtenBy: j.writtenBy || null,
|
|
4750
4821
|
raw: j
|
|
@@ -6752,7 +6823,7 @@ var require_router = __commonJS({
|
|
|
6752
6823
|
}
|
|
6753
6824
|
}
|
|
6754
6825
|
_deserializeProvider(p) {
|
|
6755
|
-
const common = { id: p.id, name: p.name, logger: this.logger, events: this.events, dist: this.dist, onPersist: () => this._save(), apiPort: p.apiPort || null, activated: p.activated === true };
|
|
6826
|
+
const common = { id: p.id, name: p.name, logger: this.logger, events: this.events, dist: this.dist, onPersist: () => this._save(), stateDir: this.config && this.config.stateFile ? path2.dirname(this.config.stateFile) : null, apiPort: p.apiPort || null, activated: p.activated === true };
|
|
6756
6827
|
let prov;
|
|
6757
6828
|
if (p.kind === "proxy") {
|
|
6758
6829
|
prov = new ProxyProvider({ ...common, kind: "proxy", proxyAppId: p.proxyAppId, app: PROXY_APPS[p.proxyAppId] || null });
|
|
@@ -10521,6 +10592,8 @@ var require_plugins = __commonJS({
|
|
|
10521
10592
|
name: "\u539F\u751F\u5B9E\u4F8B",
|
|
10522
10593
|
kind: "native",
|
|
10523
10594
|
bin: this.dshBin,
|
|
10595
|
+
// 绑定后的原生入口可能是包内 JS(`.../lib/bin.js`)——必须用 node 承载(Windows 更甚:.js 不可直接执行)。
|
|
10596
|
+
runtime: /\.(js|cjs|mjs)$/i.test(this.dshBin) ? process.execPath : null,
|
|
10524
10597
|
profileDir: this.profileDir,
|
|
10525
10598
|
profileName: this.profileName,
|
|
10526
10599
|
env: { HOME: os2.homedir(), PATH: this._pathExtra() }
|
|
@@ -10537,6 +10610,8 @@ var require_plugins = __commonJS({
|
|
|
10537
10610
|
name: inst.name || inst.id,
|
|
10538
10611
|
kind: "sandbox",
|
|
10539
10612
|
bin: path2.join(installDir, "lib", "node_modules", "@deepseek-ai", "dsh", "lib", "bin.js"),
|
|
10613
|
+
runtime: process.execPath,
|
|
10614
|
+
// 包内 JS 入口:显式 node 承载(跨平台一致)
|
|
10540
10615
|
installDir,
|
|
10541
10616
|
profileDir: path2.join(dataDir, ".dsh", "profiles", this.profileName),
|
|
10542
10617
|
profileName: this.profileName,
|
|
@@ -10846,7 +10921,9 @@ var require_plugins = __commonJS({
|
|
|
10846
10921
|
try {
|
|
10847
10922
|
const cliArgs = ["plugin", "--profile", target.profileName];
|
|
10848
10923
|
if (target.storeDir) cliArgs.push("--store-dir", target.storeDir);
|
|
10849
|
-
|
|
10924
|
+
const argv0 = target.runtime || target.bin;
|
|
10925
|
+
const argvPrefix = target.runtime ? [target.bin] : [];
|
|
10926
|
+
child = spawn(argv0, [...argvPrefix, ...cliArgs, ...args], { env, stdio: ["ignore", "pipe", "pipe"], windowsHide: true, detached: true });
|
|
10850
10927
|
} catch (e) {
|
|
10851
10928
|
return settle({ ok: false, error: e.message });
|
|
10852
10929
|
}
|
|
@@ -11763,7 +11840,7 @@ var require_shell = __commonJS({
|
|
|
11763
11840
|
var path2 = require("node:path");
|
|
11764
11841
|
var { semverCompare } = require_dist();
|
|
11765
11842
|
function shellDir() {
|
|
11766
|
-
return
|
|
11843
|
+
return require_state_root().shellDir();
|
|
11767
11844
|
}
|
|
11768
11845
|
function readJson(p) {
|
|
11769
11846
|
try {
|
|
@@ -12404,11 +12481,30 @@ var require_manager2 = __commonJS({
|
|
|
12404
12481
|
if (this.installLog.length > 60) this.installLog.splice(0, this.installLog.length - 60);
|
|
12405
12482
|
}
|
|
12406
12483
|
/* ═══════ 安装状态探测 ═══════ */
|
|
12484
|
+
/** 原生 DSH 真实安装(**唯一检测入口**,2026-09-16 架构修正):
|
|
12485
|
+
* 此前只读静态 `config.command[1]`(出厂默认裸名 'dsh')→ `fs.existsSync('dsh')` 恒 false →
|
|
12486
|
+
* 「已安装」永远判不出来,与「安装」分支形成两套相反逻辑(系统已装 DSH,守卫却报未安装)。
|
|
12487
|
+
* · 已绑定/用户显式指定且**真实存在**的绝对路径 → 尊重之;
|
|
12488
|
+
* · 否则跨平台解析:PATH/PATHEXT → 标准落点 → 包内 `lib/bin.js`(exec-path.resolveDsh)。 */
|
|
12489
|
+
detected() {
|
|
12490
|
+
const cmd2 = Array.isArray(this.config.command) ? this.config.command : [];
|
|
12491
|
+
const configured = cmd2[1];
|
|
12492
|
+
const isBare = !configured || configured === "dsh" || configured === "dsh.cmd" || !/[\\/]/.test(configured) && !String(configured).startsWith("~");
|
|
12493
|
+
if (!isBare) {
|
|
12494
|
+
return { bin: configured, runtime: cmd2[0] || null, isJs: /\.(js|cjs|mjs)$/i.test(configured) };
|
|
12495
|
+
}
|
|
12496
|
+
try {
|
|
12497
|
+
return execPath.resolveDsh({ npmRoot: this.npmRoot });
|
|
12498
|
+
} catch {
|
|
12499
|
+
return null;
|
|
12500
|
+
}
|
|
12501
|
+
}
|
|
12407
12502
|
binPath() {
|
|
12503
|
+
const d = this.detected();
|
|
12504
|
+
if (d && d.bin) return d.bin;
|
|
12408
12505
|
const bin = this.config.command && this.config.command[1];
|
|
12409
12506
|
if (!bin) return null;
|
|
12410
|
-
|
|
12411
|
-
return p;
|
|
12507
|
+
return bin === "~" ? os2.homedir() : bin.startsWith("~/") ? path2.join(os2.homedir(), bin.slice(2)) : bin;
|
|
12412
12508
|
}
|
|
12413
12509
|
/** 已安装版本:优先显式配置(installedPkgJsonPath),否则从 bin 所在目录向上找 package.json。未安装返回 null(唯一探测实现)。 */
|
|
12414
12510
|
installedVersion() {
|
|
@@ -17489,9 +17585,21 @@ var require_env_catalog = __commonJS({
|
|
|
17489
17585
|
const min = String(runtimeMeta().minNode || MIN_NODE_DEFAULT);
|
|
17490
17586
|
return { version: "v" + ver, min, meets: verAtLeast(ver, min) };
|
|
17491
17587
|
}
|
|
17588
|
+
function probeNpm() {
|
|
17589
|
+
try {
|
|
17590
|
+
const c = require_runtime_contract().read();
|
|
17591
|
+
if (c && c.npmPath) {
|
|
17592
|
+
const args = Array.isArray(c.npmArgs) ? c.npmArgs : [];
|
|
17593
|
+
const v = ex2.runOut(c.npmPath, [...args, "--version"], { timeoutMs: 3e3 });
|
|
17594
|
+
if (v && v.trim()) return v.trim();
|
|
17595
|
+
}
|
|
17596
|
+
} catch {
|
|
17597
|
+
}
|
|
17598
|
+
return cachedWhichVersion("npm");
|
|
17599
|
+
}
|
|
17492
17600
|
var SYSTEM_ENTRIES = {
|
|
17493
17601
|
node: { label: "Node.js", required: true, probe: probeNode },
|
|
17494
|
-
npm: { label: "npm", required: true, probe:
|
|
17602
|
+
npm: { label: "npm", required: true, probe: probeNpm },
|
|
17495
17603
|
git: { label: "git", required: false, probe: () => cachedWhichVersion("git") }
|
|
17496
17604
|
};
|
|
17497
17605
|
var EnvCatalog = class {
|
|
@@ -19631,6 +19739,7 @@ var require_supervisor = __commonJS({
|
|
|
19631
19739
|
} catch (e) {
|
|
19632
19740
|
this.logger.warn && this.logger.warn("ports pools configure: " + (e && e.message));
|
|
19633
19741
|
}
|
|
19742
|
+
this._bindNativeDshCommand();
|
|
19634
19743
|
this.instances = new InstanceManager({
|
|
19635
19744
|
dir: path2.dirname(this.config.stateFile),
|
|
19636
19745
|
logger: this.logger,
|
|
@@ -19715,7 +19824,7 @@ var require_supervisor = __commonJS({
|
|
|
19715
19824
|
logger: this.logger
|
|
19716
19825
|
});
|
|
19717
19826
|
this.pluginManager = new PluginManager({
|
|
19718
|
-
dshBin: "dsh",
|
|
19827
|
+
dshBin: this.config.command && this.config.command[1] ? this.config.command[1] : "dsh",
|
|
19719
19828
|
profileName: this.config.pluginsProfileName || "web",
|
|
19720
19829
|
profileDir: path2.join(os2.homedir(), ".dsh", "profiles", this.config.pluginsProfileName || "web"),
|
|
19721
19830
|
overlayFile: path2.join(path2.dirname(this.config.stateFile), "plugin-states.patch.yml"),
|
|
@@ -19763,6 +19872,40 @@ var require_supervisor = __commonJS({
|
|
|
19763
19872
|
});
|
|
19764
19873
|
this._registerFixedPorts();
|
|
19765
19874
|
}
|
|
19875
|
+
/** 原生 DSH 检测 → 绑定(2026-09-16 架构修正)。
|
|
19876
|
+
*
|
|
19877
|
+
* 原生 DSH 此前只被静态 `config.command[1]`(出厂默认裸名 'dsh')定义 —— `node dsh` 不做 PATH 解析、
|
|
19878
|
+
* Windows 裸名无扩展名 → 「已安装」永远判 false,与「安装」分支形成两套相反逻辑,
|
|
19879
|
+
* 且会去装第二个 DSH 顶替原生的那个。
|
|
19880
|
+
*
|
|
19881
|
+
* 这里在**任何消费者之前**把无法解析的 command[1] 解析为真实绝对入口:
|
|
19882
|
+
* 包内 JS → `['<node>', '<abs lib/bin.js>', ...rest]`;仅垫片 → `['<abs shim>', ...rest]`。
|
|
19883
|
+
* 用户显式给出且真实存在的路径**原样尊重**(不覆盖)。检测与接管由此同源:
|
|
19884
|
+
* 已装 → 绑定并接管;未装 → 由 NativeManager 安装后重新绑定。 */
|
|
19885
|
+
_bindNativeDshCommand() {
|
|
19886
|
+
try {
|
|
19887
|
+
const cmd2 = Array.isArray(this.config.command) ? this.config.command.slice() : [];
|
|
19888
|
+
const cur = cmd2[1];
|
|
19889
|
+
const isBare = !cur || cur === "dsh" || cur === "dsh.cmd" || !/[\\/]/.test(cur) && !String(cur).startsWith("~");
|
|
19890
|
+
if (!isBare) return;
|
|
19891
|
+
const d = require_exec_path().resolveDsh();
|
|
19892
|
+
if (!d || !d.bin) return;
|
|
19893
|
+
this.config.command = d.isJs ? [d.runtime || process.execPath, d.bin, ...cmd2.slice(2)] : [d.bin, ...cmd2.slice(2)];
|
|
19894
|
+
try {
|
|
19895
|
+
this.events && this.events.append("dsh_command_bound", { from: cur || null, to: this.config.command[1] });
|
|
19896
|
+
} catch {
|
|
19897
|
+
}
|
|
19898
|
+
try {
|
|
19899
|
+
this.logger.info && this.logger.info("\u539F\u751F DSH \u5DF2\u7ED1\u5B9A: " + this.config.command.join(" "));
|
|
19900
|
+
} catch {
|
|
19901
|
+
}
|
|
19902
|
+
} catch (e) {
|
|
19903
|
+
try {
|
|
19904
|
+
this.logger.warn && this.logger.warn("\u539F\u751F DSH \u7ED1\u5B9A\u5931\u8D25: " + (e && e.message));
|
|
19905
|
+
} catch {
|
|
19906
|
+
}
|
|
19907
|
+
}
|
|
19908
|
+
}
|
|
19766
19909
|
/** 固定端口统一登记:主DSH / 守卫API / 中转服务。冲突即抛错(守卫启动失败,避免带病运行)。
|
|
19767
19910
|
* 主程序端口动态注册:用户使用场景各异(可能先装 DSH 并自定义端口)——
|
|
19768
19911
|
* 若配置端口无监听且检测到 DSH 进程,从进程实际参数解析端口并动态覆盖(绝不硬编码 3080)。 */
|
|
@@ -19835,10 +19978,20 @@ var require_supervisor = __commonJS({
|
|
|
19835
19978
|
});
|
|
19836
19979
|
server.listen(port, this.config.apiHost, () => {
|
|
19837
19980
|
this.api = server;
|
|
19838
|
-
|
|
19981
|
+
const prev = this.config.apiPort;
|
|
19982
|
+
if (port !== prev) {
|
|
19983
|
+
try {
|
|
19984
|
+
ports.release(prev, "system:supervisor-api");
|
|
19985
|
+
} catch {
|
|
19986
|
+
}
|
|
19839
19987
|
this.config.apiPort = port;
|
|
19840
19988
|
if (this.configPath) this.persistConfigPatch({ apiPort: port });
|
|
19841
19989
|
}
|
|
19990
|
+
try {
|
|
19991
|
+
ports.register("supervisor-api", port);
|
|
19992
|
+
} catch (e) {
|
|
19993
|
+
this.logger.warn("ports.register(actual) \u5931\u8D25: " + e.message);
|
|
19994
|
+
}
|
|
19842
19995
|
this.events.append("api_listening", { host: this.config.apiHost, port });
|
|
19843
19996
|
this.logger.info("api listening on " + this.config.apiHost + ":" + port);
|
|
19844
19997
|
});
|
|
@@ -20340,6 +20493,10 @@ var require_supervisor = __commonJS({
|
|
|
20340
20493
|
server.listen(this.config.apiPort, this.config.apiHost, () => {
|
|
20341
20494
|
bind._tries = 0;
|
|
20342
20495
|
this.api = server;
|
|
20496
|
+
try {
|
|
20497
|
+
ports.register("supervisor-api", this.config.apiPort);
|
|
20498
|
+
} catch {
|
|
20499
|
+
}
|
|
20343
20500
|
this.events.append("api_listening", { host: this.config.apiHost, port: this.config.apiPort });
|
|
20344
20501
|
this.logger.info("api listening on " + this.config.apiHost + ":" + this.config.apiPort);
|
|
20345
20502
|
});
|
|
@@ -20720,7 +20877,8 @@ function findPackageRoot(start) {
|
|
|
20720
20877
|
return path.join(__dirname, "..");
|
|
20721
20878
|
}
|
|
20722
20879
|
var ROOT = findPackageRoot(__dirname);
|
|
20723
|
-
var
|
|
20880
|
+
var stateRoot = require_state_root();
|
|
20881
|
+
var SUPERVISOR_DIR = stateRoot.supervisorDir();
|
|
20724
20882
|
var USER_CONFIG = path.join(SUPERVISOR_DIR, "config.json");
|
|
20725
20883
|
var DEFAULT_CONFIG = Object.assign(
|
|
20726
20884
|
{},
|
|
@@ -20730,10 +20888,6 @@ var DEFAULT_CONFIG = Object.assign(
|
|
|
20730
20888
|
var STATE_FILE = path.join(SUPERVISOR_DIR, "state.json");
|
|
20731
20889
|
var EVENTS_FILE = path.join(SUPERVISOR_DIR, "events", "guard.events.log");
|
|
20732
20890
|
var UNIT_PATH = path.join(os.homedir(), ".config", "systemd", "user", "dsh-supervisor.service");
|
|
20733
|
-
var UNIT_TEMPLATE = path.join(ROOT, "systemd", "dsh-supervisor.service");
|
|
20734
|
-
var DESKTOP_DIR = path.join(os.homedir(), ".local", "share", "applications");
|
|
20735
|
-
var ICON_DIR = path.join(os.homedir(), ".local", "share", "icons");
|
|
20736
|
-
var DESKTOP_TEMPLATE = path.join(ROOT, "desktop", "dsh-supervisor.desktop");
|
|
20737
20891
|
var AUTOSTART_TEMPLATE = path.join(ROOT, "desktop", "dsh-supervisor-gui-autostart.desktop");
|
|
20738
20892
|
var AUTOSTART_FILE = path.join(os.homedir(), ".config", "autostart", "dsh-supervisor-gui-autostart.desktop");
|
|
20739
20893
|
var IS_WINDOWS = process.platform === "win32";
|
|
@@ -20866,6 +21020,8 @@ function releaseLock() {
|
|
|
20866
21020
|
}
|
|
20867
21021
|
}
|
|
20868
21022
|
function cmdDaemon() {
|
|
21023
|
+
const moved = stateRoot.migrateLegacy();
|
|
21024
|
+
for (const m of moved) console.log("[migrate] \u72B6\u6001\u76EE\u5F55\u8FC1\u79FB: " + m);
|
|
20869
21025
|
if (!acquireLock()) {
|
|
20870
21026
|
console.error("[supervisor] \u5DF2\u6709\u5B88\u536B\u5B9E\u4F8B\u5728\u8FD0\u884C\uFF08\u9501 " + LOCK_FILE + "\uFF09\uFF0C\u672C\u8FDB\u7A0B\u9000\u51FA\u3002");
|
|
20871
21027
|
process.exit(1);
|
|
@@ -20982,6 +21138,8 @@ function finishControl(r) {
|
|
|
20982
21138
|
}
|
|
20983
21139
|
}
|
|
20984
21140
|
function cmdInstall() {
|
|
21141
|
+
const moved = stateRoot.migrateLegacy();
|
|
21142
|
+
for (const m of moved) console.log("[migrate] \u72B6\u6001\u76EE\u5F55\u8FC1\u79FB: " + m);
|
|
20985
21143
|
fs.mkdirSync(SUPERVISOR_DIR, { recursive: true });
|
|
20986
21144
|
if (!fs.existsSync(USER_CONFIG)) {
|
|
20987
21145
|
fs.mkdirSync(SUPERVISOR_DIR, { recursive: true });
|
|
@@ -21004,50 +21162,8 @@ function cmdInstall() {
|
|
|
21004
21162
|
fs.symlinkSync(path.join(ROOT, "bin", "dsh-supervisor"), BIN_PATH);
|
|
21005
21163
|
console.log("[install] \u547D\u4EE4\u884C\u94FE\u63A5: " + BIN_PATH + " \u2192 " + __dirname + "/dsh-supervisor");
|
|
21006
21164
|
}
|
|
21007
|
-
|
|
21008
|
-
|
|
21009
|
-
console.warn("[install] \u5982\u9700 systemd \u5E38\u9A7B\uFF0C\u8BF7\u4ECE\u6E90\u7801\u4ED3\u5B89\u88C5\uFF08systemd/dsh-supervisor.service\uFF09\u6216\u624B\u52A8\u8FD0\u884C\uFF1Adsh-supervisor daemon");
|
|
21010
|
-
} else {
|
|
21011
|
-
let unit = fs.readFileSync(UNIT_TEMPLATE, "utf8");
|
|
21012
|
-
unit = unit.replace("@BIN@", BIN_PATH);
|
|
21013
|
-
const unitDir = path.dirname(UNIT_PATH);
|
|
21014
|
-
fs.mkdirSync(unitDir, { recursive: true });
|
|
21015
|
-
fs.writeFileSync(UNIT_PATH, unit);
|
|
21016
|
-
console.log("[install] systemd unit: " + UNIT_PATH);
|
|
21017
|
-
try {
|
|
21018
|
-
execInherit("systemctl", ["--user", "daemon-reload"]);
|
|
21019
|
-
execInherit("systemctl", ["--user", "enable", "dsh-supervisor.service"]);
|
|
21020
|
-
} catch (e) {
|
|
21021
|
-
console.warn("[install] systemctl \u6267\u884C\u5931\u8D25\uFF08\u53EF\u80FD\u4E0D\u5728 systemd \u4F1A\u8BDD\u4E2D\uFF09:", e.message);
|
|
21022
|
-
}
|
|
21023
|
-
try {
|
|
21024
|
-
execInherit("loginctl", ["enable-linger", os.userInfo().username]);
|
|
21025
|
-
console.log("[install] loginctl enable-linger \u5DF2\u542F\u7528");
|
|
21026
|
-
} catch {
|
|
21027
|
-
console.warn("[install] enable-linger \u5931\u8D25\uFF0C\u5F00\u673A\u81EA\u542F\u53EF\u80FD\u4E0D\u751F\u6548");
|
|
21028
|
-
}
|
|
21029
|
-
installDesktopEntry();
|
|
21030
|
-
console.log("\n\u5B89\u88C5\u5B8C\u6210\u3002\u542F\u52A8\u5B88\u536B\uFF1A\n systemctl --user start dsh-supervisor");
|
|
21031
|
-
console.log("\u67E5\u770B\u72B6\u6001\uFF1A\n dsh-supervisor status");
|
|
21032
|
-
}
|
|
21033
|
-
}
|
|
21034
|
-
function installDesktopEntry() {
|
|
21035
|
-
try {
|
|
21036
|
-
if (!fs.existsSync(DESKTOP_TEMPLATE)) return;
|
|
21037
|
-
fs.mkdirSync(ICON_DIR, { recursive: true });
|
|
21038
|
-
const shellDir = process.env.DSH_SHELL_DIR || null;
|
|
21039
|
-
const iconSrc = shellDir ? path.join(shellDir, "src-tauri", "icons", "128x128.png") : null;
|
|
21040
|
-
const iconDst = path.join(ICON_DIR, "dsh-supervisor.png");
|
|
21041
|
-
if (iconSrc && fs.existsSync(iconSrc)) fs.copyFileSync(iconSrc, iconDst);
|
|
21042
|
-
else console.warn("[install] \u672A\u627E\u5230\u58F3\u56FE\u6807\uFF08\u53EF\u8BBE DSH_SHELL_DIR \u6307\u5411\u58F3 checkout\uFF09\uFF0C\u684C\u9762\u56FE\u6807\u7F3A\u5931\uFF1B\u4E0D\u5F71\u54CD\u529F\u80FD\u3002");
|
|
21043
|
-
fs.mkdirSync(DESKTOP_DIR, { recursive: true });
|
|
21044
|
-
const entry = fs.readFileSync(DESKTOP_TEMPLATE, "utf8").replace(/@HOME@/g, os.homedir());
|
|
21045
|
-
const dst = path.join(DESKTOP_DIR, "dsh-supervisor.desktop");
|
|
21046
|
-
fs.writeFileSync(dst, entry);
|
|
21047
|
-
console.log("[install] \u684C\u9762\u83DC\u5355\u5165\u53E3: " + dst);
|
|
21048
|
-
} catch (e) {
|
|
21049
|
-
console.warn("[install] \u684C\u9762\u5165\u53E3\u90E8\u7F72\u5931\u8D25:", e.message);
|
|
21050
|
-
}
|
|
21165
|
+
console.log("[install] \u670D\u52A1\u5B9A\u4E49/\u5F00\u673A\u81EA\u542F/\u684C\u9762\u5165\u53E3\u7531\u684C\u9762\u58F3\u8D1F\u8D23\uFF08\u672C\u547D\u4EE4\u4E0D\u518D\u90E8\u7F72\uFF09\u3002");
|
|
21166
|
+
console.log("[install] \u5185\u6838\u672C\u4F53\u5DF2\u5C31\u7EEA\u3002\u542F\u52A8\u7531\u684C\u9762\u58F3\u6216\u670D\u52A1\u7BA1\u7406\u5668\u53D1\u8D77\uFF1Adsh-supervisor daemon");
|
|
21051
21167
|
}
|
|
21052
21168
|
function cmdGuiAutostart(onoff) {
|
|
21053
21169
|
if (onoff === "on") {
|