@sparkelf/dsh-plus 0.1.0-rc.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
+ # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
+ # after editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write packages/bundle/plus/README.md
5
+ README.md: 627a5b3d23b642d2c7b92926133435ae82ae2c15
6
+ README.zh.md: 1eaced04cf003ed2ef4485e6dedfcf5cfb4656ca
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ ---
2
+ description: "The npm-installable DeepSeek Harness Plus profile composition and explicit official-source materializer."
3
+ kind: "package-bundle"
4
+ ---
5
+
6
+ # @sparkelf/dsh-plus
7
+
8
+ English | [中文](README.zh.md)
9
+
10
+ ## Summary
11
+
12
+ This distribution composes official `@deepseek-ai/dsh-base` and `@deepseek-ai/dsh-web-app` with the selected external sidebar, mobile bridge, plugin market, GenUI package, five complete Plus capability packages, and nine independent patch packages. It owns only ordered composition, minimum compatibility metadata, dependency closure, explicit materialization, and the credential-free deployment lock; capability behavior and patch payloads stay in their owning packages.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Model Experience](#model-experience)
18
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
19
+ - [Dev Note](#dev-note)
20
+
21
+ -----
22
+
23
+ <a id="use-this-package"></a>
24
+ ## Use this package
25
+
26
+ Install and materialize Plus without Desktop or the tray:
27
+
28
+ ```bash
29
+ dsh plugin --profile plus add @sparkelf/dsh-plus
30
+ dsh plugin --profile plus exec dsh-plus apply --dsh-root /path/to/official-dsh
31
+ dsh --profile plus
32
+ ```
33
+
34
+ The explicit apply step requires official revision `cd5ef8148158c3a752a658978873241fdf8e2bbc`, materializes every selected runtime package as a profile-direct dependency, applies all pending source payloads together, configures exact npm patches, removes retired Plus-owned entries, and writes `.dsh-plus/patchset.lock.json` with mode `0600`. It installs `dsh-better-sidebar@0.17.1` at the profile root, explicitly allows only its `node-pty` native build, and links the profile's `@deepseek-ai` scope to the exact official source dependencies. Version conflicts and source mismatches fail before profile installation or source mutation. The package has no install lifecycle script.
35
+
36
+ Official DSH supplies onboarding, Workspace selection, Session export, Turn folding, and the base image path. The external `@changfenhuang/dsh-genui` bundle owns generated UI, including inline interactive charts emitted by the model as `dsh-ui`. The temporary GenUI streaming EChart patch targets only `0.9.6` and retires after [upstream PR #87](https://github.com/omdsh-dev/dsh-genui/pull/87) ships in npm and the real inline-chart path passes. DataOps and Document Attachments mount only when their endpoint environment variables exist. Agent Teams is excluded because the official packages are private experimental workspaces and shipped profiles disable them.
37
+
38
+ -----
39
+
40
+ <a id="model-experience"></a>
41
+ ## Model Experience
42
+
43
+ ### Profile composition
44
+
45
+ #### What the model sees
46
+
47
+ Nothing directly. `@sparkelf/dsh-plus` registers no tool, prompt section, model-facing Session event, or provider content; each selected capability owns its own model-visible behavior.
48
+
49
+ #### Token effect
50
+
51
+ Zero by itself. Token use comes only from the capability and official packages selected by the profile.
52
+
53
+ #### KV Cache effect
54
+
55
+ Independent by itself. The profile changes a request prefix only when one of its selected packages contributes or removes model-visible content.
56
+
57
+ ## Known Limitations and Deferred Work
58
+
59
+ <a id="known-limitations-and-deferred-work"></a>
60
+
61
+ - **Exact source target**: source payloads apply only to the recorded official revision; another source tree fails loudly, and the distribution provides no accepted-fork or fuzzy-apply fallback.
62
+
63
+ <a id="dev-note"></a>
64
+ ### Dev Note
65
+
66
+ <details>
67
+ <summary>Working context for maintainers, click to expand</summary>
68
+
69
+ This Dev Note is working context for maintainers; shipped behavior, limits, and rationale live in the sections above, the package code, and the linked Agent Note.
70
+
71
+ - The [distribution Agent Note](../../../.agents/notes/proposed/architecture/2026-08-29-ranged-plus-patchset-distribution.md) owns package forms, inventory, materialization, and deletion rules; `src/apply.ts` and `cordis.patch.yml` own the executable profile behavior.
72
+
73
+ </details>
package/README.zh.md ADDED
@@ -0,0 +1,73 @@
1
+ ---
2
+ description: "可通过npm安装的DeepSeek Harness Plus profile composition及explicit official-source materializer。"
3
+ kind: "package-bundle"
4
+ ---
5
+
6
+ # @sparkelf/dsh-plus
7
+
8
+ [English](README.md) | 中文
9
+
10
+ ## 概述
11
+
12
+ 该distribution把official `@deepseek-ai/dsh-base`及`@deepseek-ai/dsh-web-app`与selected external sidebar、mobile bridge、plugin market、GenUI package、五个完整Plus capability packages及九个independent patch packages组合起来。它只持有ordered composition、minimum compatibility metadata、dependency closure、explicit materialization及credential-free deployment lock;capability behavior和patch payloads仍属于各自package。
13
+
14
+ ## 目录
15
+
16
+ - [使用此软件包](#use-this-package)
17
+ - [模型体验](#model-experience)
18
+ - [已知限制和延期工作](#known-limitations-and-deferred-work)
19
+ - [开发备注](#dev-note)
20
+
21
+ -----
22
+
23
+ <a id="use-this-package"></a>
24
+ ## 使用此软件包
25
+
26
+ 无需Desktop或tray即可安装并materialize Plus:
27
+
28
+ ```bash
29
+ dsh plugin --profile plus add @sparkelf/dsh-plus
30
+ dsh plugin --profile plus exec dsh-plus apply --dsh-root /path/to/official-dsh
31
+ dsh --profile plus
32
+ ```
33
+
34
+ explicit apply步骤要求official revision `cd5ef8148158c3a752a658978873241fdf8e2bbc`,把每个selected runtime package materialize为profile-direct dependency,一次应用全部pending source payloads,配置exact npm patches,删除retired Plus-owned entries,并以`0600` mode写入`.dsh-plus/patchset.lock.json`。它在profile root安装`dsh-better-sidebar@0.17.1`,只显式允许其`node-pty` native build,并把profile的`@deepseek-ai` scope链接到exact official source dependencies。version conflict和source mismatch会在profile installation或source mutation前失败。该package没有install lifecycle script。
35
+
36
+ Official DSH提供onboarding、Workspace selection、Session export、Turn folding及base image path。External `@changfenhuang/dsh-genui` bundle拥有generated UI,包括模型以`dsh-ui`输出的inline interactive charts。Temporary GenUI streaming EChart patch只target `0.9.6`;[upstream PR #87](https://github.com/omdsh-dev/dsh-genui/pull/87)进入npm且真实inline-chart path通过后退役。DataOps和Document Attachments仅在对应endpoint environment variables存在时mount。Agent Teams被排除,因为official packages属于private experimental workspaces且shipped profiles会禁用它们。
37
+
38
+ -----
39
+
40
+ <a id="model-experience"></a>
41
+ ## 模型体验
42
+
43
+ ### Profile composition
44
+
45
+ #### 模型看到什么
46
+
47
+ 没有direct内容。`@sparkelf/dsh-plus`不注册tool、prompt section、model-facing Session event或provider content;每个selected capability持有自己的model-visible behavior。
48
+
49
+ #### Token 影响
50
+
51
+ 自身为零。Token use只来自profile选择的capability和official packages。
52
+
53
+ #### KV Cache 影响
54
+
55
+ 自身独立。仅当selected package贡献或移除model-visible content时,该profile才会改变request prefix。
56
+
57
+ ## 已知限制和延期工作
58
+
59
+ <a id="known-limitations-and-deferred-work"></a>
60
+
61
+ - **Exact source target**:source payloads只应用于recorded official revision;其他source tree会明确失败,distribution不提供accepted-fork或fuzzy-apply fallback。
62
+
63
+ <a id="dev-note"></a>
64
+ ### 开发备注
65
+
66
+ <details>
67
+ <summary>维护者工作上下文,点击展开</summary>
68
+
69
+ 该开发备注是maintainer working context;shipped behavior、limits及rationale以以上sections、package code及linked Agent Note为准。
70
+
71
+ - [Distribution Agent Note](../../../.agents/notes/proposed/architecture/2026-08-29-ranged-plus-patchset-distribution.zh.md)持有package forms、inventory、materialization及deletion rules;`src/apply.ts`和`cordis.patch.yml`持有executable profile behavior。
72
+
73
+ </details>
@@ -0,0 +1,50 @@
1
+ - id: subagent-model-selection-settings
2
+ disabled: true
3
+
4
+ - insert:
5
+ - id: plus-backup
6
+ name: '@sparkelf/dsh-plugin-backup'
7
+
8
+ - id: plus-dataops
9
+ name: '@sparkelf/dsh-plugin-dataops'
10
+ disabled: !!js "!process.env.DSH_DATAOPS_BASE_URL"
11
+ config:
12
+ baseUrl: !!js process.env.DSH_DATAOPS_BASE_URL
13
+ serverName: dataops
14
+ credentialRef: dataops_access_token
15
+ targetCredentialRef: dataops_target_ref
16
+ callbackOrigin: !!js process.env.DSH_DATAOPS_CALLBACK_ORIGIN
17
+ toolCallTimeoutMs: 60000
18
+ failOnStartupError: false
19
+
20
+ - id: plus-document-parser
21
+ name: '@sparkelf/dsh-plugin-document-attachments'
22
+ disabled: !!js "!process.env.DSH_MINERU_ENDPOINT"
23
+ config:
24
+ provider: mineru
25
+ maxDirectMarkdownBytes: 1048576
26
+ maxRequestBytes: 402653184
27
+
28
+ - id: plus-document-parser-mineru
29
+ name: '@sparkelf/dsh-plugin-document-attachments/mineru'
30
+ disabled: !!js "!process.env.DSH_MINERU_ENDPOINT"
31
+ config:
32
+ endpoint: !!js process.env.DSH_MINERU_ENDPOINT
33
+ timeoutMs: 120000
34
+ maxResponseBytes: 67108864
35
+
36
+ - id: plus-subagent-settings
37
+ name: '@sparkelf/dsh-plugin-subagent-settings/startup'
38
+ config:
39
+ settingsNamespace: subagent
40
+ provider: spawn
41
+ enabled: false
42
+ maxDepth: 0
43
+
44
+ - id: plus-subagent-fork-settings
45
+ name: '@sparkelf/dsh-plugin-subagent-settings/startup'
46
+ config:
47
+ settingsNamespace: subagent-fork
48
+ provider: fork
49
+ enabled: false
50
+ maxDepth: 0
package/lib/apply.js ADDED
@@ -0,0 +1,446 @@
1
+ import { createRequire } from "node:module";
2
+ import { spawnSync } from "node:child_process";
3
+ import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
4
+ import { dirname, isAbsolute, relative, resolve } from "node:path";
5
+ import { satisfies, valid, validRange } from "semver";
6
+ import { parseDocument } from "yaml";
7
+ //#region lib/types/apply.js
8
+ /** Materialize the Plus distribution's independent patch packages without Desktop. */
9
+ const FORMAT_VERSION = 1;
10
+ function readJsonObject(path, label) {
11
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
12
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(label + " must be a JSON object");
13
+ return parsed;
14
+ }
15
+ function requireObject(value, label) {
16
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error(label + " must be an object");
17
+ return value;
18
+ }
19
+ function requireString(value, label) {
20
+ if (typeof value !== "string" || value === "") throw new Error(label + " must be a non-empty string");
21
+ return value;
22
+ }
23
+ function requireRange(value, label) {
24
+ const range = requireString(value, label);
25
+ if (validRange(range) === null) throw new Error(label + " is not a semantic-version range: " + range);
26
+ return range;
27
+ }
28
+ function requireVersion(value, label) {
29
+ const version = requireString(value, label);
30
+ if (valid(version) === null) throw new Error(label + " is not a semantic version: " + version);
31
+ return version;
32
+ }
33
+ function requireStringArray(value, label) {
34
+ if (!Array.isArray(value) || value.length === 0) throw new Error(label + " must be a non-empty array");
35
+ const strings = value.map((entry, index) => requireString(entry, label + "[" + String(index) + "]"));
36
+ if (new Set(strings).size !== strings.length) throw new Error(label + " must not contain duplicates");
37
+ return strings;
38
+ }
39
+ function resolveInstalledPackage(distributionDirectory, packageName) {
40
+ const manifestPath = createRequire(resolve(distributionDirectory, "package.json")).resolve(packageName + "/package.json");
41
+ const manifest = readJsonObject(manifestPath, packageName + " manifest");
42
+ return {
43
+ name: packageName,
44
+ version: requireVersion(manifest.version, packageName + " version"),
45
+ directory: dirname(manifestPath),
46
+ manifest
47
+ };
48
+ }
49
+ function resolvePatchFile(packageDirectory, declared) {
50
+ const absoluteFile = resolve(packageDirectory, declared);
51
+ const local = relative(packageDirectory, absoluteFile);
52
+ if (isAbsolute(local) || local === ".." || local.startsWith("../")) throw new Error("patch file must stay inside its patch package: " + declared);
53
+ if (!existsSync(absoluteFile)) throw new Error("patch file does not exist: " + absoluteFile);
54
+ return {
55
+ relativeFile: local.replaceAll("\\", "/"),
56
+ absoluteFile
57
+ };
58
+ }
59
+ function parseVariant(value, index, patchPackage) {
60
+ const label = patchPackage.name + " dshPatch.variants[" + String(index) + "]";
61
+ const variant = requireObject(value, label);
62
+ const target = requireObject(variant.target, label + ".target");
63
+ const kind = requireString(target.kind, label + ".target.kind");
64
+ const common = {
65
+ id: requireString(variant.id, label + ".id"),
66
+ dsh: requireRange(variant.dsh, label + ".dsh"),
67
+ file: requireString(variant.file, label + ".file"),
68
+ patchPackage
69
+ };
70
+ if (kind === "npm") return {
71
+ ...common,
72
+ target: {
73
+ kind,
74
+ name: requireString(target.name, label + ".target.name"),
75
+ range: requireRange(target.range, label + ".target.range")
76
+ }
77
+ };
78
+ if (kind === "dsh-source") return {
79
+ ...common,
80
+ target: {
81
+ kind,
82
+ baseRevision: requireString(target.baseRevision, label + ".target.baseRevision")
83
+ }
84
+ };
85
+ throw new Error("unsupported patch target kind: " + kind);
86
+ }
87
+ function git(root, args, acceptFailure = false) {
88
+ const result = spawnSync("git", args, {
89
+ cwd: root,
90
+ encoding: "utf8"
91
+ });
92
+ if (result.status === 0) return result.stdout.trim();
93
+ if (acceptFailure) return void 0;
94
+ const detail = result.stderr.trim();
95
+ throw new Error("git " + args.join(" ") + " failed" + (detail === "" ? "" : ": " + detail));
96
+ }
97
+ function sourcePatchState(root, file) {
98
+ if (git(root, [
99
+ "apply",
100
+ "--check",
101
+ file
102
+ ], true) !== void 0) return "pending";
103
+ if (git(root, [
104
+ "apply",
105
+ "--reverse",
106
+ "--check",
107
+ file
108
+ ], true) !== void 0) return "applied";
109
+ git(root, [
110
+ "apply",
111
+ "--check",
112
+ file
113
+ ]);
114
+ throw new Error("unreachable");
115
+ }
116
+ function requireSourceBase(root, baseRevision) {
117
+ const checkoutRevision = requireString(git(root, ["rev-parse", "HEAD"]), "DSH checkout revision");
118
+ if (checkoutRevision !== baseRevision) throw new Error("DSH checkout must be exact official base " + baseRevision + ", found " + checkoutRevision);
119
+ return checkoutRevision;
120
+ }
121
+ function patchPackageVariants(distributionDirectory, names) {
122
+ const variants = [];
123
+ for (const name of names) {
124
+ const patchPackage = resolveInstalledPackage(distributionDirectory, name);
125
+ const declaration = requireObject(patchPackage.manifest.dshPatch, name + " dshPatch");
126
+ if (declaration.formatVersion !== FORMAT_VERSION) throw new Error("unsupported dshPatch formatVersion in " + name + ": " + String(declaration.formatVersion));
127
+ if (!Array.isArray(declaration.variants) || declaration.variants.length === 0) throw new Error(name + " dshPatch.variants must be a non-empty array");
128
+ for (const [index, value] of declaration.variants.entries()) variants.push(parseVariant(value, index, patchPackage));
129
+ }
130
+ return variants;
131
+ }
132
+ function prepareSelection(distributionDirectory, profileDirectory, dshRoot) {
133
+ const distributionManifest = readJsonObject(resolve(distributionDirectory, "package.json"), "Plus distribution manifest");
134
+ const distributionName = requireString(distributionManifest.name, "Plus distribution name");
135
+ const distributionVersion = requireVersion(distributionManifest.version, "Plus distribution version");
136
+ const plus = requireObject(distributionManifest.dshPlus, "Plus distribution dshPlus");
137
+ if (plus.formatVersion !== FORMAT_VERSION) throw new Error("unsupported dshPlus formatVersion: " + String(plus.formatVersion));
138
+ const dshRange = requireRange(requireObject(plus.compatibility, "dshPlus.compatibility").dsh, "dshPlus.compatibility.dsh");
139
+ const baseRevision = requireString(requireObject(plus.sourceBase, "dshPlus.sourceBase").revision, "dshPlus.sourceBase.revision");
140
+ const profile = requireObject(plus.profile, "dshPlus.profile");
141
+ const bundles = requireStringArray(profile.bundles, "dshPlus.profile.bundles");
142
+ const rawProfileDependencySpecs = requireObject(profile.dependencies, "dshPlus.profile.dependencies");
143
+ const profileDependencySpecs = {};
144
+ for (const [name, spec] of Object.entries(rawProfileDependencySpecs)) profileDependencySpecs[name] = requireString(spec, "dshPlus.profile.dependencies." + name);
145
+ const rawAllowBuilds = requireObject(profile.allowBuilds, "dshPlus.profile.allowBuilds");
146
+ const allowBuilds = {};
147
+ for (const [name, allowed] of Object.entries(rawAllowBuilds)) {
148
+ if (typeof allowed !== "boolean") throw new Error("dshPlus.profile.allowBuilds." + name + " must be a boolean");
149
+ allowBuilds[name] = allowed;
150
+ }
151
+ const patchPackageNames = requireStringArray(plus.patchPackages, "dshPlus.patchPackages");
152
+ const dependencies = requireObject(distributionManifest.dependencies, "Plus distribution dependencies");
153
+ const dshVersion = requireVersion(readJsonObject(resolve(dshRoot, "package.json"), "DSH source manifest").version, "DSH source version");
154
+ if (!satisfies(dshVersion, dshRange, { includePrerelease: true })) throw new Error(distributionName + "@" + distributionVersion + " requires DSH " + dshRange + ", found " + dshVersion);
155
+ const checkoutRevision = requireSourceBase(dshRoot, baseRevision);
156
+ const groups = /* @__PURE__ */ new Map();
157
+ for (const variant of patchPackageVariants(distributionDirectory, patchPackageNames)) {
158
+ const entries = groups.get(variant.id) ?? [];
159
+ entries.push(variant);
160
+ groups.set(variant.id, entries);
161
+ }
162
+ const sourceStates = /* @__PURE__ */ new Map();
163
+ for (const variant of [...groups.values()].flat()) {
164
+ if (variant.target.kind !== "dsh-source" || variant.target.baseRevision !== baseRevision || !satisfies(dshVersion, variant.dsh, { includePrerelease: true })) continue;
165
+ const file = resolvePatchFile(variant.patchPackage.directory, variant.file);
166
+ sourceStates.set(file.absoluteFile, sourcePatchState(dshRoot, file.absoluteFile));
167
+ }
168
+ const pendingSourceFiles = [...sourceStates].flatMap(([file, state]) => state === "pending" ? [file] : []);
169
+ if (pendingSourceFiles.length > 0) git(dshRoot, [
170
+ "apply",
171
+ "--check",
172
+ ...pendingSourceFiles
173
+ ]);
174
+ if (writeProfileRequirements(profileDirectory, profileDependencySpecs, allowBuilds)) runPnpm(profileDirectory, ["install"], "pnpm install Plus profile dependencies");
175
+ const profileDependencies = Object.keys(profileDependencySpecs).sort().map((name) => {
176
+ return {
177
+ name,
178
+ version: resolveInstalledPackage(profileDirectory, name).version
179
+ };
180
+ });
181
+ const runtimePackages = [...Object.keys(dependencies).filter((name) => !patchPackageNames.includes(name)).sort().map((name) => {
182
+ return {
183
+ name,
184
+ version: resolveInstalledPackage(distributionDirectory, name).version
185
+ };
186
+ }), ...profileDependencies].sort((left, right) => left.name.localeCompare(right.name));
187
+ const selected = [];
188
+ for (const id of [...groups.keys()].sort()) {
189
+ const candidates = (groups.get(id) ?? []).flatMap((variant) => {
190
+ if (!satisfies(dshVersion, variant.dsh, { includePrerelease: true })) return [];
191
+ const file = resolvePatchFile(variant.patchPackage.directory, variant.file);
192
+ if (variant.target.kind === "dsh-source") {
193
+ if (variant.target.baseRevision !== baseRevision) return [];
194
+ return [{
195
+ id,
196
+ patchPackage: {
197
+ name: variant.patchPackage.name,
198
+ version: variant.patchPackage.version
199
+ },
200
+ file: file.relativeFile,
201
+ absoluteFile: file.absoluteFile,
202
+ target: {
203
+ kind: "dsh-source",
204
+ baseRevision
205
+ },
206
+ alreadyApplied: sourceStates.get(file.absoluteFile) === "applied"
207
+ }];
208
+ }
209
+ const targetVersion = resolveInstalledPackage(variant.target.name in profileDependencySpecs ? profileDirectory : distributionDirectory, variant.target.name).version;
210
+ if (!satisfies(targetVersion, variant.target.range, { includePrerelease: true })) return [];
211
+ return [{
212
+ id,
213
+ patchPackage: {
214
+ name: variant.patchPackage.name,
215
+ version: variant.patchPackage.version
216
+ },
217
+ file: file.relativeFile,
218
+ absoluteFile: file.absoluteFile,
219
+ target: {
220
+ kind: "npm",
221
+ name: variant.target.name,
222
+ version: targetVersion
223
+ }
224
+ }];
225
+ });
226
+ const [candidate] = candidates;
227
+ if (candidate === void 0) throw new Error("no compatible patch variant for " + id + " on DSH " + dshVersion);
228
+ if (candidates.length > 1) throw new Error("multiple compatible patch variants for " + id + " on DSH " + dshVersion);
229
+ selected.push(candidate);
230
+ }
231
+ const lockPatches = selected.map((patch) => {
232
+ if ("alreadyApplied" in patch) {
233
+ const { absoluteFile: _absoluteFile, alreadyApplied: _alreadyApplied, ...locked } = patch;
234
+ return locked;
235
+ }
236
+ const { absoluteFile: _absoluteFile, ...locked } = patch;
237
+ return locked;
238
+ });
239
+ return {
240
+ patches: selected,
241
+ bundles,
242
+ runtimePackages,
243
+ profileDependencies,
244
+ allowBuilds,
245
+ lock: {
246
+ formatVersion: FORMAT_VERSION,
247
+ distribution: {
248
+ name: distributionName,
249
+ version: distributionVersion
250
+ },
251
+ dsh: {
252
+ version: dshVersion,
253
+ baseRevision,
254
+ checkoutRevision
255
+ },
256
+ runtimePackages,
257
+ patches: lockPatches
258
+ }
259
+ };
260
+ }
261
+ function materializePatchFiles(profileDirectory, patches) {
262
+ const root = resolve(profileDirectory, ".dsh-plus", "patches");
263
+ rmSync(root, {
264
+ recursive: true,
265
+ force: true
266
+ });
267
+ return patches.map((patch) => {
268
+ const destination = resolve(root, patch.patchPackage.name, patch.patchPackage.version, patch.file);
269
+ mkdirSync(dirname(destination), { recursive: true });
270
+ copyFileSync(patch.absoluteFile, destination);
271
+ return {
272
+ ...patch,
273
+ absoluteFile: destination
274
+ };
275
+ });
276
+ }
277
+ function profilePatchConfiguration(profileDirectory, patches) {
278
+ const document = parseDocument(readFileSync(resolve(profileDirectory, "pnpm-workspace.yaml"), "utf8"));
279
+ const [documentError] = document.errors;
280
+ if (documentError !== void 0) throw new Error("Plus profile workspace is not valid YAML", { cause: documentError });
281
+ let changed = false;
282
+ const desiredKeys = new Set(patches.flatMap((patch) => patch.target.kind === "npm" ? [patch.target.name + "@" + patch.target.version] : []));
283
+ const workspace = requireObject(document.toJS(), "Plus profile workspace");
284
+ const configured = workspace.patchedDependencies === void 0 ? {} : requireObject(workspace.patchedDependencies, "Plus profile patchedDependencies");
285
+ for (const [key, value] of Object.entries(configured)) if (typeof value === "string" && value.startsWith(".dsh-plus/patches/") && !desiredKeys.has(key)) {
286
+ document.deleteIn(["patchedDependencies", key]);
287
+ changed = true;
288
+ }
289
+ for (const patch of patches) {
290
+ if (patch.target.kind !== "npm") continue;
291
+ const key = patch.target.name + "@" + patch.target.version;
292
+ const value = relative(profileDirectory, patch.absoluteFile).replaceAll("\\", "/");
293
+ const current = document.getIn(["patchedDependencies", key]);
294
+ if (current !== void 0 && current !== value && (typeof current !== "string" || !current.startsWith(".dsh-plus/patches/"))) throw new Error("profile patchedDependencies." + key + " is already owned by another payload");
295
+ if (current === value) continue;
296
+ document.setIn(["patchedDependencies", key], value);
297
+ changed = true;
298
+ }
299
+ return {
300
+ text: String(document),
301
+ changed
302
+ };
303
+ }
304
+ function writeProfileRequirements(profileDirectory, dependencySpecs, allowBuilds) {
305
+ const manifestPath = resolve(profileDirectory, "package.json");
306
+ const manifest = readJsonObject(manifestPath, "DSH profile manifest");
307
+ const dependencies = requireObject(manifest.dependencies, "DSH profile dependencies");
308
+ let manifestChanged = false;
309
+ for (const [name, spec] of Object.entries(dependencySpecs)) {
310
+ const current = dependencies[name];
311
+ if (current !== void 0 && current !== spec) throw new Error("profile dependency " + name + " is configured as " + JSON.stringify(current) + ", expected " + spec);
312
+ if (current === void 0) {
313
+ dependencies[name] = spec;
314
+ manifestChanged = true;
315
+ }
316
+ }
317
+ const workspacePath = resolve(profileDirectory, "pnpm-workspace.yaml");
318
+ const document = parseDocument(readFileSync(workspacePath, "utf8"));
319
+ const [documentError] = document.errors;
320
+ if (documentError !== void 0) throw new Error("Plus profile workspace is not valid YAML", { cause: documentError });
321
+ let workspaceChanged = false;
322
+ for (const [name, allowed] of Object.entries(allowBuilds)) {
323
+ const current = document.getIn(["allowBuilds", name]);
324
+ if (current !== void 0 && current !== allowed) throw new Error("profile allowBuilds." + name + " is configured as " + JSON.stringify(current) + ", expected " + String(allowed));
325
+ if (current === void 0) {
326
+ document.setIn(["allowBuilds", name], allowed);
327
+ workspaceChanged = true;
328
+ }
329
+ }
330
+ if (manifestChanged) {
331
+ manifest.dependencies = dependencies;
332
+ writeFileSync(manifestPath, JSON.stringify(manifest, void 0, 2) + "\n");
333
+ }
334
+ if (workspaceChanged) writeFileSync(workspacePath, String(document));
335
+ return manifestChanged || workspaceChanged;
336
+ }
337
+ function writeProfileComposition(profileDirectory, bundles, runtimePackages) {
338
+ const path = resolve(profileDirectory, "package.json");
339
+ const manifest = readJsonObject(path, "DSH profile manifest");
340
+ const dependencies = requireObject(manifest.dependencies, "DSH profile dependencies");
341
+ let changed = false;
342
+ for (const runtimePackage of runtimePackages) {
343
+ if (dependencies[runtimePackage.name] === void 0) {
344
+ dependencies[runtimePackage.name] = runtimePackage.version;
345
+ changed = true;
346
+ continue;
347
+ }
348
+ const installed = resolveInstalledPackage(profileDirectory, runtimePackage.name);
349
+ if (installed.version !== runtimePackage.version) throw new Error("profile dependency " + runtimePackage.name + " resolves to " + installed.version + ", but the Plus distribution requires " + runtimePackage.version);
350
+ }
351
+ const dsh = manifest.dsh === void 0 ? {} : requireObject(manifest.dsh, "DSH profile dsh");
352
+ const profile = dsh.profile === void 0 ? {} : requireObject(dsh.profile, "DSH profile dsh.profile");
353
+ if (JSON.stringify(profile.bundles) !== JSON.stringify(bundles)) changed = true;
354
+ manifest.dependencies = dependencies;
355
+ manifest.dsh = {
356
+ ...dsh,
357
+ profile: {
358
+ ...profile,
359
+ bundles: [...bundles]
360
+ }
361
+ };
362
+ if (changed) writeFileSync(path, JSON.stringify(manifest, void 0, 2) + "\n");
363
+ return changed;
364
+ }
365
+ function runPnpm(profileDirectory, args, label) {
366
+ const result = spawnSync("pnpm", args, {
367
+ cwd: profileDirectory,
368
+ stdio: "inherit",
369
+ shell: process.platform === "win32"
370
+ });
371
+ if (result.error !== void 0) throw result.error;
372
+ if (result.status !== 0) throw new Error(label + " failed with exit code " + String(result.status));
373
+ }
374
+ function pendingSourcePatchFiles(patches) {
375
+ return patches.flatMap((patch) => "alreadyApplied" in patch && !patch.alreadyApplied ? [patch.absoluteFile] : []);
376
+ }
377
+ function applySelectedPatches(profileDirectory, dshRoot, patches, profileChanged) {
378
+ const stablePatches = materializePatchFiles(profileDirectory, patches);
379
+ const workspacePath = resolve(profileDirectory, "pnpm-workspace.yaml");
380
+ const workspace = profilePatchConfiguration(profileDirectory, stablePatches);
381
+ if (workspace.changed) writeFileSync(workspacePath, workspace.text);
382
+ if (profileChanged || workspace.changed) runPnpm(profileDirectory, ["install"], "pnpm install in Plus profile");
383
+ const sourceFiles = pendingSourcePatchFiles(stablePatches);
384
+ if (sourceFiles.length > 0) git(dshRoot, ["apply", ...sourceFiles]);
385
+ if (stablePatches.some((patch) => patch.target.kind === "dsh-source")) runPnpm(dshRoot, ["run", "build"], "official DSH build after source patches");
386
+ }
387
+ function linkOfficialPackages(profileDirectory, dshRoot) {
388
+ const source = resolve(dshRoot, "node_modules", "@deepseek-ai");
389
+ if (!existsSync(source)) throw new Error("official DSH dependencies are missing under " + source);
390
+ const destination = resolve(profileDirectory, "node_modules", "@deepseek-ai");
391
+ rmSync(destination, {
392
+ recursive: true,
393
+ force: true
394
+ });
395
+ symlinkSync(source, destination, process.platform === "win32" ? "junction" : "dir");
396
+ }
397
+ function writeLock(profileDirectory, lock) {
398
+ const directory = resolve(profileDirectory, ".dsh-plus");
399
+ mkdirSync(directory, { recursive: true });
400
+ const path = resolve(directory, "patchset.lock.json");
401
+ writeFileSync(path, JSON.stringify(lock, void 0, 2) + "\n", { mode: 384 });
402
+ chmodSync(path, 384);
403
+ return path;
404
+ }
405
+ function parseApplyArguments(argv) {
406
+ if (argv[0] !== "apply") throw new Error("usage: dsh-plus apply --dsh-root <official-dsh-root>");
407
+ let dshRoot;
408
+ for (let index = 1; index < argv.length; index += 2) {
409
+ const key = argv[index];
410
+ const value = argv[index + 1];
411
+ if (key !== "--dsh-root" || value === void 0) throw new Error("usage: dsh-plus apply --dsh-root <official-dsh-root>");
412
+ dshRoot = resolve(value);
413
+ }
414
+ if (dshRoot === void 0) throw new Error("usage: dsh-plus apply --dsh-root <official-dsh-root>");
415
+ return {
416
+ dshRoot,
417
+ profileDirectory: process.cwd()
418
+ };
419
+ }
420
+ /**
421
+ * Apply the installed Plus distribution metadata from a DSH profile directory.
422
+ * @param argv - Explicit `apply --dsh-root <path>` command arguments.
423
+ */
424
+ function runApply(argv) {
425
+ const { dshRoot, profileDirectory } = parseApplyArguments(argv);
426
+ if (requireObject(readJsonObject(resolve(profileDirectory, "package.json"), "DSH profile manifest").dependencies, "DSH profile dependencies")["@sparkelf/dsh-plus"] === void 0) throw new Error("current directory is not a DSH profile with @sparkelf/dsh-plus installed");
427
+ const selection = prepareSelection(dirname(createRequire(resolve(profileDirectory, "package.json")).resolve("@sparkelf/dsh-plus/package.json")), profileDirectory, dshRoot);
428
+ const profileChanged = writeProfileComposition(profileDirectory, selection.bundles, selection.runtimePackages);
429
+ applySelectedPatches(profileDirectory, dshRoot, selection.patches, profileChanged);
430
+ linkOfficialPackages(profileDirectory, dshRoot);
431
+ const installedProfileDependencies = requireObject(readJsonObject(resolve(profileDirectory, "package.json"), "DSH profile manifest").dependencies, "DSH profile dependencies");
432
+ selection.lock.profile = {
433
+ bundles: selection.bundles.map((name) => {
434
+ return {
435
+ name,
436
+ version: (installedProfileDependencies[name] === void 0 ? resolveInstalledPackage(dshRoot, name) : resolveInstalledPackage(profileDirectory, name)).version
437
+ };
438
+ }),
439
+ dependencies: selection.profileDependencies,
440
+ allowBuilds: selection.allowBuilds
441
+ };
442
+ const lock = writeLock(profileDirectory, selection.lock);
443
+ process.stdout.write("[dsh-plus] applied " + String(selection.patches.length) + " patches; lock " + lock + "\n");
444
+ }
445
+ //#endregion
446
+ export { runApply };
package/lib/bin.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { runApply } from "./apply.js";
3
+ //#region lib/types/bin.js
4
+ try {
5
+ runApply(process.argv.slice(2));
6
+ } catch (error) {
7
+ console.error(error instanceof Error ? error.stack : error);
8
+ process.exitCode = 1;
9
+ }
10
+ //#endregion
11
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@sparkelf/dsh-plus`.
4
+ * @module @sparkelf/dsh-plus/invariant
5
+ */
6
+ const PACKAGE_NAME = "@sparkelf/dsh-plus";
7
+ /** Cordis companion plugin name. */
8
+ const name = "plus-bundle-invariant";
9
+ /** Service required before the companion can register. */
10
+ const inject = ["invariants"];
11
+ const install = () => {};
12
+ /**
13
+ * Register this package's invariant companion.
14
+ * @param ctx - Cordis context carrying the invariant service.
15
+ * @returns the installed registration's disposer after setup succeeds.
16
+ */
17
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
18
+ //#endregion
19
+ export { apply, inject, name };
@@ -0,0 +1,7 @@
1
+ /** Materialize the Plus distribution's independent patch packages without Desktop. */
2
+ /**
3
+ * Apply the installed Plus distribution metadata from a DSH profile directory.
4
+ * @param argv - Explicit `apply --dsh-root <path>` command arguments.
5
+ */
6
+ export declare function runApply(argv: readonly string[]): void;
7
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @sparkelf/dsh-plus carries the Plus Web profile composition, ranged
3
+ * compatibility declarations, and independent patch-package references. The
4
+ * profile composer resolves its Cordis patch through the package manifest; the
5
+ * root module exposes no runtime API, while the explicit CLI lives at ./apply.
6
+ * @module @sparkelf/dsh-plus
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@sparkelf/dsh-plus`.
3
+ * @module @sparkelf/dsh-plus/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "plus-bundle-invariant";
8
+ /** Service required before the companion can register. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
package/package.json ADDED
@@ -0,0 +1,117 @@
1
+ {
2
+ "bin": {
3
+ "dsh-plus": "lib/bin.js"
4
+ },
5
+ "dependencies": {
6
+ "@changfenhuang/dsh-genui": ">=0.9.6",
7
+ "@sparkelf/dsh-mobile-bridge": ">=0.2.8",
8
+ "@sparkelf/dsh-patch-better-sidebar-app-frame": ">=0.1.0-rc.10",
9
+ "@sparkelf/dsh-patch-document-attachments": ">=0.1.0-rc.10",
10
+ "@sparkelf/dsh-patch-genui-streaming-echart": ">=0.1.0-rc.10",
11
+ "@sparkelf/dsh-patch-mobile-bridge-serialized-actions": ">=0.1.0-rc.10",
12
+ "@sparkelf/dsh-patch-mobile-web-layout": ">=0.1.0-rc.10",
13
+ "@sparkelf/dsh-patch-responses-reasoning-status": ">=0.1.0-rc.10",
14
+ "@sparkelf/dsh-patch-subagent-settings-presets": ">=0.1.0-rc.10",
15
+ "@sparkelf/dsh-patch-web-base-path": ">=0.1.0-rc.10",
16
+ "@sparkelf/dsh-patch-workspace-storage-restore": ">=0.1.0-rc.10",
17
+ "@sparkelf/dsh-plugin-backup": ">=0.1.0-rc.10",
18
+ "@sparkelf/dsh-plugin-dataops": ">=0.1.0-rc.10",
19
+ "@sparkelf/dsh-plugin-document-attachments": ">=0.1.0-rc.10",
20
+ "@sparkelf/dsh-plugin-mcp-credentials": ">=0.1.0-rc.10",
21
+ "@sparkelf/dsh-plugin-subagent-settings": ">=0.1.0-rc.10",
22
+ "dshmarket": ">=1.29.2",
23
+ "semver": ">=7.7.3",
24
+ "yaml": ">=2.9.0"
25
+ },
26
+ "description": "DeepSeek Harness Plus official-base Web distribution profile and ranged compatibility patchset",
27
+ "devDependencies": {
28
+ "@deepseek-ai/cordis": "^4.0.1",
29
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.1",
30
+ "@types/semver": ">=7.7.1",
31
+ "dsh-better-sidebar": "0.17.1"
32
+ },
33
+ "dsh": {
34
+ "bundle": {
35
+ "patch": "./cordis.patch.yml"
36
+ }
37
+ },
38
+ "dshPlus": {
39
+ "compatibility": {
40
+ "dsh": ">=0.1.2-alpha.1"
41
+ },
42
+ "formatVersion": 1,
43
+ "patchPackages": [
44
+ "@sparkelf/dsh-patch-better-sidebar-app-frame",
45
+ "@sparkelf/dsh-patch-genui-streaming-echart",
46
+ "@sparkelf/dsh-patch-mobile-bridge-serialized-actions",
47
+ "@sparkelf/dsh-patch-workspace-storage-restore",
48
+ "@sparkelf/dsh-patch-subagent-settings-presets",
49
+ "@sparkelf/dsh-patch-document-attachments",
50
+ "@sparkelf/dsh-patch-responses-reasoning-status",
51
+ "@sparkelf/dsh-patch-mobile-web-layout",
52
+ "@sparkelf/dsh-patch-web-base-path"
53
+ ],
54
+ "profile": {
55
+ "allowBuilds": {
56
+ "node-pty": true
57
+ },
58
+ "bundles": [
59
+ "@deepseek-ai/dsh-base",
60
+ "@deepseek-ai/dsh-web-app",
61
+ "dsh-better-sidebar",
62
+ "@sparkelf/dsh-mobile-bridge",
63
+ "dshmarket",
64
+ "@changfenhuang/dsh-genui",
65
+ "@sparkelf/dsh-plus"
66
+ ],
67
+ "dependencies": {
68
+ "dsh-better-sidebar": "0.17.1"
69
+ }
70
+ },
71
+ "sourceBase": {
72
+ "revision": "cd5ef8148158c3a752a658978873241fdf8e2bbc"
73
+ }
74
+ },
75
+ "exports": {
76
+ ".": {
77
+ "default": "./lib/index.js",
78
+ "types": "./lib/types/index.d.ts"
79
+ },
80
+ "./apply": {
81
+ "default": "./lib/apply.js",
82
+ "types": "./lib/types/apply.d.ts"
83
+ },
84
+ "./cordis.patch.yml": "./cordis.patch.yml",
85
+ "./invariant": {
86
+ "default": "./lib/invariant.js",
87
+ "types": "./lib/types/invariant.d.ts"
88
+ },
89
+ "./package.json": "./package.json"
90
+ },
91
+ "files": [
92
+ "lib/index.js",
93
+ "lib/invariant.js",
94
+ "lib/bin.js",
95
+ "cordis.patch.yml",
96
+ "lib/apply.js",
97
+ "lib/types/**/*.d.ts"
98
+ ],
99
+ "license": "MIT",
100
+ "main": "lib/index.js",
101
+ "name": "@sparkelf/dsh-plus",
102
+ "peerDependencies": {
103
+ "@deepseek-ai/cordis": ">=4.0.1",
104
+ "@deepseek-ai/dsh-invariants": ">=0.1.2-alpha.1"
105
+ },
106
+ "publishConfig": {
107
+ "access": "public"
108
+ },
109
+ "repository": {
110
+ "directory": "packages/bundle/plus",
111
+ "type": "git",
112
+ "url": "git+https://github.com/SparkElf/deepseek-harness-plus.git"
113
+ },
114
+ "type": "module",
115
+ "types": "lib/types/index.d.ts",
116
+ "version": "0.1.0-rc.10"
117
+ }