dsh-opencode-palette 2.0.8 → 2.0.10

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.
@@ -1,360 +0,0 @@
1
- // 派生文件(构建生成,人手不改):由 npm 包 dsh-plugin-update@0.1.1 的 dist/ 原样复制。
2
- // 为什么必须放进本包:更新包的读取器用 containingPackage(import.meta.url, 目标包名) 从自己的文件位置
3
- // 往上找目标包;以 npm 依赖形态安装时它住在别的目录,会抛 unknown-profile 且环境判定恒为 installation-changed。
4
- // 门禁:tests/update-panel.test.mjs 断言本副本与 npm 包逐字节一致(除本头部)。
5
- // vendor-source: dsh-plugin-update@0.1.1 dist/service.js
6
- // AUTO-GENERATED by node packages/dsh-plugin-update/build.mjs — DO NOT EDIT. Source: packages/dsh-plugin-update/src/service.ts
7
- const PACKAGE_NAME = "dsh-mattpocock-skills-deck";
8
- const NPM_REGISTRY = "https://registry.npmjs.org/";
9
- const CHECK_TIMEOUT_MS = 1e4;
10
- const CONFIRMATION_TTL_MS = 10 * 6e4;
11
- const RECHECK_WINDOW_MS = 2e3;
12
- const MAX_METADATA_BYTES = 256 * 1024;
13
- const INTEGRITY_PATTERN = "^sha512-[A-Za-z0-9+/]{86}==$";
14
- function validRequestId(v) {
15
- return typeof v === "string" && v.trim().length >= 1 && v.trim().length <= 128;
16
- }
17
- function updateError(code) {
18
- return Object.assign(new Error(code), { code });
19
- }
20
- function validVersion(v) {
21
- return typeof v === "string" && /^\d+\.\d+\.\d+$/.test(v);
22
- }
23
- function parseTriple(v) {
24
- const parts = String(v).split(".");
25
- if (parts.length > 3) return null;
26
- const nums = [];
27
- for (const p of parts) {
28
- if (!/^\d+$/.test(p)) return null;
29
- const n = Number(p);
30
- if (!Number.isSafeInteger(n)) return null;
31
- nums.push(n);
32
- }
33
- while (nums.length < 3) nums.push(0);
34
- return [nums[0], nums[1], nums[2]];
35
- }
36
- function compareVersions(a, b) {
37
- const pa = parseTriple(a);
38
- const pb = parseTriple(b);
39
- if (!pa || !pb) throw updateError("invalid-release");
40
- for (let i = 0; i < 3; i++) {
41
- if (pa[i] < pb[i]) return -1;
42
- if (pa[i] > pb[i]) return 1;
43
- }
44
- return 0;
45
- }
46
- function compareOne(node, op, target) {
47
- const order = compareTriple(node, target);
48
- if (op === "=" || op === "") return order === 0;
49
- if (op === ">") return order === 1;
50
- if (op === ">=") return order >= 0;
51
- if (op === "<") return order === -1;
52
- if (op === "<=") return order <= 0;
53
- return true;
54
- }
55
- function compareTriple(a, b) {
56
- for (let i = 0; i < 3; i++) {
57
- if (a[i] < b[i]) return -1;
58
- if (a[i] > b[i]) return 1;
59
- }
60
- return 0;
61
- }
62
- function upperBound(t, kind, kept) {
63
- if (kind === "^") {
64
- if (kept >= 1) return [t[0] + 1, 0, 0];
65
- return [0, t[1] + 1, 0];
66
- }
67
- if (kept >= 2) return [t[0], t[1] + 1, 0];
68
- return [t[0] + 1, 0, 0];
69
- }
70
- function satisfiesNodeRange(nodeVersion, range) {
71
- if (range === void 0 || range === null) return true;
72
- const text = String(range).trim();
73
- if (text === "" || text === "*") return true;
74
- const node = parseTriple(String(nodeVersion).replace(/^v/, ""));
75
- if (!node) return true;
76
- if (text.includes("||")) return true;
77
- const parts = text.split(/\s+/).filter(Boolean);
78
- if (parts.length === 0) return true;
79
- for (const part of parts) {
80
- const m = part.match(/^(\^|~|>=|<=|>|<|=)?(.+)$/);
81
- if (!m) return true;
82
- const op = m[1] || "";
83
- const target = parseTriple(m[2]);
84
- if (!target) return true;
85
- if (op === "^" || op === "~") {
86
- const kept = m[2].split(".").length;
87
- if (compareTriple(node, target) < 0) return false;
88
- if (compareTriple(node, upperBound(target, op, kept)) >= 0) return false;
89
- continue;
90
- }
91
- if (!compareOne(node, op, target)) return false;
92
- }
93
- return true;
94
- }
95
- function byteLength(text) {
96
- try {
97
- return new TextEncoder().encode(text).length;
98
- } catch {
99
- return text.length;
100
- }
101
- }
102
- function timeoutSignal(ms) {
103
- try {
104
- const ctor = globalThis.AbortSignal;
105
- if (ctor && typeof ctor.timeout === "function") return ctor.timeout(ms);
106
- } catch {
107
- }
108
- return void 0;
109
- }
110
- async function fetchNpmRelease(fetchImpl, timeoutMs = CHECK_TIMEOUT_MS, opts) {
111
- const targetName = opts?.targetPackageName ?? PACKAGE_NAME;
112
- const registry = opts?.registryUrl ?? NPM_REGISTRY;
113
- let response = null;
114
- try {
115
- response = await fetchImpl(`${registry}${encodeURIComponent(targetName)}/latest`, {
116
- headers: { accept: "application/json" },
117
- redirect: "error",
118
- signal: timeoutSignal(timeoutMs)
119
- });
120
- } catch {
121
- throw updateError("check-failed");
122
- }
123
- try {
124
- if (!response.ok) throw updateError("check-failed");
125
- const declared = Number(response.headers.get("content-length"));
126
- if (Number.isFinite(declared) && declared > MAX_METADATA_BYTES) throw updateError("invalid-release");
127
- const text = await response.text();
128
- if (byteLength(text) > MAX_METADATA_BYTES) throw updateError("invalid-release");
129
- const value = JSON.parse(text);
130
- if (value.name !== targetName || !validVersion(value.version)) throw updateError("invalid-release");
131
- const version = value.version;
132
- const nodeRange = value.engines?.node;
133
- if (nodeRange !== void 0 && typeof nodeRange !== "string") throw updateError("invalid-release");
134
- const tarballText = value.dist?.tarball;
135
- const integrity = value.dist?.integrity;
136
- let tarball;
137
- try {
138
- tarball = new URL(String(tarballText));
139
- } catch {
140
- throw updateError("invalid-release");
141
- }
142
- const registryOrigin = new URL(registry).origin;
143
- const shapeOk = tarball.origin === registryOrigin && !tarball.username && !tarball.password && !tarball.search && !tarball.hash && tarball.pathname === `/${targetName}/-/${targetName}-${version}.tgz` && typeof integrity === "string" && new RegExp(INTEGRITY_PATTERN).test(integrity);
144
- if (!shapeOk) throw updateError("invalid-release");
145
- return { version, nodeRange: typeof nodeRange === "string" ? nodeRange : "*", integrity, tarball: tarball.href };
146
- } catch (error) {
147
- if (error?.code === "check-failed") throw error;
148
- if (error?.code === "invalid-release") throw error;
149
- if (response !== null && response.ok) throw updateError("invalid-release");
150
- throw updateError("check-failed");
151
- }
152
- }
153
- function createUpdateCore(ports) {
154
- const checkTimeoutMs = ports.checkTimeoutMs ?? CHECK_TIMEOUT_MS;
155
- const confirmationTtlMs = ports.confirmationTtlMs ?? CONFIRMATION_TTL_MS;
156
- const targetPackageName = ports.targetPackageName ?? PACKAGE_NAME;
157
- const registryUrl = ports.registryUrl ?? NPM_REGISTRY;
158
- function fetchRelease() {
159
- return fetchNpmRelease(ports.fetchImpl, checkTimeoutMs, { targetPackageName, registryUrl });
160
- }
161
- let checked = null;
162
- let checking = null;
163
- let lastCheckAt = -Infinity;
164
- let activeJobId = null;
165
- let memJob = null;
166
- let memLock = null;
167
- async function loadJob() {
168
- try {
169
- return ports.readJob ? await ports.readJob() ?? null : memJob;
170
- } catch {
171
- throw updateError("install-failed");
172
- }
173
- }
174
- async function saveJob(job) {
175
- try {
176
- if (ports.writeJob) await ports.writeJob(job);
177
- else memJob = job;
178
- } catch {
179
- throw updateError("install-failed");
180
- }
181
- }
182
- async function acquire(lockId) {
183
- try {
184
- if (ports.tryAcquireLock) return await ports.tryAcquireLock(lockId);
185
- } catch {
186
- return false;
187
- }
188
- if (memLock !== null) return false;
189
- memLock = lockId;
190
- return true;
191
- }
192
- async function release(lockId) {
193
- try {
194
- if (ports.releaseLock) await ports.releaseLock(lockId);
195
- else if (memLock === lockId) memLock = null;
196
- } catch {
197
- }
198
- }
199
- function healJob(job, env) {
200
- if (!job) return null;
201
- if (job.state === "installing" || job.state === "verifying") {
202
- return job.id === activeJobId ? job : { ...job, state: "interrupted", message: "recovery-required", requestId: job.requestId ?? null };
203
- }
204
- if (job.state === "restart-required" || job.state === "completed") {
205
- if (!job.targetVersion || env.installedVersion !== job.targetVersion) {
206
- return { ...job, state: "interrupted", message: "installation-changed", requestId: job.requestId ?? null };
207
- }
208
- const runningVersion = ports.readRunningVersion();
209
- return { ...job, state: runningVersion === job.targetVersion ? "completed" : "restart-required", requestId: job.requestId ?? null };
210
- }
211
- return job;
212
- }
213
- function buildSnapshot(env, job) {
214
- let blockedReason = env.blockedReason ?? checked?.blockedReason ?? null;
215
- if (job?.state === "interrupted" || job?.state === "failed") {
216
- if (env.installedVersion !== ports.readRunningVersion()) blockedReason = "recovery-required";
217
- } else if (job?.state === "restart-required" || env.installedVersion && env.installedVersion !== ports.readRunningVersion()) {
218
- blockedReason = "pending-restart";
219
- }
220
- const busy = job?.state === "installing" || job?.state === "verifying";
221
- const fresh = checked !== null && checked.checkId !== null && ports.now() < checked.expiresAt;
222
- const runningVersion = ports.readRunningVersion();
223
- const canInstall = Boolean(
224
- env.eligible && !blockedReason && !busy && fresh && checked?.installationKey === env.installationKey && validVersion(runningVersion) && checked?.release && compareVersions(checked.release.version, runningVersion) === 1
225
- );
226
- return {
227
- runningVersion,
228
- installedVersion: env.installedVersion ?? null,
229
- latestVersion: checked?.release.version ?? null,
230
- canInstall,
231
- blockedReason,
232
- job
233
- };
234
- }
235
- async function status() {
236
- const env = await ports.readInstalled();
237
- const job = healJob(await loadJob(), env);
238
- return buildSnapshot(env, job);
239
- }
240
- async function check() {
241
- if (checking) return checking;
242
- if (checked?.checkId && ports.now() - lastCheckAt < RECHECK_WINDOW_MS) {
243
- const env = await ports.readInstalled();
244
- const snapshot = buildSnapshot(env, healJob(await loadJob(), env));
245
- return { snapshot, receipt: snapshot.canInstall ? toReceipt() : null };
246
- }
247
- lastCheckAt = ports.now();
248
- checking = (async () => {
249
- try {
250
- const env = await ports.readInstalled();
251
- const release2 = await fetchRelease();
252
- checked = {
253
- release: release2,
254
- checkId: ports.randomId(),
255
- checkedAt: ports.now(),
256
- expiresAt: ports.now() + confirmationTtlMs,
257
- installationKey: env.installationKey,
258
- blockedReason: satisfiesNodeRange(ports.nodeVersion, release2.nodeRange) ? null : "incompatible-node"
259
- };
260
- const snapshot = buildSnapshot(env, healJob(await loadJob(), env));
261
- return { snapshot, receipt: snapshot.canInstall ? toReceipt() : null };
262
- } catch (error) {
263
- if (checked) checked = { ...checked, checkId: null, expiresAt: 0 };
264
- throw error;
265
- } finally {
266
- checking = null;
267
- }
268
- })();
269
- return checking;
270
- }
271
- function toReceipt() {
272
- if (!checked?.checkId) return null;
273
- return { checkId: checked.checkId, checkedAt: checked.checkedAt, expiresAt: checked.expiresAt };
274
- }
275
- async function runBackground(job, envAtStart) {
276
- try {
277
- if (ports.runInstall) await ports.runInstall({ version: job.targetVersion, profileName: envAtStart.profileName, environmentKind: envAtStart.environmentKind });
278
- else throw updateError("unsupported");
279
- const doing = { ...job, state: "verifying", message: null };
280
- activeJobId = doing.id;
281
- await saveJob(doing);
282
- const env = await ports.readInstalled();
283
- if (env.installedVersion !== job.targetVersion) throw updateError("install-failed");
284
- if (env.blockedReason && env.blockedReason !== "pending-restart") throw updateError("install-failed");
285
- const done = { ...doing, state: "restart-required", message: null };
286
- await saveJob(done);
287
- } catch (error) {
288
- const code = error?.code;
289
- const message = code === "installation-changed" || code === "registry-conflict" || code === "install-failed" ? String(code) : "install-failed";
290
- const failedJob = { ...job, state: "failed", message, requestId: job.requestId ?? null };
291
- try {
292
- await saveJob(failedJob);
293
- } catch {
294
- memJob = failedJob;
295
- }
296
- } finally {
297
- await release(job.id);
298
- if (activeJobId === job.id) activeJobId = null;
299
- }
300
- }
301
- async function install(args) {
302
- const checkId = typeof args?.checkId === "string" ? args.checkId : "";
303
- const requestId = typeof args?.requestId === "string" ? args.requestId : "";
304
- if (!checkId || !validRequestId(requestId)) throw updateError("check-expired");
305
- let env = await ports.readInstalled();
306
- let previous = healJob(await loadJob(), env);
307
- if (previous?.requestId === requestId) return buildSnapshot(env, previous);
308
- if (previous?.state === "installing" || previous?.state === "verifying" || previous?.state === "restart-required") {
309
- throw updateError("update-busy");
310
- }
311
- if (!checked || !checked.checkId || checked.checkId !== checkId || ports.now() >= checked.expiresAt) {
312
- throw updateError("check-expired");
313
- }
314
- if (env.installationKey !== checked.installationKey) throw updateError("installation-changed");
315
- if (!buildSnapshot(env, previous).canInstall) {
316
- throw updateError(env.blockedReason ?? checked.blockedReason ?? "update-busy");
317
- }
318
- const job = {
319
- id: ports.randomId(),
320
- state: "installing",
321
- targetVersion: checked.release.version,
322
- message: null,
323
- requestId
324
- };
325
- if (!await acquire(job.id)) throw updateError("update-busy");
326
- try {
327
- const current = await fetchRelease();
328
- if (JSON.stringify(current) !== JSON.stringify(checked.release)) throw updateError("check-expired");
329
- env = await ports.readInstalled();
330
- if (env.installationKey !== checked.installationKey) throw updateError("installation-changed");
331
- if (!env.eligible || env.blockedReason) throw updateError(env.blockedReason ?? "update-busy");
332
- if (ports.backupJob) await ports.backupJob(job);
333
- await saveJob(job);
334
- activeJobId = job.id;
335
- } catch (error) {
336
- await release(job.id);
337
- throw error;
338
- }
339
- void runBackground(job, env).catch(() => {
340
- });
341
- return buildSnapshot(env, job);
342
- }
343
- return { status, check, install };
344
- }
345
- export {
346
- CHECK_TIMEOUT_MS,
347
- CONFIRMATION_TTL_MS,
348
- INTEGRITY_PATTERN,
349
- MAX_METADATA_BYTES,
350
- NPM_REGISTRY,
351
- PACKAGE_NAME,
352
- RECHECK_WINDOW_MS,
353
- compareVersions,
354
- createUpdateCore,
355
- fetchNpmRelease,
356
- satisfiesNodeRange,
357
- updateError,
358
- validRequestId,
359
- validVersion
360
- };