# dsh-status-rotator

> 替换 DSH Web 界面回合底部的 "Deep diving..." 状态文案，支持阶段感知切换、打字机、炫彩渐变和可视化词库编辑。

## Metadata

- Author: [@01Virex](https://github.com/01Virex)
- Repo: <https://github.com/01Virex/dsh-status-rotator.git>
- GitHub: [01Virex/dsh-status-rotator](https://github.com/01Virex/dsh-status-rotator)
- Stars: 42
- Language: JavaScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `dsh`, `dsh-plugin`
- Forks: 2
- Open Issues: 3
- Last push: 2026-08-19T07:22:24.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:01Virex/dsh-status-rotator
```

## Wiki

## 一句话定位
把 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 文件读写，无原生模块依赖 |
| 原生模块 | 无 | — |

## 安装方式
```bash
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 阶段，其它阶段自动回退

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-status-rotator](https://deepseek-plugin.org/plugins/01Virex/dsh-status-rotator)
Wiki generated by AI (model: `MiniMax-M3`)
