dsh-live-notify
为模型提供 UpdateNotify 工具,并在 DSH Web UI 输入框上方停靠一个实时进度窗,让模型在一轮任务进行中随时播报刚做了什么、发现了什么、在等什么。
安装
dsh plugin --profile web add dsh-live-notify
沙箱测试
这个插件还没测过。提交测试 →
README
dsh-live-notify
停靠在 DSH Web UI 输入框上方的实时进度窗,外加一个给模型用的 UpdateNotify 工具。
中文 | [English](#english)
模型在干活的过程中随时播报「刚刚发生了什么、发现了什么、在等什么」,你不需要等它
把整轮跑完才知道它卡在哪。
它解决什么问题
待办清单和进度播报回答的是两个不同的问题,所以这个插件是**在 todo 工具旁边再加一条
通道**,而不是把 todo 做大:
· TodoList(todo_write 之类) · UpdateNotify(本插件)
本质 · 结构化任务清单 · 叙事式进度播报
回答 · "还剩哪些事、做到哪了" · "刚刚发生了什么、发现了什么、在等什么"
数据 · 一组 {content, status},整表替换 · 一条 title + 一段轻 Markdown message
生命周期 · 跨回合持久的计划 · 回合内的流式更新,新回合清空
适合 · 开工前列计划、跟踪完成度 · 多步任务中报阶段结论、长耗时等待、阻塞、方向调整
信息量 · 短、逐项 · 可带证据、文件路径、报错片段(~1000 字符)
未使用时的风险 · 用户不知道你当前在做什么 · 计划无法表达"为什么"和"发现了什么"
简单说:TodoList 是计划与完成度,UpdateNotify 是过程与结论。
前置条件
- 一个带插件机制的 DSH(Harness)宿主,且宿主已提供
@deepseek-ai/dsh-client-ui-conversation
(本插件的面板挂在它提供的 conversation.input.dock 槽位上)。
- 插件本身零运行时依赖:
dependencies是空的,装插件不会往 profile 里拖任何包。 - 只有在改这个仓库时才需要 Node.js ≥ 22 和 Bun(Bun 负责装依赖、跑
lint/format 和打包;测试用 Node 内置的 node:test)。
面板位置和可用性取决于宿主版本:宿主没有该槽位时,工具与投影照常工作,只是没有面板。
安装
本包发布到 npm,同时以 tarball 形式可用:
# 方式一:直接按包名安装到当前 DSH profile # 在 Harness 的插件管理里执行 install_bundle,target 用包名 dsh-live-notify # 方式二:离线 / 指定版本,用打包产物安装 bun pm pack # 或 npm pack;得到 dsh-live-notify-<version>.tgz # 再执行 install_bundle,target 用该 tarball 的绝对路径
安装会写进 $DSH_PROFILE_DIR/node_modules/dsh-live-notify。
升级时的注意点:Client 半(client.js)随页面刷新就会换新;**Host 半(host.js)
是已加载的 JS 模块,改完必须重启一次 dsh web 才会生效**。重启不会丢会话历史——
投影是按 stateVersion 从会话日志重新折叠出来的。
使用
模型侧只有两条参数:
title(可选):单行纯文本,建议 ≲60 字符,作为结论或当前阶段独立可读。message(必填):轻 Markdown,开头 2–4 句散文讲证据与推理,细节用要点 / 短段落 /
key-value 行(可带文件路径、报错片段),建议 ≲1000 字符。
宿主侧的限制:title 硬上限 120 字符(超出截断加省略号),message 硬上限 4000 字符,
面板保留本回合最近 12 条。参数校验与工具描述一致(title 不许换行且不许为空,
message 不许为空)。
你不需要手动做什么:系统提示里有一段 guidance 要求模型主动播报,并且连续 8 个工具
调用轮次没有更新时会通过动态 runtime context 提醒模型补一条。
设计要点
- 结果确认后才上屏:
tool/call先落到 projection 的pending,只有配对的
tool/result 且不是错误时才提交到面板。模型谎报「已通知」也骗不到面板。
- 不新增会话事件类型(这是本插件最要紧的一条约束):进度已经天然存在于普通
tool/call / tool/result 事件里,投影只是对既有事件的纯折叠。会话日志仍是唯一
事实来源,所以恢复、分叉、回放都免费可用;也不会出现「打开一个含未知事件类型的旧
会话就报错」这类问题——Session.append 无法把仓库外的事件类型标记为 ignorable。
- 回合内保留、结束后仍可见:新回合开始才清空,上一回合的结论留到你读完。
- 只用宿主主题 token:CSS 只消费
--dsw-alias-/--dsh-变量,不写死颜色,
跟随宿主的深色 / 浅色主题。
- 可访问:键盘可展开,
aria-live="polite"播报新标题,尊重
prefers-reduced-motion。
实现
- Host 半(
host.js):注册UpdateNotify工具 +liveNotify会话投影
(stateVersion: 3)+ 系统提示 section + 每 agent 的轮次计数器(agent/created /
agent/session/event)驱动的 8 轮提醒。
- Client 半(
client.js):在conversation.input.dock注册一条 entry,通过槽位标准
的 useProjection(PROJECTION_KEY) 读取宿主机算好的值,客户端不做任何会话折叠;
zh / en 双语。
文件
文件 · 用途
host.js · Host:UpdateNotify 工具 + liveNotify 投影 + 提示/nudge
client.js · Client:输入框上方的实时进度窗
cordis.patch.yml · Loader 行(id: live-notify)
package.json · bundle manifest + dsh.client 声明
locale/*.json · 插件管理页显示文案
icon.svg · 插件管理页图标
test/*.test.js · node --test 测试(host 折叠 / 工具契约 / 打包与客户端不变量)
.oxfmtrc.json · oxfmt 配置(Markdown 交给 .prettierignore 排除,CJK 段落手工折行)
开发
包管理器是 Bun(bun.lock 已提交);测试跑在 Node 内置的
node:test 上。
bun install bun run test # node --test test/*.test.js bun run lint # oxlint . bun run fmt # oxfmt .(格式化;bun run fmt:check 只检查) bun run check # 语法检查 host.js / client.js bun pm pack # 打包产物 bun publish # 发布到 npm(需要先 bunx npm login)
测试不需要宿主:apply() 通过一个 stub registrant context 驱动,逐条事件重放投影;
另外一组静态检查盯着打包清单、loader id、双语词表对齐、主题 token 与「模型输出不走
HTML 注入」这类不变量。CI 在 Node 22 / 24 上跑 check → lint → fmt:check → test → pack。
安全
模型输出按纯文本处理:轻 Markdown 渲染器把段落、要点、行内代码渲染成 React 元素,
不用 dangerouslySetInnerHTML,也不解释 HTML。面板不发起网络请求,不读本地文件;
数据来源就是会话日志本身。
许可证
[Mozilla Public License 2.0](./LICENSE)(MPL-2.0)。
MPL 是文件级 copyleft:可以自由使用、修改、再分发,包括商用与闭源组合;但对
本仓库源文件的修改,在分发时需要同样以 MPL-2.0 提供对应源文件。npm 包内已包含全部
源码(host.js / client.js),因此「源码可得性」这一条随之满足。
English
A live progress panel docked above the composer in the DSH Web UI, plus an
UpdateNotify tool for the model.
While a task runs, the model narrates what it just did, what it found, and what
it is waiting on — so you are not left guessing until the whole turn finishes.
Why not just a todo list
A todo list is a durable, structured plan: what is left. This is a narrative
progress channel: what just happened, what was learned, what is being waited on.
They are complementary, so the plugin sits next to a todo tool instead of
replacing it. Todos persist across turns; progress updates live inside a turn
and stay on screen after it ends.
Requirements
- A DSH (Harness) host with the plugin mechanism, providing
@deepseek-ai/dsh-client-ui-conversation — the panel is registered on the
conversation.input.dock slot that package contributes. Without that slot the
tool and the projection still work, there is just no panel.
- The plugin itself has no runtime dependencies (
dependenciesis empty), so
installing it pulls nothing extra into your profile.
- Working on this repo needs Node.js ≥ 22 and Bun; Bun installs
dev dependencies, runs lint/format and packs, while tests run on Node's built-in
node:test.
Install
Published to npm as dsh-live-notify:
# install_bundle with target: dsh-live-notify (in the Harness plugin manager) # or, from a packed tarball: bun pm pack # or npm pack # install_bundle with target: /abs/path/to/dsh-live-notify-<version>.tgz
The bundle lands in $DSH_PROFILE_DIR/node_modules/dsh-live-notify.
After upgrading: the client half reloads on page refresh, but the host half is
a loaded JS module — restart dsh web once to pick up a new host.js. Session
history survives the restart; the projection is refolded from the log.
Usage
The model calls UpdateNotify with an optio
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:2,最后更新 2026-10-20