@dsh-sup/dsh-core-linux-x64 0.1.5-BETA.3 → 0.1.5-BETA.5
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 +107 -283
- package/package.json +1 -1
- package/ui-react/assets/{InstancesPage-CKN1Eies.js → InstancesPage-B2OXFYf0.js} +2 -2
- package/ui-react/assets/{LanPage-BDx2kibu.js → LanPage-sgjnj_nP.js} +1 -1
- package/ui-react/assets/{OverviewPage-C0jq81HS.js → OverviewPage-Dliy1IS_.js} +1 -1
- package/ui-react/assets/{PluginsPage-5avVpMvM.js → PluginsPage-B9d78QnQ.js} +1 -1
- package/ui-react/assets/{RouterPage-30bf9HFw.js → RouterPage-CwG-QYRs.js} +1 -1
- package/ui-react/assets/{SettingsPage-BKnx_9pb.js → SettingsPage-DNScdpR7.js} +4 -2
- package/ui-react/assets/{TasksPage-BahVLxU4.js → TasksPage-3cctVYFY.js} +1 -1
- package/ui-react/assets/{external-link-SYs4QOvn.js → external-link-B3goz-0m.js} +1 -1
- package/ui-react/assets/{refresh-cw-CQuKs_Tk.js → refresh-cw-Cv-9galq.js} +1 -1
- package/ui-react/assets/{rocket-Dt6NGQXE.js → rocket-B9cBKQUY.js} +1 -1
- package/ui-react/assets/{shield-check-B-D3XDKa.js → shield-check-UgQY0o2B.js} +1 -1
- package/ui-react/assets/{supervisor-DX8HnT5i.js → supervisor-4Q6BBx68.js} +3 -3
- package/ui-react/assets/{supervisor-BVac7io-.js → supervisor-DdCExALH.js} +1 -1
- package/ui-react/assets/{useSupervisorAction-B1Piyga4.js → useSupervisorAction-C0KJmCu7.js} +1 -1
- package/ui-react/assets/{widgets-DMpjcPY5.js → widgets-BXmNWJy5.js} +1 -1
- package/ui-react/supervisor.html +2 -2
package/core.cjs
CHANGED
|
@@ -131,15 +131,13 @@ var require_config = __commonJS({
|
|
|
131
131
|
notifyEnabled: true,
|
|
132
132
|
routerAutostart: false,
|
|
133
133
|
// 智能路由启动开关(旧键 switcherAutoStart 已迁移)
|
|
134
|
-
//
|
|
135
|
-
//(形如 @dsh-sup/dsh-core-linux-x64
|
|
134
|
+
// 内核更新(单写入者 = 桌面壳):corePackageName = 内核自身 npm 子包名
|
|
135
|
+
//(形如 @dsh-sup/dsh-core-linux-x64,按平台/架构发布)。守卫**只读**它来查询版本状态;
|
|
136
|
+
//安装/升级由桌面壳执行(见 RELEASE-AND-UPDATE-MECHANISM.md §6)。
|
|
136
137
|
corePackageName: null,
|
|
137
|
-
// ⚠ `selfUpdateManifestUrl` / `selfUpdateDir`
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
// 新代码**不得**再依赖这两个键。
|
|
141
|
-
selfUpdateManifestUrl: null,
|
|
142
|
-
selfUpdateDir: null,
|
|
138
|
+
// ⚠ 2026-09-15:旧 manifest 模式的残留键 `selfUpdateManifestUrl` / `selfUpdateDir` **已删除**
|
|
139
|
+
// (全仓无赋值点;其唯一消费方曾改为按 corePackageName 判定)。既有用户 config.json 若仍含
|
|
140
|
+
// 这两键,加载时忽略即可(未知键不报错)。新代码**不得**再引入 manifest 更新通道。
|
|
143
141
|
pluginsProfileName: "web",
|
|
144
142
|
packageName: "@deepseek-ai/dsh",
|
|
145
143
|
// **最小兜底**镜像源(2026-09-11 契约化)。
|
|
@@ -225,7 +223,7 @@ var require_version = __commonJS({
|
|
|
225
223
|
var fs2 = require("node:fs");
|
|
226
224
|
var path2 = require("node:path");
|
|
227
225
|
function guardVersion() {
|
|
228
|
-
if (true) return String("0.1.5-BETA.
|
|
226
|
+
if (true) return String("0.1.5-BETA.5");
|
|
229
227
|
try {
|
|
230
228
|
return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version || "unknown";
|
|
231
229
|
} catch {
|
|
@@ -269,7 +267,7 @@ var require_matrix = __commonJS({
|
|
|
269
267
|
function isSupported(platform, arch) {
|
|
270
268
|
const p = platform || process.platform;
|
|
271
269
|
const a = arch || process.arch;
|
|
272
|
-
return
|
|
270
|
+
return SUPPORTED.some((x) => x.platform === p && x.arch === a);
|
|
273
271
|
}
|
|
274
272
|
function frpTag(platform, arch) {
|
|
275
273
|
const p = platform || process.platform;
|
|
@@ -4721,6 +4719,60 @@ var require_proxy_apps = __commonJS({
|
|
|
4721
4719
|
}
|
|
4722
4720
|
});
|
|
4723
4721
|
|
|
4722
|
+
// src/platform/runtime-contract.js
|
|
4723
|
+
var require_runtime_contract = __commonJS({
|
|
4724
|
+
"src/platform/runtime-contract.js"(exports2, module2) {
|
|
4725
|
+
"use strict";
|
|
4726
|
+
var fs2 = require("node:fs");
|
|
4727
|
+
var os2 = require("node:os");
|
|
4728
|
+
var path2 = require("node:path");
|
|
4729
|
+
var SUPPORTED_SCHEMA = 2;
|
|
4730
|
+
function file() {
|
|
4731
|
+
return path2.join(os2.homedir(), ".dsh", "supervisor", "runtime.json");
|
|
4732
|
+
}
|
|
4733
|
+
function read() {
|
|
4734
|
+
let j;
|
|
4735
|
+
try {
|
|
4736
|
+
j = JSON.parse(fs2.readFileSync(file(), "utf8"));
|
|
4737
|
+
} catch {
|
|
4738
|
+
return null;
|
|
4739
|
+
}
|
|
4740
|
+
if (!j || typeof j !== "object" || Array.isArray(j)) return null;
|
|
4741
|
+
const node = j.node && typeof j.node === "object" ? j.node : {};
|
|
4742
|
+
const npm = j.npm && typeof j.npm === "object" ? j.npm : {};
|
|
4743
|
+
return {
|
|
4744
|
+
schema: Number(j.schema) || 1,
|
|
4745
|
+
nodePath: j.nodePath || node.path || null,
|
|
4746
|
+
nodeBinDir: j.nodeBinDir || node.binDir || null,
|
|
4747
|
+
npmPath: j.npmPath || npm.path || null,
|
|
4748
|
+
minNode: j.minNode || null,
|
|
4749
|
+
writtenBy: j.writtenBy || null,
|
|
4750
|
+
raw: j
|
|
4751
|
+
};
|
|
4752
|
+
}
|
|
4753
|
+
function npmBin(fallback) {
|
|
4754
|
+
const c = read();
|
|
4755
|
+
if (c && c.npmPath) {
|
|
4756
|
+
try {
|
|
4757
|
+
if (fs2.existsSync(c.npmPath)) return c.npmPath;
|
|
4758
|
+
} catch {
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
return typeof fallback === "function" ? fallback() : fallback;
|
|
4762
|
+
}
|
|
4763
|
+
function withPath(env) {
|
|
4764
|
+
const e = Object.assign({}, env || {});
|
|
4765
|
+
const c = read();
|
|
4766
|
+
if (c && c.nodeBinDir) {
|
|
4767
|
+
const cur = e.PATH || e.Path || "";
|
|
4768
|
+
e.PATH = c.nodeBinDir + path2.delimiter + cur;
|
|
4769
|
+
}
|
|
4770
|
+
return e;
|
|
4771
|
+
}
|
|
4772
|
+
module2.exports = { SUPPORTED_SCHEMA, file, read, npmBin, withPath };
|
|
4773
|
+
}
|
|
4774
|
+
});
|
|
4775
|
+
|
|
4724
4776
|
// src/platform/registry-contract.js
|
|
4725
4777
|
var require_registry_contract = __commonJS({
|
|
4726
4778
|
"src/platform/registry-contract.js"(exports2, module2) {
|
|
@@ -4832,6 +4884,7 @@ var require_dist = __commonJS({
|
|
|
4832
4884
|
var matrix = require_matrix();
|
|
4833
4885
|
var { spawn } = require("node:child_process");
|
|
4834
4886
|
var { npmBin } = require_exec_path();
|
|
4887
|
+
var runtimeContract = require_runtime_contract();
|
|
4835
4888
|
var registryContract = require_registry_contract();
|
|
4836
4889
|
var CONTRACT_TTL_MS = 60 * 1e3;
|
|
4837
4890
|
var service = require_service().current();
|
|
@@ -5227,17 +5280,17 @@ var require_dist = __commonJS({
|
|
|
5227
5280
|
const pkg = o.pkg || "@deepseek-ai/dsh";
|
|
5228
5281
|
if (!o.version) return Promise.resolve({ ok: false, error: "runNpmInstall: \u7F3A\u5C11 version\uFF08\u5FC5\u987B\u663E\u5F0F\u643A\u5E26\uFF09", output: [] });
|
|
5229
5282
|
let argv;
|
|
5230
|
-
let bin = npmBin();
|
|
5283
|
+
let bin = runtimeContract.npmBin(npmBin);
|
|
5231
5284
|
if (Array.isArray(o.commandTemplate) && o.commandTemplate.length) {
|
|
5232
5285
|
argv = o.commandTemplate.map((s) => String(s).replace(/{pkg}/g, pkg).replace(/{version}/g, o.version).replace(/{prefix}/g, o.prefix || ""));
|
|
5233
|
-
bin = argv[0] === "npm" ? npmBin() : argv[0];
|
|
5286
|
+
bin = argv[0] === "npm" ? runtimeContract.npmBin(npmBin) : argv[0];
|
|
5234
5287
|
argv = argv.slice(1);
|
|
5235
5288
|
} else {
|
|
5236
5289
|
argv = ["install", "-g", "--no-audit", "--no-fund"];
|
|
5237
5290
|
if (o.prefix) argv.push("--prefix", o.prefix);
|
|
5238
5291
|
argv.push(pkg + "@" + o.version);
|
|
5239
5292
|
}
|
|
5240
|
-
const envVars =
|
|
5293
|
+
const envVars = runtimeContract.withPath(process.env);
|
|
5241
5294
|
if (o.registry) {
|
|
5242
5295
|
envVars.npm_config_registry = o.registry;
|
|
5243
5296
|
envVars.NPM_CONFIG_REGISTRY = o.registry;
|
|
@@ -10387,60 +10440,6 @@ var require_fs_utils = __commonJS({
|
|
|
10387
10440
|
"use strict";
|
|
10388
10441
|
var fs2 = require("node:fs");
|
|
10389
10442
|
var path2 = require("node:path");
|
|
10390
|
-
var zlib = require("node:zlib");
|
|
10391
|
-
function extractTarGz(tgzBuf, destDir, opts) {
|
|
10392
|
-
const strip = opts && opts.stripComponents !== void 0 ? opts.stripComponents : 1;
|
|
10393
|
-
const tarData = zlib.gunzipSync(tgzBuf);
|
|
10394
|
-
fs2.mkdirSync(destDir, { recursive: true });
|
|
10395
|
-
const written = [];
|
|
10396
|
-
const stripName = (name) => {
|
|
10397
|
-
const parts = String(name).split("/").filter((p) => p !== "" && p !== ".");
|
|
10398
|
-
const cut = Math.min(strip, parts.length - 1);
|
|
10399
|
-
const rel = parts.slice(cut).join("/");
|
|
10400
|
-
if (!rel || rel.split("/").some((s) => s === "..") || rel.startsWith("/")) return null;
|
|
10401
|
-
return rel;
|
|
10402
|
-
};
|
|
10403
|
-
let offset = 0;
|
|
10404
|
-
let pendingLong = null;
|
|
10405
|
-
while (offset + 512 <= tarData.length) {
|
|
10406
|
-
const header = tarData.slice(offset, offset + 512);
|
|
10407
|
-
if (header.every((b) => b === 0)) break;
|
|
10408
|
-
let name = header.slice(0, 100).toString("utf8").split("\0")[0];
|
|
10409
|
-
const size = parseInt(header.slice(124, 136).toString("utf8").replace(/[\0 ]/g, ""), 8) || 0;
|
|
10410
|
-
const typeFlag = String.fromCharCode(header[156] || 48);
|
|
10411
|
-
const dataStart = offset + 512;
|
|
10412
|
-
const data = tarData.slice(dataStart, dataStart + size);
|
|
10413
|
-
offset = dataStart + Math.ceil(size / 512) * 512;
|
|
10414
|
-
if (pendingLong !== null) {
|
|
10415
|
-
name = pendingLong;
|
|
10416
|
-
pendingLong = null;
|
|
10417
|
-
}
|
|
10418
|
-
if (typeFlag === "L") {
|
|
10419
|
-
pendingLong = name;
|
|
10420
|
-
continue;
|
|
10421
|
-
}
|
|
10422
|
-
const rel = stripName(name);
|
|
10423
|
-
if (rel === null) continue;
|
|
10424
|
-
const target = path2.join(destDir, rel);
|
|
10425
|
-
if (typeFlag === "5") {
|
|
10426
|
-
fs2.mkdirSync(target, { recursive: true });
|
|
10427
|
-
continue;
|
|
10428
|
-
}
|
|
10429
|
-
if (typeFlag === "2") {
|
|
10430
|
-
const linkTo = header.slice(157, 157 + 100).toString("utf8").split("\0")[0];
|
|
10431
|
-
try {
|
|
10432
|
-
fs2.unlinkSync(target);
|
|
10433
|
-
} catch {
|
|
10434
|
-
}
|
|
10435
|
-
fs2.symlinkSync(linkTo, target);
|
|
10436
|
-
continue;
|
|
10437
|
-
}
|
|
10438
|
-
fs2.mkdirSync(path2.dirname(target), { recursive: true });
|
|
10439
|
-
fs2.writeFileSync(target, data);
|
|
10440
|
-
written.push(rel);
|
|
10441
|
-
}
|
|
10442
|
-
return written;
|
|
10443
|
-
}
|
|
10444
10443
|
function dirSizeBytes(root) {
|
|
10445
10444
|
let total = 0;
|
|
10446
10445
|
let seen = 0;
|
|
@@ -10474,7 +10473,7 @@ var require_fs_utils = __commonJS({
|
|
|
10474
10473
|
}
|
|
10475
10474
|
return total;
|
|
10476
10475
|
}
|
|
10477
|
-
module2.exports = { dirSizeBytes
|
|
10476
|
+
module2.exports = { dirSizeBytes };
|
|
10478
10477
|
}
|
|
10479
10478
|
});
|
|
10480
10479
|
|
|
@@ -11635,7 +11634,7 @@ var require_watchdog = __commonJS({
|
|
|
11635
11634
|
if (inUpdate && !phaseStale) return true;
|
|
11636
11635
|
try {
|
|
11637
11636
|
const j = shell.readJournal && shell.readJournal();
|
|
11638
|
-
if (j && j.to && !j.confirmed
|
|
11637
|
+
if (j && j.to && !j.confirmed) return true;
|
|
11639
11638
|
} catch {
|
|
11640
11639
|
}
|
|
11641
11640
|
return false;
|
|
@@ -11790,11 +11789,7 @@ var require_shell = __commonJS({
|
|
|
11790
11789
|
return readJson(journalPath()) || {
|
|
11791
11790
|
from: null,
|
|
11792
11791
|
to: null,
|
|
11793
|
-
attempts: 0,
|
|
11794
|
-
maxAttempts: 2,
|
|
11795
11792
|
confirmed: false,
|
|
11796
|
-
rolledBack: false,
|
|
11797
|
-
pinnedVersions: [],
|
|
11798
11793
|
startedAt: null,
|
|
11799
11794
|
lastAttemptAt: null
|
|
11800
11795
|
};
|
|
@@ -11806,9 +11801,7 @@ var require_shell = __commonJS({
|
|
|
11806
11801
|
const j = readJournal();
|
|
11807
11802
|
j.from = from || j.from;
|
|
11808
11803
|
j.to = to;
|
|
11809
|
-
j.attempts = 0;
|
|
11810
11804
|
j.confirmed = false;
|
|
11811
|
-
j.rolledBack = false;
|
|
11812
11805
|
j.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11813
11806
|
writeJournal(j);
|
|
11814
11807
|
return j;
|
|
@@ -11821,45 +11814,19 @@ var require_shell = __commonJS({
|
|
|
11821
11814
|
if (cur && cur === j.to && id && id.phase === "ready") {
|
|
11822
11815
|
if (!j.confirmed) {
|
|
11823
11816
|
j.confirmed = true;
|
|
11824
|
-
j.attempts = 0;
|
|
11825
11817
|
writeJournal(j);
|
|
11826
11818
|
}
|
|
11827
11819
|
return { state: "confirmed", version: cur, reason: "\u58F3\u5DF2\u5065\u5EB7\u8FD0\u884C\u65B0\u7248\u672C", journal: j, identity: id };
|
|
11828
11820
|
}
|
|
11829
|
-
const attempt = id && typeof id.attempt === "number" ? id.attempt : 0;
|
|
11830
|
-
if (cur && cur !== j.to && attempt >= (j.maxAttempts || 2)) {
|
|
11831
|
-
return {
|
|
11832
|
-
state: "should-rollback",
|
|
11833
|
-
target: j.to,
|
|
11834
|
-
current: cur,
|
|
11835
|
-
attempts: attempt,
|
|
11836
|
-
reason: `\u58F3 ${attempt} \u6B21\u672A\u80FD\u5728 ${j.to} \u4E0A\u5C31\u7EEA\uFF08\u5F53\u524D ${cur}\uFF09`,
|
|
11837
|
-
journal: j,
|
|
11838
|
-
identity: id
|
|
11839
|
-
};
|
|
11840
|
-
}
|
|
11841
11821
|
return {
|
|
11842
11822
|
state: "pending",
|
|
11843
11823
|
target: j.to,
|
|
11844
11824
|
current: cur,
|
|
11845
|
-
attempts: attempt,
|
|
11846
11825
|
reason: cur === j.to ? "\u7B49\u5F85\u58F3\u4E0A\u62A5\u5C31\u7EEA" : "\u7B49\u5F85\u58F3\u91CD\u542F\u5230\u65B0\u7248\u672C",
|
|
11847
11826
|
journal: j,
|
|
11848
11827
|
identity: id
|
|
11849
11828
|
};
|
|
11850
11829
|
}
|
|
11851
|
-
function rollback(reason) {
|
|
11852
|
-
const j = readJournal();
|
|
11853
|
-
const bad = j.to;
|
|
11854
|
-
if (bad && !j.pinnedVersions.includes(bad)) j.pinnedVersions.push(bad);
|
|
11855
|
-
j.rolledBack = true;
|
|
11856
|
-
j.confirmed = false;
|
|
11857
|
-
j.attempts = 0;
|
|
11858
|
-
j.to = null;
|
|
11859
|
-
j.lastAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11860
|
-
writeJournal(j);
|
|
11861
|
-
return { ok: true, pinned: bad, reason: reason || null, journal: j };
|
|
11862
|
-
}
|
|
11863
11830
|
function health(payload) {
|
|
11864
11831
|
const p = payload || {};
|
|
11865
11832
|
const dir = shellDir();
|
|
@@ -11882,7 +11849,6 @@ var require_shell = __commonJS({
|
|
|
11882
11849
|
journal: j,
|
|
11883
11850
|
state: ev.state,
|
|
11884
11851
|
reason: ev.reason || null,
|
|
11885
|
-
pinned: j.pinnedVersions || [],
|
|
11886
11852
|
dir: shellDir()
|
|
11887
11853
|
};
|
|
11888
11854
|
}
|
|
@@ -11988,7 +11954,7 @@ var require_shell = __commonJS({
|
|
|
11988
11954
|
return { ok: false, error: "\u62C9\u8D77\u65B0\u58F3\u5931\u8D25: " + (e && e.message || e), killed };
|
|
11989
11955
|
}
|
|
11990
11956
|
}
|
|
11991
|
-
module2.exports = { status, evaluate, health, markPending,
|
|
11957
|
+
module2.exports = { status, evaluate, health, markPending, identity, readJournal, shellDir, checkUpdate, restartShell, SHELL_RELEASE_PKG };
|
|
11992
11958
|
}
|
|
11993
11959
|
});
|
|
11994
11960
|
|
|
@@ -15657,20 +15623,22 @@ var require_guard = __commonJS({
|
|
|
15657
15623
|
return;
|
|
15658
15624
|
}
|
|
15659
15625
|
if (req.method === "POST" && pathname === "/self-update/apply") {
|
|
15660
|
-
|
|
15661
|
-
|
|
15662
|
-
|
|
15663
|
-
|
|
15664
|
-
|
|
15665
|
-
|
|
15626
|
+
req.resume();
|
|
15627
|
+
return send(410, {
|
|
15628
|
+
ok: false,
|
|
15629
|
+
code: "KERNEL_UPDATE_SINGLE_WRITER",
|
|
15630
|
+
owner: "desktop-shell",
|
|
15631
|
+
error: "\u5185\u6838\u66F4\u65B0\u7531\u684C\u9762\u58F3\u6267\u884C\uFF08\u5355\u5199\u5165\u8005\u5951\u7EA6\uFF09\uFF1A\u8BF7\u5728\u684C\u9762\u58F3\u7684\u9762\u677F\u4E2D\u70B9\u300C\u66F4\u65B0\u300D\uFF0C\u6216\u5347\u7EA7/\u91CD\u88C5\u684C\u9762\u58F3\u3002"
|
|
15632
|
+
});
|
|
15666
15633
|
}
|
|
15667
15634
|
if (req.method === "POST" && pathname === "/self-update/restart-guard") {
|
|
15668
|
-
|
|
15669
|
-
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
|
|
15673
|
-
|
|
15635
|
+
req.resume();
|
|
15636
|
+
return send(410, {
|
|
15637
|
+
ok: false,
|
|
15638
|
+
code: "KERNEL_UPDATE_SINGLE_WRITER",
|
|
15639
|
+
owner: "desktop-shell",
|
|
15640
|
+
error: "\u5B88\u536B\u91CD\u542F\u7531\u684C\u9762\u58F3\u7ECF\u670D\u52A1\u7BA1\u7406\u5668\u6267\u884C\uFF08\u5B88\u536B\u4ECE\u4E0D\u91CD\u542F\u81EA\u5DF1\uFF09\uFF1A\u66F4\u65B0\u5185\u6838\u8BF7\u7528\u684C\u9762\u58F3\u3002"
|
|
15641
|
+
});
|
|
15674
15642
|
}
|
|
15675
15643
|
if (req.method === "GET" && pathname === "/env/dsh") {
|
|
15676
15644
|
if (!originAllowed(req, sup.config.apiPort)) {
|
|
@@ -16323,26 +16291,6 @@ var require_shell2 = __commonJS({
|
|
|
16323
16291
|
return send(r.ok ? 200 : 500, r);
|
|
16324
16292
|
}).catch((e) => send(500, { ok: false, error: e.message }));
|
|
16325
16293
|
}
|
|
16326
|
-
if (req.method === "POST" && pathname === "/shell/rollback") {
|
|
16327
|
-
if (!originAllowed(req, sup.config.apiPort)) {
|
|
16328
|
-
req.resume();
|
|
16329
|
-
return send(403, {});
|
|
16330
|
-
}
|
|
16331
|
-
return collectBody(req, res, 8192, (body) => {
|
|
16332
|
-
let j = {};
|
|
16333
|
-
try {
|
|
16334
|
-
j = body ? JSON.parse(body) : {};
|
|
16335
|
-
} catch {
|
|
16336
|
-
}
|
|
16337
|
-
try {
|
|
16338
|
-
const r = shell.rollback(j.reason || "manual");
|
|
16339
|
-
if (sup.events) sup.events.append("shell_update_rolled_back", { pinned: r.pinned, reason: r.reason });
|
|
16340
|
-
return send(200, r);
|
|
16341
|
-
} catch (e) {
|
|
16342
|
-
return send(500, { ok: false, error: e.message });
|
|
16343
|
-
}
|
|
16344
|
-
});
|
|
16345
|
-
}
|
|
16346
16294
|
if (req.method === "GET" || req.method === "POST") return send(404, { error: "not found", path: pathname });
|
|
16347
16295
|
return send(405, { error: "method not allowed" });
|
|
16348
16296
|
}
|
|
@@ -17513,15 +17461,8 @@ var require_env_catalog = __commonJS({
|
|
|
17513
17461
|
function runtimeMeta() {
|
|
17514
17462
|
const now = Date.now();
|
|
17515
17463
|
if (_runtimeMetaCache && now - _runtimeMetaAt < 1e4) return _runtimeMetaCache;
|
|
17516
|
-
|
|
17517
|
-
|
|
17518
|
-
const os2 = require("node:os");
|
|
17519
|
-
const path2 = require("node:path");
|
|
17520
|
-
const f = path2.join(os2.homedir(), ".dsh", "supervisor", "runtime.json");
|
|
17521
|
-
meta = JSON.parse(fs2.readFileSync(f, "utf8")) || {};
|
|
17522
|
-
} catch {
|
|
17523
|
-
meta = {};
|
|
17524
|
-
}
|
|
17464
|
+
const c = require_runtime_contract().read();
|
|
17465
|
+
const meta = c && c.raw || {};
|
|
17525
17466
|
_runtimeMetaCache = meta;
|
|
17526
17467
|
_runtimeMetaAt = now;
|
|
17527
17468
|
return meta;
|
|
@@ -17588,27 +17529,24 @@ var require_env_catalog = __commonJS({
|
|
|
17588
17529
|
}
|
|
17589
17530
|
return out;
|
|
17590
17531
|
}
|
|
17591
|
-
/**
|
|
17592
|
-
*
|
|
17593
|
-
* ⚠ 2026-09-12 校正(P2):本条目原先依据 `selfUpdateManifestUrl` / `selfUpdateDir`,
|
|
17594
|
-
* 但**真实机制早已换成 npm 通道**(`corePackageName` + `runNpmInstall`,见 settings-view 的
|
|
17595
|
-
* `guardSelfUpdateStatus` / `guardCorePkg`)。那两个键**没有任何发行流程赋值**(默认恒为 null),
|
|
17596
|
-
* 于是 `/env/status` 里的「守卫自更新」**恒报 unconfigured**,且把原因归到了无效键上 ——
|
|
17597
|
-
* 用户与排障者据此查 `selfUpdateManifestUrl`,而真正该看的是 `corePackageName`。
|
|
17532
|
+
/** 内核更新依赖条目(单写入者契约:安装/重启归桌面壳)。
|
|
17598
17533
|
*
|
|
17599
|
-
*
|
|
17534
|
+
* 2026-09-15(A 方案):守卫**不再自更新**,`corePackageName` 只用于查询内核版本状态;
|
|
17535
|
+
* 安装/升级由桌面壳执行(见 RELEASE-AND-UPDATE-MECHANISM.md §6)。
|
|
17536
|
+
* 本条目因此只报告「壳执行内核更新所需的包名」是否就位 —— 不再暗示守卫能自己装。
|
|
17537
|
+
* id 仍为 `selfUpdate` 以兼容既有 `/env/status` 消费方。
|
|
17600
17538
|
*/
|
|
17601
17539
|
selfUpdateEntry() {
|
|
17602
17540
|
const pkg = this.config.corePackageName;
|
|
17603
17541
|
if (!pkg) {
|
|
17604
17542
|
return {
|
|
17605
|
-
label: "\
|
|
17543
|
+
label: "\u5185\u6838\u66F4\u65B0\uFF08\u684C\u9762\u58F3\u6267\u884C\uFF09",
|
|
17606
17544
|
required: false,
|
|
17607
17545
|
state: "unconfigured",
|
|
17608
|
-
detail: "\u672A\u914D\u7F6E corePackageName\
|
|
17546
|
+
detail: "\u672A\u914D\u7F6E corePackageName\uFF08\u5F62\u5982 @dsh-sup/dsh-core-<os>-<arch>\uFF09"
|
|
17609
17547
|
};
|
|
17610
17548
|
}
|
|
17611
|
-
return { label: "\
|
|
17549
|
+
return { label: "\u5185\u6838\u66F4\u65B0\uFF08\u684C\u9762\u58F3\u6267\u884C\uFF09", required: false, state: "configured", detail: pkg };
|
|
17612
17550
|
}
|
|
17613
17551
|
/** DSH 本体条目(外传判定:bin 可执行 + 已装版本)。 */
|
|
17614
17552
|
dshEntry(binOk, installed, bin) {
|
|
@@ -17776,7 +17714,6 @@ var require_settings_view = __commonJS({
|
|
|
17776
17714
|
"use strict";
|
|
17777
17715
|
var fs2 = require("node:fs");
|
|
17778
17716
|
var path2 = require("node:path");
|
|
17779
|
-
var os2 = require("node:os");
|
|
17780
17717
|
var { spawn } = require("node:child_process");
|
|
17781
17718
|
var { execFile } = require("node:child_process");
|
|
17782
17719
|
var ex2 = require_exec();
|
|
@@ -17879,54 +17816,24 @@ var require_settings_view = __commonJS({
|
|
|
17879
17816
|
return { ok: false, error: e.message };
|
|
17880
17817
|
}
|
|
17881
17818
|
}
|
|
17882
|
-
|
|
17883
|
-
* 否则返回明确指引(避免误杀/误起守卫)。 */
|
|
17884
|
-
/** 自更新后的守卫重启(A2):能力按部署形态自动判定(SEA=systemd 重启闭环;源码形态=拒绝),
|
|
17885
|
-
* 去掉 guardRestartAllowed 人工配置门槛。重启前落盘「预期版本」,重启后 /status 校验自报版本
|
|
17886
|
-
* 达标才算更新成功——闭环可观测,不再出现"装了没生效"的静默失败。 */
|
|
17887
|
-
guardSelfUpdateRestart() {
|
|
17888
|
-
const dep = deploy.detect();
|
|
17889
|
-
if (!dep.updatable) {
|
|
17890
|
-
return { ok: false, error: dep.reason || "\u5F53\u524D\u90E8\u7F72\u5F62\u6001\u4E0D\u652F\u6301\u81EA\u52A8\u91CD\u542F", form: dep.form };
|
|
17891
|
-
}
|
|
17892
|
-
const unit = path2.join(os2.homedir(), ".config", "systemd", "user", "dsh-supervisor.service");
|
|
17893
|
-
if (!fs2.existsSync(unit)) return { ok: false, error: "\u7CFB\u7EDF\u672A\u542F\u7528 systemd \u7528\u6237\u5355\u5143\uFF0C\u8BF7\u624B\u52A8\u91CD\u542F\u5B88\u536B" };
|
|
17894
|
-
const swDir = path2.dirname(this.config.stateFile);
|
|
17895
|
-
try {
|
|
17896
|
-
fs2.writeFileSync(path2.join(swDir, "self-update-expected.json"), JSON.stringify({ expectedVersion: this._selfUpdateExpectedVersion || null, at: Date.now() }), { mode: 384 });
|
|
17897
|
-
} catch {
|
|
17898
|
-
}
|
|
17899
|
-
if (this.events) this.events.append("guard_self_update_restart", { expectedVersion: this._selfUpdateExpectedVersion || null, via: "exit+systemd-restart" });
|
|
17900
|
-
this.logger && this.logger.info && this.logger.info("[self-update] \u5B88\u536B\u5C06\u9000\u51FA\uFF0C\u7531 systemd Restart=always \u62C9\u8D77\u65B0\u5185\u6838");
|
|
17901
|
-
setTimeout(() => {
|
|
17902
|
-
const bail = setTimeout(() => process.exit(0), 8e3);
|
|
17903
|
-
if (bail.unref) bail.unref();
|
|
17904
|
-
Promise.resolve().then(() => this.shutdown()).catch((e) => {
|
|
17905
|
-
this.logger && this.logger.warn && this.logger.warn("[self-update] shutdown \u5F02\u5E38: " + (e && e.message || e));
|
|
17906
|
-
}).then(() => {
|
|
17907
|
-
clearTimeout(bail);
|
|
17908
|
-
process.exit(0);
|
|
17909
|
-
});
|
|
17910
|
-
}, 500).unref();
|
|
17911
|
-
return { ok: true, restarted: true, via: "exit+systemd-restart" };
|
|
17912
|
-
}
|
|
17913
|
-
// ---- 守卫自更新(2026-09 收敛:npm 通道取代 manifest/目录翻转)----
|
|
17819
|
+
// ---- 内核更新(单写入者契约:安装/重启归桌面壳)----
|
|
17914
17820
|
//
|
|
17915
|
-
// ⚠
|
|
17916
|
-
//
|
|
17917
|
-
//
|
|
17918
|
-
//
|
|
17821
|
+
// ⚠ 2026-09-15(A 方案):`guardSelfUpdateApply` 与 `guardSelfUpdateRestart` **已删除** ——
|
|
17822
|
+
// 内核 npm 包的唯一写入者是桌面壳(见 RELEASE-AND-UPDATE-MECHANISM.md §6);
|
|
17823
|
+
// 守卫只保留只读的 `guardSelfUpdateStatus`,接口 `/self-update/apply|restart-guard` 返回 410。
|
|
17824
|
+
// (此前 2026-09-12 已删除零调用点的 `guardSelfUpdateDir()`。)
|
|
17919
17825
|
/** 内核 npm 子包名(按当前平台/架构)。corePackageName 可为显式常量或含 {os}/{arch} 占位的模板。 */
|
|
17920
17826
|
guardCorePkg() {
|
|
17921
17827
|
const raw = this.config.corePackageName;
|
|
17922
17828
|
if (!raw) return null;
|
|
17923
17829
|
return String(raw).replace(/{os}/g, matrix.osTag()).replace(/{arch}/g, matrix.current().arch) || null;
|
|
17924
17830
|
}
|
|
17925
|
-
/**
|
|
17926
|
-
* BETA/RC
|
|
17831
|
+
/** 内核更新状态(**只读**;安装/重启归桌面壳,单写入者契约)。
|
|
17832
|
+
* 查 @dsh-sup/dsh-core-<os>-<arch> 全 tag 最高版本(BETA/RC/正式都算更新),与本机 guardVersion 比较。
|
|
17833
|
+
* 本方法**不写任何东西**:面板据此显示「可更新」,实际安装由桌面壳 kernel_update_apply 执行。 */
|
|
17927
17834
|
async guardSelfUpdateStatus() {
|
|
17928
17835
|
const pkg = this.guardCorePkg();
|
|
17929
|
-
if (!pkg) return { ok: false, error: "\u672A\u914D\u7F6E\u5185\u6838\
|
|
17836
|
+
if (!pkg) return { ok: false, error: "\u672A\u914D\u7F6E\u5185\u6838\u5305\uFF08corePackageName\uFF09" };
|
|
17930
17837
|
if (!this.dist || typeof this.dist.fetchLatestVersion !== "function") return { ok: false, error: "\u53D1\u5E03\u670D\u52A1\u672A\u521D\u59CB\u5316" };
|
|
17931
17838
|
const dep = deploy.detect();
|
|
17932
17839
|
if (!dep.updatable) {
|
|
@@ -17943,82 +17850,6 @@ var require_settings_view = __commonJS({
|
|
|
17943
17850
|
return { ok: false, error: e.message };
|
|
17944
17851
|
}
|
|
17945
17852
|
}
|
|
17946
|
-
/** 应用内核更新(npm 通道,全更新强制语义):`npm i -g <pkg>@<latest>`。
|
|
17947
|
-
* 安装后由调用方(壳/面板)据 restartRequired 调 /self-update/restart-guard(或手动重启)生效。 */
|
|
17948
|
-
async guardSelfUpdateApply() {
|
|
17949
|
-
const pkg = this.guardCorePkg();
|
|
17950
|
-
if (!pkg) return { ok: false, error: "\u672A\u914D\u7F6E\u5185\u6838\u81EA\u66F4\u65B0\u5305\uFF08corePackageName\uFF09" };
|
|
17951
|
-
if (!this.dist || typeof this.dist.runNpmInstall !== "function") return { ok: false, error: "\u53D1\u5E03\u670D\u52A1\u672A\u521D\u59CB\u5316" };
|
|
17952
|
-
if (!this.config.installCommandTemplate || !Array.isArray(this.config.installCommandTemplate)) return { ok: false, error: "\u672A\u914D\u7F6E\u5B89\u88C5\u547D\u4EE4\u6A21\u677F\uFF08installCommandTemplate\uFF09" };
|
|
17953
|
-
const latest = await this.guardSelfUpdateStatus();
|
|
17954
|
-
if (!latest.ok || !latest.latest) return { ok: false, error: latest && latest.error || "\u7248\u672C\u67E5\u8BE2\u5931\u8D25" };
|
|
17955
|
-
if (latest.updatable === false) return { ok: false, error: latest.error || "\u5F53\u524D\u90E8\u7F72\u5F62\u6001\u4E0D\u652F\u6301\u81EA\u66F4\u65B0", form: latest.form };
|
|
17956
|
-
if (!latest.updateAvailable) return { ok: true, upToDate: true, version: this.guardVersion };
|
|
17957
|
-
const target = latest.latest;
|
|
17958
|
-
try {
|
|
17959
|
-
const registry = "https://registry.npmjs.org";
|
|
17960
|
-
const r = await this.dist.runNpmInstall({
|
|
17961
|
-
pkg,
|
|
17962
|
-
version: target,
|
|
17963
|
-
commandTemplate: this.config.installCommandTemplate,
|
|
17964
|
-
registry,
|
|
17965
|
-
onLine: (l) => {
|
|
17966
|
-
if (this.logger && this.logger.info) this.logger.info("[self-update] " + l);
|
|
17967
|
-
}
|
|
17968
|
-
});
|
|
17969
|
-
if (r && r.ok) {
|
|
17970
|
-
let diskVersion = null;
|
|
17971
|
-
try {
|
|
17972
|
-
diskVersion = deploy.detect().runningTarget ? this._readBinarySelfVersion() : null;
|
|
17973
|
-
} catch {
|
|
17974
|
-
}
|
|
17975
|
-
const verified = diskVersion === target;
|
|
17976
|
-
this._selfUpdateExpectedVersion = verified ? target : null;
|
|
17977
|
-
const restartRequired = true;
|
|
17978
|
-
if (this.events) {
|
|
17979
|
-
this.events.append("guard_self_update_applied", { from: this.guardVersion, version: target, pkg, diskVersion, verified });
|
|
17980
|
-
}
|
|
17981
|
-
if (!verified) {
|
|
17982
|
-
return {
|
|
17983
|
-
ok: true,
|
|
17984
|
-
from: this.guardVersion,
|
|
17985
|
-
version: target,
|
|
17986
|
-
diskVersion,
|
|
17987
|
-
verified: false,
|
|
17988
|
-
restartRequired,
|
|
17989
|
-
warn: "\u5DF2\u5B89\u88C5\u4F46\u78C1\u76D8\u7248\u672C\u6821\u9A8C\u672A\u901A\u8FC7\uFF08\u88C5\u5230\u975E\u8FD0\u884C\u4F4D/\u955C\u50CF stale\uFF09\uFF0C\u8BF7\u68C0\u67E5\u90E8\u7F72\u5F62\u6001"
|
|
17990
|
-
};
|
|
17991
|
-
}
|
|
17992
|
-
return { ok: true, from: this.guardVersion, version: target, diskVersion, verified: true, restartRequired };
|
|
17993
|
-
}
|
|
17994
|
-
return { ok: false, error: r && r.error || "npm \u5B89\u88C5\u5931\u8D25" };
|
|
17995
|
-
} catch (e) {
|
|
17996
|
-
return { ok: false, error: e.message };
|
|
17997
|
-
}
|
|
17998
|
-
}
|
|
17999
|
-
/** 自更新「已安装待重启生效」判定(A3):最近一次 apply 落盘的预期版本存在、
|
|
18000
|
-
* 且进程运行版本仍低于它 → updatePending=true(面板显示重启提示;重启达标后自动清除)。 */
|
|
18001
|
-
_selfUpdatePending() {
|
|
18002
|
-
try {
|
|
18003
|
-
const swDir = path2.dirname(this.config.stateFile);
|
|
18004
|
-
const f = path2.join(swDir, "self-update-expected.json");
|
|
18005
|
-
if (!fs2.existsSync(f)) return false;
|
|
18006
|
-
const j = JSON.parse(fs2.readFileSync(f, "utf8"));
|
|
18007
|
-
const expected = j && j.expectedVersion;
|
|
18008
|
-
if (!expected) return false;
|
|
18009
|
-
if (this.guardVersion === expected) {
|
|
18010
|
-
try {
|
|
18011
|
-
fs2.unlinkSync(f);
|
|
18012
|
-
} catch {
|
|
18013
|
-
}
|
|
18014
|
-
if (this.events) this.events.append("guard_self_update_verified", { version: expected });
|
|
18015
|
-
return false;
|
|
18016
|
-
}
|
|
18017
|
-
return semverCompare(expected, this.guardVersion) > 0;
|
|
18018
|
-
} catch {
|
|
18019
|
-
return false;
|
|
18020
|
-
}
|
|
18021
|
-
}
|
|
18022
17853
|
/** 读磁盘上**运行位**的自报版本(A1 校验用):spawn `--version`,解析 guardVersion= 行。
|
|
18023
17854
|
*
|
|
18024
17855
|
* ⚠ 2026-09-12(P0 配套):条件从 `form === 'sea-binary'` 放宽为「**可更新的标准形态**」
|
|
@@ -19695,7 +19526,6 @@ var require_supervisor = __commonJS({
|
|
|
19695
19526
|
this.manualRestart = false;
|
|
19696
19527
|
this._ticking = false;
|
|
19697
19528
|
this.intents = new IntentLedger();
|
|
19698
|
-
this._selfUpdateExpectedVersion = null;
|
|
19699
19529
|
this._stopping = false;
|
|
19700
19530
|
this._sessionState = "starting";
|
|
19701
19531
|
this._crashHalted = false;
|
|
@@ -20263,8 +20093,6 @@ var require_supervisor = __commonJS({
|
|
|
20263
20093
|
backoffUntil: this._mBackoffUntil(),
|
|
20264
20094
|
lastFailure: this._mLastFailure(),
|
|
20265
20095
|
lastRestartAt: this._mLastRestartAt(),
|
|
20266
|
-
updatePending: this._selfUpdatePending(),
|
|
20267
|
-
// A3:更新已安装待重启生效
|
|
20268
20096
|
upgradeHold: this._upgradeHold,
|
|
20269
20097
|
commandMissing: !!(this._mSpawnBlockedUntil() && Date.now() < this._mSpawnBlockedUntil()),
|
|
20270
20098
|
dshTokenCaptured: !!(this.tokenService && this.tokenService.get("main")),
|
|
@@ -21329,20 +21157,16 @@ function cmdSelfUpdate(action) {
|
|
|
21329
21157
|
if (s.ok) {
|
|
21330
21158
|
console.log("\u5B88\u536B\u5F53\u524D\u7248\u672C: " + s.installed);
|
|
21331
21159
|
console.log("\u6700\u65B0\u7248\u672C: " + s.latest);
|
|
21332
|
-
console.log(s.updateAvailable ? "\u2192 \u6709\u53EF\u7528\u66F4\u65B0\
|
|
21160
|
+
console.log(s.updateAvailable ? "\u2192 \u6709\u53EF\u7528\u66F4\u65B0\uFF1A\u8BF7\u5728\u684C\u9762\u58F3\u9762\u677F\u300C\u5173\u4E8E\u300D\u4E2D\u70B9\u300C\u66F4\u65B0\u300D" : "\u5DF2\u662F\u6700\u65B0\u3002");
|
|
21333
21161
|
}
|
|
21334
21162
|
return;
|
|
21335
21163
|
}
|
|
21336
21164
|
if (action === "apply") {
|
|
21337
|
-
|
|
21338
|
-
|
|
21339
|
-
|
|
21340
|
-
console.log("\u5DF2\u66F4\u65B0\u5230 v" + r.version + (r.restartRequired ? "\uFF0C\u9700\u8981\u91CD\u542F\u5B88\u536B\u751F\u6548" : "\uFF08\u65E0\u53D8\u5316\uFF09"));
|
|
21341
|
-
console.log("\u91CD\u542F: systemctl --user restart dsh-supervisor");
|
|
21342
|
-
}
|
|
21343
|
-
return;
|
|
21165
|
+
console.error("\u5185\u6838\u66F4\u65B0\u7531\u684C\u9762\u58F3\u6267\u884C\uFF08\u5355\u5199\u5165\u8005\u5951\u7EA6\uFF09\uFF1A\u8BF7\u5728\u684C\u9762\u58F3\u9762\u677F\u300C\u5173\u4E8E\u300D\u4E2D\u70B9\u300C\u66F4\u65B0\u300D\u3002");
|
|
21166
|
+
console.error("\u672C\u547D\u4EE4\u4E0D\u518D\u5B89\u88C5\u5185\u6838\u3002");
|
|
21167
|
+
process.exit(2);
|
|
21344
21168
|
}
|
|
21345
|
-
console.log("\u7528\u6CD5: dsh-supervisor self-update [check
|
|
21169
|
+
console.log("\u7528\u6CD5: dsh-supervisor self-update [check]");
|
|
21346
21170
|
})();
|
|
21347
21171
|
}
|
|
21348
21172
|
function cmdUpgrade(requested) {
|