dsh-plugin-shop 0.8.5 → 0.8.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/lib/client.js +1788 -358
- package/lib/index.js +87 -33
- package/lib/typert.host.js +20 -15
- package/lib/typert.remote-client.js +16 -11
- package/lib/types/client/ShopTab.d.ts +6 -0
- package/lib/types/client/index.d.ts +11 -0
- package/lib/types/client/locales.d.ts +32 -0
- package/lib/types/client/present.d.ts +21 -1
- package/lib/types/client/restart-monitor.d.ts +38 -7
- package/lib/types/client/useFlows.d.ts +6 -0
- package/lib/types/client/useUpdateSelf.d.ts +5 -0
- package/lib/types/host/index.d.ts +21 -2
- package/lib/types/host/restart.d.ts +9 -1
- package/lib/types/host/types.d.ts +4 -0
- package/lib/types/own-version.d.ts +13 -1
- package/lib/types/shared/zh-intents.d.ts +89 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
|
3
3
|
import { loadOptionalPatches, readProfileManifest, resolveProfileDir } from "@deepseek-ai/dsh-app-boot";
|
|
4
4
|
import { lt, minVersion, parse, satisfies, valid, validRange } from "semver";
|
|
5
5
|
import { createHash, randomUUID } from "node:crypto";
|
|
6
|
-
import { appendFileSync, chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { appendFileSync, chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
8
|
import { basename, delimiter, dirname, isAbsolute, join, posix, relative, resolve, sep, win32 } from "node:path";
|
|
9
9
|
import { homedir } from "node:os";
|
|
@@ -16,7 +16,8 @@ import { isMap, isSeq, parseDocument } from "yaml";
|
|
|
16
16
|
//#region src/own-version.ts
|
|
17
17
|
/** The shop's own published version, read from the package.json that ships
|
|
18
18
|
* next to this package — the RUNNING version, not the manifest's range
|
|
19
|
-
* spec
|
|
19
|
+
* spec — and the identity of the process running it (`bootId`). This lives
|
|
20
|
+
* at the package root (not under src/host) on purpose:
|
|
20
21
|
* both the source tree (tests) and the bundled `lib/index.js` sit exactly
|
|
21
22
|
* one level below the package root, so the same relative URL resolves in
|
|
22
23
|
* both. */
|
|
@@ -49,6 +50,17 @@ function versionAtLoad(read) {
|
|
|
49
50
|
* evaluated — at boot, before any self-update could rewrite the file. */
|
|
50
51
|
const runningVersion = versionAtLoad(() => ownManifest().version);
|
|
51
52
|
/**
|
|
53
|
+
* Which run of the code this is: drawn when the module is first evaluated,
|
|
54
|
+
* fixed for the life of the process, and different in the next one.
|
|
55
|
+
*
|
|
56
|
+
* The version cannot answer that. A restart that installed no new shop keeps
|
|
57
|
+
* it, and so does one that never happened — which is what a page reloaded
|
|
58
|
+
* into the process it asked to restart could not tell apart from success,
|
|
59
|
+
* and showed as a self-update that silently did not land (design §8,
|
|
60
|
+
* 2026-10-06 amendment).
|
|
61
|
+
*/
|
|
62
|
+
const bootId = randomUUID();
|
|
63
|
+
/**
|
|
52
64
|
* The peer ranges this build declares — the input to the load-time harness
|
|
53
65
|
* self-check. Read from the same shipped manifest as `runningVersion`, so the
|
|
54
66
|
* ranges checked are the ones this build was actually published with, never
|
|
@@ -638,7 +650,8 @@ const entrySchema = z.object({
|
|
|
638
650
|
}).optional(),
|
|
639
651
|
dshPeers: z.record(z.string(), z.string()).optional(),
|
|
640
652
|
unpackedSize: z.number().int().nonnegative().optional(),
|
|
641
|
-
installSize: z.number().int().nonnegative().optional()
|
|
653
|
+
installSize: z.number().int().nonnegative().optional(),
|
|
654
|
+
archived: z.boolean().optional()
|
|
642
655
|
}).superRefine((entry, ctx) => {
|
|
643
656
|
if (entry.source === "npm") {
|
|
644
657
|
if (!NPM_NAME.test(entry.name)) ctx.addIssue({
|
|
@@ -2661,29 +2674,43 @@ function restartCommand(options) {
|
|
|
2661
2674
|
args: [...argv]
|
|
2662
2675
|
};
|
|
2663
2676
|
}
|
|
2677
|
+
/** One line of the handoff's own in the log, stamped in UTC ISO 8601 so a
|
|
2678
|
+
* reader can line it up against the new process's output and the browser's
|
|
2679
|
+
* clock. The helper stamps its line with `date -u` to the same shape, to the
|
|
2680
|
+
* second. */
|
|
2681
|
+
function stamped(text) {
|
|
2682
|
+
return `${(/* @__PURE__ */ new Date()).toISOString()} dsh-plugin-shop: ${text}\n`;
|
|
2683
|
+
}
|
|
2664
2684
|
function startRestart(options) {
|
|
2665
2685
|
const { command, args, parentPid, logFile, env } = options;
|
|
2666
2686
|
const logFd = openSync(logFile, "a");
|
|
2667
2687
|
try {
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
"sh",
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2688
|
+
writeSync(logFd, stamped(`restart committed; the new dsh starts once pid ${parentPid} exits: ${[command, ...args].join(" ")}`));
|
|
2689
|
+
let helper;
|
|
2690
|
+
try {
|
|
2691
|
+
helper = spawn("sh", [
|
|
2692
|
+
"-c",
|
|
2693
|
+
"while kill -0 \"$1\" 2>/dev/null; do sleep 0.2; done; echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) dsh-plugin-shop: pid $1 exited; starting the new dsh\"; shift; exec \"$@\"",
|
|
2694
|
+
"sh",
|
|
2695
|
+
String(parentPid),
|
|
2696
|
+
command,
|
|
2697
|
+
...args
|
|
2698
|
+
], {
|
|
2699
|
+
stdio: [
|
|
2700
|
+
"ignore",
|
|
2701
|
+
logFd,
|
|
2702
|
+
logFd
|
|
2703
|
+
],
|
|
2704
|
+
env: env ?? process.env,
|
|
2705
|
+
detached: true
|
|
2706
|
+
});
|
|
2707
|
+
} catch (error) {
|
|
2708
|
+
writeSync(logFd, stamped(`the restart helper could not start: ${error.message}`));
|
|
2709
|
+
throw error;
|
|
2710
|
+
}
|
|
2684
2711
|
helper.on("error", (error) => {
|
|
2685
2712
|
try {
|
|
2686
|
-
appendFileSync(logFile, `
|
|
2713
|
+
appendFileSync(logFile, stamped(`the restart helper could not start: ${error.message}`));
|
|
2687
2714
|
} catch {}
|
|
2688
2715
|
});
|
|
2689
2716
|
helper.unref();
|
|
@@ -5851,10 +5878,12 @@ let ShopGateway = (() => {
|
|
|
5851
5878
|
return present.length === 0 || present.every(([, enabled]) => enabled);
|
|
5852
5879
|
};
|
|
5853
5880
|
const installed = [];
|
|
5881
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
5854
5882
|
for (const entry of snapshot.entries) {
|
|
5855
5883
|
const spec = ownDependencySpec(dependencies, entry.name);
|
|
5856
5884
|
if (spec === void 0) continue;
|
|
5857
5885
|
if (!installedSpecMatches(entry, spec)) continue;
|
|
5886
|
+
claimed.add(entry.name);
|
|
5858
5887
|
const identity = {
|
|
5859
5888
|
source: entry.source,
|
|
5860
5889
|
repo: entry.repo,
|
|
@@ -5879,6 +5908,25 @@ let ShopGateway = (() => {
|
|
|
5879
5908
|
enabled: enabledOf(entry.name)
|
|
5880
5909
|
});
|
|
5881
5910
|
}
|
|
5911
|
+
for (const name of Object.keys(dependencies)) {
|
|
5912
|
+
if (claimed.has(name)) continue;
|
|
5913
|
+
const spec = ownDependencySpec(dependencies, name);
|
|
5914
|
+
if (spec === void 0) continue;
|
|
5915
|
+
const origin = parseSpec(spec);
|
|
5916
|
+
if (origin?.kind !== "github") continue;
|
|
5917
|
+
const pinPrefix = `github:${origin.repo}#`;
|
|
5918
|
+
const pinKey = pins[pinPrefix] !== void 0 ? pinPrefix : Object.keys(pins).find((key) => key.startsWith(pinPrefix));
|
|
5919
|
+
installed.push({
|
|
5920
|
+
name,
|
|
5921
|
+
source: "github",
|
|
5922
|
+
repo: origin.repo,
|
|
5923
|
+
installed: (pinKey === void 0 ? void 0 : pins[pinKey]) ?? pins[name] ?? spec,
|
|
5924
|
+
latest: null,
|
|
5925
|
+
outdated: false,
|
|
5926
|
+
enabled: enabledOf(name),
|
|
5927
|
+
shadowed: true
|
|
5928
|
+
});
|
|
5929
|
+
}
|
|
5882
5930
|
return installed;
|
|
5883
5931
|
}
|
|
5884
5932
|
/** Whether an installed dependency spec sits behind the catalog's version.
|
|
@@ -5908,11 +5956,17 @@ let ShopGateway = (() => {
|
|
|
5908
5956
|
detail: DESKTOP_PROFILE_DETAIL
|
|
5909
5957
|
};
|
|
5910
5958
|
const named = (await this.snapshotNow()).entries.filter((entry) => entry.name === args.name);
|
|
5911
|
-
if (named.length === 0) return {
|
|
5912
|
-
ok: false,
|
|
5913
|
-
detail: `dsh-plugin-shop: ${args.name} is not in the catalog`
|
|
5914
|
-
};
|
|
5915
5959
|
const spec = ownDependencySpec(readProfileManifest("dsh-plugin-shop", this.profileDirResolved()).dependencies ?? {}, args.name);
|
|
5960
|
+
if (named.length === 0) {
|
|
5961
|
+
if (spec === void 0) return {
|
|
5962
|
+
ok: false,
|
|
5963
|
+
detail: `dsh-plugin-shop: ${args.name} is not in the catalog`
|
|
5964
|
+
};
|
|
5965
|
+
if (parseSpec(spec)?.kind !== "github") return {
|
|
5966
|
+
ok: false,
|
|
5967
|
+
detail: `dsh-plugin-shop: ${args.name} is not in the catalog`
|
|
5968
|
+
};
|
|
5969
|
+
}
|
|
5916
5970
|
if (spec === void 0) return {
|
|
5917
5971
|
ok: false,
|
|
5918
5972
|
detail: `dsh-plugin-shop: ${args.name} is not installed`
|
|
@@ -5966,10 +6020,7 @@ let ShopGateway = (() => {
|
|
|
5966
6020
|
* response is out. The browser monitors the origin and refreshes when the
|
|
5967
6021
|
* new server answers. Refusals are issued before anything is torn down. */
|
|
5968
6022
|
async restart() {
|
|
5969
|
-
if (this.committedRestart !== null) return
|
|
5970
|
-
ok: true,
|
|
5971
|
-
logFile: this.committedRestart.logFile
|
|
5972
|
-
};
|
|
6023
|
+
if (this.committedRestart !== null) return this.committedRestart;
|
|
5973
6024
|
if (this.hasRunningCommand()) return {
|
|
5974
6025
|
ok: false,
|
|
5975
6026
|
detail: "dsh-plugin-shop: an install is still running in this profile; a restart now would boot the new dsh against a half-written profile. Wait for it to finish and try again."
|
|
@@ -6003,12 +6054,14 @@ let ShopGateway = (() => {
|
|
|
6003
6054
|
detail: `dsh-plugin-shop: restart could not be started: ${error.message}`
|
|
6004
6055
|
};
|
|
6005
6056
|
}
|
|
6006
|
-
this.committedRestart = {
|
|
6007
|
-
setTimeout(() => this.exit(0), this.restartExitDelayMs);
|
|
6008
|
-
return {
|
|
6057
|
+
this.committedRestart = {
|
|
6009
6058
|
ok: true,
|
|
6010
|
-
logFile
|
|
6059
|
+
logFile,
|
|
6060
|
+
bootId,
|
|
6061
|
+
pid: this.restartParentPid
|
|
6011
6062
|
};
|
|
6063
|
+
setTimeout(() => this.exit(0), this.restartExitDelayMs);
|
|
6064
|
+
return this.committedRestart;
|
|
6012
6065
|
}
|
|
6013
6066
|
/** The shop's own version and whether npm has a newer one (§7.3). The
|
|
6014
6067
|
* check is advisory: a registry that cannot answer leaves `latest` null
|
|
@@ -6022,7 +6075,8 @@ let ShopGateway = (() => {
|
|
|
6022
6075
|
latest,
|
|
6023
6076
|
outdated: latest !== null && lt(installed, latest),
|
|
6024
6077
|
restartBlocked: this.staticRestartBlock(),
|
|
6025
|
-
pendingVersion: this.pendingVersion(installed)
|
|
6078
|
+
pendingVersion: this.pendingVersion(installed),
|
|
6079
|
+
bootId
|
|
6026
6080
|
};
|
|
6027
6081
|
}
|
|
6028
6082
|
/**
|
package/lib/typert.host.js
CHANGED
|
@@ -52,6 +52,7 @@ const dsh_plugin_shop_shop_catalog_result$schema = z.object({
|
|
|
52
52
|
'dshPeers': z.union([z.undefined(), z.record(z.string(), z.string())]).optional(),
|
|
53
53
|
'unpackedSize': z.union([z.undefined(), z.number()]).optional(),
|
|
54
54
|
'installSize': z.union([z.undefined(), z.number()]).optional(),
|
|
55
|
+
'archived': z.union([z.undefined(), z.literal(false), z.literal(true)]).optional(),
|
|
55
56
|
})),
|
|
56
57
|
'denied': z.array(z.object({
|
|
57
58
|
'name': z.string(),
|
|
@@ -83,9 +84,10 @@ const dsh_plugin_shop_shop_installed_result$schema = z.array(z.object({
|
|
|
83
84
|
'repo': z.union([z.undefined(), z.string()]).optional(),
|
|
84
85
|
'subdir': z.union([z.undefined(), z.string()]).optional(),
|
|
85
86
|
'installed': z.string(),
|
|
86
|
-
'latest': z.string(),
|
|
87
|
+
'latest': z.union([z.literal(null), z.string()]),
|
|
87
88
|
'outdated': z.boolean(),
|
|
88
89
|
'enabled': z.boolean(),
|
|
90
|
+
'shadowed': z.union([z.undefined(), z.literal(true)]).optional(),
|
|
89
91
|
}))
|
|
90
92
|
const dsh_plugin_shop_shop_installedSpecs_result$schema = z.union([z.literal(null), z.record(z.string(), z.string())])
|
|
91
93
|
const dsh_plugin_shop_shop_installStart_parameter_0$schema = z.object({
|
|
@@ -119,6 +121,8 @@ const dsh_plugin_shop_shop_installStatus_result$schema = z.object({
|
|
|
119
121
|
const dsh_plugin_shop_shop_restart_result$schema = z.union([z.object({
|
|
120
122
|
'ok': z.literal(true),
|
|
121
123
|
'logFile': z.union([z.undefined(), z.string()]).optional(),
|
|
124
|
+
'bootId': z.union([z.undefined(), z.string()]).optional(),
|
|
125
|
+
'pid': z.union([z.undefined(), z.number()]).optional(),
|
|
122
126
|
}), z.object({
|
|
123
127
|
'ok': z.literal(false),
|
|
124
128
|
'detail': z.string(),
|
|
@@ -161,6 +165,7 @@ const dsh_plugin_shop_shop_version_result$schema = z.object({
|
|
|
161
165
|
'outdated': z.boolean(),
|
|
162
166
|
'restartBlocked': z.union([z.literal(null), z.literal("desktop"), z.literal("windows"), z.literal("systemd"), z.literal("port-zero")]),
|
|
163
167
|
'pendingVersion': z.union([z.undefined(), z.literal(null), z.string()]).optional(),
|
|
168
|
+
'bootId': z.union([z.undefined(), z.string()]).optional(),
|
|
164
169
|
})
|
|
165
170
|
|
|
166
171
|
export const TYPERT = {
|
|
@@ -195,7 +200,7 @@ export const TYPERT = {
|
|
|
195
200
|
schema: dsh_plugin_shop_shop_catalog_result$schema,
|
|
196
201
|
create: () => dsh_plugin_shop_shop_catalog_result$schema,
|
|
197
202
|
},
|
|
198
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
203
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1272,"column":9},
|
|
199
204
|
},
|
|
200
205
|
{
|
|
201
206
|
id: 'dsh-plugin-shop#shop/installed',
|
|
@@ -211,7 +216,7 @@ export const TYPERT = {
|
|
|
211
216
|
schema: dsh_plugin_shop_shop_installed_result$schema,
|
|
212
217
|
create: () => dsh_plugin_shop_shop_installed_result$schema,
|
|
213
218
|
},
|
|
214
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
219
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1739,"column":9},
|
|
215
220
|
},
|
|
216
221
|
{
|
|
217
222
|
id: 'dsh-plugin-shop#shop/installedSpecs',
|
|
@@ -227,7 +232,7 @@ export const TYPERT = {
|
|
|
227
232
|
schema: dsh_plugin_shop_shop_installedSpecs_result$schema,
|
|
228
233
|
create: () => dsh_plugin_shop_shop_installedSpecs_result$schema,
|
|
229
234
|
},
|
|
230
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
235
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1730,"column":9},
|
|
231
236
|
},
|
|
232
237
|
{
|
|
233
238
|
id: 'dsh-plugin-shop#shop/installStart',
|
|
@@ -255,7 +260,7 @@ export const TYPERT = {
|
|
|
255
260
|
schema: dsh_plugin_shop_shop_installStart_result$schema,
|
|
256
261
|
create: () => dsh_plugin_shop_shop_installStart_result$schema,
|
|
257
262
|
},
|
|
258
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
263
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1398,"column":9},
|
|
259
264
|
},
|
|
260
265
|
{
|
|
261
266
|
id: 'dsh-plugin-shop#shop/installStatus',
|
|
@@ -282,7 +287,7 @@ export const TYPERT = {
|
|
|
282
287
|
schema: dsh_plugin_shop_shop_installStatus_result$schema,
|
|
283
288
|
create: () => dsh_plugin_shop_shop_installStatus_result$schema,
|
|
284
289
|
},
|
|
285
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
290
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1706,"column":3},
|
|
286
291
|
},
|
|
287
292
|
{
|
|
288
293
|
id: 'dsh-plugin-shop#shop/restart',
|
|
@@ -298,7 +303,7 @@ export const TYPERT = {
|
|
|
298
303
|
schema: dsh_plugin_shop_shop_restart_result$schema,
|
|
299
304
|
create: () => dsh_plugin_shop_shop_restart_result$schema,
|
|
300
305
|
},
|
|
301
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
306
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1990,"column":9},
|
|
302
307
|
},
|
|
303
308
|
{
|
|
304
309
|
id: 'dsh-plugin-shop#shop/setEnabled',
|
|
@@ -325,7 +330,7 @@ export const TYPERT = {
|
|
|
325
330
|
schema: dsh_plugin_shop_shop_setEnabled_result$schema,
|
|
326
331
|
create: () => dsh_plugin_shop_shop_setEnabled_result$schema,
|
|
327
332
|
},
|
|
328
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
333
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":943,"column":9},
|
|
329
334
|
},
|
|
330
335
|
{
|
|
331
336
|
id: 'dsh-plugin-shop#shop/uninstallStart',
|
|
@@ -353,7 +358,7 @@ export const TYPERT = {
|
|
|
353
358
|
schema: dsh_plugin_shop_shop_uninstallStart_result$schema,
|
|
354
359
|
create: () => dsh_plugin_shop_shop_uninstallStart_result$schema,
|
|
355
360
|
},
|
|
356
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
361
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1884,"column":9},
|
|
357
362
|
},
|
|
358
363
|
{
|
|
359
364
|
id: 'dsh-plugin-shop#shop/updateStart',
|
|
@@ -380,7 +385,7 @@ export const TYPERT = {
|
|
|
380
385
|
schema: dsh_plugin_shop_shop_updateStart_result$schema,
|
|
381
386
|
create: () => dsh_plugin_shop_shop_updateStart_result$schema,
|
|
382
387
|
},
|
|
383
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
388
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":2097,"column":9},
|
|
384
389
|
},
|
|
385
390
|
{
|
|
386
391
|
id: 'dsh-plugin-shop#shop/version',
|
|
@@ -396,7 +401,7 @@ export const TYPERT = {
|
|
|
396
401
|
schema: dsh_plugin_shop_shop_version_result$schema,
|
|
397
402
|
create: () => dsh_plugin_shop_shop_version_result$schema,
|
|
398
403
|
},
|
|
399
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
404
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":2054,"column":9},
|
|
400
405
|
},
|
|
401
406
|
],
|
|
402
407
|
model: {
|
|
@@ -493,7 +498,7 @@ export const TYPERT = {
|
|
|
493
498
|
},
|
|
494
499
|
{
|
|
495
500
|
"name": "CatalogEntry",
|
|
496
|
-
"declaration": "export interface CatalogEntry {\n name: string;\n version: string;\n integrity: string | null;\n publishedAt: string | null;\n repository: string | null;\n license: string | null;\n tier: 'verified' | 'verified-stale' | 'community';\n metadata: 'declared' | 'derived';\n review?: { reviewedVersion?: string; reviewedCommit?: string; reviewedSha256?: string; repo?: string; reviewer: string; reviewCommit: string; notes: string; };\n catalog?: CatalogSection;\n source: 'npm' | 'github';\n publisher?: string;\n repo?: string;\n subdir?: string;\n tarball?: { url: string; sha256: string; };\n added?: string;\n peers?: string[];\n compatibility?: { dsh?: string; profiles?: string[]; };\n dshPeers?: Record<string, string>;\n unpackedSize?: number;\n installSize?: number;\n}"
|
|
501
|
+
"declaration": "export interface CatalogEntry {\n name: string;\n version: string;\n integrity: string | null;\n publishedAt: string | null;\n repository: string | null;\n license: string | null;\n tier: 'verified' | 'verified-stale' | 'community';\n metadata: 'declared' | 'derived';\n review?: { reviewedVersion?: string; reviewedCommit?: string; reviewedSha256?: string; repo?: string; reviewer: string; reviewCommit: string; notes: string; };\n catalog?: CatalogSection;\n source: 'npm' | 'github';\n publisher?: string;\n repo?: string;\n subdir?: string;\n tarball?: { url: string; sha256: string; };\n added?: string;\n peers?: string[];\n compatibility?: { dsh?: string; profiles?: string[]; };\n dshPeers?: Record<string, string>;\n unpackedSize?: number;\n installSize?: number;\n archived?: boolean;\n}"
|
|
497
502
|
},
|
|
498
503
|
{
|
|
499
504
|
"name": "CatalogSection",
|
|
@@ -541,7 +546,7 @@ export const TYPERT = {
|
|
|
541
546
|
},
|
|
542
547
|
{
|
|
543
548
|
"name": "RestartOutcome",
|
|
544
|
-
"declaration": "export type RestartOutcome = { ok: true; logFile?: string; } | { ok: false; detail: string; };"
|
|
549
|
+
"declaration": "export type RestartOutcome = { ok: true; logFile?: string; bootId?: string; pid?: number; } | { ok: false; detail: string; };"
|
|
545
550
|
},
|
|
546
551
|
{
|
|
547
552
|
"name": "ShopCatalogResult",
|
|
@@ -549,7 +554,7 @@ export const TYPERT = {
|
|
|
549
554
|
},
|
|
550
555
|
{
|
|
551
556
|
"name": "ShopInstalledEntry",
|
|
552
|
-
"declaration": "export interface ShopInstalledEntry {\n name: string;\n source: 'npm' | 'github';\n repo?: string;\n subdir?: string;\n installed: string;\n latest: string;\n outdated: boolean;\n enabled: boolean;\n}"
|
|
557
|
+
"declaration": "export interface ShopInstalledEntry {\n name: string;\n source: 'npm' | 'github';\n repo?: string;\n subdir?: string;\n installed: string;\n latest: string | null;\n outdated: boolean;\n enabled: boolean;\n shadowed?: true;\n}"
|
|
553
558
|
},
|
|
554
559
|
{
|
|
555
560
|
"name": "ShopInstallResult",
|
|
@@ -577,7 +582,7 @@ export const TYPERT = {
|
|
|
577
582
|
},
|
|
578
583
|
{
|
|
579
584
|
"name": "ShopVersionResult",
|
|
580
|
-
"declaration": "export interface ShopVersionResult {\n installed: string;\n latest: string | null;\n outdated: boolean;\n restartBlocked: RestartBlockedReason | null;\n pendingVersion?: string | null;\n}"
|
|
585
|
+
"declaration": "export interface ShopVersionResult {\n installed: string;\n latest: string | null;\n outdated: boolean;\n restartBlocked: RestartBlockedReason | null;\n pendingVersion?: string | null;\n bootId?: string;\n}"
|
|
581
586
|
}
|
|
582
587
|
]
|
|
583
588
|
}
|
|
@@ -52,6 +52,7 @@ const dsh_plugin_shop_shop_catalog_result$schema = z.object({
|
|
|
52
52
|
'dshPeers': z.union([z.undefined(), z.record(z.string(), z.string())]).optional(),
|
|
53
53
|
'unpackedSize': z.union([z.undefined(), z.number()]).optional(),
|
|
54
54
|
'installSize': z.union([z.undefined(), z.number()]).optional(),
|
|
55
|
+
'archived': z.union([z.undefined(), z.literal(false), z.literal(true)]).optional(),
|
|
55
56
|
})),
|
|
56
57
|
'denied': z.array(z.object({
|
|
57
58
|
'name': z.string(),
|
|
@@ -83,9 +84,10 @@ const dsh_plugin_shop_shop_installed_result$schema = z.array(z.object({
|
|
|
83
84
|
'repo': z.union([z.undefined(), z.string()]).optional(),
|
|
84
85
|
'subdir': z.union([z.undefined(), z.string()]).optional(),
|
|
85
86
|
'installed': z.string(),
|
|
86
|
-
'latest': z.string(),
|
|
87
|
+
'latest': z.union([z.literal(null), z.string()]),
|
|
87
88
|
'outdated': z.boolean(),
|
|
88
89
|
'enabled': z.boolean(),
|
|
90
|
+
'shadowed': z.union([z.undefined(), z.literal(true)]).optional(),
|
|
89
91
|
}))
|
|
90
92
|
const dsh_plugin_shop_shop_installedSpecs_result$schema = z.union([z.literal(null), z.record(z.string(), z.string())])
|
|
91
93
|
const dsh_plugin_shop_shop_installStart_parameter_0$schema = z.object({
|
|
@@ -119,6 +121,8 @@ const dsh_plugin_shop_shop_installStatus_result$schema = z.object({
|
|
|
119
121
|
const dsh_plugin_shop_shop_restart_result$schema = z.union([z.object({
|
|
120
122
|
'ok': z.literal(true),
|
|
121
123
|
'logFile': z.union([z.undefined(), z.string()]).optional(),
|
|
124
|
+
'bootId': z.union([z.undefined(), z.string()]).optional(),
|
|
125
|
+
'pid': z.union([z.undefined(), z.number()]).optional(),
|
|
122
126
|
}), z.object({
|
|
123
127
|
'ok': z.literal(false),
|
|
124
128
|
'detail': z.string(),
|
|
@@ -161,6 +165,7 @@ const dsh_plugin_shop_shop_version_result$schema = z.object({
|
|
|
161
165
|
'outdated': z.boolean(),
|
|
162
166
|
'restartBlocked': z.union([z.literal(null), z.literal("desktop"), z.literal("windows"), z.literal("systemd"), z.literal("port-zero")]),
|
|
163
167
|
'pendingVersion': z.union([z.undefined(), z.literal(null), z.string()]).optional(),
|
|
168
|
+
'bootId': z.union([z.undefined(), z.string()]).optional(),
|
|
164
169
|
})
|
|
165
170
|
|
|
166
171
|
export const TYPERT_REMOTE = {
|
|
@@ -192,7 +197,7 @@ export const TYPERT_REMOTE = {
|
|
|
192
197
|
schema: dsh_plugin_shop_shop_catalog_result$schema,
|
|
193
198
|
create: () => dsh_plugin_shop_shop_catalog_result$schema,
|
|
194
199
|
},
|
|
195
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
200
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1272,"column":9},
|
|
196
201
|
},
|
|
197
202
|
{
|
|
198
203
|
id: 'dsh-plugin-shop#shop/installed',
|
|
@@ -208,7 +213,7 @@ export const TYPERT_REMOTE = {
|
|
|
208
213
|
schema: dsh_plugin_shop_shop_installed_result$schema,
|
|
209
214
|
create: () => dsh_plugin_shop_shop_installed_result$schema,
|
|
210
215
|
},
|
|
211
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
216
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1739,"column":9},
|
|
212
217
|
},
|
|
213
218
|
{
|
|
214
219
|
id: 'dsh-plugin-shop#shop/installedSpecs',
|
|
@@ -224,7 +229,7 @@ export const TYPERT_REMOTE = {
|
|
|
224
229
|
schema: dsh_plugin_shop_shop_installedSpecs_result$schema,
|
|
225
230
|
create: () => dsh_plugin_shop_shop_installedSpecs_result$schema,
|
|
226
231
|
},
|
|
227
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
232
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1730,"column":9},
|
|
228
233
|
},
|
|
229
234
|
{
|
|
230
235
|
id: 'dsh-plugin-shop#shop/installStart',
|
|
@@ -252,7 +257,7 @@ export const TYPERT_REMOTE = {
|
|
|
252
257
|
schema: dsh_plugin_shop_shop_installStart_result$schema,
|
|
253
258
|
create: () => dsh_plugin_shop_shop_installStart_result$schema,
|
|
254
259
|
},
|
|
255
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
260
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1398,"column":9},
|
|
256
261
|
},
|
|
257
262
|
{
|
|
258
263
|
id: 'dsh-plugin-shop#shop/installStatus',
|
|
@@ -279,7 +284,7 @@ export const TYPERT_REMOTE = {
|
|
|
279
284
|
schema: dsh_plugin_shop_shop_installStatus_result$schema,
|
|
280
285
|
create: () => dsh_plugin_shop_shop_installStatus_result$schema,
|
|
281
286
|
},
|
|
282
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
287
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1706,"column":3},
|
|
283
288
|
},
|
|
284
289
|
{
|
|
285
290
|
id: 'dsh-plugin-shop#shop/restart',
|
|
@@ -295,7 +300,7 @@ export const TYPERT_REMOTE = {
|
|
|
295
300
|
schema: dsh_plugin_shop_shop_restart_result$schema,
|
|
296
301
|
create: () => dsh_plugin_shop_shop_restart_result$schema,
|
|
297
302
|
},
|
|
298
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
303
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1990,"column":9},
|
|
299
304
|
},
|
|
300
305
|
{
|
|
301
306
|
id: 'dsh-plugin-shop#shop/setEnabled',
|
|
@@ -322,7 +327,7 @@ export const TYPERT_REMOTE = {
|
|
|
322
327
|
schema: dsh_plugin_shop_shop_setEnabled_result$schema,
|
|
323
328
|
create: () => dsh_plugin_shop_shop_setEnabled_result$schema,
|
|
324
329
|
},
|
|
325
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
330
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":943,"column":9},
|
|
326
331
|
},
|
|
327
332
|
{
|
|
328
333
|
id: 'dsh-plugin-shop#shop/uninstallStart',
|
|
@@ -350,7 +355,7 @@ export const TYPERT_REMOTE = {
|
|
|
350
355
|
schema: dsh_plugin_shop_shop_uninstallStart_result$schema,
|
|
351
356
|
create: () => dsh_plugin_shop_shop_uninstallStart_result$schema,
|
|
352
357
|
},
|
|
353
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
358
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":1884,"column":9},
|
|
354
359
|
},
|
|
355
360
|
{
|
|
356
361
|
id: 'dsh-plugin-shop#shop/updateStart',
|
|
@@ -377,7 +382,7 @@ export const TYPERT_REMOTE = {
|
|
|
377
382
|
schema: dsh_plugin_shop_shop_updateStart_result$schema,
|
|
378
383
|
create: () => dsh_plugin_shop_shop_updateStart_result$schema,
|
|
379
384
|
},
|
|
380
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
385
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":2097,"column":9},
|
|
381
386
|
},
|
|
382
387
|
{
|
|
383
388
|
id: 'dsh-plugin-shop#shop/version',
|
|
@@ -393,7 +398,7 @@ export const TYPERT_REMOTE = {
|
|
|
393
398
|
schema: dsh_plugin_shop_shop_version_result$schema,
|
|
394
399
|
create: () => dsh_plugin_shop_shop_version_result$schema,
|
|
395
400
|
},
|
|
396
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
401
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":2054,"column":9},
|
|
397
402
|
},
|
|
398
403
|
],
|
|
399
404
|
}
|
|
@@ -47,6 +47,12 @@ export interface ShopTabInjected {
|
|
|
47
47
|
noteUninstalled?: (name: string) => void;
|
|
48
48
|
restart: () => Promise<ShopRestartResult>;
|
|
49
49
|
version: () => Promise<ShopVersionResult>;
|
|
50
|
+
/** Be told when the version answers start coming from another dsh process
|
|
51
|
+
* — dsh restarted under the page, which nothing reloads — with the first
|
|
52
|
+
* answer from it; returns the unsubscribe. The receipts a restart settles
|
|
53
|
+
* are the tab's to clear (design §8, 2026-10-06 amendment). Optional: a
|
|
54
|
+
* stub may not offer it. */
|
|
55
|
+
onRestarted?: (listener: (fresh: ShopVersionResult) => void) => () => void;
|
|
50
56
|
updateStart: (args: {
|
|
51
57
|
version: string;
|
|
52
58
|
}) => Promise<ShopUpdateResult>;
|
|
@@ -13,6 +13,17 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
13
13
|
'settings.shop': ShopLocaleKey;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
declare module '@deepseek-ai/cordis' {
|
|
17
|
+
interface Events {
|
|
18
|
+
/** A connection generation was established: the first connect after
|
|
19
|
+
* plugin boot, and every reconnect. `@deepseek-ai/dsh-client-connection`
|
|
20
|
+
* declares it, in these words, from 0.1.5-rc.3 on, and dsh-api-gateway's
|
|
21
|
+
* client emits it there through 0.2.0-rc.2; the 0.1.1-rc.2 this package
|
|
22
|
+
* builds against predates the declaration. A harness that never emits
|
|
23
|
+
* it leaves the shop as it was before it listened. */
|
|
24
|
+
'connection/reset'(): void;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
16
27
|
/** Dictionary namespace owned by this plugin. */
|
|
17
28
|
export declare const NS = "settings.shop";
|
|
18
29
|
/** How long a stashed catalog may satisfy a plain open. The host applies the
|
|
@@ -11,6 +11,11 @@ export declare const zh: {
|
|
|
11
11
|
* 2026-09-26-market-borrowings §4). */
|
|
12
12
|
tabCrashed: string;
|
|
13
13
|
search: string;
|
|
14
|
+
/** One subdued line under the search box when a Chinese query fired a
|
|
15
|
+
* dictionary intent (design 2026-10-08-search-query-expansion §4).
|
|
16
|
+
* `{terms}` is the comma-joined recall terms, without the `#` marker
|
|
17
|
+
* (boundary-only surface detail, not a reader's fact). */
|
|
18
|
+
zhExpansionNote: string;
|
|
14
19
|
all: string;
|
|
15
20
|
catalog: string;
|
|
16
21
|
catalogStats: string;
|
|
@@ -27,6 +32,10 @@ export declare const zh: {
|
|
|
27
32
|
tierVerified: string;
|
|
28
33
|
tierVerifiedStale: string;
|
|
29
34
|
tierCommunity: string;
|
|
35
|
+
/** The github repository GitHub reports as archived (design 2026-10-08 §1.3).
|
|
36
|
+
* Subdued register, like `tierCommunity`: nothing is wrong with the install
|
|
37
|
+
* itself; the owner has simply frozen the project. */
|
|
38
|
+
archivedBadge: string;
|
|
30
39
|
capabilitiesNote: string;
|
|
31
40
|
install: string;
|
|
32
41
|
confirm: string;
|
|
@@ -108,6 +117,14 @@ export declare const zh: {
|
|
|
108
117
|
nameTakenDetail: string;
|
|
109
118
|
npmSource: string;
|
|
110
119
|
githubSource: string;
|
|
120
|
+
/** The badge and the explanation for an installed github entry no catalog
|
|
121
|
+
* row claims (C10 MVP). The mechanism synthesizes a row for ANY github spec
|
|
122
|
+
* with no catalog row — shadowed by a same-named npm package, an unlisted
|
|
123
|
+
* fork, a removed listing, or a same-named conflict with a different repo —
|
|
124
|
+
* so the copy names the catalog fact and lists the causes, rather than
|
|
125
|
+
* claiming the npm-twin one. */
|
|
126
|
+
shadowedBadge: string;
|
|
127
|
+
shadowedDetail: string;
|
|
111
128
|
updatableSection: string;
|
|
112
129
|
installedVersion: string;
|
|
113
130
|
latestVersion: string;
|
|
@@ -133,6 +150,9 @@ export declare const zh: {
|
|
|
133
150
|
* that answered and then died. */
|
|
134
151
|
restartFailedLogNotice: string;
|
|
135
152
|
restartTransportFailed: string;
|
|
153
|
+
notRestartedNotice: string;
|
|
154
|
+
notRestartedPidNotice: string;
|
|
155
|
+
notRestartedLogNotice: string;
|
|
136
156
|
restartBlockedDesktopNotice: string;
|
|
137
157
|
restartBlockedWindowsNotice: string;
|
|
138
158
|
restartBlockedSystemdNotice: string;
|
|
@@ -159,6 +179,9 @@ export declare const en: {
|
|
|
159
179
|
retry: string;
|
|
160
180
|
tabCrashed: string;
|
|
161
181
|
search: string;
|
|
182
|
+
/** One subdued line under the search box when a Chinese query fired a
|
|
183
|
+
* dictionary intent (design 2026-10-08-search-query-expansion §4). */
|
|
184
|
+
zhExpansionNote: string;
|
|
162
185
|
all: string;
|
|
163
186
|
catalog: string;
|
|
164
187
|
catalogStats: string;
|
|
@@ -173,6 +196,10 @@ export declare const en: {
|
|
|
173
196
|
empty: string;
|
|
174
197
|
emptySearch: string;
|
|
175
198
|
tierVerified: string;
|
|
199
|
+
/** The github repository GitHub reports as archived (design 2026-10-08 §1.3).
|
|
200
|
+
* Subdued register: nothing is wrong with the install; the owner has simply
|
|
201
|
+
* frozen the project. */
|
|
202
|
+
archivedBadge: string;
|
|
176
203
|
tierVerifiedStale: string;
|
|
177
204
|
tierCommunity: string;
|
|
178
205
|
capabilitiesNote: string;
|
|
@@ -232,6 +259,8 @@ export declare const en: {
|
|
|
232
259
|
nameTakenDetail: string;
|
|
233
260
|
npmSource: string;
|
|
234
261
|
githubSource: string;
|
|
262
|
+
shadowedBadge: string;
|
|
263
|
+
shadowedDetail: string;
|
|
235
264
|
updatableSection: string;
|
|
236
265
|
installedVersion: string;
|
|
237
266
|
latestVersion: string;
|
|
@@ -252,6 +281,9 @@ export declare const en: {
|
|
|
252
281
|
restartFailedNotice: string;
|
|
253
282
|
restartFailedLogNotice: string;
|
|
254
283
|
restartTransportFailed: string;
|
|
284
|
+
notRestartedNotice: string;
|
|
285
|
+
notRestartedPidNotice: string;
|
|
286
|
+
notRestartedLogNotice: string;
|
|
255
287
|
restartBlockedDesktopNotice: string;
|
|
256
288
|
restartBlockedWindowsNotice: string;
|
|
257
289
|
restartBlockedSystemdNotice: string;
|
|
@@ -5,7 +5,7 @@ export { isShopLike } from '../shared/shop-like.ts';
|
|
|
5
5
|
export { identityKey, type EntryIdentity } from '../shared/identity.ts';
|
|
6
6
|
import { type EntryIdentity } from '../shared/identity.ts';
|
|
7
7
|
import type { ShopLocaleKey } from './locales.ts';
|
|
8
|
-
import type { CatalogEntry, HarnessVerdict, HotRestartReason, InstallRejectionCode, RestartBlockedReason } from '../host/index.ts';
|
|
8
|
+
import type { CatalogEntry, HarnessVerdict, HotRestartReason, InstallRejectionCode, RestartBlockedReason, ShopVersionResult } from '../host/index.ts';
|
|
9
9
|
import type { Activation } from '../host/activation.ts';
|
|
10
10
|
import { type InstallState } from '../shared/install-state.ts';
|
|
11
11
|
export type { Activation };
|
|
@@ -287,6 +287,26 @@ export declare function restartMonitorVerdict(input: {
|
|
|
287
287
|
elapsedMs: number;
|
|
288
288
|
stableSinceMs: number | null;
|
|
289
289
|
}): 'wait' | 'reload' | 'failed';
|
|
290
|
+
/**
|
|
291
|
+
* Whether two `version()` answers came from different dsh processes — dsh
|
|
292
|
+
* restarted under the page between them (design §8, 2026-10-06 amendment).
|
|
293
|
+
*
|
|
294
|
+
* A process names itself by `bootId` for as long as it lives, so where either
|
|
295
|
+
* answer carries one, a difference decides: a host older than the field never
|
|
296
|
+
* starts naming itself, and a newer one never stops. Where neither does, only
|
|
297
|
+
* the code they run can differ — one process runs one version, read once at
|
|
298
|
+
* its boot — which still catches the first restart after a self-update from
|
|
299
|
+
* a host older than the field, the one that matters most.
|
|
300
|
+
*/
|
|
301
|
+
export declare function answeredByAnotherProcess(previous: ShopVersionResult, next: ShopVersionResult): boolean;
|
|
302
|
+
/**
|
|
303
|
+
* Whether dsh restarting under the page settles this receipt: a change that
|
|
304
|
+
* landed and was waiting for exactly that. The tab clears these once the
|
|
305
|
+
* answers come from another process, and nothing else — a reload is still
|
|
306
|
+
* owed by a page nobody reloaded, a failure still happened, and a flow still
|
|
307
|
+
* running settles by its own poll.
|
|
308
|
+
*/
|
|
309
|
+
export declare function settledByRestart(view: InstallView): boolean;
|
|
290
310
|
/** How long the check-update button reports "up to date" after a re-check
|
|
291
311
|
* finds no newer release, before reverting to its idle label. */
|
|
292
312
|
export declare const CHECK_UP_TO_DATE_MS = 3000;
|