dsh-todo-dock: Pin the DSH Web todo panel to the top-right corner, so it doesn't disappear across wheels.

前言

在 DSH 的 Web GUI 里,todo 面板由内置组件挂在 conversation.input.dock 槽(order: 0),默认显示在聊天输入框上方。这里有两个问题:一是面板占文档流,挤占输入区空间;二是原生机制下,turn/start(用户发消息开启新一轮)会把 todos 投影清空,面板随之整体消失,要等 agent 本轮重新调用 todo_write 才会回来。如果你的工作流依赖任务列表跟踪进度,这两个行为都会打断节奏。

下面介绍 dsh-todo-dock。它针对这两点做处理:一段 CSS 注入把面板钉到右上角,一段 host 侧重放逻辑让列表跨轮保持可见。

这是什么

dsh-todo-dock 是一个 DeepSeek Harness Web GUI 插件,作者是 lsxblh,License 为 MIT,当前版本 0.3.2。v0.3.0 起由 dsh-ui-todo-fix 更名为 dsh-todo-dock(v0.2.x 及更早均为原名)。

它是纯 Host 插件,零依赖,核心代码约 50 行,走官方注入钩子 webServer.tapIndex 注入(与内置主题插件同构),不碰任何组件逻辑。标准 dsh.bundle 形态,dsh plugin add 会自动登记进 profile bundles。

核心功能

面板停靠右上角

插件向 index.html 注入一段 <style>,把 todo 面板(section[data-testid="todo-panel"])用 position: fixed 钉到右上角,加阴影、圆角和滚动,不占文档流、不挡输入。包内 lib/index.jsDEFAULT_CSS 是内置默认样式,装完即有默认效果:

body section[data-testid="todo-panel"]{
  position: fixed; top: 104px; right: 16px;
  width: 320px; max-width: min(320px, calc(100vw - 32px));
  z-index: 9999; margin: 0;
  box-sizing: border-box;
  box-shadow: 0 8px 32px rgba(0,0,0,.35);
  max-height: calc(100vh - 120px); overflow-y: auto;
}

注意:TodoPanel 是条件渲染的——当前会话没有 todo 任务时不显示面板,这是产品行为,与插件无关。

跨轮常驻

原生机制是 turn/start 把 todos 投影清空,面板消失,直到 agent 本轮重新调用 todo_write。本插件在 host 侧监听 session/event:按会话记录最近一次 todo/write 的列表,turn/start 后立即重放一条 todo/write。这样任务列表跨轮保持可见,任何 agent 都无需额外动作,不依赖 agent 的行为习惯(v0.2 新增)。

默认开启;config.keepAcrossTurns 设为 false 可关闭,恢复原生行为。两点边界需要知道:

1、agent 主动清空(写入空列表)后不会复活。
2、每次 turn 会在会话事件流多追加一条 todo/write——这是合法事件,仅用于恢复。

跨重启恢复

v0.3.2 新增。关闭重开 dsh 后,重开同一会话时,插件会从 DSH 已持久化的会话日志恢复最后一条 todo 列表。实现上是零新增存储:懒扫描 + 增量游标。进程重启后游标为空,首个 turn/start 会从该会话的持久化事件日志倒序懒扫描最后一条 todo/write(仅此一次,之后增量 O(1));日志里没有 todo(新会话,或已被 compaction 剪掉)则安全回退为不重放。

健壮性加固

v0.2.1 / v0.3.2 做了四项加固:非数组 junk 不重放;Map 随会话销毁清理;重放错误隔离;日志无 todo 时安全回退。tests/ 目录附回归测试,可用下面的命令运行:

node tests/keep-across-turns.test.mjs

安装与启用

依赖 DSH Web profile。dsh plugin 基于 pnpm,需本机已安装 pnpm。

1、安装插件。方式一,GitHub 发布包(推荐):

dsh plugin --profile web add https://github.com/lsxblh/dsh-todo-dock/archive/refs/tags/v0.3.2.tar.gz

方式二,本地源码目录:

dsh plugin --profile web add file:/path/to/dsh-todo-dock

2、重启一次 dsh web 服务(bundle 层在启动时组合)。

3、刷新页面,面板即出现在右上角。

样式热调

注入的 CSS 默认取包内 DEFAULT_CSS。想覆盖或调整,在 ~/.dsh/profiles/web/cordis.patch.yml 追加 id/name 为 dsh-todo-dock 的条目,设置 config.css

- id: dsh-todo-dock
  name: dsh-todo-dock
  config:
    css: |
      body section[data-testid="todo-panel"]{
        position: fixed; top: 104px; right: 16px;
        width: 320px; z-index: 9999; margin: 0;
        box-shadow: 0 8px 32px rgba(0,0,0,.35);
      }

改完无需重启:HMR 自动应用,刷新页面即生效。

卸载 / 回滚

dsh plugin --profile web remove dsh-todo-dock

如果改过 cordis.patch.yml,把相关 override 行一并删除。

适用场景与注意

适合在 DSH Web GUI 里用 todo 列表跟踪多步任务、希望列表常驻可见、不想让它挤占输入区的使用者。配置项只有两个:config.keepAcrossTurns(关掉跨轮常驻,恢复原生行为)和 config.css(覆盖默认 CSS)。

安装前注意:

1、插件以当前 dsh 进程权限运行,安装前建议先检查源码(仓库见文末)与许可证(MIT)。
2、依赖 DSH Web profile 和本机 pnpm。
3、面板是否显示取决于当前会话有没有 todo 任务,没有时 TodoPanel 不渲染,这是产品行为。
4、开启跨轮常驻后,每次 turn 会在会话事件流多追加一条 todo/write

结尾

总结:dsh-todo-dock 用一段 CSS 注入加 host 侧机制级重放,解决了 DSH Web todo 面板的停靠位置和跨轮消失两个问题,改动不碰组件逻辑,样式可热调,跨重启也能恢复,卸载也只需一条命令。

  • GitHub 仓库:https://github.com/lsxblh/dsh-todo-dock
  • 社区插件目录页:https://www.skillhub.cn/plugins/lsxblh/dsh-todo-dock
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye