替换 DSH Web 界面回合底部的 "Deep diving..." 状态文案,支持阶段感知切换、打字机、炫彩渐变和可视化词库编辑。
- 语言
- JavaScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add github:01Virex/dsh-status-rotator在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 01Virex/dsh-status-rotator:先查看仓库 https://github.com/01Virex/dsh-status-rotator.git 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
把 DSH Web 界面回合底部那行固定的 "Deep diving..." 状态文字替换成你自己写的话:按回合阶段切换、打字机逐字出现、流动的炫彩渐变(可关),并随 DSH 语言自动切中英文。
核心能力
- 替换回合状态文字:接管 DSH 聊天底部的 TurnStatus 文案,不再显示 "Deep diving..."
- 按回合阶段切换文案:thinking(回合刚启动)/ running(时钟出现后)/ long(超过阈值)三组词库
- 打字机逐字输出:每句按字符间隔逐字打出,速度可调,0 即关闭
- 流动炫彩渐变文字:默认开启七彩渐变,可一键关闭或自定义配色与流速
- 中英文案自动切换:跟随 DSH 设置里的语言实时刷新,未知语言回退中文
- DSH 设置页编辑词库:插件在设置侧栏新增「状态文案」页,中英 × 三阶段文本框可视化编辑
- 热更新:页面打开时定时重读配置,切回标签页立即重读,改文案不需要刷新或重启
技术实现
- 语言: JavaScript (ESM)
- 关键依赖: 无外部 npm 依赖;node 端只使用
node:fs/promises、node:url、node:path;浏览器端使用 DSH 自带的 React(来自__ModuleLoader__.load)与内置locale/slots服务 - 架构模式: Cordis 双端插件;node 端
lib/index.js通过ctx.webServer.register注册GET/PUT /plugins/dsh-status-rotator/config.json路由负责读写本地config.json;client 端lib/client.js通过window.__ModuleLoader__.load注入 Web UI,监听 DOM 找到[role="status"][aria-live="polite"]元素并轮换文案;通过ctx.slots.inject("settings.section")注册设置面板 - 入口文件:
lib/index.js(node 端)+lib/client.js(浏览器端),由package.json的main与exports暴露
适用场景
希望自定义 DSH Web 界面回合等待体验的用户:可以替换成更口语的中文("正在帮你想"、"再等一下下")、英文("Cooking up a response"、"Still thinking…"),也可以做 QQ 群成员轮番出场的彩蛋文案,让等待过程更轻松。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 未声明 | package.json 未声明 dsh 版本依赖;按 cordis.patch.yml 与 lib/index.js 的 webServer / locale / slots 服务名运行 |
| Node.js | 未声明 | 节点脚本 gen-config.cjs 与 scripts/fetch-qq-group.cjs 用 CommonJS,需 Node 14+;lib/index.js 用 node: 协议,Node 18+ |
| 平台 | 跨平台 | 纯前端注入 + 纯 node 文件读写,无原生模块依赖 |
| 原生模块 | 无 | — |
安装方式
dsh plugin --profile web add github:01Virex/dsh-status-rotator
配置项
词库保存在插件根目录的 config.json(首次安装需运行 node gen-config.cjs 从 config.example.json 初始化)。
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
config.intervalMs | 数字(毫秒) | 同一阶段内轮换下一句文案的间隔 | 10000 |
config.typeSpeedMs | 数字(毫秒/字) | 打字机每个字符的间隔,0 关闭打字机直接显示完整文案 | 30 |
config.longAfterMs | 数字(毫秒) | 进入 long 阶段(回合慢/卡顿)的阈值 | 60000 |
config.reloadIntervalMs | 数字(毫秒) | 页面保持打开时自动重新读取 config.json 的间隔,0 关闭 | 15000 |
config.debug | 布尔 | 是否在浏览器控制台输出诊断日志 | false |
config.gradient.enabled | 布尔 | 是否给状态文字加流动炫彩渐变 | true |
config.gradient.colors | 字符串数组(≥2) | 渐变颜色序列,循环首尾相接 | ["#ff5f6d", "#ffc371", "#ffdd55", "#7dff7d", "#5fd4ff", "#a78bfa", "#ff8adb"] |
config.gradient.speed | 数字(秒/圈) | 渐变流动速度 | 4 |
phrases.zh.thinking | 字符串数组 | 中文 thinking 阶段文案(回合刚启动、还没出现时钟时) | 取自 config.example.json |
phrases.zh.running | 字符串数组 | 中文 running 阶段文案(时钟出现、未超过阈值) | 取自 config.example.json |
phrases.zh.long | 字符串数组 | 中文 long 阶段文案(超过 longAfterMs) | 取自 config.example.json |
phrases.en.thinking | 字符串数组 | 英文 thinking 阶段文案 | 取自 config.example.json |
phrases.en.running | 字符串数组 | 英文 running 阶段文案 | 取自 config.example.json |
phrases.en.long | 字符串数组 | 英文 long 阶段文案 | 取自 config.example.json |
常见问题
Q: 首次安装后需要重启 dsh web 吗?
A: 需要。node 端的 HTTP 路由(/plugins/dsh-status-rotator/config.json)必须在重启 dsh web 后才会被注册;之后改文案、保存词库都不需要再重启。
Q: 修改文案后要刷新页面才生效吗?
A: 不需要。插件每 reloadIntervalMs(默认 15 秒)会自动重读 config.json,切回浏览器标签页也会立即重读一次;通过 DSH 设置 → 状态文案页保存是即时热应用。
Q: 看不到炫彩渐变文字怎么办?
A: 检查 config.json 里 gradient.enabled 是否为 true。如果你的浏览器或 DSH 主题对动画做了特殊处理,渐变可能被压缩成纯色;可以临时把 gradient.colors 改成对比度更高的两色验证。
Q: 编辑后页面仍显示旧的文案,控制台有 ⚠ 告警?
A: 浏览器 localStorage 里有 dsh-status-rotator.texts、dsh-status-rotator.config 或 dsh-status-rotator.url 之一覆盖了 config.json。在 DevTools → Application → Local Storage 清掉对应键后刷新即可。
Q: 怎么用 QQ 群成员名生成文案?
A: 默认群号 684306814。连接 OneBot v11 HTTP API 后跑 node scripts/fetch-qq-group.cjs --url http://127.0.0.1:3000 --token 你的token,加 --activate 会直接覆盖当前 config.json(旧文件备份成 config.backup-<时间戳>.json);没有机器人也可准备 members.txt(每行一个昵称)后用 --input members.txt。
Q: 插件会影响"15秒后出现"的运行时长时钟吗?
A: 不会。插件只替换 TurnStatus 里的文字,时钟本身保持原样,并且时钟的读数会被用来判断阶段(出现 = running,超过 longAfterMs = long)。
Q: 怎么卸载?
A: 从 cordis.patch.yml 里删除 status-rotator 那一行(手动安装时),然后重启 dsh web。
上手难度
入门 — 不需要写代码,只编辑 config.json 或在 DSH 设置面板改文案就能用;想用 QQ 群成员生成器或自定义外部 JSON 才需要再多一步。
已知问题与限制
- 时钟文本解析仅识别 DSH 本地化的几种格式(
15秒/1分02秒/15s/1m 02s/mm:ss/h:mm:ss),普通文案里出现的数字不会被误判为时长 - 设置页通过
PUT保存配置时,请求体上限 5 MiB(lib/index.js的MAX_BODY_BYTES),超出时返回 413 - 若浏览器 localStorage 里设置了
dsh-status-rotator.texts/.config/.url之一,会静默压住config.json;只有通过__ModuleLoader__注入的版本会在控制台打[status-rotator] ⚠ localStorage 覆盖生效告警 - 设置页「保存」按钮不会触碰 DSH 主题外的样式,覆盖配置项修改需保存后才能继续生效
- 旧形态的纯文案 JSON(
{ "zh": [...] }或{ "thinking": [...] })仍兼容,会被视作 thinking 阶段,其它阶段自动回退
English | 中文
Replaces the Deep diving... status line in the DeepSeek Harness (dsh) Web UI's turn footer with your own text: phase-aware switching, typewriter output, animated rainbow gradient (optional), and timed rotation. The elapsed-time clock (which appears after 15 seconds) is untouched.
Installation
Two ways to install: the recommended dsh plugin add command, or the manual copy. Either way, you need to restart dsh web once after first install.
Option A: dsh plugin add (recommended)
The plugin's package.json declares a dsh.bundle.patch manifest, so it's recognized automatically after install — no extra flags needed. The command syntax is dsh plugin --profile <name> add <package> (e.g. --profile web):
- From npm (easiest):
dsh plugin --profile web add dsh-status-rotator - From a clone:
dsh plugin --profile web add ./dsh-status-rotator - From a release package: download the packaged tarball from the Release page, then
dsh plugin --profile web add /path/to/dsh-status-rotator-<version>.tgz.
Option B: manual install
-
Put this project directory under your profile's node_modules (default
C:\Users\<you>\.dsh\profiles\node_modules\dsh-status-rotator\); -
Insert the following into the profile's
cordis.patch.yml:- insert: - id: status-rotator name: dsh-status-rotator -
Run
node gen-config.cjsto initialize the localconfig.json(copied fromconfig.example.json); -
Restart
dsh weband hard-refresh the browser with Ctrl+F5.
Features
- Phase-aware: three sets of phrases —
thinking(just started) /running(after 15s) /long(past the threshold). Switches immediately when the clock appears or the timeout hits, no need to wait for the rotation interval; - Typewriter effect: phrases are typed out character by character, speed configurable, 0 disables it;
- Rainbow gradient: text rendered with an animated gradient, colors and speed configurable, can be turned off with one switch;
- Phrases separated from code: all phrases live in
config.json, editing them requires zero code and no restart; - Settings page: a new "Status Texts" page in DSH's Settings, with visual editing for the Chinese/English × three-phase phrase banks, saves take effect immediately;
- Auto-loading: the node half registers an HTTP route to serve
config.json, works out of the box with no localStorage or deployment needed; - Hot reload: while the page stays open it re-reads
config.jsonperiodically, and re-reads immediately when you switch back to the tab — no refresh needed to apply new phrases; - Multilingual: phrases switch live between Chinese and English following Settings → Language, unknown languages fall back to Chinese;
- Zero-intrusion targeting: locates TurnStatus precisely by
role="status"+aria-live="polite", so it never touches code snippets in the chat history or other aria-live regions, and never touches the clock.
Phase Awareness
Phrases are split into three groups based on turn progress (determined by whether a clock has appeared in the TurnStatus element and its reading):
| Phase | Trigger | Default duration |
|---|---|---|
thinking | Turn just started, no clock | 0 ~ 15s |
running | Clock visible, under the limit | 15s ~ longAfterMs |
long | Clock past longAfterMs | ≥ 60s |
Phase changes swap the phrase immediately without waiting for the rotation interval. If a phase has no phrase group, it falls back automatically (running → thinking → any non-empty group).
Rainbow Gradient
Status text is shown with an animated rainbow gradient by default (applies to the text only, not the clock). Can be disabled or re-colored in the config:
"gradient": {
"enabled": false, // false to disable; true for default colors
"colors": ["#ff5f6d", "#00ff88", "#4da6ff"], // gradient color sequence (at least 2, first/last cycle)
"speed": 4 // animation speed (seconds per cycle)
}
Configuration
Phrases are fully separated from the source code and live in JSON config files. There are two config files at the project root:
config.example.json— the complete template committed to the repo: default config + all phrases (bilingual, split into three phases);config.json— your local personalized config, initialized bynode gen-config.cjs(only created when missing, never overwrites your changes). It's in.gitignore, so edit freely without polluting git.
Auto-loading (default): the plugin's node half registers an HTTP route (/plugins/dsh-status-rotator/config.json) that serves the config.json next to the plugin (read from disk on every request). The browser fetches it automatically by default, and while the page stays open it re-reads every reloadIntervalMs, plus immediately when you switch back to the tab, so as long as config.json sits in the plugin directory, phrase edits take effect without a refresh or restart. The only restart of dsh web needed is on first install.
{
"config": { "intervalMs": 10000, "typeSpeedMs": 30, "longAfterMs": 60000, "reloadIntervalMs": 15000, "debug": false, "gradient": { "enabled": true, "colors": ["#ff5f6d", "#ffc371", "#ffdd55", "#7dff7d", "#5fd4ff", "#a78bfa", "#ff8adb"], "speed": 4 } },
"phrases": { "zh": { "thinking": ["…"], "running": ["…"], "long": ["…"] }, "en": { "thinking": ["…"], "running": ["…"], "long": ["…"] } }
}
| Key | Default | Description |
|---|---|---|
intervalMs | 10000 | Rotation interval (ms) |
typeSpeedMs | 30 | Typewriter delay per character (ms), 0 disables the typewriter |
longAfterMs | 60000 | Threshold for entering the long phase |
reloadIntervalMs | 15000 | Interval for auto re-reading config.json while the page is open (ms), 0 disables |
debug | false | Console diagnostic logs |
gradient | see above | Rainbow gradient: false / true / {enabled, colors, speed} |
phrases | from config file | The phrases (Chinese/English × three phases; partial entries allowed, missing ones fall back to other sources) |
Phrase source priority, highest first:
- localStorage single-text override
dsh-status-rotator.texts[.<locale>]/texts; - localStorage full config
dsh-status-rotator.config(paste JSON, applies after refresh); - External JSON:
dsh-status-rotator.url>EXTERNAL_URLconstant > local auto-load (/plugins/dsh-status-rotator/config.json); - Built-in defaults: only
DEFAULT_CONFIGat the top oflib/client.js(no phrases).
If a localStorage override matches, the external config.json is silently suppressed; the new version logs a [status-rotator] ⚠ localStorage override active warning in the browser console — when you see it, clear the corresponding key.
Old phrase-only external JSON ({ "zh": [...], "en": [...] } or { "thinking": [...] }) is still supported and treated as a "phrases-only config".
Phrases switch live between Chinese and English following Settings → Language; unknown languages fall back to Chinese.
Editing the Phrase Bank in the Settings Page
Open Settings in the bottom-left of DSH and a new Status Texts page appears in the navigation:
- 中文 / English tabs, each with three text boxes for
thinking/running/long, one phrase per line, blank lines are ignored; - Each phase shows the current phrase count in real time;
- Basic settings (rotation interval, typewriter speed, long-task threshold, auto-reload interval) live on the same page;
- Clicking "Save Phrase Bank" makes the browser
PUTthe full JSON to/plugins/dsh-status-rotator/config.json; the node half validates it and writes it back atomically, and already-open pages hot-apply it immediately without a refresh; - Submitted content is validated (phrases must be string arrays, etc.); invalid content returns 400 and shows an error on the page, so the config file can't be corrupted.
After upgrading to a version with the settings page, restart dsh web once (so the node half registers the write endpoint); everything after that can be done from the page.
QQ Group Member Phrase Generator
To turn every member of a QQ group into a phrase like 正在路由(群成员)写代码... (meaning "routing (group member) to write code..."), use scripts/fetch-qq-group.cjs to generate a standalone config file in one go — no need to type out the member list by hand.
Prerequisites: the bot is in the target group and you have a OneBot v11 compatible HTTP API (e.g. NapCat / LLOneBot / go-cqhttp / OpenShamrock).
# The default group is 684306814; generates config.qq684306814.json directly
node scripts/fetch-qq-group.cjs --url http://127.0.0.1:3000 --token your-token
# Directly replace the config.json the plugin actually uses (the old one is backed up as config.backup-<timestamp>.json)
node scripts/fetch-qq-group.cjs --url http://127.0.0.1:3000 --token your-token --activate
# No bot API? Save the member list as members.txt (one nickname per line) and generate from it
node scripts/fetch-qq-group.cjs --input members.txt
| Option | Default | Description |
|---|---|---|
-g, --group | 684306814 | QQ group ID (also reads the QQ_GROUP_ID env var) |
-u, --url | http://127.0.0.1:3000 | OneBot HTTP URL (also reads ONEBOT_HTTP_URL) |
-t, --token | empty | Access token (also reads ONEBOT_ACCESS_TOKEN) |
-a, --action | get_group_member_list | Action path; frameworks with a prefix use /api/... |
-i, --input | none | Local member list: txt (one per line) / json (array) / csv (first column) |
-o, --output | config.qq684306814.json | Output file |
--activate | off | Write back to config.json directly and back up the old file |
--dry-run | off | Preview only, writes nothing |
The display name prefers the group card name, falling back to the nickname. The generated file contains only the zh.thinking group: per this plugin's fallback rules, the thinking phase uses it directly and the other phases fall back to the same group. Template: config.qq684306814.example.json; the generated config.qq684306814.json is gitignored.
Project Structure
dsh-status-rotator/
├── lib/
│ ├── index.js # node half: registers the HTTP route for config.json
│ └── client.js # client half: status text replacement / gradient / typewriter
├── config.example.json # complete template (default config + all phrases, committed)
├── config.qq684306814.example.json # QQ group member phrase template (scripts/fetch-qq-group.cjs generates the real file)
├── config.json # local personalized config (gitignored)
├── gen-config.cjs # script that initializes config.json
├── scripts/
│ └── fetch-qq-group.cjs # fetches QQ group members and generates the phrase config
├── package.json
├── README.md # English docs
├── README_ZH.md # Chinese docs
├── CONTRIBUTORS.md # English contributors
├── CONTRIBUTORS_ZH.md # Chinese contributors
└── LICENSE
Uninstall
Remove the status-rotator line from cordis.patch.yml and restart dsh web.
Contributing
Issues and pull requests are welcome. The easiest way to add phrases: edit the phrases field in config.json or config.example.json directly — no code changes needed.
Credits
This project wouldn't exist without the help of its contributors — see CONTRIBUTORS.md.
License
收录徽章
[](https://deepseek-plugin.org/plugins/01Virex/dsh-status-rotator)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。