dsh-plugin-shop 0.8.3 → 0.8.4-beta.0

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.
@@ -3,6 +3,10 @@
3
3
  export interface UserLayerRow {
4
4
  id: string;
5
5
  disabled: boolean;
6
+ /** The module the entry mounts, when the caller knows it. A user-layer row
7
+ * that names a DIFFERENT module is one the harness skips
8
+ * (applyEntryPatches), so only this name lets a named row be written. */
9
+ name?: string;
6
10
  }
7
11
  /**
8
12
  * Find the profile directory that owns `startPath`.
@@ -19,10 +23,10 @@ export declare function discoverProfile(startPath: string, baseDir?: string): {
19
23
  dir: string;
20
24
  };
21
25
  /**
22
- * Upsert one row of the profile's user layer (`cordis.patch.yml`). Enabling
23
- * removes the row so the bundle default rules again; disabling writes
24
- * `{ id, disabled: true }` (§8: the CLI's watchUserPatches applies the change
25
- * hot through HMR). Existing rows for other ids are preserved verbatim.
26
+ * Set one entry's `disabled` key in the profile's user layer
27
+ * (`cordis.patch.yml`) — {@link setUserLayerRows} for a single row, with the
28
+ * same rules: one key changes and nothing else does (§8: the CLI's
29
+ * watchUserPatches applies the change hot through HMR).
26
30
  */
27
31
  export declare function setUserLayerRow(options: {
28
32
  profileDir: string;
@@ -35,6 +39,31 @@ export declare function setUserLayerRow(options: {
35
39
  * {@link ownedEntryIds}), and they toggle together: writing them one at a
36
40
  * time would read-modify-write the file once per entry, so a crash between
37
41
  * two writes would leave the package half disabled.
42
+ *
43
+ * The edit changes one key and nothing else (design
44
+ * 2026-09-26-market-borrowings §2). The layer is validated by the harness's
45
+ * own parser first, so one it cannot load still throws and is never
46
+ * rewritten; it is then edited as a YAML document, which keeps every comment,
47
+ * every other row, every other key and every `!!js` scalar as the user wrote
48
+ * them. The whole-file rewrite this replaced dropped each toggled id's row —
49
+ * and with it a `config:` override the user had put there — and dumped the
50
+ * list back through a library that models no comments, so the first toggle
51
+ * erased the header dsh writes into every new profile.
52
+ *
53
+ * For each entry the row written is the LAST one carrying its id, when the
54
+ * harness is sure to apply it: applyEntryPatches applies rows in order and
55
+ * each key replaces the entry's value, so the last row that sets `disabled`
56
+ * decides it. A row with `insert` is an insertion into a group, never an
57
+ * override; a row naming another module is skipped by the harness; a named
58
+ * row whose module the caller did not say cannot be judged. In each of those
59
+ * cases a row is appended instead, which the harness applies last whatever
60
+ * came before it — so appending is never wrong, only less tidy.
61
+ *
62
+ * An enable writes `disabled: false` rather than deleting the row, which is
63
+ * what lost a user's row or the comment above it; it is also the harness's
64
+ * own convention for this file from 0.1.7. The file keeps its permission bits
65
+ * across the rename (a new one is created owner-only, as the harness's writer
66
+ * does), because a config override can hold a credential.
38
67
  */
39
68
  export declare function setUserLayerRows(options: {
40
69
  profileDir: string;
@@ -65,6 +94,34 @@ export declare function ownedEntryIds(options: {
65
94
  profileDir: string;
66
95
  packageName: string;
67
96
  }): string[];
97
+ /** One loader entry a package's bundle patch inserts: its id, and the module
98
+ * it mounts when the patch names one as a plain string. */
99
+ export interface OwnedEntry {
100
+ id: string;
101
+ name: string | undefined;
102
+ }
103
+ /**
104
+ * {@link ownedEntryIds} with the module each entry mounts beside its id. The
105
+ * name is what the harness judges a NAMED user-layer row by — a row naming a
106
+ * different module is skipped (applyEntryPatches) — so it is what lets the
107
+ * toggle write a user's own named row rather than append one beside it. It is
108
+ * read through the harness's parser, so a relative name arrives anchored to a
109
+ * file URL exactly as the composed entry carries it; an `!!js` name has no
110
+ * plain value and reads as undefined. Throws where `ownedEntryIds` does.
111
+ */
112
+ export declare function ownedEntries(options: {
113
+ profileDir: string;
114
+ packageName: string;
115
+ }): OwnedEntry[];
116
+ /**
117
+ * An installed package's own `dsh.bundle.patch`, exactly as declared, or
118
+ * undefined when the package, its manifest or the field is absent — or the
119
+ * manifest cannot be read, which no post-install check can judge either.
120
+ */
121
+ export declare function declaredBundlePatch(options: {
122
+ profileDir: string;
123
+ packageName: string;
124
+ }): unknown;
68
125
  /**
69
126
  * Does a live loader entry id belong to the package that owns `owned`?
70
127
  *
@@ -12,9 +12,13 @@
12
12
  /** `shop/restart` result: committed, or a typed refusal issued BEFORE
13
13
  * anything is torn down. Once `ok` is returned the old process WILL exit —
14
14
  * the client monitors the new server and reports a failed boot with the
15
- * manual command. */
15
+ * manual command and `logFile`, the file the new process's output goes to:
16
+ * where a boot that died explains itself, at a path that depends on DSH_HOME
17
+ * and the shop row's `cacheDir`, which only the host knows. A host older than
18
+ * the field answers without it, so the client reads it as optional. */
16
19
  export type RestartOutcome = {
17
20
  ok: true;
21
+ logFile?: string;
18
22
  } | {
19
23
  ok: false;
20
24
  detail: string;
@@ -56,8 +56,34 @@ export interface CatalogEntry {
56
56
  };
57
57
  /** The date this entry first appeared in the catalog (YYYY-MM-DD). */
58
58
  added?: string;
59
- /** The package's declared peer dependency names (schemaVersion 6). */
59
+ /** The names of the package's REQUIRED peer dependencies — a peer its
60
+ * author marks optional in `peerDependenciesMeta` is left out at harvest.
61
+ * Additive and optional, so it rides every schemaVersion: the version-6
62
+ * gate this comment used to name came off on 2026-09-03 without ever being
63
+ * opened. Present on npm entries. Not on github entries yet: the registry
64
+ * harvests their peers from 2026-09-24 but withholds them from the catalog
65
+ * (`withholdRepoPeers`) until `SHOP_EMIT_REPO_PEERS` flips, in the release
66
+ * commit that first promotes a shop refining peers against the browser's
67
+ * module table to `latest` (design 2026-09-01-harness-compatibility §9.8).
68
+ * An absent list forms no peer verdict. */
60
69
  peers?: string[];
70
+ /** The author's own `dsh.compatibility` declaration, when they published
71
+ * one. A REQUIREMENT, never a verdict: the host compares it against the
72
+ * running installation (`ShopCatalogResult.incompatibleHarness`). Additive
73
+ * and optional, so it rides every schemaVersion. */
74
+ compatibility?: {
75
+ dsh?: string;
76
+ profiles?: string[];
77
+ };
78
+ /** The package's peers on the harness itself (`@deepseek-ai/dsh` and
79
+ * `@deepseek-ai/dsh-*`) with their ranges verbatim, optional ones and empty
80
+ * ranges included — what dsh 0.1.7 refuses an install on. The host hands
81
+ * them to the running dsh's own check (`peerVerdictsOf`). npm entries only:
82
+ * dsh keys the exemption that clears its refusal by the installed
83
+ * manifest's version, which a github entry's catalog version is not
84
+ * (registry `Entry.dshPeers`). Absent when the package declares none, or
85
+ * when its catalog predates the field. */
86
+ dshPeers?: Record<string, string>;
61
87
  /** Wire-compatibility key, not a field to read — see {@link installSize},
62
88
  * which the catalog parse fills from this one. It names npm's OWN quantity
63
89
  * (`dist.unpackedSize`), so it is npm-only and the parse REFUSES one on a
@@ -4,10 +4,26 @@
4
4
  * both the source tree (tests) and the bundled `lib/index.js` sit exactly
5
5
  * one level below the package root, so the same relative URL resolves in
6
6
  * both. */
7
- export declare function ownVersion(): string;
7
+ /**
8
+ * Read a version once and keep it: the answer to "which code is this".
9
+ *
10
+ * The file cannot answer that question later. A profile installs hoisted, so
11
+ * a self-update rewrites package.json in the directory the RUNNING code was
12
+ * loaded from, and every read after it names the version that will run after
13
+ * the next restart — which the version row then printed as the one running
14
+ * (design §7.3, 2026-09-27 amendment).
15
+ *
16
+ * A first read that throws is not kept: the module import must not fail over
17
+ * a version string, so the answer falls back to reading on demand, which is
18
+ * what the row always did.
19
+ */
20
+ export declare function versionAtLoad(read: () => string): () => string;
21
+ /** The version of the code in this process, read when the module was first
22
+ * evaluated — at boot, before any self-update could rewrite the file. */
23
+ export declare const runningVersion: () => string;
8
24
  /**
9
25
  * The peer ranges this build declares — the input to the load-time harness
10
- * self-check. Read from the same shipped manifest as `ownVersion`, so the
26
+ * self-check. Read from the same shipped manifest as `runningVersion`, so the
11
27
  * ranges checked are the ones this build was actually published with, never
12
28
  * a second copy that can drift from them.
13
29
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-shop",
3
- "version": "0.8.3",
3
+ "version": "0.8.4-beta.0",
4
4
  "description": "The DeepSeek Harness plugin shop: browse, install, enable, and update dsh plugins from a git-auditable catalog.",
5
5
  "keywords": [
6
6
  "dsh-plugin",
@@ -75,6 +75,7 @@
75
75
  "dependencies": {
76
76
  "js-yaml": "^4.2.0",
77
77
  "semver": "^7.6.3",
78
+ "yaml": "^2.5.1",
78
79
  "zod": "^4.4.3"
79
80
  },
80
81
  "peerDependencies": {