dsh-update-status 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +12 -8
- package/README.zh.md +12 -8
- package/lib/client.js +95 -9
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +27 -8
- package/lib/index.js +53 -24
- package/package.json +5 -4
package/lib/index.d.ts
CHANGED
|
@@ -22,6 +22,23 @@ type ReleaseCompatibility = 'verified' | 'unverified' | 'incompatible';
|
|
|
22
22
|
*/
|
|
23
23
|
type UpdateWarningKind = 'failure' | 'notice';
|
|
24
24
|
type InstallKind = 'npm-global' | 'pnpm-global' | 'source-checkout' | 'unknown';
|
|
25
|
+
/** Language-neutral warning facts; the browser renders them in its own locale. */
|
|
26
|
+
type UpdateWarning = {
|
|
27
|
+
code: 'registry-unavailable';
|
|
28
|
+
detail: string;
|
|
29
|
+
} | {
|
|
30
|
+
code: 'channel-unavailable';
|
|
31
|
+
channel: ReleaseChannel;
|
|
32
|
+
} | {
|
|
33
|
+
code: 'version-incomparable';
|
|
34
|
+
currentVersion: string;
|
|
35
|
+
channel: ReleaseChannel;
|
|
36
|
+
selectedVersion: string;
|
|
37
|
+
} | {
|
|
38
|
+
code: 'preview-unverified';
|
|
39
|
+
channel: ReleaseChannel;
|
|
40
|
+
version: string;
|
|
41
|
+
};
|
|
25
42
|
interface ChannelRelease {
|
|
26
43
|
channel: ReleaseChannel;
|
|
27
44
|
version: string | null;
|
|
@@ -39,9 +56,12 @@ interface UpdateStatus {
|
|
|
39
56
|
hasUpdate: boolean;
|
|
40
57
|
cached: boolean;
|
|
41
58
|
checkedAt: string | null;
|
|
59
|
+
/** English fallback for older clients; current clients localize `warnings`. */
|
|
42
60
|
warning: string | null;
|
|
43
61
|
/** Severity of `warning`; absent from a Host older than the field. */
|
|
44
62
|
warningKind?: UpdateWarningKind | null;
|
|
63
|
+
/** Structured warning facts; absent from a Host older than this field. */
|
|
64
|
+
warnings?: UpdateWarning[];
|
|
45
65
|
installKind: InstallKind;
|
|
46
66
|
upgradeCommand: string;
|
|
47
67
|
releaseUrl: string;
|
|
@@ -80,7 +100,7 @@ interface UpdateStatusConfig {
|
|
|
80
100
|
* input side takes, so the inferred schema type cannot be named by the emitted
|
|
81
101
|
* `.d.ts` (TS2883) without stating the input side here.
|
|
82
102
|
*/
|
|
83
|
-
declare const Config: z<UpdateStatusConfig, Record<string, unknown>>;
|
|
103
|
+
export declare const Config: z<UpdateStatusConfig, Record<string, unknown>>;
|
|
84
104
|
//#endregion
|
|
85
105
|
//#region src/host/installation.d.ts
|
|
86
106
|
interface InstallationInfo {
|
|
@@ -104,7 +124,7 @@ interface UpdateStatusServiceOptions {
|
|
|
104
124
|
ttlMs?: number;
|
|
105
125
|
releaseUrl?: string;
|
|
106
126
|
}
|
|
107
|
-
declare class UpdateStatusService {
|
|
127
|
+
export declare class UpdateStatusService {
|
|
108
128
|
private readonly installation;
|
|
109
129
|
private readonly fetchLatest;
|
|
110
130
|
private readonly now;
|
|
@@ -119,15 +139,14 @@ declare class UpdateStatusService {
|
|
|
119
139
|
private refreshRelease;
|
|
120
140
|
private statusAfterFailure;
|
|
121
141
|
private statusFromCache;
|
|
122
|
-
/** No remote data at all: the registry read itself failed, never a notice. */
|
|
123
142
|
private statusWithoutRemoteRelease;
|
|
124
143
|
}
|
|
125
144
|
//#endregion
|
|
126
145
|
//#region src/index.d.ts
|
|
127
|
-
declare const name = "dsh-update-status";
|
|
146
|
+
export declare const name = "dsh-update-status";
|
|
128
147
|
/** Connection supplies the authenticated transport; settings remains optional. */
|
|
129
|
-
declare const inject: string[];
|
|
130
|
-
type Config = UpdateStatusConfig;
|
|
131
|
-
declare function apply(ctx: Context, config?: Config): void;
|
|
148
|
+
export declare const inject: string[];
|
|
149
|
+
export type Config = UpdateStatusConfig;
|
|
150
|
+
export declare function apply(ctx: Context, config?: Config): void;
|
|
132
151
|
//#endregion
|
|
133
|
-
export {
|
|
152
|
+
export type { InstallKind, UpdateStatus };
|
package/lib/index.js
CHANGED
|
@@ -12,7 +12,11 @@ const UPDATE_STATUS_CHANNEL = "/api";
|
|
|
12
12
|
* release the registry reports stays `unverified` — the plugin never claims a
|
|
13
13
|
* compatibility nobody checked.
|
|
14
14
|
*/
|
|
15
|
-
const VERIFIED_DSH_VERSIONS = [
|
|
15
|
+
const VERIFIED_DSH_VERSIONS = [
|
|
16
|
+
"0.1.7-alpha.2",
|
|
17
|
+
"0.1.7-rc.1",
|
|
18
|
+
"0.1.7-rc.2"
|
|
19
|
+
];
|
|
16
20
|
const RELEASE_CHANNELS = [
|
|
17
21
|
"latest",
|
|
18
22
|
"next",
|
|
@@ -124,8 +128,8 @@ function upgradeCommandFor(installKind, packageName = PACKAGE_NAME, channel = "l
|
|
|
124
128
|
switch (installKind) {
|
|
125
129
|
case "npm-global": return `npm install -g ${specifier}`;
|
|
126
130
|
case "pnpm-global": return `pnpm add -g ${specifier}`;
|
|
127
|
-
case "source-checkout": return "
|
|
128
|
-
default: return "
|
|
131
|
+
case "source-checkout": return "Update the DSH source checkout, install its dependencies, and rebuild it; this plugin cannot replace it in place from the GUI";
|
|
132
|
+
default: return "Confirm how DSH was installed before upgrading; this plugin cannot perform the upgrade for you";
|
|
129
133
|
}
|
|
130
134
|
}
|
|
131
135
|
/**
|
|
@@ -313,10 +317,20 @@ function boundedMessage(error) {
|
|
|
313
317
|
const trimmed = (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim();
|
|
314
318
|
return trimmed === "" ? "unknown error" : trimmed.slice(0, 220);
|
|
315
319
|
}
|
|
316
|
-
function
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
+
function warningText(warning) {
|
|
321
|
+
switch (warning.code) {
|
|
322
|
+
case "registry-unavailable": return `Unable to check the npm registry: ${warning.detail}`;
|
|
323
|
+
case "channel-unavailable": return `The npm registry does not publish a ${warning.channel} channel.`;
|
|
324
|
+
case "version-incomparable": return `Unable to compare the current version ${warning.currentVersion} with ${warning.channel} channel version ${warning.selectedVersion} using SemVer.`;
|
|
325
|
+
case "preview-unverified": return `${warning.channel} is a preview channel; version ${warning.version} has not been verified as compatible with this plugin.`;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
function warningFallback(warnings) {
|
|
329
|
+
return warnings.length === 0 ? null : warnings.map(warningText).join(" ");
|
|
330
|
+
}
|
|
331
|
+
function warningKindOf(warnings) {
|
|
332
|
+
if (warnings.length === 0) return null;
|
|
333
|
+
return warnings.every((warning) => warning.code === "preview-unverified") ? "notice" : "failure";
|
|
320
334
|
}
|
|
321
335
|
function dateOrNull(value) {
|
|
322
336
|
if (typeof value !== "string" || value === "") return null;
|
|
@@ -401,16 +415,16 @@ var UpdateStatusService = class {
|
|
|
401
415
|
async check(force = false, channel = "latest", cacheTtlMinutes) {
|
|
402
416
|
const ttlMs = isCacheTtlMinutes(cacheTtlMinutes) ? cacheTtlMinutes * 60 * 1e3 : this.ttlMs;
|
|
403
417
|
const cached = this.cache;
|
|
404
|
-
if (!force && cached !== void 0 && this.now() - cached.checkedAtMs < ttlMs) return this.statusFromCache(cached, channel, true,
|
|
418
|
+
if (!force && cached !== void 0 && this.now() - cached.checkedAtMs < ttlMs) return this.statusFromCache(cached, channel, true, []);
|
|
405
419
|
if (this.inFlight !== void 0) try {
|
|
406
|
-
return this.statusFromCache(await this.inFlight, channel, false,
|
|
420
|
+
return this.statusFromCache(await this.inFlight, channel, false, []);
|
|
407
421
|
} catch (error) {
|
|
408
422
|
return this.statusAfterFailure(channel, error);
|
|
409
423
|
}
|
|
410
424
|
const run = this.refreshRelease();
|
|
411
425
|
this.inFlight = run;
|
|
412
426
|
try {
|
|
413
|
-
return this.statusFromCache(await run, channel, false,
|
|
427
|
+
return this.statusFromCache(await run, channel, false, []);
|
|
414
428
|
} catch (error) {
|
|
415
429
|
return this.statusAfterFailure(channel, error);
|
|
416
430
|
} finally {
|
|
@@ -426,10 +440,13 @@ var UpdateStatusService = class {
|
|
|
426
440
|
return cache;
|
|
427
441
|
}
|
|
428
442
|
statusAfterFailure(channel, error) {
|
|
429
|
-
const
|
|
430
|
-
|
|
443
|
+
const warnings = [{
|
|
444
|
+
code: "registry-unavailable",
|
|
445
|
+
detail: boundedMessage(error)
|
|
446
|
+
}];
|
|
447
|
+
return this.cache === void 0 ? this.statusWithoutRemoteRelease(channel, warnings) : this.statusFromCache(this.cache, channel, true, warnings);
|
|
431
448
|
}
|
|
432
|
-
statusFromCache(cache, channel, cached,
|
|
449
|
+
statusFromCache(cache, channel, cached, initialWarnings) {
|
|
433
450
|
const selected = cache.release.channels.find((release) => release.channel === channel) ?? {
|
|
434
451
|
channel,
|
|
435
452
|
version: null,
|
|
@@ -437,19 +454,31 @@ var UpdateStatusService = class {
|
|
|
437
454
|
compatibility: "unverified"
|
|
438
455
|
};
|
|
439
456
|
const comparison = selected.version === null ? void 0 : compareSemver(this.installation.currentVersion, selected.version);
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
457
|
+
const warnings = [...initialWarnings];
|
|
458
|
+
if (selected.version === null) warnings.push({
|
|
459
|
+
code: "channel-unavailable",
|
|
460
|
+
channel
|
|
461
|
+
});
|
|
462
|
+
if (selected.version !== null && comparison === void 0) warnings.push({
|
|
463
|
+
code: "version-incomparable",
|
|
464
|
+
currentVersion: this.installation.currentVersion,
|
|
465
|
+
channel,
|
|
466
|
+
selectedVersion: selected.version
|
|
467
|
+
});
|
|
468
|
+
if (channel !== "latest" && selected.version !== null && selected.compatibility !== "verified") warnings.push({
|
|
469
|
+
code: "preview-unverified",
|
|
470
|
+
channel,
|
|
471
|
+
version: selected.version
|
|
472
|
+
});
|
|
445
473
|
return {
|
|
446
474
|
currentVersion: this.installation.currentVersion,
|
|
447
475
|
latestVersion: selected.version,
|
|
448
476
|
hasUpdate: comparison !== void 0 && comparison < 0,
|
|
449
477
|
cached,
|
|
450
478
|
checkedAt: new Date(cache.checkedAtMs).toISOString(),
|
|
451
|
-
warning,
|
|
452
|
-
warningKind:
|
|
479
|
+
warning: warningFallback(warnings),
|
|
480
|
+
warningKind: warningKindOf(warnings),
|
|
481
|
+
warnings,
|
|
453
482
|
installKind: this.installation.installKind,
|
|
454
483
|
upgradeCommand: upgradeCommandFor(this.installation.installKind, this.installation.packageName || "@deepseek-ai/dsh", channel),
|
|
455
484
|
releaseUrl: this.releaseUrl,
|
|
@@ -461,16 +490,16 @@ var UpdateStatusService = class {
|
|
|
461
490
|
canApplyInPlace: false
|
|
462
491
|
};
|
|
463
492
|
}
|
|
464
|
-
|
|
465
|
-
statusWithoutRemoteRelease(channel, warning) {
|
|
493
|
+
statusWithoutRemoteRelease(channel, warnings) {
|
|
466
494
|
return {
|
|
467
495
|
currentVersion: this.installation.currentVersion,
|
|
468
496
|
latestVersion: null,
|
|
469
497
|
hasUpdate: false,
|
|
470
498
|
cached: false,
|
|
471
499
|
checkedAt: null,
|
|
472
|
-
warning,
|
|
473
|
-
warningKind:
|
|
500
|
+
warning: warningFallback(warnings),
|
|
501
|
+
warningKind: warningKindOf(warnings),
|
|
502
|
+
warnings,
|
|
474
503
|
installKind: this.installation.installKind,
|
|
475
504
|
upgradeCommand: upgradeCommandFor(this.installation.installKind, this.installation.packageName || "@deepseek-ai/dsh", channel),
|
|
476
505
|
releaseUrl: this.releaseUrl,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-update-status",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Read-only DeepSeek Harness Web plugin that shows the running DSH version, discovers latest/next/alpha releases, warns about compatibility, and generates copy-only upgrade commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -63,7 +63,8 @@
|
|
|
63
63
|
"compatibility": {
|
|
64
64
|
"dshReleases": {
|
|
65
65
|
"0.1.7-alpha.2": "compatible",
|
|
66
|
-
"0.1.7-rc.1": "compatible"
|
|
66
|
+
"0.1.7-rc.1": "compatible",
|
|
67
|
+
"0.1.7-rc.2": "compatible"
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
},
|
|
@@ -88,9 +89,9 @@
|
|
|
88
89
|
"@types/node": "^26.2.0",
|
|
89
90
|
"@types/react": "^18.3.31",
|
|
90
91
|
"react": "^18.3.1",
|
|
91
|
-
"tsdown": "^0.
|
|
92
|
+
"tsdown": "^0.23.0",
|
|
92
93
|
"typescript": "^7.0.2",
|
|
93
|
-
"vitest": "^
|
|
94
|
+
"vitest": "^5.0.1"
|
|
94
95
|
},
|
|
95
96
|
"scripts": {
|
|
96
97
|
"build": "tsdown",
|