把 dsh 回合状态行换成 1059 条中英文案的轮播:打字机输出、流动彩虹渐变、弹幕、12 个可开关的主题词库包、实时占位符与标签页标题轮换。两个 star 包默认关闭;星标者包每位星标者一条文案,由工作流每周刷新。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-status-rotator
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:01Virex/dsh-status-rotator
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
把 DSH Web 底部那行
Deep diving.../深度求索中...换成你自己的文案库:1105 条梗、13 个主题词库包、打字机 + 白天/黑夜炫彩渐变 + 弹幕。
English | 中文 · 30 秒上手 · 特性总览 · 配置 · 更新日志
30 秒上手
dsh plugin --profile web add dsh-status-rotator # 1. 安装(包内自带 bundle manifest,自动识别)
dsh web # 2. 重启一次,仅首次需要
- 打开左下角 设置 → 状态文案:挑词库包、改文案、调渐变与弹幕 —— 改动即保存、即时生效,不用刷新页面。
一个 DeepSeek Harness (dsh) 客户端插件:把 Web 界面底部回合运行时那行硬编码的 Deep diving... / 深度求索中... 状态文字,替换成你自己的文案库 —— 按回合阶段切换、打字机逐字输出、定时轮换、加权随机抽取、带实时取值的模板占位符、白天 / 黑夜两套配色自动跟随界面深浅色的流动炫彩渐变、视频网站风格的弹幕,以及一个同时喂给文案和浏览器标签页标题的实时状态引擎。界面自带的运行时长时钟不受影响。
dsh 0.1.7 起的状态行:宿主把运行时文案塞进了回合折叠头
button[data-turn-process](Deep diving for 12s/深度求索中,用时12秒,长回合里早被滚出视口)。插件把状态行搬回旧版位置 —— 对话下方、输入框正上方那一行,水平方向与消息列同一左边界(复刻 dsh ≤0.1.6 的.turnStatus:26px 高 / 自带 shimmer / 时钟 13px + 8px 间距),跟着输入框常驻可见;回合折叠头里那行藏起来避免重复,回合结束再把状态行撤掉、放出宿主自己的Took 12s/Worked。时长与阶段照旧从折叠头标签文本读(React 每秒整段重写它,插件不往里塞东西),读屏公告 span 不改写。0.1.6 及更早的role="status"状态行本就在旧位置,行为不变。没有文案可轮换时不会留空行:
config.labelSource(默认"phrases")管状态行写什么。短语库为空(比如装了插件但没config.json)时,插件自己那条线会回落宿主原文「Deep diving…」/「深度求索中」,而不是一条空状态行;写成"host"则完全不轮换,只用宿主原文,外观逐项对齐 0.1.6 的.turnStatus(字重 500、inline-flex、26px、shimmer、时钟 15 秒后出现)—— 在 0.1.7 上得到 0.1.6 的观感。详见状态行文案来源。
特性总览
核心
- 状态文字替换 — 宿主那行(
Deep diving.../ 0.1.7 的Deep diving for 12s)换成你的文案,每intervalMs轮换、逐字打字(typeSpeedMs,0 关闭); - 阶段感知 —
thinking/running/long三组按回合时长切换,不用等轮换间隔; - 加权随机 — 文案条目可带权重(
weightedRandom: false= 完全均匀); - 零侵入定位 — 老宿主按
role="status"+aria-live="polite"、0.1.7+ 按button[data-turn-process]定位,不碰聊天记录里的代码片段、其它 aria-live 区域与宿主时钟。
内容
- 文案与代码分离 + 词库包模块化 — 文案全在 JSON 里,拆成具名词库包(
packs[]/enabledPacks[]),设置页逐个开关、独立编辑; - 模板占位符 —
{elapsed}{phase}{phaseLabel}{locale}{date}{time},实时字段{model}{provider}{tps}{pending}{tools}{running},见模板占位符; - 观测通道 — 把宿主的
llm/retry结构化信号显示成小徽标(默认⟳ 3/5),并提供{retry}{retryMax}{retryProvider}{retryCode}{detail};拿不到事件窗口就什么都不显示; - 多语言 — 跟随「设置 → 语言」实时切换,未知语言回退中文;
- 社区词库机器人 — Issue 表单 + 自动校验 + 自动开 PR,分支自动跟随 main 重建(见通过 Issue 投稿词库)。
视觉与实时
- 炫彩渐变 — 白天 / 黑夜两套配色跟随界面主题(也可
mode强制),颜色与流速可配,一键关闭; - 弹幕 — 文案以弹幕飘过页面(含 bilibili 风格顶部 / 底部),字号、颜色、透明度、层级可调;
- 标签页标题 — 用模板轮换
document.title(默认关闭;只写自己接管过的标题); - 预设与调度 — 多套命名词库,手动切换或按星期 / 时段自动切换。
工作流
- 自动加载 + 热更新 — node half 注册 HTTP 路由 serve 配置,页面打开时定时重读,改完不用重启;
- 持久化 — 保存的设置写进
$DSH_HOME/status-rotator/config.json,不属于任何包,升级不丢; - 设置页 — DSH「设置 → 状态文案」可视化编辑,保存即生效。
安装
两种方式:推荐用 dsh plugin add 命令,或手动复制。无论哪种方式,首次安装后都需要重启一次 dsh web。
方式 A:dsh plugin add(推荐)
本插件在 package.json 里声明了 dsh.bundle.patch manifest,安装后自动识别,无需额外标志。命令语法是 dsh plugin --profile <name> add <package>(例如 --profile web):
- npm 安装(最简单):
dsh plugin --profile web add dsh-status-rotator← 永远装最新版 - 克隆仓库:
dsh plugin --profile web add ./dsh-status-rotator - Release 打包产物:从 Release 页下载
dsh-status-rotator-<版本>.zip(里面是解压即用的插件目录,含config.json,不是 npm tarball),解压后执行dsh plugin --profile web add /path/to/dsh-status-rotator。
方式 B:手动安装
把本项目目录放到 profile 的 node_modules 下(默认
C:\Users\<你>\.dsh\profiles\node_modules\dsh-status-rotator\);在 profile 的
cordis.patch.yml里插入:- insert: - id: status-rotator name: dsh-status-rotator运行
node gen-config.cjs初始化本地config.json(从config.example.json复制);重启
dsh web,浏览器 Ctrl+F5 硬刷新。
首次使用
首次启动时伺服顺序是:你保存的设置($DSH_HOME/status-rotator/config.json)→ 包目录 config.json → config.example.json(npm 安装时就是这一份,默认的全部 1105 条文案都在里面,见词库现状)。另有自动更新词库(每 6 小时,见词库自动更新)与可选的外部词库($DSH_HOME/status-rotator/phrases.json,优先级最高,见可热重载的外部词库)。改文案可直接改文件(页面开着时热更新),也可走 DSH 左下角「设置 → 状态文案」。
工作原理
阶段感知
文案按回合进展分三组(判定依据是状态元素里是否出现时钟及其读数):
| 阶段 | 触发条件 | 默认时长 |
|---|---|---|
thinking |
回合刚启动,无时钟 | 0 ~ 15s |
running |
时钟出现,未超时 | 15s ~ longAfterMs |
long |
时钟超过 longAfterMs |
≥ 60s |
阶段切换会立即触发换文案,无需等轮换间隔。某阶段缺文案组时自动回退(running → thinking → 任意非空组)。
零侵入定位
状态标签按 role="status" + aria-live="polite"(dsh ≤0.1.6)或 button[data-turn-process](0.1.7+)精确定位,不碰聊天记录里的代码片段或其它 aria-live 区域。0.1.7+ 上插件只做三件事:在输入框座位里插自己的一行、把折叠头那行藏起来、读折叠头的标签文本取时长;宿主时钟只被读取,阶段与时长由实时引擎按回合开始时刻推导。
状态行文案来源(label source)
config.labelSource 决定状态行里写什么,两代宿主都认:
| 取值 | 状态行文案 | 什么时候用 |
|---|---|---|
"phrases"(默认) |
从短语库里抽一句,按阶段轮换 | 插件本来的样子 |
"host" |
只用宿主原文 Deep diving... / 深度求索中 |
想要纯 0.1.6 观感、不要梗文案 |
- 没文案也不会空行:短语库为空时(没
config.json/ 预设清空了文案),"phrases"模式回落宿主原文,0.1.7 上不会只剩一条空行配时钟; "host"连外观一起对齐 0.1.6:插件那条线逐项照抄.turnStatus(字重 500、height: calc(26px + …)、inline-flex、同一套 shimmer 与prefers-reduced-motion降级)与.turnStatusClock(13px、tabular-nums、8px 间距、400 字重),时钟也按旧时机(elapsedMs >= 15s)出现,文案一次性写出而不打字;旧宿主(≤0.1.6)在"host"下插件完全不碰;- 设置页有同名下拉框(「状态行文案来源」),
{"labelSource": "host"}也可直接写进config.json或预设。
词库现状
默认词库当前共 1105 条,拆为 13 个主题词库包(核心 phrases 表为空——词条全部住在包里)。其中 10 个默认启用,两个 star 包随包发布但默认关闭——想用就在「设置 → 状态文案 → 词库包」里打开:
| 词库包 | zh | en | 小计 | 默认 |
|---|---|---|---|---|
deepseek DeepSeek 专场 |
107 | 111 | 218 | 开 |
coding 写代码日常 |
84 | 81 | 165 | 开 |
daily 日常 |
77 | 64 | 141 | 开 |
internet-memes 网络梗 |
56 | 33 | 89 | 开 |
sysadmin 系统管理 |
41 | 38 | 79 | 开 |
slacking 摸鱼 |
36 | 29 | 65 | 开 |
math-physics 数学与物理 |
31 | 18 | 49 | 开 |
western-ai 西方 AI 圈 |
16 | 18 | 34 | 开 |
reverse-proxy 反代 |
14 | 16 | 30 | 开 |
china-ai 中国 AI 圈 |
18 | 10 | 28 | 开 |
star-ask 求 star |
11 | 12 | 23 | 关 |
star-route 星标者路由 |
89 | 89 | 178 | 关 |
| 合计 | 586 | 519 | 1105 | 开 898 / 关 207 |
- 大部分条目 zh/en 成对镜像;近期社区投稿常为中文单语——投稿表单选「zh + en (两种都要)」即可双语收录;
- 含 5 条加权示范条目(见加权随机),其余均为默认权重 1 的纯文案;
- 词库通过社区投稿表单持续增长:校验通过并合入的投稿会在 CONTRIBUTORS.md 名单里致谢;
- 统计由
node scripts/sync-bank-counts.cjs从config.example.json现算并写回(投稿机器人与 star 词库刷新会自动调用;手改词库后跑一次即可);本地用node scripts/check-bank-memes.mjs可随时审计当前词库(查重/超长/省略号/系列占比)。
star 词库包(默认关闭) — 拆成两个独立的包,想只要求 star 文案、不要星标者点名,就只开前者:
| 词库包 | 内容 |
|---|---|
star-ask 求 star |
纯求 star 文案,如「正在向你讨一个 star…」/ Begging for a star… |
star-route 星标者路由 |
每位当前星标者一条——正在路由 <login> 写代码… / Routing <login> to write code…,让状态轮换真的"路由每个点星的人去干活" |
默认关闭是口味问题不是坏了:在「设置 → 状态文案 → 词库包」打开即可。星标名单由 Star packs 工作流刷新(每周、文件有改动时、手动),用仓库自带 GITHUB_TOKEN 读 stargazers,刷新走机器人 PR 且 Test 绿了自动合并;fork 里该 job 整条跳过(那里的令牌看不到上游星标),可用 STAR_TOKEN 覆盖。本地刷新:node scripts/update-star-pack.cjs --token <pat>。
词库包
词库可在核心 phrases 之上按具名「词库包」组合:
{
"packs": [
{ "id": "community",
"label": { "zh": "社区投稿", "en": "Community" },
"phrases": { "zh": { "running": ["正在试用词库包…"] } } }
],
"enabledPacks": ["community"] // 缺省 = 全部包启用;[] = 只用核心库
}
- 启用的包按顺序并入生效词库,按文本去重——核心库(或更早的包)已存在的条目会被跳过,保留其权重;
enabledPacks缺省/null= 全部启用;[]= 只用核心库;名单里的未知 id 直接忽略;- 包内条目与核心库完全同构(字符串或
{text, weight}、三阶段分组、占位符); - 设置页列出每个包:逐个启用开关 + 包编辑目标(选中某包后,词库编辑区读写该包文案);
- 默认自带 12 个包(
deepseek/western-ai/china-ai/coding/reverse-proxy/sysadmin/math-physics/slacking/internet-memes/daily/star-ask/star-route);community(社区投稿)在首次有投稿时创建,enabledPacks钉住默认启用的包。 - 投稿表单的**「目标词库包」**选择器含同样 10 个包 +
community(默认落点)+star-ask(只求 star 文案;星标者路由包由脚本自动生成,不接受投稿):投稿进入所选包,community包在首次使用时自动创建——核心词库本体不被改动,想关掉或裁剪社区内容一处搞定; - 旧配置没有 packs 字段,零改动兼容。
加权随机
默认按权重抽取。文案条目写成 "文案 | 3"(或 { "text": "文案", "weight": 3 })即为权重 3,未写 = 1;权重上限 1000,非法值按 1 处理。weightedRandom: false 回到完全均匀。词库里有 5 条展示用的加权条目。
模板占位符
任意文案(以及标题模板)都支持占位符,渲染时替换:
| 占位符 | 含义 | 示例 |
|---|---|---|
{elapsed} |
当前回合已运行时长(本地化,风格同时钟) | 正在写代码 1分02秒… |
{phase} |
阶段 id:thinking / running / long / idle |
running |
{phaseLabel} |
阶段的本地化短标签 | 运行中 |
{model} |
当前会话的模型名(实时引擎,未知为 —) |
deepseek-chat |
{provider} |
当前会话的供应商路由(实时引擎) | deepseek |
{tps} |
流式 token/秒 估算(实时引擎) | 12 |
{pending} |
正在等待作答的交互数 —— 审批与提问共用这一个计数(实时引擎) | 1 |
{tools} |
正在运行的工具名,+ 连接(实时引擎) |
bash+web_search |
{running} |
run / idle(实时引擎) |
run |
{retry} |
当前步的重试次数(实时引擎,无重试为空) | 3 |
{retryMax} |
该重试策略的上限(旧宿主 / always 模式可能为空) | 5 |
{retryProvider} |
触发重试的 provider(provider 中立,原样透传) | deepseek-official |
{retryCode} |
失败短码(≤32 字符的安全 token;URL / 路径 / 报文一律不显示) | sampling_error |
{retryStarted} |
重试的那次尝试是否已开始跑(llm/retry-started 之后为 1,否则为空) |
1 |
{detail} |
整条观测徽标(按 config.details.badge 模板渲染) |
⟳ 3/5 |
{locale} |
当前界面语言(zh / en) |
zh |
{date} |
本地日期 YYYY-MM-DD |
2026-08-07 |
{time} |
本地时间 HH:MM:SS |
12:34:56 |
随时间变化的占位符(
{elapsed}{date}{time}{tps}{pending}{tools}{model}{provider}{retry}{detail})按liveTickMs(默认 1000ms)实时刷新,设为0则只随轮换更新;观测通道(参考 discussion #3669):把宿主写进会话事件日志的结构化信号显示成状态行上的小徽标(
llm/retry等,默认⟳ 3/5)并提供同名占位符;拿不到事件窗口就什么都不显示,绝不从日志文本里猜次数。
"details": { "enabled": true, "badge": "⟳ {retry}/{max}" }
"phrases": { "zh": { "thinking": ["正在写代码 {elapsed}…", "正在{phaseLabel}中 ({elapsed})…"] } }
{pending} 与所在会话的审批策略
{pending} 数的是待作答交互——和界面里那些「接管输入框」的面板同一份数据;审批与提问共用这一个计数,只要有一样在等你回答,它就是 1。dsh 对每个会话最多只发布一条(按优先级取最高的一条),所以它实际是个 0 / 1 状态位,不是队列长度。它由事件驱动而非定时器驱动:交互一出现或一消失,标签立刻重渲染,不必等下一次轮换。
审批能贡献多少,完全取决于该会话自己的权限预设(沙箱模式 + 审批策略,用 /permission 切换)——插件既不读也不改这个设置:
ask—— 敏感动作先问一句:审批面板等待期间计数为1,你点完(允许或拒绝)立刻回到0;never—— 审批提示被关闭:dsh 直接把这类请求判为拒绝,客户端根本不会建面板,所以审批不贡献任何计数。要注意这个计数不表达什么:被拒绝不算「待作答」,所以{pending}永远不会告诉你「刚才有动作被拒了」;- 提问是另一套域,与审批策略无关:即便在
never下,dsh 等你回答(比如计划评审)时{pending}依然可以是1。
所以 {pending} 只回答一个问题 —— 现在是不是在等我? —— 而 never 下能让它非零的只剩提问。旧版 dsh 没有待作答交互表时,它保持 0。
炫彩渐变
状态文字默认以流动的七彩渐变显示(仅作用于文案,不影响时钟)。v0.22.0 起渐变带两套配色 —— 黑夜(深色主题)与白天(浅色主题),默认跟随 DSH 界面的深浅色自动切换(mode: "auto");mode: "day" / "night" 可强制其中一套。切主题即时换色,不用刷新。流光方向也可选:direction 为 "rtl"(默认,从右向左)或 "ltr"(从左向右,与打字机同向,issue #41)。可在配置里关闭或自定义配色:
"gradient": {
"enabled": false, // false 关闭;true 用默认配色
"mode": "auto", // auto 跟随界面深浅色自动切换;day / night 强制其中一套
"direction": "rtl", // rtl 从右向左(默认);ltr 从左向右(与打字机同向)
"colors": ["#ff5f6d", "#00ff88", "#4da6ff"], // 黑夜(深色主题)颜色序列(至少 2 个,循环首尾)
"dayColors": ["#d92b4b", "#0e7490", "#6d28d9"], // 白天(浅色主题)颜色序列(至少 2 个,循环首尾)
"speed": 4 // 流动速度(秒/圈)
}
只写过 colors 的老配置会继续在两种主题下使用它(升级后观感不变);想要单独的浅色配色,加上 dayColors 即可。
弹幕模式
可选:所有文案随机生成视频网站弹幕,从右到左飘过页面(默认在界面后面——弹幕层夹在应用背景与聊天内容之间,可见于空隙,不遮挡聊天):
"danmaku": {
"enabled": true,
"intervalMs": 2500, // 发射间隔(毫秒);越小越接近刷屏
"speedMs": 18000, // 从右到左穿过屏幕的时长(毫秒);越大飘得越慢
"fontSizeMin": 14, // 随机字号下限(px)
"fontSizeMax": 30, // 随机字号上限(px)
"rainbow": true, // 炫彩:每颗弹幕从 colors 里随机取色
"colors": ["#ff5f6d", "#00ff88", "#4da6ff"], // 炫彩色板(至少 1 个)
"color": "#ffffff", // rainbow=false 时的单色
"opacity": 0.3, // 不透明度(0.05 ~ 1);每颗在此基础上取 75%~100% 抖动,更有层次
"maxCount": 12, // 同屏弹幕数量上限
"zIndex": -1, // 负数 = 界面后面(默认);非负数 = 浮于界面之上
"scope": "all", // all = 当前语言全部文案;phase = 只取当前阶段(带回退)
"marginTop": 16, // 弹幕活动区顶部留白(px)
"marginBottom": 160, // 底部留白(px),避开输入区
// ── v0.19 新增:顶部 / 底部弹幕(bilibili 风格)──
"types": { // 类型开关 + 相对权重;scroll = 原有滚动弹幕
"scroll": { "enabled": true, "weight": 2 },
"top": { "enabled": true, "weight": 1 },
"bottom": { "enabled": true, "weight": 1 }
},
"mode": "scroll", // 可选:强制所有弹幕都发成这一种(scroll/top/bottom,或 bilibili 的 1/4/5);不写 = 按权重分发
"fixed": { // 顶部 / 底部样式 —— 所有数值集中在这一处,改一句就全改
"fontSize": 25, // 字号(px)
"color": "#ffffff", // 单色:关闭炫彩时生效(默认白字)
"shadow": "1px 0 1px rgba(0,0,0,.85),-1px 0 1px rgba(0,0,0,.85),0 1px 1px rgba(0,0,0,.85),0 -1px 1px rgba(0,0,0,.85)",
"marginTop": 16, // 顶部弹幕距播放区域上边(px)
"marginBottom": 160, // 底部弹幕距播放区域下边(px)
"gap": 4, // 多条堆叠间距(px)
"durationMs": 4500, // 单条停留时长(ms)
"maxCount": 3, // 同类弹幕同屏上限
"zIndex": 10, // 前层层级:10 压住聊天内容、又低于外壳 overlay 层(20)
"reserveBands": true, // 滚动弹幕避开顶部/底部弹幕占用的竖直带(不叠字)
"anchorBottomToHost": true, // 底部弹幕贴住输入区上沿(状态行上方),而不是只靠 marginBottom
"overflow": "drop" // 超限处理:丢弃这一拍(与滚动弹幕一致)
}
}
zIndex为负(默认)时,弹幕层挂进画应用底色的那个元素内部(通常就是会话面板),夹在底色与聊天内容之间:弹幕在空隙和聊天后面可见,不会盖住气泡或侧边栏。如果主题背景不透明导致看不到,把zIndex调成非负数即可浮到界面之上——弹幕层pointer-events: none,永远不拦截鼠标操作;- 挂载点每次发射都会重新解析(v0.15.2 / v0.16.1 两次修的就是它):先按外壳的
data-shell-overlay找主框架,再取其中「最内层、画不透明底色、覆盖会话列大部分面积」的元素当宿主(给它加isolation: isolate);外壳还没渲染完时先落到document.body以可见层级显示,目标出现即搬进去。仍不可见就开debug,控制台里找danmaku layer mounted inside the background panel。 - 弹幕文案支持与状态文案相同的占位符(
{elapsed}、{model}、{phase}…),发射时用实时引擎当前值渲染; danmaku: false完全关闭;fontSizeMin/fontSizeMax构成随机字号区间(写反了自动纠正,并钳制到 8~96 px)。
与宿主弹窗共存:遮罩期间自动暂停(自 v0.25)
dsh 设置弹窗的遮罩是全屏 backdrop-filter: blur(2px) 层:弹幕层在它后面继续位移时,浏览器每帧都要重算全屏模糊,设置弹窗会持续闪烁(issue #60)。pauseBehindMask(默认 true)命中这种层就停掉弹幕——拆掉弹幕层与在途弹幕、清掉发射定时器、还原宿主的 isolation,遮罩一消失全部重建恢复。判定用四角 + 中心的命中测试(250ms 合流一次,2 秒一次 rescanAll 兜底),dsh 自己的菜单 / 卡片 / 提示这类小面积或没有模糊的层不会误判。
顶部 / 底部弹幕(bilibili 风格,自 v0.19)
danmaku.types 三种类型(滚动 / 顶部 / 底部)各有开关与权重,样式集中在 danmaku.fixed(字号、单色、描边、间距、停留时长、同类上限、层级、reserveBands 让滚动弹幕避开顶底车道、anchorBottomToHost 让底部弹幕贴住输入区上沿)。
mode可强制所有弹幕发成某一种(scroll/top/bottom,或 bilibili 的1/4/5);不写则按权重分发;- 顶部 / 底部弹幕默认样式与滚动弹幕不同(白字 + 描边,字号与停留时长独立),数值都在
danmaku.fixed一处; - ⚠️ 默认分布变了:配置里没有
types时三种都开(scroll 2 : top 1 : bottom 1),想保持 v0.19 之前的样子就把top/bottom的enabled设为false(或设置页关掉)。
浏览器标签页标题
可选:默认关闭。开着的时候,回合进行中让标签页标题也按模板轮换:
"title": {
"enabled": true,
"templates": ["⏳ {phaseLabel} {elapsed}", "🤔 {phaseLabel}… {elapsed}"], // 每 intervalMs 换一条
"idleTemplate": "💤 dsh 空闲", // 无回合时显示;"" = 把标题交还宿主
"intervalMs": 8000
}
模板支持与文案相同的占位符。没有回合进行中时显示 idleTemplate;idleTemplate 设为 ""(或关掉 enabled)就把标题交还宿主。title: false 完全关闭。
在设置页里改(v0.27.0 起):DSH「设置 → 状态文案 → 行为」页有「标签页标题」一组 —— 开关、模板(每行一条)、空闲时的标题、轮换间隔,保存后随其余设置一起写进插件的配置存储(升级不丢),不用手改 config.json。
只写自己的标题(重要):插件给 document.title 写入的前提是「这个标题是它自己写上去的」;从没接管过、或已经把标题交还之后,它一个字都不会碰 —— 包括宿主自己写的会话标题(<会话名> — DeepSeek Harness)和别的插件对标题的改动。关掉这个开关时,插件把最近一次宿主写的标题还回去,然后就不再插手。
v0.27.0 起插件只写自己接管过的标题:读回的值与启动时缓存不一致(宿主或别的插件写的)就交还并停手。此前是「值变了就写回去」,会把 oh-my-dsh 这类标题写者的成果顶掉(实测 2.6 秒内互相重写 10 次)。
预设与调度
预设 = 命名的词库快照(可带自己的 config),设置页一键切换,或按 schedule 规则自动切换:
"presets": [{ "id": "night", "name": "夜间", "phrases": { "zh": { "thinking": ["夜深了…"] } } }],
"activePreset": null,
"schedule": [{ "preset": "night", "days": [1,2,3,4,5], "from": "22:00", "to": "06:00" }]
days为0(周日)~6(周六);from/to支持跨零点(22:00→06:00);- 命中规则时自动切到该预设,离开时段回到
activePreset;设置页「自动化」tab 有可视化编辑器并实时显示当前生效的预设; - 预设里没写的键沿用全局配置。
配置
文案已从源码分离,全部放在 JSON 配置文件里。项目根有两个配置文件:
config.example.json— 入库的完整模板:默认配置 + 全部文案(中英双语,分三阶段);config.json— 你的本地个性化配置,由node gen-config.cjs初始化(仅当不存在时创建,不覆盖你的改动)。已被.gitignore忽略,随便改不会污染 git。
自动加载(默认):插件的 node half 注册了一个 HTTP route(/plugins/dsh-status-rotator/config.json)来 serve 插件同目录的 config.json(每次请求实时读文件)。浏览器端默认自动 fetch 它,并且页面保持打开时每 reloadIntervalMs 自动重读、切回标签页立即重读,所以只要 config.json 放在插件目录里,改完文案不用刷新页面、不用重启就会生效。首次安装才需要重启一次 dsh web。
可热重载的外部词库
v0.20.0 起,node 半区还会读取一个包外、可写的词库文件——默认 $DSH_HOME/status-rotator/phrases.json,可用环境变量 DSH_STATUS_ROTATOR_BANK 覆盖(绝对路径,或相对进程工作目录)。它是与 config.example.json 同构的普通 JSON,只写要覆盖的键即可,最小的一份通常就是一个包的一个阶段:
{ "packs": [{ "id": "china-ai", "phrases": { "zh": { "thinking": ["正在飞唐杰马…"] } } }] }
node 半区每次请求都会检查这个文件:变了就重新读取解析(mtimeNs + size 走快速路径,再比内容,同一时间粒度内的改写也不会漏),浏览器半区在下一次 reloadIntervalMs 轮询时拿到新内容——不用重启进程、不用重装包、也不用重发一次 npm 包。规则:
- 只取文件里的
packs/phrases,里面的config会被忽略——运行时选项仍然只由设置页 /config.json管理; - 外部词库是优先级最高的词库层:生效文档按 内置
config.example.json→config.json→ 自动更新词库 → 用户配置存储 → 外部词库 合并;词库包按id逐条合并,写一个包不会动到另外 11 个。想让某个包回到设置页管理,把该包从外部词库文件里删掉即可(词库内容不会被算成你的改动写进配置存储或兼容镜像,所以删掉之后随包 / 上游那份立刻回来); - 内置词库始终是兜底:文件不存在时行为与之前完全一致;文件损坏时保留上一次成功加载的内容继续服务,错误可从
externalBankStatus()读到; - 单进程自验:
node scripts/verify-phrase-hot-reload.cjs会 apply 插件、起一个真实 HTTP server、GET 路由,然后连续两次改写词库文件再 GET,全程不重启。
词库自动更新
v0.21.0 起 node 半区每 6 小时拉一次上游 main 的 config.example.json(默认走 jsDelivr,选它是为了可达性),缓存到 $DSH_HOME/status-rotator/bank.remote.json。响应与其它词库层同样校验,只留 packs / phrases,内容真的变了才原子写盘 —— 所以合进 main 的投稿、每周的 star 包刷新都能到达正在运行的实例,不用重启、重装或重发 npm 包。
DSH_STATUS_ROTATOR_BANK_URL—— 上游地址(可换自己的镜像);off或留空 = 关闭自动更新;DSH_STATUS_ROTATOR_BANK_INTERVAL_MS—— 检查间隔(毫秒,0= 关闭);不设 = 6 小时。
上游更新只作用于你没显式改过的包:设置页改过的包、或在本地词库文件里声明过的包仍以你为准。上游新增的包会合并进来,但在发版带上 enabledPacks 之前保持关闭(自动更新层刻意不带 config)。拉取失败(CDN 不可达 / HTTP 错误 / JSON 非法 / 空文档)只记进 remoteBankStatus(),继续用上一次成功的副本。默认会周期性向 jsDelivr 发请求,想完全本地化就设 BANK_URL=off 或间隔 0。
持久化存储(v0.6.1 起;v0.26.1 起真正落在插件自己的数据目录):保存的设置写入 $DSH_HOME/status-rotator/config.json(可用 DSH_STATUS_ROTATOR_CONFIG 覆盖)——与词库文件同目录,不属于任何包,升级插件不会碰它。
- 旧方案两次静默失效:配置曾在插件目录里(升级即被替换),后来改存 dsh 官方设置存储,而 0.1.7-rc.1 的 settings 服务没有
register(),整条链路失效 → 设置又被重置(issue #51)。v0.26.1 起持久化不再依赖宿主设置 API 的形状。 - 插件目录的
config.json保留为兼容镜像:保存时照样写一份,README 允许的「直接改文件」也照旧 —— 手改内容会在它还在时被搬进用户配置存储(每次 GET 检查,最迟一个reloadIntervalMs)。 - 存储里只存与随包默认的差异,装载时按 内置默认 →
config.json→ 自动更新词库 → 用户配置存储 → 外部词库 合并;带id的数组(词库包、预设)按 id 逐条比,每次保存都从零重算差异 —— 所以把某项改回默认值就是把它从存储里去掉,老安装里整份词库也会收敛(实测 82,966 B → 1,586 B,词条零丢失)。
版本变更史见 CHANGELOG.md。升级插件后重启一次
dsh web让 node 半区加载新代码,客户端半区刷新页面即可。
{
"config": { "intervalMs": 10000, "typeSpeedMs": 30, "longAfterMs": 60000, "reloadIntervalMs": 15000, "liveTickMs": 1000, "labelSource": "phrases", "weightedRandom": true, "debug": false, "fontWeight": "inherit", "gradient": { "enabled": true, "colors": ["#ff5f6d", "#ffc371", "#ffdd55", "#7dff7d", "#5fd4ff", "#a78bfa", "#ff8adb"], "speed": 4 }, "title": { "enabled": false, "templates": ["⏳ {phaseLabel} {elapsed}", "🤔 {phaseLabel}… {elapsed}"], "idleTemplate": "💤 dsh 空闲", "intervalMs": 8000 }, "danmaku": { "enabled": true, "pauseBehindMask": true, "intervalMs": 2500, "speedMs": 18000, "fontSizeMin": 14, "fontSizeMax": 30, "rainbow": true, "colors": ["#ff5f6d", "#ffc371", "#ffdd55", "#7dff7d", "#5fd4ff", "#a78bfa", "#ff8adb"], "color": "#ffffff", "opacity": 0.3, "maxCount": 12, "zIndex": -1, "scope": "all", "marginTop": 16, "marginBottom": 160 } },
"phrases": { "zh": { "thinking": ["…"], "running": ["…"], "long": ["…"] }, "en": { "thinking": ["…"], "running": ["…"], "long": ["…"] } },
"packs": [], // 可选,见「词库包」(默认配置自带 12 个主题包)
"enabledPacks": null, // null/缺省 = 全部启用;默认配置钉在 10 个非 star 包上
"presets": [], // 可选,见「预设与调度」
"activePreset": null, // 可选预设 id
"schedule": [] // 可选时段规则
}
| 键 | 默认 | 说明 |
|---|---|---|
intervalMs |
10000 | 轮换间隔(毫秒) |
typeSpeedMs |
30 | 打字机每字符间隔(毫秒),0 关闭打字机 |
longAfterMs |
60000 | 进入 long 阶段的阈值 |
reloadIntervalMs |
15000 | 页面打开时自动重读 config.json 的间隔(毫秒),0 关闭 |
liveTickMs |
1000 | 实时占位符({elapsed} / {date} / {time} / {tps} 等)在文案与标题里的刷新间隔(毫秒),0 关闭 |
weightedRandom |
true | 加权随机抽取;false = 完全均匀。文案条目可为 "text" 或 { "text": "...", "weight": 3 }(weight 为正数,上限 1000,非法/缺省按 1) |
debug |
false | 控制台诊断日志 |
fontWeight |
"inherit" |
状态文字 / 弹幕的字体粗细:数字(1normal/bold/bolder/lighter);"inherit" = 跟随界面(默认;弹幕保持原有的 600) |
labelSource |
"phrases" |
状态行文案来源:"phrases" = 轮换短语库;"host" = 只用宿主原文(Deep diving... / 深度求索中),外观逐项对齐 0.1.6 的 .turnStatus。短语库为空时两种模式都回落宿主原文,见 状态行文案来源 |
gradient |
见上 | 炫彩渐变:false / true / {enabled, mode, direction, colors, dayColors, speed}(mode:auto 跟随深浅色,day / night 强制;direction:rtl 默认 / ltr 从左向右) |
title |
见上 | 标签页标题:false / {enabled, templates, idleTemplate, intervalMs} |
danmaku |
见上 | 弹幕模式:false / {enabled, pauseBehindMask, intervalMs, speedMs, fontSizeMin, fontSizeMax, rainbow, colors, color, opacity, maxCount, zIndex, scope, marginTop, marginBottom, types, fixed};pauseBehindMask 默认 true,见「与宿主弹窗共存」 |
phrases |
来自配置文件 | 文案(中英 × 三阶段;可只写部分,缺的用其它源回退) |
packs |
无 | 词库包:[{ id, label?, phrases? }],按顺序并入生效词库(按文本去重) |
enabledPacks |
null(全部) | 已启用的词库包;null/缺省 = 全部,[] = 只用核心词库。默认配置列出 10 个非 star id,因此 star-ask / star-route 默认关闭 |
presets |
无 | 命名词库,每项可带独立的 config / phrases |
activePreset |
null | 当前启用的预设(null = 用顶层 config/phrases) |
schedule |
无 | 自动切换预设的时段规则 |
取值保护:数值字段在保存与加载时都会钳制(轮换间隔 ≥ 250ms、打字机 ≤ 1000ms/字、弹幕发射间隔 ≥ 200ms、同屏上限 ≤ 60、层级 ±1000 等);颜色只接受 #rrggbb / rgb() / hsl() / CSS 颜色名,非法值会被丢弃并在设置页标红。原因很实在:颜色会被拼进注入的 <style>,数值会直接喂给 setInterval。
写接口只接受同源请求:PUT/POST /plugins/dsh-status-rotator/config.json 要求 content-type: application/json 且来源与 Host 同源(sec-fetch-site 只允许 same-origin / none),跨站请求一律 403 —— 否则任意网页都能改写你的本地配置。
文案来源优先级,从高到低:
- localStorage 单条覆盖
dsh-status-rotator.texts[.<locale>]/texts; - localStorage 完整配置
dsh-status-rotator.config(粘贴 JSON,刷新生效); - 外部 JSON:
dsh-status-rotator.url>EXTERNAL_URL常量 > 本地自动加载(/plugins/dsh-status-rotator/config.json); - 内置默认值:仅
lib/client.js顶部的DEFAULT_CONFIG(不含文案)。
如果 localStorage 覆盖命中,外部 config.json 会被静默压住;新版本会在浏览器控制台输出一条 [status-rotator] ⚠ localStorage 覆盖生效 告警,看到它就去清掉对应键。
旧的纯文案外部 JSON({ "zh": [...], "en": [...] } 或 { "thinking": [...] })依然兼容,视为"只带文案的配置"(扁平数组落到 thinking 组)。
文案跟随「设置 → 语言」在中英文之间实时切换,未知语言回退到中文。
设置页
打开 DSH 左下角「设置」,导航里会多出一页 状态文案。页面按语义拆成四个 tab,排版与官方插件设置页同规格(760 列,同一套 tab / 字段 / 输入框语言):
文案
- 编辑目标 —— 一个下拉覆盖基础词库、任意预设(
preset:<id>)与任意词库包(pack:<id>),保存时按它决定写进哪里;目标失效(预设或包被删)自动退回基础词库; - 中文 / English 两个标签页,各含
thinking/running/long三个文本框,每行一句,空行自动忽略;行内写文案 | 权重可设置该句权重,每个阶段实时显示句数; - 词库包开关 —— 逐个启用/停用主题包(十个非 star 包默认全开);
- 预设管理 —— 选预设、新建、就地改名(名称按当前编辑语言保存)、删除(引用它的调度规则会一并移除)、「设为当前」写入
activePreset。
外观
- 字体粗细(状态文字与弹幕共用);
- 炫彩渐变:启用开关、配色模式(跟随界面深浅色 / 强制白天 / 强制黑夜)、流动方向(从右向左 / 从左向右)、白天 + 黑夜两套颜色序列、流动速度;
- 弹幕:启用开关、发射间隔、穿越时长、随机字号范围、炫彩开关 + 色板、透明度、同屏上限、层级与文案范围。
行为
- 轮换间隔、打字机速度、长任务阈值、自动重读间隔、占位符刷新间隔、加权随机开关。
自动化
- 调度编辑器:以列表增删「星期 + 时段」规则,自动切换预设;页面上实时显示当前生效的预设(含调度命中)。
整页通用:
- 改动即保存:开关与下拉立即写盘,文本 / 数值停顿 400ms 写盘(预设改名在失焦时),没有保存按钮,只有写盘失败时工具栏标红;
- 每次写盘把整份 JSON
PUT到/plugins/dsh-status-rotator/config.json,node half 校验后原子写回,已打开页面立即热应用;非法内容返回 400 并在页面报错,不会写坏文件; - 切换编辑目标 / 「重读」都会先落盘再操作,草稿不会被静默丢弃;数值越界即标红,偏离默认时出现「恢复默认」;页脚直接跳源码仓库。
升级到带设置页的版本后,需要重启一次 dsh web(让 node half 注册写接口),之后全部在页面里操作即可。
QQ 群成员文案生成器
想要把某个 QQ 群的每个成员变成一句 正在路由(群成员)写代码... 文案时,用 scripts/fetch-qq-group.cjs 一键生成独立配置文件,不用手抄群成员名单。
前置条件:机器人在目标群内且你有 OneBot v11 兼容 HTTP API(如 NapCat / LLOneBot / go-cqhttp / OpenShamrock)。
# 默认群号是占位符 0——务必用 -g 传你自己的群号,否则默认只生成 config.qq0.json
node scripts/fetch-qq-group.cjs --group 123456789 --url http://localhost:3000 --token 你的token
# 直接替换插件实际使用的 config.json(旧的自动备份为 config.backup-<时间戳>.json)
node scripts/fetch-qq-group.cjs --group 123456789 --url http://localhost:3000 --token 你的token --activate
# 没有机器人接口?把群成员名单存成 members.txt(每行一个昵称)再生成
node scripts/fetch-qq-group.cjs --input members.txt
| 选项 | 默认 | 说明 |
|---|---|---|
-g, --group |
0(占位符) |
QQ 群号(也读环境变量 QQ_GROUP_ID)。0 是故意的无意义默认值——务必传真实群号,如 --group 123456789 |
-u, --url |
http://localhost:3000 |
OneBot HTTP 地址(也读 ONEBOT_HTTP_URL) |
-t, --token |
空 | access token(也读 ONEBOT_ACCESS_TOKEN) |
-a, --action |
get_group_member_list |
动作路径(也读 ONEBOT_ACTION),带前缀的框架改 /api/... |
-i, --input |
无 | 本地名单:txt(每行一个)/ json(数组)/ csv(第一列) |
-o, --output |
config.qq0.json |
输出文件 |
--activate |
关 | 直接写回 config.json 并备份旧文件 |
--dry-run |
关 | 只预览不写文件 |
显示名优先取群名片,没有群名片再取昵称。生成的文件只有 zh.thinking 一组:按照本插件的回退规则,thinking 阶段直接用,其余阶段自动回退到同一组。生成产物 config.qq*.json 已被 .gitignore 忽略。
项目结构
dsh-status-rotator/
├── .github/
│ ├── workflows/
│ │ ├── phrase-submit.yml # 词库投稿机器人(issue opened → 校验 → 自动开 PR)
│ │ ├── release.yml # 打 tag 发布 GitHub Release
│ │ ├── star-pack.yml # 用仓库自带的 GITHUB_TOKEN 刷新 star-ask / star-route
│ │ └── test.yml # 每次 push / PR 跑 npm test
│ └── ISSUE_TEMPLATE/
│ └── phrase-submit.yml # 「词库投稿」表单模板(自动打 词库投稿 标签)
├── lib/
│ ├── index.js # node half:注册 config.json 的 HTTP 路由(GET/PUT,带校验)
│ └── client.js # client half:状态文字替换 / 占位符 / 渐变 / 标题 / 弹幕 / 预设
├── config.example.json # 完整模板(默认配置 + 全部 1078 条文案,分 12 个词库包,入库)
├── config.json # 本地个性化配置(被 .gitignore 忽略)
├── gen-config.cjs # 初始化 config.json 的脚本
├── cordis.patch.yml # dsh bundle patch manifest(被 package.json 的 dsh.bundle.patch 引用)
├── scripts/
│ ├── fetch-qq-group.cjs # 抓取 QQ 群成员并生成文案配置
│ ├── check-bank-memes.mjs # 词库质检(开发期):查重/超长/省略号/系列占比
│ ├── package-release.cjs # 打包发布文件
│ ├── phrase-bot.cjs # 词库投稿机器人(解析表单 / 校验 / 写入词库 / 开 PR)
│ ├── smoke-test.cjs # 纯函数冒烟测试(npm test)
│ ├── sync-bank-counts.cjs # 词库计数同步:从 config.example.json 现算并写回 README/描述/注释
│ ├── update-star-pack.cjs # 从星标名单重建 star-ask / star-route
│ ├── verify-phrase-hot-reload.cjs # 外部词库热重载验证:改完文件不重启即可生效(dev-only)
│ ├── verify-bank-auto-update.cjs # 词库自动更新验证:本地上游 A→B→500,全程不重启(dev-only)
│ ├── verify-settings-survive-upgrade.cjs # 设置跨升级存活验证:手改 config.json / 设置页保存 → 升级 → 设置仍在(#51,dev-only,CI 也跑)
│ ├── danmaku-mount-test.html # 弹幕挂载点的真浏览器回归页(dev-only)
│ ├── label-layout-test.html # 状态行布局回归页:锁宽/截断/配色回退/设置页渲染(dev-only)
│ ├── live-pending-test.html # {pending} 实时刷新回归页:待作答交互 → 标签(dev-only)
│ ├── title-coexistence-test.html # 标签页标题所有权回归页:与 oh-my-dsh 品牌替换共存(v0.27.0,dev-only)
│ ├── run-danmaku-mount-test.cjs # 无头驱动上述回归页(--page=danmaku|label|pending|title,dev-only)
│ ├── turn-process-017-test.html # 0.1.7+ 状态行回归页:折叠头接管/简回合/宿主原文回落/0.1.6 观感比对(dev-only)
│ ├── run-turn-process-test.cjs # 无头驱动 0.1.7+ 状态行回归页(dev-only)
│ ├── probe-danmaku-live.cjs # 探针:检查正在运行的 dsh web 弹幕挂载点/绘制顺序(dev-only)
│ └── unify-ellipsis.cjs # 默认词库省略号统一 / 完整性校验
├── package.json
├── README.md # 英文文档
├── README_ZH.md # 中文文档
├── CHANGELOG.md # 更新日志
├── CONTRIBUTORS.md # 英文贡献者
├── CONTRIBUTORS_ZH.md # 中文贡献者
└── LICENSE
仅本地存在、不入库的产物:
demo-wallpapers/、.dsh-web-restart/、dist-release/、config.qq*.json、config.backup-*.json——都列在.gitignore里。
通过 Issue 投稿词库
在仓库 Issues 选 「词库投稿」 表单:语种(zh / en / 两种都要)、分组(thinking / running / long)、目标词库包(默认 community)、文案(一行一条,最多 60 条,单条 ≤200 字符)、可选署名。
会被拒绝的写法:行内出现分号 ; ; ﹔ ;(分号串起来的整行只会读成一条连不通的长句;中文冒号 :、逗号 ,、顿号 、 不受影响)、HTML / 链接 / 控制字符、与现有词库重复、未勾选提交须知。被拒会收到 ❌ 原因说明,改完重新提交即可。
机器人接手后:校验并归一化(... → …、末尾补 …)→ 在 Issue 里回复预览表格与**「立即试用」JSON**(粘到设置页即可看到效果)→ 开一个改 config.example.json 的 PR(带 词库投稿 标签),维护者点 Merge 即收录,随下一次 npm 发版分发。
- 分支自动跟随 main:main 前进(以及每 6 小时、手动触发)时,机器人把每条开着的投稿分支按当前 main 重建,PR 永远可合并 —— 不需要人工解
config.example.json的冲突(手工解容易出重复键,JSON.parse会静默丢掉前一个,条目无声少一半); - 规则变了会复核:不再合规的投稿会在 PR 与 Issue 上写明原因并自动关闭 PR;机器人读库 / 写盘回读都查重复键,
npm test也断言config.example.json无重复键; - 只追加进目标词库包,不改代码、不碰默认词库本体;被收录的投稿记入 CONTRIBUTORS.md。实现见 .github/workflows/phrase-submit.yml 与
scripts/phrase-bot.cjs。
测试
npm test(node scripts/smoke-test.cjs)在 Node 沙箱里加载 lib/client.js 跑纯逻辑断言:占位符插值、时长格式化、时钟解析、配置 / 预设 / 调度归一化、调度匹配、node half 的配置校验、词库计数与文档一致;CI 每次 push / PR 都跑(.github/workflows/test.yml)。
依赖真实 DOM 的部分(弹幕挂载、状态行锁宽 / 截断 / 配色回退、{pending} 实时刷新、标签页标题所有权)另有四个真浏览器回归页,由 npm run test:browser 用 CDP 无头跑完(需要本机 Edge / Chrome):
| 页面 | 覆盖 |
|---|---|
danmaku-mount-test.html |
挂载时序、顶 / 底弹幕、宿主全屏模糊遮罩下的暂停与恢复 |
label-layout-test.html |
打字机锁宽、超长截断、配色非法回退、设置页渲染 |
live-pending-test.html |
真插件跑 pending 0 → 1 → 0 → 1,以及无 uiSession 服务时的兜底 |
title-coexistence-test.html |
标签页标题所有权:与 oh-my-dsh 的品牌替换共存 |
单跑用 npm run test:browser:label / :pending / :title;0.1.7+ 状态行另有 node scripts/run-turn-process-test.cjs(15 档:折叠头接管、回合结束交还、座位缺失降级、观测徽标、labelSource: "host" 与 0.1.6 逐项比对)。手动打开页面时用 URL 参数切场景(?modes=1、?mask=1、?case=…、--page=danmaku|label|pending|title)。
卸载
从 cordis.patch.yml 删掉 status-rotator 那一行,重启 dsh web 即可。
贡献
欢迎提交 Issue 和 Pull Request。加新文案最简单的方式:直接编辑 config.json 或 config.example.json 的 phrases 字段,不需要动任何代码;或者用上面的 通过 Issue 投稿词库,机器人会自动帮你校验并开好合并请求。
致谢
本项目的诞生离不开贡献者的帮助,详见 CONTRIBUTORS_ZH.md。
License
链接
同类插件
zhu1090093659/dsh-web#packages/dsh-task-board★ 8076
侧边栏多列任务看板:卡片交给真实 DSH 智能体会话执行,支持 cron 定时(Host 侧到点执行,关浏览器也生效)。
zhu1090093659/dsh-web#packages/dsh-web-all★ 8076
DSH Web UI 插件与皮肤合集:任务看板、git 图、右侧面板、远程移动端 UI、桌宠、实时 token 统计与皮肤中心。
omdsh-dev/DSH-better-sidebar★ 3828
侧边栏完整工作台:内置文件渲染编辑、终端、Git 与子代理,支持三方插件注册新 Tab。
ccch1mneyyy/dsh-TUI★ 3661
Claude Code 风格全屏终端 UI:像素鲸鱼顶栏、实时工作状态行、思考流式展开。
MeteorNOX/DeepSeek-Balance-Whale-Widget★ 3277
右下角常驻的小鲸鱼挂件:余额、今日已用与每轮对话消耗(含峰谷价),余额预警与今日预算的泡泡内容都可编辑;泡泡点击序列模块化自定义,支持并列加权 A/B、随机台词与随机图片;内置 30+ 厂商模板(OpenAI / OpenRouter / Kimi / 硅基流动 / 方舟 / 智谱 / MiniMax 等),按模型查余额与订阅额度;另有任务结束音效、导入音频、自定义角色与资源管理。数据全在本机,无遥测。
Devin-AXIS/deepseek-design#deepseek-idesign★ 1628
可视化设计工作室,支持网站、App 原型、海报、信息卡、报告和杂志的模板创建、元素编辑、选区级 AI 草稿衔接与导出。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。