dsh-wechat-remote 1.7.4 → 1.7.6
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/README.md +14 -12
- package/assets/plugin.tgz +0 -0
- package/assets/release.json +72 -35
- package/bin/dsh-discovery.mjs +165 -0
- package/bin/native-control.mjs +4 -2
- package/bin/release-selection.mjs +36 -33
- package/bin/setup.mjs +51 -43
- package/lib/install-control.js +1268 -1268
- package/lib/install-profile.js +210 -210
- package/lib/install-runtime.js +64 -64
- package/lib/package.json +1 -1
- package/lib/secure-file.js +76 -76
- package/lib/update-download.js +98 -98
- package/lib/update-policy.js +146 -147
- package/lib/update-worker.js +740 -689
- package/package.json +1 -1
package/lib/update-policy.js
CHANGED
|
@@ -1,147 +1,146 @@
|
|
|
1
|
-
/* Generated from the shared plugin installation sources. */
|
|
2
|
-
|
|
3
|
-
// src/update-policy.ts
|
|
4
|
-
var UPDATE_SCHEMA = 1;
|
|
5
|
-
var RELEASE_REPOSITORY = "https://github.com/martinbear1/dsh-wechat-remote";
|
|
6
|
-
var versionPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
7
|
-
function validVersion(value) {
|
|
8
|
-
if (typeof value !== "string" || value.length > 80) return false;
|
|
9
|
-
const match = versionPattern.exec(value);
|
|
10
|
-
return Boolean(match && !(match[4] || "").split(".").some((p) => /^0\d+$/.test(p)) && (!value.includes("+") || /^[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*$/.test(value.split("+")[1])));
|
|
11
|
-
}
|
|
12
|
-
function compareVersions(a, b) {
|
|
13
|
-
if (!validVersion(a) || !validVersion(b)) throw new Error("Invalid version");
|
|
14
|
-
const x = versionPattern.exec(a), y = versionPattern.exec(b);
|
|
15
|
-
if (!x || !y) throw new Error("Invalid version");
|
|
16
|
-
for (let i = 1; i <= 3; i++) if (x[i] !== y[i]) return BigInt(x[i]) > BigInt(y[i]) ? 1 : -1;
|
|
17
|
-
if (!x[4] || !y[4]) return x[4] === y[4] ? 0 : !x[4] ? 1 : -1;
|
|
18
|
-
const xp = x[4].split("."), yp = y[4].split(".");
|
|
19
|
-
for (let i = 0; i < Math.max(xp.length, yp.length); i++) {
|
|
20
|
-
if (xp[i] === yp[i]) continue;
|
|
21
|
-
if (xp[i] === void 0 || yp[i] === void 0) return xp[i] === void 0 ? -1 : 1;
|
|
22
|
-
const xn = /^\d+$/.test(xp[i]), yn = /^\d+$/.test(yp[i]);
|
|
23
|
-
if (xn && yn) return BigInt(xp[i]) > BigInt(yp[i]) ? 1 : -1;
|
|
24
|
-
if (xn !== yn) return xn ? -1 : 1;
|
|
25
|
-
return xp[i] > yp[i] ? 1 : -1;
|
|
26
|
-
}
|
|
27
|
-
return 0;
|
|
28
|
-
}
|
|
29
|
-
function trustedReleaseAsset(asset, version) {
|
|
30
|
-
if (!asset || !/^[a-f0-9]{64}$/.test(asset.sha256) || !Number.isSafeInteger(asset.bytes) || asset.bytes < 1 || asset.bytes > 32 * 1024 * 1024) return false;
|
|
31
|
-
try {
|
|
32
|
-
const u = new URL(asset.url);
|
|
33
|
-
return u.origin === "https://github.com" && !u.username && !u.password && !u.search && !u.hash && u.pathname.startsWith(`/martinbear1/dsh-wechat-remote/releases/download/v${version}/`) && /^[-A-Za-z0-9_.]+\.tgz$/.test(u.pathname.slice(`/martinbear1/dsh-wechat-remote/releases/download/v${version}/`.length));
|
|
34
|
-
} catch {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function validateCatalog(value) {
|
|
39
|
-
const c = value;
|
|
40
|
-
const strings = (v, max = 100) => Array.isArray(v) && v.length <= max && v.every((s) => typeof s === "string" && s.length > 0 && s.length <= 100);
|
|
41
|
-
if (!c || c.schemaVersion !== 1 || typeof c.revision !== "string" || !/^[\w.-]{1,80}$/.test(c.revision) || !Number.isSafeInteger(c.issuedAt) || !Number.isSafeInteger(c.expiresAt) || c.expiresAt <= c.issuedAt || c.expiresAt - c.issuedAt > 32 * 864e5 || !Array.isArray(c.releases) || c.releases.length > 100 || !Array.isArray(c.blocked) || c.blocked.length > 100 || !strings(c.retiredDsh)) throw new Error("Invalid update catalog");
|
|
42
|
-
const versions = /* @__PURE__ */ new Set();
|
|
43
|
-
for (const r of c.releases) {
|
|
44
|
-
if (!r || !validVersion(r.version) || versions.has(r.version) || !["stable", "preview"].includes(r.channel) || r.channel === "stable" && versionPattern.exec(r.version)[4] || !strings(r.dsh) || !r.dsh.length || !r.dsh.every(validVersion) || !strings(r.platforms, 3) || !r.platforms.length || !r.platforms.every((p) => ["windows", "macos", "linux"].includes(p)) || !strings(r.architectures,
|
|
45
|
-
versions.add(r.version);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
};
|
|
1
|
+
/* Generated from the shared plugin installation sources. */
|
|
2
|
+
|
|
3
|
+
// src/update-policy.ts
|
|
4
|
+
var UPDATE_SCHEMA = 1;
|
|
5
|
+
var RELEASE_REPOSITORY = "https://github.com/martinbear1/dsh-wechat-remote";
|
|
6
|
+
var versionPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
7
|
+
function validVersion(value) {
|
|
8
|
+
if (typeof value !== "string" || value.length > 80) return false;
|
|
9
|
+
const match = versionPattern.exec(value);
|
|
10
|
+
return Boolean(match && !(match[4] || "").split(".").some((p) => /^0\d+$/.test(p)) && (!value.includes("+") || /^[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*$/.test(value.split("+")[1])));
|
|
11
|
+
}
|
|
12
|
+
function compareVersions(a, b) {
|
|
13
|
+
if (!validVersion(a) || !validVersion(b)) throw new Error("Invalid version");
|
|
14
|
+
const x = versionPattern.exec(a), y = versionPattern.exec(b);
|
|
15
|
+
if (!x || !y) throw new Error("Invalid version");
|
|
16
|
+
for (let i = 1; i <= 3; i++) if (x[i] !== y[i]) return BigInt(x[i]) > BigInt(y[i]) ? 1 : -1;
|
|
17
|
+
if (!x[4] || !y[4]) return x[4] === y[4] ? 0 : !x[4] ? 1 : -1;
|
|
18
|
+
const xp = x[4].split("."), yp = y[4].split(".");
|
|
19
|
+
for (let i = 0; i < Math.max(xp.length, yp.length); i++) {
|
|
20
|
+
if (xp[i] === yp[i]) continue;
|
|
21
|
+
if (xp[i] === void 0 || yp[i] === void 0) return xp[i] === void 0 ? -1 : 1;
|
|
22
|
+
const xn = /^\d+$/.test(xp[i]), yn = /^\d+$/.test(yp[i]);
|
|
23
|
+
if (xn && yn) return BigInt(xp[i]) > BigInt(yp[i]) ? 1 : -1;
|
|
24
|
+
if (xn !== yn) return xn ? -1 : 1;
|
|
25
|
+
return xp[i] > yp[i] ? 1 : -1;
|
|
26
|
+
}
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
function trustedReleaseAsset(asset, version) {
|
|
30
|
+
if (!asset || !/^[a-f0-9]{64}$/.test(asset.sha256) || !Number.isSafeInteger(asset.bytes) || asset.bytes < 1 || asset.bytes > 32 * 1024 * 1024) return false;
|
|
31
|
+
try {
|
|
32
|
+
const u = new URL(asset.url);
|
|
33
|
+
return u.origin === "https://github.com" && !u.username && !u.password && !u.search && !u.hash && u.pathname.startsWith(`/martinbear1/dsh-wechat-remote/releases/download/v${version}/`) && /^[-A-Za-z0-9_.]+\.tgz$/.test(u.pathname.slice(`/martinbear1/dsh-wechat-remote/releases/download/v${version}/`.length));
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function validateCatalog(value) {
|
|
39
|
+
const c = value;
|
|
40
|
+
const strings = (v, max = 100) => Array.isArray(v) && v.length <= max && v.every((s) => typeof s === "string" && s.length > 0 && s.length <= 100);
|
|
41
|
+
if (!c || c.schemaVersion !== 1 || typeof c.revision !== "string" || !/^[\w.-]{1,80}$/.test(c.revision) || !Number.isSafeInteger(c.issuedAt) || !Number.isSafeInteger(c.expiresAt) || c.expiresAt <= c.issuedAt || c.expiresAt - c.issuedAt > 32 * 864e5 || !Array.isArray(c.releases) || c.releases.length > 100 || !Array.isArray(c.blocked) || c.blocked.length > 100 || !strings(c.retiredDsh)) throw new Error("Invalid update catalog");
|
|
42
|
+
const versions = /* @__PURE__ */ new Set();
|
|
43
|
+
for (const r of c.releases) {
|
|
44
|
+
if (!r || !validVersion(r.version) || versions.has(r.version) || !["stable", "preview"].includes(r.channel) || r.channel === "stable" && versionPattern.exec(r.version)[4] || !strings(r.dsh) || !r.dsh.length || !r.dsh.every(validVersion) || !strings(r.platforms, 3) || !r.platforms.length || !r.platforms.every((p) => ["windows", "macos", "linux"].includes(p)) || !strings(r.architectures, 32) || !r.architectures.length || !r.architectures.every((a) => /^[a-z0-9_-]{1,32}$/.test(a)) || r.asset && !trustedReleaseAsset(r.asset, r.version)) throw new Error("Invalid release entry");
|
|
45
|
+
versions.add(r.version);
|
|
46
|
+
if (r.targets !== void 0) {
|
|
47
|
+
if (!Array.isArray(r.targets) || !r.targets.length || r.targets.length > 12) throw new Error("Invalid release targets");
|
|
48
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49
|
+
for (const target of r.targets) {
|
|
50
|
+
const key = `${target?.platform}:${target?.arch}`;
|
|
51
|
+
if (!target || !r.platforms.includes(target.platform) || !r.architectures.includes(target.arch) || !strings(target.dsh) || !target.dsh.length || !target.dsh.every((v) => r.dsh.includes(v)) || seen.has(key)) throw new Error("Invalid release target");
|
|
52
|
+
seen.add(key);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const b of c.blocked) if (!b || !validVersion(b.pluginVersion) || typeof b.reason !== "string" || !b.reason || b.reason.length > 240 || b.dsh && !strings(b.dsh) || b.platforms && !strings(b.platforms, 3)) throw new Error("Invalid blocked entry");
|
|
57
|
+
if (!c.retiredDsh.every(validVersion)) throw new Error("Invalid retired DSH");
|
|
58
|
+
if (c.manualUpgradePlugins && (!strings(c.manualUpgradePlugins) || !c.manualUpgradePlugins.every(validVersion))) throw new Error("Invalid manual-upgrade plugins");
|
|
59
|
+
return c;
|
|
60
|
+
}
|
|
61
|
+
function releaseMatches(r, current) {
|
|
62
|
+
return r.dsh.includes(current.agentVersion) && r.platforms.includes(current.platform) && Boolean(current.arch && r.architectures.includes(current.arch)) && (!r.targets || r.targets.some((t) => t.platform === current.platform && (!current.arch || t.arch === current.arch) && t.dsh.includes(current.agentVersion)));
|
|
63
|
+
}
|
|
64
|
+
function assessUpdate(raw, current, now = Date.now(), preview = false) {
|
|
65
|
+
const base = {
|
|
66
|
+
schemaVersion: 1,
|
|
67
|
+
revision: "",
|
|
68
|
+
checkedAt: now,
|
|
69
|
+
expiresAt: now,
|
|
70
|
+
severity: "unknown",
|
|
71
|
+
component: "none",
|
|
72
|
+
code: "unavailable",
|
|
73
|
+
label: "\u6682\u65F6\u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0",
|
|
74
|
+
message: "\u517C\u5BB9\u4FE1\u606F\u6682\u4E0D\u53EF\u7528\uFF0C\u4E0D\u5F71\u54CD\u73B0\u6709\u8FDE\u63A5\uFF1B\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
75
|
+
current
|
|
76
|
+
};
|
|
77
|
+
let c;
|
|
78
|
+
try {
|
|
79
|
+
c = validateCatalog(raw);
|
|
80
|
+
} catch {
|
|
81
|
+
return base;
|
|
82
|
+
}
|
|
83
|
+
base.revision = c.revision;
|
|
84
|
+
base.expiresAt = c.expiresAt;
|
|
85
|
+
if (c.expiresAt <= now || c.issuedAt > now + 3e5) return { ...base, code: "stale", label: "\u68C0\u67E5\u4FE1\u606F\u5DF2\u8FC7\u671F" };
|
|
86
|
+
if (!["dsh", "deepseek-harness"].includes(current.agentKind)) return { ...base, code: "unknown-agent", label: "\u5C1A\u672A\u63D0\u4F9B\u517C\u5BB9\u4FE1\u606F" };
|
|
87
|
+
if (!validVersion(current.agentVersion) || !validVersion(current.pluginVersion) || !["windows", "macos", "linux"].includes(current.platform)) return { ...base, code: "missing-version", label: "\u7248\u672C\u4FE1\u606F\u4E0D\u5B8C\u6574" };
|
|
88
|
+
const blocked = (version) => c.blocked.find((b) => b.pluginVersion === version && (!b.dsh || b.dsh.includes(current.agentVersion)) && (!b.platforms || b.platforms.includes(current.platform)));
|
|
89
|
+
const own = c.releases.find((r) => r.version === current.pluginVersion);
|
|
90
|
+
const compatible = Boolean(current.arch && own && releaseMatches(own, current) && !blocked(own.version));
|
|
91
|
+
if (c.retiredDsh.includes(current.agentVersion)) return {
|
|
92
|
+
...base,
|
|
93
|
+
severity: "required",
|
|
94
|
+
component: "agent",
|
|
95
|
+
code: "agent-retired",
|
|
96
|
+
label: "\u9700\u8981\u66F4\u65B0 DSH",
|
|
97
|
+
message: "\u6B64 DSH \u7248\u672C\u5DF2\u505C\u6B62\u652F\u6301\u3002\u8BF7\u5728\u4E3B\u673A\u4E0A\u6309\u53D1\u5E03\u8BF4\u660E\u5347\u7EA7 DSH\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u4FEE\u6539 DSH\u3002",
|
|
98
|
+
releaseUrl: `${RELEASE_REPOSITORY}/releases`
|
|
99
|
+
};
|
|
100
|
+
const target = c.releases.filter((r) => (r.channel === "stable" || preview) && !blocked(r.version) && compareVersions(r.version, current.pluginVersion) > 0).sort((a, b) => compareVersions(b.version, a.version))[0];
|
|
101
|
+
const issue = blocked(current.pluginVersion);
|
|
102
|
+
if (target) {
|
|
103
|
+
const manual = c.manualUpgradePlugins?.includes(current.pluginVersion) ? {
|
|
104
|
+
manualUpdate: `\u6B64\u65E7\u63D2\u4EF6\u6CA1\u6709\u68C0\u67E5\u66F4\u65B0\u548C\u4E00\u952E\u66F4\u65B0\u529F\u80FD\u3002\u9996\u6B21\u9700\u5728\u8282\u70B9\u6240\u5728\u7535\u8111\uFF0C\u6309\u76EE\u6807\u7248\u672C ${target.version} \u7684\u53D1\u5E03\u8BF4\u660E\u624B\u5DE5\u5347\u7EA7\u63D2\u4EF6\uFF0C\u5E76\u4F7F\u7528\u539F\u6765\u7684 DSH_HOME \u548C profile \u91CD\u542F\u3002\u4E0D\u8981\u5220\u9664\u8282\u70B9\u6216\u91CD\u65B0\u914D\u5BF9\uFF1B\u5347\u7EA7\u540E\u624D\u53EF\u4F7F\u7528\u4E00\u952E\u66F4\u65B0\u3002`
|
|
105
|
+
} : {};
|
|
106
|
+
const required = Boolean(issue);
|
|
107
|
+
return {
|
|
108
|
+
...base,
|
|
109
|
+
...manual,
|
|
110
|
+
severity: required ? "required" : compatible ? "info" : "recommended",
|
|
111
|
+
component: "plugin",
|
|
112
|
+
code: required ? "plugin-required" : "plugin-available",
|
|
113
|
+
label: required ? "\u5FC5\u987B\u66F4\u65B0\u63D2\u4EF6" : "\u63D2\u4EF6\u53EF\u66F4\u65B0",
|
|
114
|
+
message: (issue ? issue.reason + "\u3002" : "") + `\u53EF\u66F4\u65B0\u81F3\u63D2\u4EF6 ${target.version}\uFF1B\u66F4\u65B0\u524D\u4F1A\u68C0\u67E5\u5F53\u524D\u4E3B\u673A\u7684\u5B89\u88C5\u4E0E\u91CD\u542F\u6761\u4EF6\uFF0C\u4E0D\u4F1A\u66F4\u6362 DSH \u672C\u4F53\u3002`,
|
|
115
|
+
targetVersion: target.version,
|
|
116
|
+
releaseUrl: `${RELEASE_REPOSITORY}/releases/tag/v${target.version}`
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (issue) return {
|
|
120
|
+
...base,
|
|
121
|
+
severity: "required",
|
|
122
|
+
component: "plugin",
|
|
123
|
+
code: "blocked-no-target",
|
|
124
|
+
label: "\u63D2\u4EF6\u9700\u5904\u7406",
|
|
125
|
+
message: `${issue.reason}\u6682\u65E0\u53EF\u5B89\u5168\u81EA\u52A8\u5B89\u88C5\u7684\u5339\u914D\u7248\u672C\uFF0C\u8BF7\u67E5\u770B\u53D1\u5E03\u8BF4\u660E\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u5347\u7EA7\u6216\u964D\u7EA7 DSH\u3002`,
|
|
126
|
+
releaseUrl: `${RELEASE_REPOSITORY}/releases`
|
|
127
|
+
};
|
|
128
|
+
if (compatible) return { ...base, severity: "none", code: "compatible", label: "\u6682\u65E0\u53EF\u7528\u66F4\u65B0", message: "\u5F53\u524D\u7EC4\u5408\u5DF2\u9A8C\u8BC1\uFF0C\u6682\u672A\u53D1\u73B0\u9002\u7528\u4E8E\u6B64 DSH \u548C\u4E3B\u673A\u7684\u66F4\u65B0\u3002" };
|
|
129
|
+
return {
|
|
130
|
+
...base,
|
|
131
|
+
severity: "none",
|
|
132
|
+
code: "no-update",
|
|
133
|
+
label: "\u6682\u65E0\u53EF\u7528\u66F4\u65B0",
|
|
134
|
+
message: "\u5F53\u524D\u901A\u9053\u6682\u65E0\u66F4\u9AD8\u7248\u672C\uFF0C\u4E0D\u5F71\u54CD\u7EE7\u7EED\u4F7F\u7528\u3002",
|
|
135
|
+
releaseUrl: `${RELEASE_REPOSITORY}/releases`
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
RELEASE_REPOSITORY,
|
|
140
|
+
UPDATE_SCHEMA,
|
|
141
|
+
assessUpdate,
|
|
142
|
+
compareVersions,
|
|
143
|
+
releaseMatches,
|
|
144
|
+
trustedReleaseAsset,
|
|
145
|
+
validateCatalog
|
|
146
|
+
};
|