dsh-client-auto-continue 0.2.1 → 0.2.2
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 +8 -62
- package/README.zh.md +7 -61
- package/package.json +2 -1
- package/scripts/patch-expose.mjs +92 -0
package/README.md
CHANGED
|
@@ -100,15 +100,19 @@ dsh web
|
|
|
100
100
|
|
|
101
101
|
> **Known DSH limitation (0.1.0-rc.6):** the web plugin-configuration section only
|
|
102
102
|
> exposes settings namespaces on a hardcoded allowlist in the installed
|
|
103
|
-
> `@deepseek-ai/dsh-host-apiproxy` bundle.
|
|
104
|
-
>
|
|
103
|
+
> `@deepseek-ai/dsh-host-apiproxy` bundle. Until upstream moves exposure into
|
|
104
|
+
> `settings.register()`, one idempotent vendor patch is required for the
|
|
105
|
+
> settings card to appear (re-run it after reinstalling dsh):
|
|
105
106
|
>
|
|
106
107
|
> ```sh
|
|
107
|
-
> node scripts/patch-expose.mjs
|
|
108
|
+
> node node_modules/dsh-client-auto-continue/scripts/patch-expose.mjs
|
|
108
109
|
> dsh web
|
|
109
110
|
> ```
|
|
110
111
|
>
|
|
111
|
-
> The
|
|
112
|
+
> The patch script ships inside the npm package (no repo clone needed) and
|
|
113
|
+
> covers every reachable dsh installation: the profile-linked copy, a global
|
|
114
|
+
> `npm i -g @deepseek-ai/dsh` install, and the invoking directory's own. The
|
|
115
|
+
> auto-continue engine itself works without this patch — it only gates the
|
|
112
116
|
> GUI settings card.
|
|
113
117
|
|
|
114
118
|
### Verify & uninstall
|
|
@@ -146,36 +150,6 @@ Everything is configurable from the GUI — no file or console edits needed. Ope
|
|
|
146
150
|
|
|
147
151
|
---
|
|
148
152
|
|
|
149
|
-
## Tech Stack & Structure
|
|
150
|
-
|
|
151
|
-
| Layer | Choice |
|
|
152
|
-
| --- | --- |
|
|
153
|
-
| Platform | DSH Web GUI client plugin (browser half + host half registering the settings namespace) |
|
|
154
|
-
| Language | TypeScript |
|
|
155
|
-
| Build | esbuild (browser bundle + node half) + tsc declarations |
|
|
156
|
-
| Runtime deps | Browser bundle: `react` (platform seed) + `createSnapshotStore` (module table); host half: `schemastery` + `dsh-settings` (resolved from the dsh installation) |
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
dsh-auto-continue/
|
|
160
|
-
├── package.json # plugin manifest (dsh.client / dsh.bundle)
|
|
161
|
-
├── cordis.patch.yml # profile patch layer: registers the plugin row
|
|
162
|
-
├── build.mjs # esbuild build (browser bundle + node half)
|
|
163
|
-
├── tsconfig.json / tsconfig.build.json
|
|
164
|
-
├── src/
|
|
165
|
-
│ ├── index.ts # host half: registers the auto-continue settings namespace
|
|
166
|
-
│ └── client/
|
|
167
|
-
│ ├── index.ts # browser half entry: engine + settings card wiring
|
|
168
|
-
│ ├── engine.ts # the auto-continue engine (reads the settings scope)
|
|
169
|
-
│ ├── settings-card.tsx / settings-form.ts / locales.ts / styles.ts
|
|
170
|
-
│ └── # settings card UI (staged form, zh/en copy, theme styles)
|
|
171
|
-
├── tests/simulate.mjs # headless behavioral tests (mock API + settings scope)
|
|
172
|
-
├── lib/ # build output (committed, ready to link)
|
|
173
|
-
├── docs/ # banner artwork (en + zh)
|
|
174
|
-
└── README.md / README.zh.md / LICENSE
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
153
|
## Development
|
|
180
154
|
|
|
181
155
|
```bash
|
|
@@ -189,36 +163,8 @@ While `npm run watch` runs, the profile's client-hmr row polls `lib/client.js` e
|
|
|
189
163
|
|
|
190
164
|
---
|
|
191
165
|
|
|
192
|
-
|
|
193
|
-
## Publishing
|
|
194
|
-
|
|
195
|
-
Tagging `v<version>` (matching `package.json`) triggers the publish workflow:
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
git tag v0.2.1
|
|
199
|
-
git push origin v0.2.1
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
The CI (`.github/workflows/publish.yml`) then:
|
|
203
|
-
|
|
204
|
-
1. Verifies the tag matches `package.json` version
|
|
205
|
-
2. Installs dependencies, builds (`npm run build`) and runs the test suite
|
|
206
|
-
3. Publishes the package to npm (`dsh-client-auto-continue`)
|
|
207
|
-
4. Creates a GitHub Release with the packed tarball and built artifacts
|
|
208
|
-
(`lib/client.js`, `lib/client.js.map`, `lib/index.js`) attached
|
|
209
|
-
|
|
210
|
-
The workflow requires the `NPM_TOKEN` repository secret (an npm automation
|
|
211
|
-
token with publish scope):
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
gh secret set NPM_TOKEN --repo HsiangNianian/dsh-auto-continue
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
166
|
## Links
|
|
220
167
|
|
|
221
|
-
|
|
222
168
|
- **Repository**: [github.com/HsiangNianian/dsh-auto-continue](https://github.com/HsiangNianian/dsh-auto-continue)
|
|
223
169
|
- **DeepSeek Harness**: [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
224
170
|
|
package/README.zh.md
CHANGED
|
@@ -99,15 +99,18 @@ dsh web
|
|
|
99
99
|
> 从手动安装切换到 `dsh plugin add` 时, 请先删掉手动加的 `insert` 条目——包自带的 bundle patch 会注册插件行, 重复注册会冲突。
|
|
100
100
|
|
|
101
101
|
> **已知 DSH 限制(0.1.0-rc.6):** webui 的插件配置区只暴露已安装
|
|
102
|
-
> `@deepseek-ai/dsh-host-apiproxy`
|
|
103
|
-
>
|
|
102
|
+
> `@deepseek-ai/dsh-host-apiproxy` 包中硬编码白名单里的设置命名空间。在官方把暴露
|
|
103
|
+
> 逻辑移入 `settings.register()` 之前, 要让设置卡片显示出来, 需要执行一次幂等的
|
|
104
|
+
> 供应商补丁(重新安装 dsh 后重跑一次即可):
|
|
104
105
|
>
|
|
105
106
|
> ```sh
|
|
106
|
-
> node scripts/patch-expose.mjs
|
|
107
|
+
> node node_modules/dsh-client-auto-continue/scripts/patch-expose.mjs
|
|
107
108
|
> dsh web
|
|
108
109
|
> ```
|
|
109
110
|
>
|
|
110
|
-
>
|
|
111
|
+
> 补丁脚本随 npm 包一起发布(无需克隆仓库), 并覆盖所有可达的 dsh 安装: profile
|
|
112
|
+
> 链接副本、全局 `npm i -g @deepseek-ai/dsh` 安装、以及当前目录的安装。自动续跑
|
|
113
|
+
> 引擎本身不依赖这个补丁——它只影响 GUI 设置卡片是否可见。
|
|
111
114
|
|
|
112
115
|
### 验证与卸载
|
|
113
116
|
|
|
@@ -144,36 +147,6 @@ dsh web
|
|
|
144
147
|
|
|
145
148
|
---
|
|
146
149
|
|
|
147
|
-
## 技术栈与结构
|
|
148
|
-
|
|
149
|
-
| 分层 | 选型 |
|
|
150
|
-
| --- | --- |
|
|
151
|
-
| 平台 | DSH Web GUI 客户端插件(浏览器半区 + 注册设置命名空间的宿主半区) |
|
|
152
|
-
| 语言 | TypeScript |
|
|
153
|
-
| 构建 | esbuild(浏览器包 + 宿主半区)+ tsc 声明文件 |
|
|
154
|
-
| 运行时依赖 | 浏览器包: `react`(平台种子)+ `createSnapshotStore`(模块表); 宿主半区: `schemastery` + `dsh-settings`(由 dsh 安装解析) |
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
dsh-auto-continue/
|
|
158
|
-
├── package.json # 插件清单(dsh.client / dsh.bundle)
|
|
159
|
-
├── cordis.patch.yml # profile 补丁层: 注册插件行
|
|
160
|
-
├── build.mjs # esbuild 构建(浏览器包 + 宿主半区)
|
|
161
|
-
├── tsconfig.json / tsconfig.build.json
|
|
162
|
-
├── src/
|
|
163
|
-
│ ├── index.ts # host 半区: 注册 auto-continue 设置命名空间
|
|
164
|
-
│ └── client/
|
|
165
|
-
│ ├── index.ts # browser 半区入口: 引擎 + 设置卡片接线
|
|
166
|
-
│ ├── engine.ts # 自动续跑引擎(读取设置作用域)
|
|
167
|
-
│ ├── settings-card.tsx / settings-form.ts / locales.ts / styles.ts
|
|
168
|
-
│ └── # 设置卡片 UI(暂存表单、中英文案、主题样式)
|
|
169
|
-
├── tests/simulate.mjs # 无头行为测试(模拟 API + 设置作用域)
|
|
170
|
-
├── lib/ # 构建产物(已提交, 可直接链接)
|
|
171
|
-
├── docs/ # banner 图(英文 + 中文)
|
|
172
|
-
└── README.md / README.zh.md / LICENSE
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
150
|
## 开发
|
|
178
151
|
|
|
179
152
|
```bash
|
|
@@ -187,35 +160,8 @@ npm run test # node tests/simulate.mjs — 8 个行为场景
|
|
|
187
160
|
|
|
188
161
|
---
|
|
189
162
|
|
|
190
|
-
|
|
191
|
-
## 发布
|
|
192
|
-
|
|
193
|
-
打一个与 `package.json` 版本一致的 `v<version>` tag, 即可触发发布流水线:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
git tag v0.2.1
|
|
197
|
-
git push origin v0.2.1
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
CI(`.github/workflows/publish.yml`)会依次:
|
|
201
|
-
|
|
202
|
-
1. 校验 tag 与 `package.json` 版本一致
|
|
203
|
-
2. 安装依赖、构建(`npm run build`)并跑测试套件
|
|
204
|
-
3. 发布到 npm(`dsh-client-auto-continue`)
|
|
205
|
-
4. 创建 GitHub Release, 附带打包好的 tarball 与构建产物
|
|
206
|
-
(`lib/client.js`、`lib/client.js.map`、`lib/index.js`)
|
|
207
|
-
|
|
208
|
-
流水线依赖仓库的 `NPM_TOKEN` secret(带 publish 权限的 npm automation token):
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
gh secret set NPM_TOKEN --repo HsiangNianian/dsh-auto-continue
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
163
|
## 链接
|
|
217
164
|
|
|
218
|
-
|
|
219
165
|
- **仓库**: [github.com/HsiangNianian/dsh-auto-continue](https://github.com/HsiangNianian/dsh-auto-continue)
|
|
220
166
|
- **DeepSeek Harness**: [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
221
167
|
|
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.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"lib",
|
|
21
21
|
"cordis.patch.yml",
|
|
22
|
+
"scripts",
|
|
22
23
|
"README.md",
|
|
23
24
|
"README.zh.md",
|
|
24
25
|
"LICENSE"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Vendor patch for a known DSH limitation (0.1.0-rc.6):
|
|
4
|
+
*
|
|
5
|
+
* The web plugin-configuration section only exposes settings namespaces listed
|
|
6
|
+
* in `WEB_SETTINGS_NAMESPACES`, hardcoded in the installed
|
|
7
|
+
* `@deepseek-ai/dsh-host-apiproxy` bundle ("adding a section to that page is a
|
|
8
|
+
* decision made here rather than by the registering plugin. Moving that
|
|
9
|
+
* declaration to `settings.register()` ... is deferred work"). Without this
|
|
10
|
+
* patch the browser half of a third-party plugin's settings card reads
|
|
11
|
+
* `settings-not-exposed` and renders nothing.
|
|
12
|
+
*
|
|
13
|
+
* This script adds the `auto-continue` namespace to that allowlist in EVERY
|
|
14
|
+
* reachable dsh installation: the profile-linked copy (pnpm store / npx cache)
|
|
15
|
+
* and a global `npm i -g @deepseek-ai/dsh` install under the active Node
|
|
16
|
+
* version, plus the invoking directory's own install. It is idempotent:
|
|
17
|
+
* re-running it after any dsh reinstall reapplies the patch to the copies
|
|
18
|
+
* that lack it.
|
|
19
|
+
*
|
|
20
|
+
* Usage: node scripts/patch-expose.mjs
|
|
21
|
+
*/
|
|
22
|
+
import { createRequire } from 'node:module';
|
|
23
|
+
import { readFileSync, writeFileSync, realpathSync } from 'node:fs';
|
|
24
|
+
import { dirname, join } from 'node:path';
|
|
25
|
+
import { homedir } from 'node:os';
|
|
26
|
+
|
|
27
|
+
/** The namespace this plugin's settings card edits. */
|
|
28
|
+
const NS = 'auto-continue';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Collect candidate dsh-host-apiproxy package.json paths: the profile-linked
|
|
32
|
+
* copy, a global install under the active Node version (nvm layout), and the
|
|
33
|
+
* invoking directory's own install. Deduplicated by real path.
|
|
34
|
+
*/
|
|
35
|
+
function candidatePackageJsons() {
|
|
36
|
+
const found = new Set();
|
|
37
|
+
const add = (pkgJson) => {
|
|
38
|
+
try {
|
|
39
|
+
found.add(realpathSync(pkgJson));
|
|
40
|
+
} catch {
|
|
41
|
+
/* candidate not present */
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const tryResolve = (requireFn) => {
|
|
45
|
+
try {
|
|
46
|
+
add(requireFn.resolve('@deepseek-ai/dsh-host-apiproxy/package.json'));
|
|
47
|
+
} catch {
|
|
48
|
+
/* not resolvable from this anchor */
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// 1. The copy the profile's node_modules links to.
|
|
53
|
+
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`).
|
|
56
|
+
try {
|
|
57
|
+
const globalRoot = realpathSync(join(process.execPath, '..', '..', 'lib', 'node_modules'));
|
|
58
|
+
tryResolve(createRequire(join(globalRoot, '@deepseek-ai', 'dsh', 'package.json')));
|
|
59
|
+
} catch {
|
|
60
|
+
/* not an nvm-style global root */
|
|
61
|
+
}
|
|
62
|
+
// 3. The invoking directory's own install.
|
|
63
|
+
tryResolve(createRequire(join(process.cwd(), 'package.json')));
|
|
64
|
+
return [...found];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const candidates = candidatePackageJsons();
|
|
68
|
+
if (candidates.length === 0) {
|
|
69
|
+
console.error('[patch-expose] could not resolve any @deepseek-ai/dsh-host-apiproxy installation');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let patchedAny = false;
|
|
74
|
+
for (const packageJson of candidates) {
|
|
75
|
+
const bundlePath = join(dirname(packageJson), 'lib', 'index.js');
|
|
76
|
+
const source = readFileSync(bundlePath, 'utf8');
|
|
77
|
+
if (source.includes(`"${NS}"`)) {
|
|
78
|
+
console.log(`[patch-expose] ${NS} already present in ${bundlePath} — skipped.`);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const marker = `\t"web-search-deepseek"\n];`;
|
|
82
|
+
if (!source.includes(marker)) {
|
|
83
|
+
console.error(`[patch-expose] could not locate the WEB_SETTINGS_NAMESPACES tail in ${bundlePath}`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const patched = source.replace(marker, `\t"web-search-deepseek",\n\t"${NS}"\n];`);
|
|
87
|
+
writeFileSync(bundlePath, patched);
|
|
88
|
+
patchedAny = true;
|
|
89
|
+
console.log(`[patch-expose] added "${NS}" to WEB_SETTINGS_NAMESPACES in ${bundlePath}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (patchedAny) console.log('[patch-expose] restart `dsh web` for the change to take effect.');
|