DeepSeek Harness 插件

stuarthu/dsh-update-notifier

Star 数 ★ 0 分类 通知与集成 收录于 2026-08-17 npm dsh-update-notifier

每小时检查 npm 上已安装插件的新版本,并询问升级其中哪些。

安装

# npm 包(预构建)

dsh plugin --profile web add dsh-update-notifier

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:stuarthu/dsh-update-notifier

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本。请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

English | 中文

每小时——或用 /check-updates 随时手动触发——检查已安装的 DeepSeek Harness(dsh) 插件有无新版本,并用一个一键审批气泡让你决定是否升级。

dsh 本身不会告诉你某个已安装插件已经出了新版,只能靠自己记得去 npm view。 本插件补上这一环:每小时把每个已安装插件和注册表比对一次,发现更新时直接在会话里 弹出一个真正的提问气泡,问你要升级哪些。勾选之后由智能体当着你的面执行升级。 它绝不会擅自升级任何东西

行为

每小时(可配置)对每个支撑已加载插件的 npm 包:

  • 查询注册表的 latest,与 profile 的 node_modules 中已安装的版本比对。 版本比较严格遵循 semver——预发布版本排序正确,绝不建议降级;不符合严格 X.Y.Z 格式的版本会被跳过,而不是猜测其含义。

  • 用一个气泡询问。 所有更新的版本会汇总成一个多选提问,由 dsh 自己渲染 (dsh-chrome 0.1.2 -> 0.1.3,每个插件一个选项),挂在你最近活跃的会话上。 它不占用模型轮次、不消耗 token,断线重连后还会重放。

  • 把勾选的交给智能体:以一条后续消息指示它执行

    pnpm --dir <profileDir> add <pkg>@<latest> ...
    

    智能体会立即被唤醒,你可以直接看到升级过程。搭配 dsh-hot-reload 使用,新版本无需重启 dsh 即可生效。

/check-updates

不想等下一个整点?在会话里输入 /check-updates

/check-updates
check-updates · 2 updates — see the question above (7 plugins checked)

它会立即针对你输入命令的那个会话跑一轮完整检查,并在注册表查询结束的那一刻就 结算这条命令——它弹出的气泡就是一个普通气泡,你可以随时回答,刷新页面也不会丢。 如果当前根本无法弹出气泡,结算文本里会直接给出 pnpm ... add 命令,而不是只 告诉你"做不到"。

查询不到的包(网络故障、超时、5xx、限流,或响应里根本没有版本号)会在结算文本中 单独计数,而不会被当成"已是最新";如果所有包都查不到,这条命令会以错误结算, 而不是报告"没有更新"。两个数字相加即为本轮总数:5 plugins checked, 2 unreachable 表示一共查了 7 个。 取消这条命令会同时中止检查,因此被你取消的检查不会过一会儿又弹出气泡。

手动检查会忽略下面的拒绝记忆:既然是你主动问的,就把完整列表给你,包括你此前 未勾选的版本。它不会打乱定时检查的节奏;如果已有气泡未回答、或已有检查正在进行, 它会带着原因拒绝执行。

只要 dsh 组合了命令注册表,该命令就会出现——@deepseek-ai/dsh-base 就会组合它, 因此基于它的 profile 都能用 /check-updates。命令通过 ctx.inject 注册,所以 没有命令注册表的 headless profile 依然能加载本插件并照常执行定时检查。

只问一次

同一个版本只会问你一次(指定时检查;上面的命令可以越过这条规则):

  • 未勾选的视为拒绝,记录在 <profileDir>/.dsh-update-notifier.json 中, 跨重启永不再提,直到注册表的 latest 变成另一个仍然高于你已安装版本的 版本为止。删除该文件即可重新开始询问。
  • 已批准的不会记录:升级成功后它自然就是当前版本;升级失败的话,重启后重新 提醒才是合理的。
  • 你从未回答过的气泡(会话结束、dsh 停止)不算拒绝——下次仍会询问。

尚无活跃会话时,提醒会挂起:在你下一条消息之后立即重试,下一轮定时检查也会重试。 如果根本没有任何界面能渲染气泡——headless profile,或者虽然组合了 userQuestions 服务但没有任何 UI 向它注册 provider——提醒同样会挂起,并且会把可用更新和确切的 升级命令一并写入日志,因为这种情况下你再发消息也不会有气泡出现。

安装

dsh plugin --profile web add dsh-update-notifier

然后重启一次 dsh(bundle patch 层在启动时加载)。适用于任何 profile——把 web 换成你实际使用的 profile 即可,它检查的就是自己被加载进的那个 profile。 需要 Node 18+(依赖全局 fetch),任何 dsh 宿主都已满足。

兼容性

基于 dsh 0.1.0-rc.6(Node 22 / 24)构建并测试。它只使用宿主的公开服务, 因此某项缺失时只会降级而不会崩溃:

宿主接口 用途
loader.entries() 找出哪些包支撑着已加载的插件
userQuestions.ask() 渲染审批气泡
userQuestions.provider 没有 UI 注册渲染时,不承诺会有气泡
agents.get(sessionId) 解析会话对应的活跃智能体
agent.followup() 唤醒该智能体执行升级
session/eventuser/message 追踪最近活跃的会话
agent/disposed 撤回会话已销毁的气泡
commands.register() 注册 /check-updates 命令
agents.roots() 避免承诺一个 ask() 会拒绝的气泡

userQuestionscommands 都是用到时才解析的,而不是声明为依赖,因此在两者 都不存在的 headless profile 中,插件依然能正常加载。

退出检查

不希望被提示升级的插件,可以在自己的 package.json 中声明:

{ "dsh": { "updateNotifier": false } }

对于不由你掌控的插件,用下面的 exclude 让它闭嘴。

配置

设置在 profile 的 cordis.patch.ymlupdate-notifier 那一行上:

默认值 含义
interval 3600000 检查间隔毫秒数(下限钳制为 60000)
initialDelay 10000 启动后首次检查前的延迟毫秒数
registry https://registry.npmjs.org 要查询的 npm 兼容注册表
exclude [] 永不检查/提及的包名列表
fetchTimeout 10000 单个注册表请求超时,毫秒(下限 1000)
profileDir 自动 profile 目录的绝对路径(省略时从 loader base URL 自动探测)

安全

  • 未经点击不会有任何升级。 本插件从不自行启动包管理器,只负责组装气泡, 以及在你批准后生成那条由智能体当着你的面执行的指令。
  • 注册表的自由文本不会进入 UI 或模型。 进入气泡和智能体消息的,只有来自你 本地 profile 的包名,以及通过 /^[0-9A-Za-z.+-]{1,64}$/ 校验的版本号——绝不 包含从注册表取回的描述、README 或变更日志。
  • 后续消息的 source.kind"plugin",明确列出已批准的包,并指示智能体不得 改动其他任何内容。

局限 —— 请务必阅读

  • 它只负责询问,不负责验证。 你批准之后,升级就交给智能体执行了。失败会显示 在会话里,但本插件既不会重试,也不会事后确认新版本是否真的装上了。
  • 只能看到从注册表安装的插件。 从本地检出 link 过来的插件,或 dsh 内置的 插件,在 profile 的 node_modules 下没有对应的包,会被静默跳过——没有气泡, 也没有日志。
  • 只查询 latest dist-tag。 不支持固定版本范围、next/beta 通道,也无法 把某个包压在某个大版本上;对于永远不想升级的插件,请使用 exclude
  • 同一时间只有一个气泡。 在它等待回答期间,定时检查会跳过,/check-updates 也会以"已有升级提问未回答"为由拒绝执行;这期间发布的新版本,会在你回答之后的 第一轮检查中被发现。
  • 拒绝是针对那个确切版本的,而不是"到此为止的所有版本":如果注册表的 latest 变成另一个仍然高于你当前版本的版本——包括 unpublish 之后降下来的 版本——你还是会被再次询问。
  • 气泡需要一个 dsh 能挂载提问的会话。注册表故障、loader 状态异常、状态文件不可 写,都只会降级为日志;只有两种情况会让插件直接停用——上下文里没有插件 loader, 以及定位不到 profile 目录——此时日志中会明确说明是哪一种。

许可

MIT © Stuart Hu

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →