dsh-client-auto-continue 0.6.2 → 0.6.3
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 +3 -21
- package/README.zh.md +3 -16
- package/package.json +1 -4
- package/scripts/patch-expose.mjs +0 -133
package/README.md
CHANGED
|
@@ -75,6 +75,8 @@ All knobs live in the plugin's settings card — see [Configuration](#configurat
|
|
|
75
75
|
|
|
76
76
|
DSH plugins install into a **profile** (`dsh web` → `web` profile). Install, restart `dsh web`, done.
|
|
77
77
|
|
|
78
|
+
> **Requires DSH ≥ 0.1.0-rc.7** — newer versions register the settings card through the keyed `settings.plugin.item` slot; on rc.6 and earlier the plugin fails to load (`list slot ... requires options.id`). Upgrade dsh first.
|
|
79
|
+
|
|
78
80
|
### From npm (recommended)
|
|
79
81
|
|
|
80
82
|
Published as [`dsh-client-auto-continue`](https://www.npmjs.com/package/dsh-client-auto-continue):
|
|
@@ -125,27 +127,7 @@ dsh web
|
|
|
125
127
|
|
|
126
128
|
> Switching from a manual install to `dsh plugin add`? Remove the manual `insert` entry first — the bundle patch registers the row and a duplicate would conflict.
|
|
127
129
|
|
|
128
|
-
> **
|
|
129
|
-
> — every namespace a plugin registers is served to the web settings surface,
|
|
130
|
-
> so the settings card just works, no vendor patch needed. Only DSH 0.1.0-rc.6
|
|
131
|
-
> and earlier gate exposure behind a hardcoded allowlist in
|
|
132
|
-
> `@deepseek-ai/dsh-host-apiproxy`; on those versions, run the idempotent
|
|
133
|
-
> vendor patch once (and re-run after reinstalling dsh):
|
|
134
|
-
>
|
|
135
|
-
> ```sh
|
|
136
|
-
> npx --yes --package dsh-client-auto-continue patch-expose
|
|
137
|
-
> dsh web
|
|
138
|
-
> ```
|
|
139
|
-
>
|
|
140
|
-
> The patch script ships inside the npm package as a `bin` (works from any
|
|
141
|
-
> directory in a fresh environment — no repo clone, no profile-path guessing)
|
|
142
|
-
> and covers every reachable dsh installation: the profile-linked copy, a
|
|
143
|
-
> global `npm i -g @deepseek-ai/dsh` install, and the invoking directory's
|
|
144
|
-
> own. If you installed from this repository instead, the same script is
|
|
145
|
-
> `node scripts/patch-expose.mjs` at the repo root. The auto-continue engine
|
|
146
|
-
> itself works without this patch — it only gates the GUI settings section;
|
|
147
|
-
> on rc.6 and earlier, configure everything directly in `~/.dsh/settings.yaml`
|
|
148
|
-
> (see [Configuration](#configuration)).
|
|
130
|
+
> **Settings exposure:** since DSH 0.1.0-rc.7 the web settings surface is **registry-driven** — every namespace a plugin registers is served, so the settings card works out of the box, no vendor patch needed (the plugin requires rc.7+, see Quick Start).
|
|
149
131
|
|
|
150
132
|
### Verify & uninstall
|
|
151
133
|
|
package/README.zh.md
CHANGED
|
@@ -75,6 +75,8 @@
|
|
|
75
75
|
|
|
76
76
|
DSH 插件安装进 **profile**(`dsh web` 对应 `web` profile)。安装后重启 `dsh web` 即可。
|
|
77
77
|
|
|
78
|
+
> **要求 DSH ≥ 0.1.0-rc.7** — 新版本通过 keyed 的 `settings.plugin.item` 槽位注册设置卡片; 在 rc.6 及更早版本上插件会加载失败(`list slot ... requires options.id`), 请先升级 dsh。
|
|
79
|
+
|
|
78
80
|
### 从 npm 安装(推荐)
|
|
79
81
|
|
|
80
82
|
已发布为 [`dsh-client-auto-continue`](https://www.npmjs.com/package/dsh-client-auto-continue):
|
|
@@ -125,22 +127,7 @@ dsh web
|
|
|
125
127
|
|
|
126
128
|
> 从手动安装切换到 `dsh plugin add` 时, 请先删掉手动加的 `insert` 条目——包自带的 bundle patch 会注册插件行, 重复注册会冲突。
|
|
127
129
|
|
|
128
|
-
>
|
|
129
|
-
> 任何命名空间都会直接出现在 webui 设置区, 设置卡片开箱即用, 无需任何供应商补丁。
|
|
130
|
-
> 仅 DSH 0.1.0-rc.6 及更早版本仍在 `@deepseek-ai/dsh-host-apiproxy` 里用硬编码白名单
|
|
131
|
-
> 门禁暴露; 这些版本需要执行一次幂等的供应商补丁(重新安装 dsh 后重跑):
|
|
132
|
-
>
|
|
133
|
-
> ```sh
|
|
134
|
-
> npx --yes --package dsh-client-auto-continue patch-expose
|
|
135
|
-
> dsh web
|
|
136
|
-
> ```
|
|
137
|
-
>
|
|
138
|
-
> 补丁脚本随 npm 包以 `bin` 形式发布(全新环境下任意目录都能直接执行, 无需克隆仓库、
|
|
139
|
-
> 无需猜测 profile 路径), 并覆盖所有可达的 dsh 安装: profile 链接副本、全局
|
|
140
|
-
> `npm i -g @deepseek-ai/dsh` 安装、以及当前目录的安装。若是从本仓库安装,
|
|
141
|
-
> 同一脚本在仓库根目录执行 `node scripts/patch-expose.mjs` 即可。自动续跑引擎
|
|
142
|
-
> 本身不依赖这个补丁——它只影响 GUI 设置区是否可见; 在 rc.6 及更早版本上,
|
|
143
|
-
> 可以直接在 `~/.dsh/settings.yaml` 里配置全部参数(见 [配置](#配置))。
|
|
130
|
+
> **设置暴露:** DSH 0.1.0-rc.7 起 webui 设置区是**注册表驱动**的——插件注册的命名空间直接可见, 设置卡片开箱即用, 无需任何供应商补丁(插件要求 rc.7+, 见快速开始)。
|
|
144
131
|
|
|
145
132
|
### 验证与卸载
|
|
146
133
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-client-auto-continue",
|
|
3
3
|
"description": "DSH Web UI plugin: automatically sends \"继续\" (continue) when a request is interrupted by network errors or other non-human causes",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -84,8 +84,5 @@
|
|
|
84
84
|
"@deepseek-ai/dsh-settings": "^0.1.0-rc.7",
|
|
85
85
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
86
86
|
"@deepseek-ai/cordis": "^4.0.1"
|
|
87
|
-
},
|
|
88
|
-
"bin": {
|
|
89
|
-
"patch-expose": "./scripts/patch-expose.mjs"
|
|
90
87
|
}
|
|
91
88
|
}
|
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.');
|