dsh-client-auto-continue 0.6.2 → 0.7.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 +16 -23
- package/README.zh.md +16 -18
- package/lib/client.js +210 -12
- package/lib/client.js.map +2 -2
- package/lib/index.js +11 -1
- package/lib/types/client/engine.d.ts +27 -0
- package/lib/types/client/locales.d.ts +11 -0
- package/lib/types/client/settings-card.d.ts +5 -0
- package/lib/types/index.d.ts +20 -0
- package/package.json +1 -4
- package/src/client/engine.ts +154 -7
- package/src/client/locales.ts +22 -0
- package/src/client/settings-card.tsx +65 -1
- package/src/index.ts +12 -0
- package/scripts/patch-expose.mjs +0 -133
package/scripts/patch-expose.mjs
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Vendor patch for a known DSH limitation (0.1.0-rc.6 and earlier):
|
|
4
|
-
*
|
|
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
|
-
*
|
|
13
|
-
* Since DSH 0.1.0-rc.7 upstream made exposure REGISTRY-DRIVEN, so this script
|
|
14
|
-
* is a no-op there (it detects the missing function and reports accordingly).
|
|
15
|
-
* On rc.6 and earlier it patches `exposedNamespaces()` to also expose every
|
|
16
|
-
* namespace currently registered with the settings provider. The patch
|
|
17
|
-
* contains NO plugin-specific string, so the settings of ANY plugin that
|
|
18
|
-
* registers a namespace (and mounts its own settings section) appear
|
|
19
|
-
* automatically — this plugin included.
|
|
20
|
-
*
|
|
21
|
-
* It is applied to every reachable dsh installation: the profile-linked copy
|
|
22
|
-
* (pnpm store / npx cache), a global `npm i -g @deepseek-ai/dsh` install under
|
|
23
|
-
* the active Node version, and the invoking directory's own install. Re-run it
|
|
24
|
-
* after any dsh reinstall; it is idempotent and also removes the previous
|
|
25
|
-
* per-plugin allowlist entry (pre-0.4.0 installs).
|
|
26
|
-
*
|
|
27
|
-
* Usage: node scripts/patch-expose.mjs
|
|
28
|
-
*/
|
|
29
|
-
import { createRequire } from 'node:module';
|
|
30
|
-
import { readFileSync, writeFileSync, realpathSync } from 'node:fs';
|
|
31
|
-
import { dirname, join } from 'node:path';
|
|
32
|
-
import { homedir } from 'node:os';
|
|
33
|
-
|
|
34
|
-
/** The registry-driven patch: expose every namespace the provider knows. */
|
|
35
|
-
const GENERIC_ADD = `\t\tconst settings = ctx.get("settings");
|
|
36
|
-
\t\tif (settings !== void 0) for (const descriptor of settings.describe()) exposed.add(String(descriptor.ns));`;
|
|
37
|
-
|
|
38
|
-
/** Marker proving the generic patch is already applied. */
|
|
39
|
-
const GENERIC_MARKER = 'for (const descriptor of settings.describe()) exposed.add(String(descriptor.ns))';
|
|
40
|
-
|
|
41
|
-
/** The hardcoded allowlist tail, as shipped (and as the old patch rewrote it). */
|
|
42
|
-
const ARRAY_TAIL_PLAIN = `\t"web-search-deepseek"\n];`;
|
|
43
|
-
const ARRAY_TAIL_OLD_PATCH = `\t"web-search-deepseek",\n\t"auto-continue"\n];`;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Collect candidate dsh-host-apiproxy package.json paths: the profile-linked
|
|
47
|
-
* copy, a global install under the active Node version's nvm layout
|
|
48
|
-
* (`<nvm>/<version>/lib/node_modules/@deepseek-ai/dsh`), and the invoking
|
|
49
|
-
* directory's own install. Deduplicated by real path.
|
|
50
|
-
*/
|
|
51
|
-
function candidatePackageJsons() {
|
|
52
|
-
const found = new Set();
|
|
53
|
-
const add = (pkgJson) => {
|
|
54
|
-
try {
|
|
55
|
-
found.add(realpathSync(pkgJson));
|
|
56
|
-
} catch {
|
|
57
|
-
/* candidate not present */
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const tryResolve = (requireFn) => {
|
|
61
|
-
try {
|
|
62
|
-
add(requireFn.resolve('@deepseek-ai/dsh-host-apiproxy/package.json'));
|
|
63
|
-
} catch {
|
|
64
|
-
/* not resolvable from this anchor */
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// 1. The copy the profile's node_modules links to.
|
|
69
|
-
tryResolve(createRequire(join(homedir(), '.dsh', 'profiles', 'web', 'package.json')));
|
|
70
|
-
// 2. A global install under the active Node version's nvm layout.
|
|
71
|
-
try {
|
|
72
|
-
const globalRoot = realpathSync(join(process.execPath, '..', '..', 'lib', 'node_modules'));
|
|
73
|
-
tryResolve(createRequire(join(globalRoot, '@deepseek-ai', 'dsh', 'package.json')));
|
|
74
|
-
} catch {
|
|
75
|
-
/* not an nvm-style global root */
|
|
76
|
-
}
|
|
77
|
-
// 3. The invoking directory's own install.
|
|
78
|
-
tryResolve(createRequire(join(process.cwd(), 'package.json')));
|
|
79
|
-
return [...found];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const candidates = candidatePackageJsons();
|
|
83
|
-
if (candidates.length === 0) {
|
|
84
|
-
console.error('[patch-expose] could not resolve any @deepseek-ai/dsh-host-apiproxy installation');
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
let changedAny = false;
|
|
89
|
-
for (const packageJson of candidates) {
|
|
90
|
-
const bundlePath = join(dirname(packageJson), 'lib', 'index.js');
|
|
91
|
-
let source = readFileSync(bundlePath, 'utf8');
|
|
92
|
-
let changed = false;
|
|
93
|
-
|
|
94
|
-
// 1. Remove the previous per-plugin allowlist entry (pre-0.4.0 installs).
|
|
95
|
-
if (source.includes(ARRAY_TAIL_OLD_PATCH)) {
|
|
96
|
-
source = source.replace(ARRAY_TAIL_OLD_PATCH, ARRAY_TAIL_PLAIN);
|
|
97
|
-
changed = true;
|
|
98
|
-
console.log(`[patch-expose] removed per-plugin allowlist entry in ${bundlePath}`);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// 2. Make exposure registry-driven (idempotent).
|
|
102
|
-
if (!source.includes(GENERIC_MARKER)) {
|
|
103
|
-
const fnStart = source.indexOf('\tfunction exposedNamespaces() {');
|
|
104
|
-
if (fnStart === -1) {
|
|
105
|
-
// DSH ≥ 0.1.0-rc.7 已把设置暴露改为注册表驱动, 没有这个函数也不需要补丁。
|
|
106
|
-
console.log(
|
|
107
|
-
`[patch-expose] ${bundlePath}: DSH ≥ 0.1.0-rc.7 已原生支持 registry-driven 设置暴露, 无需补丁 — skipped.`,
|
|
108
|
-
);
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
const fnEnd = source.indexOf('\t}', fnStart);
|
|
112
|
-
if (fnEnd === -1) {
|
|
113
|
-
console.error(`[patch-expose] could not locate the end of exposedNamespaces() in ${bundlePath}`);
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
const body = source.slice(fnStart, fnEnd);
|
|
117
|
-
if (!body.includes('return exposed;')) {
|
|
118
|
-
console.error(`[patch-expose] unexpected exposedNamespaces() body in ${bundlePath}`);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
const patchedBody = body.replace('\t\treturn exposed;', `${GENERIC_ADD}\n\t\treturn exposed;`);
|
|
122
|
-
source = source.slice(0, fnStart) + patchedBody + source.slice(fnEnd);
|
|
123
|
-
changed = true;
|
|
124
|
-
console.log(`[patch-expose] made exposure registry-driven in ${bundlePath}`);
|
|
125
|
-
} else {
|
|
126
|
-
console.log(`[patch-expose] registry-driven exposure already present in ${bundlePath} — skipped.`);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (changed) writeFileSync(bundlePath, source);
|
|
130
|
-
changedAny = changedAny || changed;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (changedAny) console.log('[patch-expose] restart `dsh web` for the change to take effect.');
|