dsh-client-auto-continue 0.3.1 → 0.4.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.
- package/README.md +45 -10
- package/README.zh.md +43 -8
- package/docs/banner-dark.svg +1 -25
- package/docs/banner-zh-dark.svg +1 -25
- package/docs/banner-zh.svg +1 -25
- package/docs/banner.svg +1 -25
- package/docs/demo-zh.svg +1 -50
- package/docs/demo.svg +1 -50
- package/docs/social-preview.png +0 -0
- package/docs/social-preview.svg +1 -43
- package/lib/client.js +6 -3
- package/lib/client.js.map +2 -2
- package/lib/types/client/locales.d.ts +1 -0
- package/lib/types/client/settings-card.d.ts +3 -3
- package/package.json +1 -1
- package/scripts/patch-expose.mjs +69 -33
package/scripts/patch-expose.mjs
CHANGED
|
@@ -2,20 +2,25 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Vendor patch for a known DSH limitation (0.1.0-rc.6):
|
|
4
4
|
*
|
|
5
|
-
* The web
|
|
6
|
-
*
|
|
7
|
-
* `@deepseek-ai/dsh-host-apiproxy` bundle
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* The web settings surface only exposes namespaces listed in the hardcoded
|
|
6
|
+
* `WEB_SETTINGS_NAMESPACES` / `PRODUCT_SETTINGS_NAMESPACES` allowlists inside
|
|
7
|
+
* the installed `@deepseek-ai/dsh-host-apiproxy` bundle. Any other registered
|
|
8
|
+
* namespace answers `settings-not-exposed`, so a third-party plugin's settings
|
|
9
|
+
* section renders nothing even though its namespace registered fine (the
|
|
10
|
+
* proxy's own comment calls moving exposure into `settings.register()` "deferred
|
|
11
|
+
* work").
|
|
12
12
|
*
|
|
13
|
-
* This script
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
13
|
+
* This script makes the exposure REGISTRY-DRIVEN instead of hardcoded: it
|
|
14
|
+
* patches `exposedNamespaces()` to also expose every namespace currently
|
|
15
|
+
* registered with the settings provider. The patch contains NO plugin-specific
|
|
16
|
+
* string, so the settings of ANY plugin that registers a namespace (and mounts
|
|
17
|
+
* its own settings section) appear automatically — this plugin included.
|
|
18
|
+
*
|
|
19
|
+
* It is applied to every reachable dsh installation: the profile-linked copy
|
|
20
|
+
* (pnpm store / npx cache), a global `npm i -g @deepseek-ai/dsh` install under
|
|
21
|
+
* the active Node version, and the invoking directory's own install. Re-run it
|
|
22
|
+
* after any dsh reinstall; it is idempotent and also removes the previous
|
|
23
|
+
* per-plugin allowlist entry (pre-0.4.0 installs).
|
|
19
24
|
*
|
|
20
25
|
* Usage: node scripts/patch-expose.mjs
|
|
21
26
|
*/
|
|
@@ -24,13 +29,22 @@ import { readFileSync, writeFileSync, realpathSync } from 'node:fs';
|
|
|
24
29
|
import { dirname, join } from 'node:path';
|
|
25
30
|
import { homedir } from 'node:os';
|
|
26
31
|
|
|
27
|
-
/** The
|
|
28
|
-
const
|
|
32
|
+
/** The registry-driven patch: expose every namespace the provider knows. */
|
|
33
|
+
const GENERIC_ADD = `\t\tconst settings = ctx.get("settings");
|
|
34
|
+
\t\tif (settings !== void 0) for (const descriptor of settings.describe()) exposed.add(String(descriptor.ns));`;
|
|
35
|
+
|
|
36
|
+
/** Marker proving the generic patch is already applied. */
|
|
37
|
+
const GENERIC_MARKER = 'for (const descriptor of settings.describe()) exposed.add(String(descriptor.ns))';
|
|
38
|
+
|
|
39
|
+
/** The hardcoded allowlist tail, as shipped (and as the old patch rewrote it). */
|
|
40
|
+
const ARRAY_TAIL_PLAIN = `\t"web-search-deepseek"\n];`;
|
|
41
|
+
const ARRAY_TAIL_OLD_PATCH = `\t"web-search-deepseek",\n\t"auto-continue"\n];`;
|
|
29
42
|
|
|
30
43
|
/**
|
|
31
44
|
* Collect candidate dsh-host-apiproxy package.json paths: the profile-linked
|
|
32
|
-
* copy, a global install under the active Node version
|
|
33
|
-
*
|
|
45
|
+
* copy, a global install under the active Node version's nvm layout
|
|
46
|
+
* (`<nvm>/<version>/lib/node_modules/@deepseek-ai/dsh`), and the invoking
|
|
47
|
+
* directory's own install. Deduplicated by real path.
|
|
34
48
|
*/
|
|
35
49
|
function candidatePackageJsons() {
|
|
36
50
|
const found = new Set();
|
|
@@ -51,8 +65,7 @@ function candidatePackageJsons() {
|
|
|
51
65
|
|
|
52
66
|
// 1. The copy the profile's node_modules links to.
|
|
53
67
|
tryResolve(createRequire(join(homedir(), '.dsh', 'profiles', 'web', 'package.json')));
|
|
54
|
-
// 2. A global install under the active Node version's nvm layout
|
|
55
|
-
// (`<nvm>/<version>/lib/node_modules/@deepseek-ai/dsh`).
|
|
68
|
+
// 2. A global install under the active Node version's nvm layout.
|
|
56
69
|
try {
|
|
57
70
|
const globalRoot = realpathSync(join(process.execPath, '..', '..', 'lib', 'node_modules'));
|
|
58
71
|
tryResolve(createRequire(join(globalRoot, '@deepseek-ai', 'dsh', 'package.json')));
|
|
@@ -70,23 +83,46 @@ if (candidates.length === 0) {
|
|
|
70
83
|
process.exit(1);
|
|
71
84
|
}
|
|
72
85
|
|
|
73
|
-
let
|
|
86
|
+
let changedAny = false;
|
|
74
87
|
for (const packageJson of candidates) {
|
|
75
88
|
const bundlePath = join(dirname(packageJson), 'lib', 'index.js');
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
let source = readFileSync(bundlePath, 'utf8');
|
|
90
|
+
let changed = false;
|
|
91
|
+
|
|
92
|
+
// 1. Remove the previous per-plugin allowlist entry (pre-0.4.0 installs).
|
|
93
|
+
if (source.includes(ARRAY_TAIL_OLD_PATCH)) {
|
|
94
|
+
source = source.replace(ARRAY_TAIL_OLD_PATCH, ARRAY_TAIL_PLAIN);
|
|
95
|
+
changed = true;
|
|
96
|
+
console.log(`[patch-expose] removed per-plugin allowlist entry in ${bundlePath}`);
|
|
80
97
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
|
|
99
|
+
// 2. Make exposure registry-driven (idempotent).
|
|
100
|
+
if (!source.includes(GENERIC_MARKER)) {
|
|
101
|
+
const fnStart = source.indexOf('\tfunction exposedNamespaces() {');
|
|
102
|
+
if (fnStart === -1) {
|
|
103
|
+
console.error(`[patch-expose] could not locate exposedNamespaces() in ${bundlePath}`);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const fnEnd = source.indexOf('\t}', fnStart);
|
|
107
|
+
if (fnEnd === -1) {
|
|
108
|
+
console.error(`[patch-expose] could not locate the end of exposedNamespaces() in ${bundlePath}`);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const body = source.slice(fnStart, fnEnd);
|
|
112
|
+
if (!body.includes('return exposed;')) {
|
|
113
|
+
console.error(`[patch-expose] unexpected exposedNamespaces() body in ${bundlePath}`);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const patchedBody = body.replace('\t\treturn exposed;', `${GENERIC_ADD}\n\t\treturn exposed;`);
|
|
117
|
+
source = source.slice(0, fnStart) + patchedBody + source.slice(fnEnd);
|
|
118
|
+
changed = true;
|
|
119
|
+
console.log(`[patch-expose] made exposure registry-driven in ${bundlePath}`);
|
|
120
|
+
} else {
|
|
121
|
+
console.log(`[patch-expose] registry-driven exposure already present in ${bundlePath} — skipped.`);
|
|
85
122
|
}
|
|
86
|
-
|
|
87
|
-
writeFileSync(bundlePath,
|
|
88
|
-
|
|
89
|
-
console.log(`[patch-expose] added "${NS}" to WEB_SETTINGS_NAMESPACES in ${bundlePath}`);
|
|
123
|
+
|
|
124
|
+
if (changed) writeFileSync(bundlePath, source);
|
|
125
|
+
changedAny = changedAny || changed;
|
|
90
126
|
}
|
|
91
127
|
|
|
92
|
-
if (
|
|
128
|
+
if (changedAny) console.log('[patch-expose] restart `dsh web` for the change to take effect.');
|