dsh-vocab-study
Offline vocabulary panel: a capsule beside the composer opens a word card, and a dockable tabbed panel tracks today, progress, the mistake book and settings.
Install
dsh plugin --profile web add dsh-vocab-study
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
今日词汇 · dsh-vocab-study
DSH(DeepSeek Harness)的一个纯客户端 UI 插件:在输入框右边放一颗胶囊,点开就是一个背单词面板。
数据只存在你自己的浏览器里,不上报、不联网、不占 Host 服务。
不装插件先看效果:[demo/index.html](demo/index.html) 双击就开,纯本地。
<p align="center">
<img src="assets/screenshot-3-today.png" width="200" alt="今日:词卡与三档评分">
<img src="assets/screenshot-4-progress.png" width="200" alt="进度:留存曲线与半月热力图">
<img src="assets/screenshot-5-vocab.png" width="200" alt="生词本:收录的词自动补上音标与释义">
<img src="assets/screenshot-6-settings.png" width="200" alt="设置:轮次大小、加量步长、攻守天平">
</p>
目录
想干的事 · 去哪看
看它长什么样、有什么功能 · [它长什么样](#它长什么样)
不装插件先试试 · [demo/index.html](demo/index.html) 双击打开
装进 DSH / 卸载 / 出问题自救 · [装进 DSH](#装进-dsh)
生词本:收录的词怎么自动有了释义 · [生词本](#生词本收录的词会自动补上释义)
搞懂它内部怎么组织的 · [它是怎么工作的](#它是怎么工作的)
跑测试 · [测试](#测试)
它承诺不做什么(12 条硬约束) · [12 条硬约束](#12-条硬约束)
它现在还做不到什么(诚实清单) · [已知缺口](#已知缺口诚实清单)
开发中踩过的坑(14 个事故) · [docs/INCIDENTS.md](docs/INCIDENTS.md)
状态
项 · 说明
版本 · 0.3.2(Releases)
成熟度 · 功能可用、在真界面里逐条点过;13 套件 / 约 600 条断言全绿(详见[测试](#测试))
依赖 · 零。没有 node_modules,不联网、不上报,数据只在本机浏览器里
体积 · lib/client.js 5,674,364 B ≈ 5.41 MB(内含六本词库共 34,216 词,见[为什么这么大](#构建))
装法 · dsh plugin --profile web add dsh-vocab-study(npm,推荐)<br>或 dsh plugin --profile web add github:wt0812/dsh-vocab-study
国内镜像 · gitee.com/wutong2005/dsh-vocab-study(与 GitHub 逐提交一致,见下)
市场收录 · 已提 PR awesome-dsh-plugin#7043,等上游合并
已知缺口 · 见[已知缺口](#已知缺口诚实清单)(8 条,含"未在真实网络环境验证词库拉取"这种)
国内镜像(Gitee)
GitHub 在国内时常连不上,所以有一份 Gitee 镜像:https://gitee.com/wutong2005/dsh-vocab-study
它和 GitHub 逐提交一致(HEAD sha 相同,全部提交 + 标签都在)。
我在两边的克隆里各跑过 12 个套件,都是 0 失败。
从 Gitee 装的做法是「先克隆,再装本地目录」(dsh plugin 没有 gitee: 这种形态):
git clone https://gitee.com/wutong2005/dsh-vocab-study.git cd dsh-vocab-study python tools/install.py
install.py 默认装到 desktop(桌面客户端)。要装进浏览器 Web 界面那套 profile,
把脚本里的 DEFAULT_PROFILE 指到 web 下的同名目录。
镜像不是自动同步的,是我推的。一切以 GitHub 为准。
「成熟度」这一行我写得很克制:能用是真的(你亲手点过),
但它是 0.2.9、只有一个人在用、只有一台机器验过 —— 不是"生产级"。
它长什么样
① 输入框旁那颗胶囊(conversation.input.right,排在「权限」与「模型」之间):
胶囊当时显示成「3 词收好」;左侧栏底部那张「今天背过的词 abandon」是 0.3.1 加的眼熟小组件。
② 右侧栏里的面板 · 卡片背面(sidebar.right.pane.tab,四个页签:今日 / 进度 / 生词本 / 设置):
这张特意截的是背面 —— 常见搭配、词根词缀、词源、同族词、例句,
0.2.8 之后卡片才逐项加上这些(abject,五项全在)。
位置 · 内容
conversation.input.right · 一颗胶囊 今天第一词,排在「权限」与「模型」之间
sidebar.right.pane.tab · 一个叫「今日背单词」的标签页,四个页签:今日 / 进度 / 生词本 / 设置
截图:上面两张图就在assets/里(screenshot-1-capsule.png、screenshot-2-panel.png),
同时由 screenshots.json 声明,市场详情页会用同一份声明
(上游 probe-screenshots.mjs 从仓库 HEAD 实时读取,不需要另外提 PR)。
四个页签各自的样子
上面那两张是"它长在哪";下面这四张是它长什么样 —— 每个页签一张,都是把面板展开到内容结束拍的整图:
页签 · 一句话 · 图
今日 · 一张词卡 + 三档评分;下方是今天这批的进度环、KPI、半月热力图 · 
进度 · 30 天留存曲线、半月热力图、顽固词榜、需要对着练的混淆对 · 
生词本 · 从对话里收的词,自动补上音标 + 词性 + 释义,可以手改 · 
设置 · 一轮几个词、加量步长、攻守天平、数据导入导出 · 
这四张图是 node tools/make-releasshots.mjs 出的,脚本自带两道闸门(裁切区里只能有面板和背景、
产出图四角必须是背景色),拍错了会直接报错拒绝出图。
不用它的日子它什么都不做。面板永远不会自己弹出来(这是刻意的,见下面「12 条硬约束」)。
背完一轮之后(不是死角)
一轮走完时不再只剩一个「换词库」,而是给三条各自不同的出路:
控件 · 做什么 · 什么时候出现
再背一轮 · 把刚才这一批原样重来一遍(不动记忆数据,不算新词) · 这一轮有内容可重背时
再来 N 个新词 · 往后加量:容器扩大,接在队列后面,不重复(N 在设置里可调,默认 5) · 新词闸门开着时
我还是想继续 · 打开新词闸门(安全阀仍然自动触发,只是给了用户自己开门的权力) · 闸门自动关闭时
换词库 · 换一本词库 · 始终有,但降到最弱的样式
两个容易搞混的数字,故意分开:
- 进度环 = 这一轮(
0/20→5/20→ 走完5/20),点「再背一轮」后归零; - 今天已背 = 今天累计(KPI 里第一个,抽空背 3 个也看得见),跨轮累加、不归零。
为什么拆开:环原来用的是跨轮累加的值,点了「再背一轮」之后环显示上一轮的数字,
和「今天已背」互相矛盾(实测:环说 1、今日说 6)。用户会以为数字坏了。
「再来 N 个」的 N 可以自己定(设置页「点「再来几个」时加几个」,3 / 5 / 10,默认 5)——
加量是用户的决定,不该由插件自作主张定死一个数(P4)。
新词安全阀(规格 §7.6):今天新词错得太多时自动停新词。这是安全阀不是拦路虎 ——
它仍然自动触发,但界面上给一个「我还是想继续」,用户自己决定要不要开。
生词本:收录的词会自动补上释义
在对话里选中一个纯英文单词,输入框旁会出现「加入生词本」。点了之后:
它做什么 · 说明
自动补音标 + 词性 + 释义 · 从内置的 29,841 词里离线查一遍(lookupWord),命中就填上
顺手抓例句 · 把你在对话里选中它的那句话存下来当例句
查不到就留空并说明 · 生词本上标「(还没释义)」,并给一个手填输入框 —— 不编造(P7)
手填的会标来源 · 自己填的释义标 manual,查到的标 lookup,一眼看得出哪个是它自己查的
「收服」的意思是:这个词真的记住了,就不该再占着生词本。
所以判定为收服(记忆强度 ≥ 0.9 且拼写答对)之后,它会自动从生词本移走,
但不会凭空消失 —— 进「已收服 N 个」的归档,带时间戳,随时能查。
这一条以前是坏的:收录进来的词永远没有释义,生词本是个空壳 ——
因为只有几万条释义摆在旁边,代码里却根本没有查询动作。
症状 → 根因 → 修法见 [排查笔记 · 事故十三](docs/INCIDENTS.md)。
不熟的词不给提示?给。
今天错过的词会攒起来,生词本页顶上有一条提示问你要不要一起收进去 ——
但它只是提示,不会自动加:加什么进你的生词本是你的决定(P4)。
想先看效果,不装插件
# 双击即可,纯本地,不需要装任何东西 start demo\index.html
demo/ 是一个自包含的演示页:里面有一个假的 DSH 外壳(对话区 + 输入框 + 工具栏),
胶囊和面板都是同一份源码编译出来的,不是另写的仿制品。
demo/ 里的几个文件:
文件 · 用途
index.html · 打开就是这个 demo,可以真的点着背
smoke.html · 自检页:外壳 11 项检查 + core 自检,全绿才算过
preview.html · 直接截到「词卡」态(未揭晓)
preview-reveal.html · 截到「已揭晓」态
preview-progress.html · 截到「进度」页
preview-settings.html · 截到「设置」页
preview-vocab.html · 截到「生词本」页
preview-hook.html · 截到「记忆钩子」相关态
preview*.html 只是为了截图/看态方便,它们会在打开后自动点开对应页签。
装进 DSH
给别人用
# 推荐:从 npm 装(快,国内有镜像) dsh plugin --profile web add dsh-vocab-study # 或者从 GitHub 源码装(npm 上不去时用) dsh plugin --profile web add github:wt0812/dsh-vocab-study
装完 完全退出 DeepSeek Harness 再打开(cordis.patch.yml 是启动时读的,刷新页面没用)。
关于 --profile,这是最容易搞错的一处 —— 上面这两种写法就是对的。
dsh plugin 是命令行工具,它把后面的参数原样转发给 profile 目录里的 pnpm
(读的是 DSH 本体的命令定义:「manage a profile's plugins by forwarding the
remaining arguments to pnpm in the profile directory」),其中 --profile 是必填项。
⚠️
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::14,最后更新 2026-10-27