dsh-prompt-predict 0.2.1 → 0.2.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/CHANGELOG.md +22 -0
- package/CHANGELOG_zh.md +19 -0
- package/README.md +29 -9
- package/README_zh.md +27 -9
- package/client/client.js +15 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,28 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
[中文](CHANGELOG_zh.md)
|
|
8
8
|
|
|
9
|
+
## [0.2.3] — 2026-10-18
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **The suggestion is visible again.** `0.2.2` drew it as a row inside `conversation.composer.dock`;
|
|
14
|
+
the row rendered in tests and `Tab` accepted it, but it was **invisible in the real app**, so
|
|
15
|
+
rendering went back to the original overlay.
|
|
16
|
+
- **The ghost text disappears as soon as you start typing.** DSH `0.2.1-rc.2` stopped exposing the
|
|
17
|
+
composer draft through the slot's `useInput` (it now returns the Lexical input state), so the
|
|
18
|
+
overlay stayed on screen and sat on top of what you were writing. It now hides on the first
|
|
19
|
+
printable keypress, which needs no draft state at all, and comes back with the next prediction.
|
|
20
|
+
- Verified end to end on DSH `0.2.1-rc.2`: the suggestion appears after a reply, and the first
|
|
21
|
+
keystroke removes it.
|
|
22
|
+
|
|
23
|
+
## [0.2.2] — 2026-10-18 (deprecated)
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- The suggestion was drawn as a row inside `conversation.composer.dock` instead of a fixed overlay.
|
|
28
|
+
**Deprecated:** that row turned out not to be visible in the real app. Use `0.2.3` instead.
|
|
29
|
+
|
|
30
|
+
|
|
9
31
|
## [0.2.1] — 2026-10-17
|
|
10
32
|
|
|
11
33
|
### Fixed
|
package/CHANGELOG_zh.md
CHANGED
|
@@ -5,6 +5,25 @@
|
|
|
5
5
|
|
|
6
6
|
[English](CHANGELOG.md)
|
|
7
7
|
|
|
8
|
+
## [0.2.3] — 2026-10-18
|
|
9
|
+
|
|
10
|
+
### 修复
|
|
11
|
+
|
|
12
|
+
- **建议重新可见。** `0.2.2` 把它画成 `conversation.composer.dock` 里的一行;这一行在测试里能渲染、
|
|
13
|
+
`Tab` 也能采纳,但在**真实 app 里看不见**,所以渲染退回原来的覆盖层。
|
|
14
|
+
- **一开始打字,ghost 提示就消失。** DSH `0.2.1-rc.2` 不再通过 slot 的 `useInput` 暴露草稿
|
|
15
|
+
(现在返回的是 Lexical 输入态),覆盖层会一直留在屏幕上、压住你正在写的内容。现在改为在第一个
|
|
16
|
+
可打印按键时隐藏——完全不依赖草稿状态——下一次预测到达时再出现。
|
|
17
|
+
- 已在 DSH `0.2.1-rc.2` 上端到端验证:回复结束后出现建议,第一个按键后消失。
|
|
18
|
+
|
|
19
|
+
## [0.2.2] — 2026-10-18(已弃用)
|
|
20
|
+
|
|
21
|
+
### 变更
|
|
22
|
+
|
|
23
|
+
- 建议改为画在 `conversation.composer.dock` 内的一行,不再是 fixed 覆盖层。
|
|
24
|
+
**已弃用:** 这一行在真实 app 里看不见。请使用 `0.2.3`。
|
|
25
|
+
|
|
26
|
+
|
|
8
27
|
## [0.2.1] — 2026-10-17
|
|
9
28
|
|
|
10
29
|
### 修复
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<a href="https://www.npmjs.com/package/dsh-prompt-predict"><img alt="npm version" src="https://img.shields.io/npm/v/dsh-prompt-predict" /></a>
|
|
7
7
|
<a href="https://www.npmjs.com/package/dsh-prompt-predict"><img alt="npm downloads" src="https://img.shields.io/npm/dm/dsh-prompt-predict" /></a>
|
|
8
8
|
<a href="https://github.com/ferrisching/dsh-prompt-predict/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/ferrisching/dsh-prompt-predict" /></a>
|
|
9
|
-
<img alt="Verified on DSH 0.2.
|
|
9
|
+
<img alt="Verified on DSH 0.2.1-rc.2" src="https://img.shields.io/badge/DSH-0.2.1--rc.2-4d6bfe" />
|
|
10
10
|
<img alt="Zero runtime dependencies" src="https://img.shields.io/badge/dependencies-zero%20runtime-41ba41" />
|
|
11
11
|
<img alt="Host + client plugin" src="https://img.shields.io/badge/shape-host%20%2B%20client-8250df" />
|
|
12
12
|
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" /></a>
|
|
@@ -54,15 +54,35 @@ The plugin is published on npm. Options are ordered by convenience.
|
|
|
54
54
|
|
|
55
55
|
**GUI**: open the plugins page → **Add plugin** → enter the package name `dsh-prompt-predict` → install.
|
|
56
56
|
|
|
57
|
-
**Or the dsh CLI
|
|
57
|
+
**Or the dsh CLI** — pin any published version with pnpm's `@version` syntax:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
dsh plugin --profile desktop add dsh-prompt-predict
|
|
60
|
+
dsh plugin --profile desktop add dsh-prompt-predict@0.2.3
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
Replace `--profile` with your own profile (usually `desktop` on the desktop app, `web` for the web build)
|
|
63
|
+
Replace `--profile` with your own profile (usually `desktop` on the desktop app, `web` for the web build), then **restart DSH**.
|
|
64
64
|
|
|
65
|
-
>
|
|
65
|
+
> ⚠️ **The CLI only installs the package.** DSH loads a plugin only when it is also listed in
|
|
66
|
+
> `dsh.profile.bundles` inside `~/.dsh/profiles/<profile>/package.json`. Verified: with the package
|
|
67
|
+
> installed but not in that list, the plugin's routes answer `404` and nothing loads. The GUI route
|
|
68
|
+
> above handles it for you; with the CLI add `"dsh-prompt-predict"` to that array yourself, or just
|
|
69
|
+
> run `scripts/install.sh` below, which does both steps.
|
|
70
|
+
|
|
71
|
+
> You'll find the switch and all parameters under **Settings → Prompt Suggestions**.
|
|
72
|
+
|
|
73
|
+
### Install from a release tarball
|
|
74
|
+
|
|
75
|
+
Every [release](https://github.com/ferrisching/dsh-prompt-predict/releases) carries the exact
|
|
76
|
+
tarball that is on npm (`shasum` matches the registry), which is handy for offline machines or for
|
|
77
|
+
pinning an artifact you can verify:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
gh release download v0.2.3 --repo ferrisching/dsh-prompt-predict --pattern '*.tgz'
|
|
81
|
+
dsh plugin --profile desktop add ./dsh-prompt-predict-0.2.3.tgz
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Same caveat as the CLI route above: add `"dsh-prompt-predict"` to `dsh.profile.bundles` yourself,
|
|
85
|
+
or run `scripts/install.sh` instead.
|
|
66
86
|
|
|
67
87
|
### Install from source
|
|
68
88
|
|
|
@@ -93,7 +113,7 @@ Then open that profile's `package.json` and add `"dsh-prompt-predict"` to the `d
|
|
|
93
113
|
|
|
94
114
|
### Requirements
|
|
95
115
|
|
|
96
|
-
- Verified on **DSH `0.2.
|
|
116
|
+
- Verified on **DSH `0.2.1-rc.2`** (web build; the desktop app runs the same host and client code)
|
|
97
117
|
- `node` / `pnpm`: the install script prefers DSH's own runtime under `~/.dsh/dsh-runtimes/*/dependencies` and only falls back to `PATH`
|
|
98
118
|
- macOS / Linux; Windows untested
|
|
99
119
|
|
|
@@ -168,7 +188,7 @@ For model selection, `provider` / `model` set to `auto` means "follow the sessio
|
|
|
168
188
|
```bash
|
|
169
189
|
git clone https://github.com/ferrisching/dsh-prompt-predict.git
|
|
170
190
|
cd dsh-prompt-predict
|
|
171
|
-
npm test #
|
|
191
|
+
npm test # 71 cases: 51 host-side + 20 client render smoke tests
|
|
172
192
|
```
|
|
173
193
|
|
|
174
194
|
```
|
|
@@ -183,7 +203,7 @@ npm test # 66 cases: 51 host-side + 15 client render smoke tests
|
|
|
183
203
|
│ └── client.js Client: composer ghost-text overlay + settings page
|
|
184
204
|
├── test/
|
|
185
205
|
│ ├── predict.mjs 51 cases: trimming, cleanup, route inheritance, settings validation, degrade-retry, dedup, bilingual errors, HTTP end-to-end
|
|
186
|
-
│ └── client-render.mjs
|
|
206
|
+
│ └── client-render.mjs 20 cases: renders the ghost overlay and settings page through a tiny React stand-in, incl. both locales and dictionary self-checks
|
|
187
207
|
├── scripts/
|
|
188
208
|
│ └── install.sh One-shot install / upgrade
|
|
189
209
|
├── cordis.patch.yml Plugin mount patch
|
|
@@ -203,7 +223,7 @@ The tests need no DSH runtime: a fake ctx plus a local HTTP server cover route r
|
|
|
203
223
|
|
|
204
224
|
## ⚠️ Known limitations
|
|
205
225
|
|
|
206
|
-
- Verified only on DSH `0.2.
|
|
226
|
+
- Verified only on DSH `0.2.1-rc.2`; other versions untested
|
|
207
227
|
- Depends on the host's `conversation.composer.dock` and `settings.section` slot names — a major DSH update may require adapting
|
|
208
228
|
- Predictions consume quota on the selected model; pinning a fast small model is cheaper than following a reasoning model
|
|
209
229
|
|
package/README_zh.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<a href="https://www.npmjs.com/package/dsh-prompt-predict"><img alt="npm version" src="https://img.shields.io/npm/v/dsh-prompt-predict" /></a>
|
|
7
7
|
<a href="https://www.npmjs.com/package/dsh-prompt-predict"><img alt="npm downloads" src="https://img.shields.io/npm/dm/dsh-prompt-predict" /></a>
|
|
8
8
|
<a href="https://github.com/ferrisching/dsh-prompt-predict/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/ferrisching/dsh-prompt-predict" /></a>
|
|
9
|
-
<img alt="已验证 DSH 0.2.
|
|
9
|
+
<img alt="已验证 DSH 0.2.1-rc.2" src="https://img.shields.io/badge/DSH-0.2.1--rc.2-4d6bfe" />
|
|
10
10
|
<img alt="零运行时依赖" src="https://img.shields.io/badge/%E4%BE%9D%E8%B5%96-%E9%9B%B6%E8%BF%90%E8%A1%8C%E6%97%B6%E4%BE%9D%E8%B5%96-41ba41" />
|
|
11
11
|
<img alt="客户端 + Host 双端插件" src="https://img.shields.io/badge/%E5%BD%A2%E6%80%81-Host%20%2B%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%8F%92%E4%BB%B6-8250df" />
|
|
12
12
|
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" /></a>
|
|
@@ -54,15 +54,33 @@
|
|
|
54
54
|
|
|
55
55
|
**图形界面**:打开插件页 →「添加插件」→ 填入包名 `dsh-prompt-predict` → 安装。
|
|
56
56
|
|
|
57
|
-
**或者用 dsh CLI
|
|
57
|
+
**或者用 dsh CLI**——想装某个已发布版本就用 pnpm 的 `@版本` 语法:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
dsh plugin --profile desktop add dsh-prompt-predict
|
|
60
|
+
dsh plugin --profile desktop add dsh-prompt-predict@0.2.3
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
`--profile` 换成你自己的 profile(桌面端一般是 `desktop`,Web 端是 `web
|
|
63
|
+
`--profile` 换成你自己的 profile(桌面端一般是 `desktop`,Web 端是 `web`),**装完重启 DSH 生效**。
|
|
64
64
|
|
|
65
|
-
>
|
|
65
|
+
> ⚠️ **CLI 只负责装包。** DSH 只有在 `~/.dsh/profiles/<profile>/package.json` 的
|
|
66
|
+
> `dsh.profile.bundles` 里也列出该插件时才会加载它。实测:包装了但不在该列表里,插件路由返回 `404`,
|
|
67
|
+
> 什么都不会加载。上面的图形界面路径会替你处理;用 CLI 的话请自己把 `"dsh-prompt-predict"` 加进该数组,
|
|
68
|
+
> 或直接跑下面的 `scripts/install.sh`——它两步都做。
|
|
69
|
+
|
|
70
|
+
> 装完在 **设置 → 提示词联想** 里能看到开关与各项参数。
|
|
71
|
+
|
|
72
|
+
### 从 release 的 tarball 安装
|
|
73
|
+
|
|
74
|
+
每个 [release](https://github.com/ferrisching/dsh-prompt-predict/releases) 都附了与 npm 上
|
|
75
|
+
**完全一致**的 tarball(`shasum` 与 registry 相同),适合离线机器或需要自行校验产物的场景:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
gh release download v0.2.3 --repo ferrisching/dsh-prompt-predict --pattern '*.tgz'
|
|
79
|
+
dsh plugin --profile desktop add ./dsh-prompt-predict-0.2.3.tgz
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
与上面 CLI 路径同样的注意点:请自己把 `"dsh-prompt-predict"` 加进 `dsh.profile.bundles`,
|
|
83
|
+
或改用 `scripts/install.sh`。
|
|
66
84
|
|
|
67
85
|
### 从源码安装
|
|
68
86
|
|
|
@@ -93,7 +111,7 @@ pnpm add /path/to/dsh-prompt-predict
|
|
|
93
111
|
|
|
94
112
|
### 安装要求
|
|
95
113
|
|
|
96
|
-
- 已在 **DSH `0.2.
|
|
114
|
+
- 已在 **DSH `0.2.1-rc.2`** 上验证(Web 构建;桌面端跑的是同一套 host 与 client 代码)
|
|
97
115
|
- `node` / `pnpm`:安装脚本优先使用 `~/.dsh/dsh-runtimes/*/dependencies` 下 DSH 自带的运行时,找不到才回退 `PATH`
|
|
98
116
|
- macOS / Linux;Windows 未验证
|
|
99
117
|
|
|
@@ -168,7 +186,7 @@ pnpm add /path/to/dsh-prompt-predict
|
|
|
168
186
|
```bash
|
|
169
187
|
git clone https://github.com/ferrisching/dsh-prompt-predict.git
|
|
170
188
|
cd dsh-prompt-predict
|
|
171
|
-
npm test #
|
|
189
|
+
npm test # 71 项:51 项 Host 端 + 20 项客户端渲染冒烟
|
|
172
190
|
```
|
|
173
191
|
|
|
174
192
|
```
|
|
@@ -183,7 +201,7 @@ npm test # 66 项:51 项 Host 端 + 15 项客户端渲染冒烟
|
|
|
183
201
|
│ └── client.js 客户端:输入框 ghost text 覆盖层 + 设置页
|
|
184
202
|
├── test/
|
|
185
203
|
│ ├── predict.mjs 51 项用例:文本裁剪、建议清洗、路由继承、设置校验、降级重试、去重、双语错误、接口端到端
|
|
186
|
-
│ └── client-render.mjs
|
|
204
|
+
│ └── client-render.mjs 20 项用例:极简 React 替身渲染 ghost 覆盖层与设置页,含中英双语与词典自检
|
|
187
205
|
├── scripts/
|
|
188
206
|
│ └── install.sh 一键安装 / 升级
|
|
189
207
|
├── cordis.patch.yml 插件挂载补丁
|
|
@@ -203,7 +221,7 @@ npm test # 66 项:51 项 Host 端 + 15 项客户端渲染冒烟
|
|
|
203
221
|
|
|
204
222
|
## ⚠️ 已知限制
|
|
205
223
|
|
|
206
|
-
- 仅在 DSH `0.2.
|
|
224
|
+
- 仅在 DSH `0.2.1-rc.2` 上验证过,其它版本未测
|
|
207
225
|
- 依赖宿主的 `conversation.composer.dock` 与 `settings.section` 两个 slot 名称,DSH 大版本调整后可能需要适配
|
|
208
226
|
- 联想会消耗所选模型的额度;固定到快速小模型比跟随推理模型更省
|
|
209
227
|
|
package/client/client.js
CHANGED
|
@@ -361,6 +361,10 @@ window.__ModuleLoader__.load({
|
|
|
361
361
|
var abortRef = useRef(null);
|
|
362
362
|
var sessionRef = useRef(sessionId);
|
|
363
363
|
var dismissedByDraft = useRef(false);
|
|
364
|
+
// rc.2 不再把 draft 暴露给 slot,拿不到「输入框是否为空」。
|
|
365
|
+
// 用等价信号:建议可见时按下任何可打印键 = 用户开始输入 → 立即隐藏。
|
|
366
|
+
var _tk = useState(0), typedTick = _tk[0], setTypedTick = _tk[1];
|
|
367
|
+
var typedSince = useRef(false);
|
|
364
368
|
// 逐段采纳的前缀,只有「输入框里确实还留着它」时才算数:
|
|
365
369
|
// 用户把它删掉后必须重新完整展示整条建议,否则会出现从中间截断的鬼影。
|
|
366
370
|
var prefixKept = accepted !== "" && suggestion.indexOf(accepted) === 0 && draft === accepted;
|
|
@@ -368,7 +372,7 @@ window.__ModuleLoader__.load({
|
|
|
368
372
|
// 打字即隐藏,两种例外:
|
|
369
373
|
// (a) 草稿又被删空 —— 用户回到了「需要建议」的状态,让它重新浮现(只有 Esc 才是永久忽略)
|
|
370
374
|
// (b) 草稿正是我们逐段写进去、且没有改动的前缀 —— 不能把自己插的内容误判成用户打字
|
|
371
|
-
dismissedByDraft.current = draft.trim() !== "" && !prefixKept;
|
|
375
|
+
dismissedByDraft.current = (draft.trim() !== "" || typedSince.current) && !prefixKept;
|
|
372
376
|
var visibleSuggestion = dismissedByDraft.current ? "" : remaining;
|
|
373
377
|
|
|
374
378
|
// 首次读取启用状态;设置页保存后通过事件让当前会话立即生效。
|
|
@@ -395,6 +399,7 @@ window.__ModuleLoader__.load({
|
|
|
395
399
|
dismissedByDraft.current = false;
|
|
396
400
|
setSuggestion("");
|
|
397
401
|
setAccepted("");
|
|
402
|
+
typedSince.current = false;
|
|
398
403
|
if (abortRef.current) abortRef.current.abort();
|
|
399
404
|
}, [sessionId]);
|
|
400
405
|
|
|
@@ -405,6 +410,7 @@ window.__ModuleLoader__.load({
|
|
|
405
410
|
dismissedByDraft.current = false;
|
|
406
411
|
setSuggestion("");
|
|
407
412
|
setAccepted("");
|
|
413
|
+
typedSince.current = false;
|
|
408
414
|
if (abortRef.current) abortRef.current.abort();
|
|
409
415
|
return;
|
|
410
416
|
}
|
|
@@ -418,6 +424,7 @@ window.__ModuleLoader__.load({
|
|
|
418
424
|
.then(function (result) {
|
|
419
425
|
if (controller.signal.aborted || sessionRef.current !== sessionId) return;
|
|
420
426
|
if (result && result.ok && typeof result.suggestion === "string") {
|
|
427
|
+
typedSince.current = false;
|
|
421
428
|
setSuggestion(result.suggestion.trim());
|
|
422
429
|
recordRun(result, null);
|
|
423
430
|
} else {
|
|
@@ -483,6 +490,11 @@ window.__ModuleLoader__.load({
|
|
|
483
490
|
var onKey = function (event) {
|
|
484
491
|
if (event.isComposing) return;
|
|
485
492
|
if (event.key === "Escape") { event.preventDefault(); setSuggestion(""); setAccepted(""); return; }
|
|
493
|
+
// 任何可打印字符 → 认定用户开始输入,隐藏建议(与「开始输入自动消失」一致)
|
|
494
|
+
if (!typedSince.current && typeof event.key === "string" && event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
495
|
+
typedSince.current = true;
|
|
496
|
+
setTypedTick(function (n) { return n + 1; });
|
|
497
|
+
}
|
|
486
498
|
// Option/Alt + → :逐段采纳(对齐 Codex 的手感)
|
|
487
499
|
if (event.key === "ArrowRight" && event.altKey) {
|
|
488
500
|
if (!acceptChunk()) return;
|
|
@@ -501,6 +513,8 @@ window.__ModuleLoader__.load({
|
|
|
501
513
|
|
|
502
514
|
// 建议直接以灰色 ghost text 覆盖在 Lexical 输入框首字符处。
|
|
503
515
|
if (!enabled || dismissedByDraft.current || !visibleSuggestion) return null;
|
|
516
|
+
// 回到覆盖层:它在真实环境里是可见的(dock 内联行实测看不见)。
|
|
517
|
+
// 「打字即隐藏」由上面的 typedSince 信号负责,不再依赖草稿状态。
|
|
504
518
|
return h(GhostOverlay, { suggestion: visibleSuggestion, sessionId: sessionId, onAccept: accept, onReroll: reroll, t: t });
|
|
505
519
|
}
|
|
506
520
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-prompt-predict",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "输入框提示词联想插件:助手回复结束后预测你的下一句话,以灰色 ghost text 浮在输入框里,Tab 采纳、Esc 忽略 | Codex-style composer prompt predictions for DeepSeek Harness: your next message ghosted into the composer, accepted with Tab.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|