跳过主要内容
全部文章
教程

如何更新和卸载 DeepSeek Harness 插件

dsh plugin update、why、remove 的精确命令用法,bundle 列表如何自动保持同步,以及彻底卸载一个插件前该检查什么。

要更新一个 DeepSeek Harness(dsh)插件,运行 dsh plugin --profile <name> update <包名>;要卸载它,运行 dsh plugin --profile <name> remove <包名>。这两条命令底层都是纯粹的 pnpm 命令——dsh 自己没有一套独立的版本系统或卸载系统,而且它会在命令执行后自动重新同步生效配置。

本文讲清楚这些命令到底做了什么、在动手之前如何查一个包为什么会被装进来,以及每次更新或卸载之后值得核实的那一件事。

没有 dsh 专属的版本系统

如果你读过我们如何安装插件那篇指南,你已经知道 dsh plugin --profile <name> <参数...> 会把 profile 参数之后的所有内容原样转发给 pnpm,并以该 profile 目录为工作目录执行。更新和卸载的工作方式一样——updatewhyremove 都是 pnpm 的子命令,不是 dsh 自己发明的:

# 更新该 profile 下的全部插件
dsh plugin --profile demo update

# 只更新某一个插件
dsh plugin --profile demo update dsh-hello-plugin

# 查一下这个包到底为什么被装进来
dsh plugin --profile demo why dsh-hello-plugin

# 卸载一个插件
dsh plugin --profile demo remove dsh-hello-plugin

因为本质就是 pnpm,插件的版本管理对于 npm 发布的包遵循普通的 semver/registry 语义,对于 GitHub 来源的包则遵循普通的 git ref 语义。dsh 不会为插件维护自己的 changelog、兼容性矩阵,或者更新提醒系统。

why 是干什么的、什么时候该用

在卸载任何东西之前,why 能告诉你,你即将删掉的这个包,到底是你自己装的顶层插件,还是别的东西需要的传递依赖:

dsh plugin --profile web why dsh-hello-plugin

这是 pnpm 自己的依赖溯源输出,作用域限定在这个 profile 目录内。在你下决心之前,这是确认"我要删的是不是那个对的东西"最快的方法——尤其是在一个几周内陆续装了十几个插件的 profile 里,你已经记不清是谁引入了谁的时候特别有用。

bundle 列表如何保持同步

这是从其他插件系统转过来的人最容易搞错的一点:你永远不需要自己手动维护一份"当前生效插件"的列表。每次执行完 dsh plugin 命令,dsh 都会重新核对该 profile 下实际安装的依赖,并据此核对 dsh.profile.bundles——profile 自己 package.json 里那份有序列表,决定了哪些配置补丁真正会生效。

  • 更新:如果更新拉到了某个包的新版本,而这个新版本第一次声明了 dsh.bundle 字段(之前没有),dsh 会自动激活它。如果某个依赖在新版本里去掉了 dsh.bundle 声明,dsh 会停用对应的配置补丁。
  • 卸载:一旦一个包从 node_modules 里消失,它就会从生效的 bundle 列表里消失。没有单独的"禁用但保留安装"状态——卸载就是卸载,它的配置补丁会在这个 profile 下次启动时(如果开着热重载,则是立刻)停止生效。

实际操作中,这意味着"这个 profile 里当前生效的是什么"这件事,它的事实来源永远是实际安装的依赖树,而不是你手动维护的某个配置文件。如果你想在更新或卸载之后确认一下当前到底生效了什么,运行:

dsh --profile web --dump-config

这会打印出完整组合后的配置树——按生效顺序列出每一个 bundle 补丁——而不会实际启动进程。这是确认一次卸载真的生效了最可靠的方法,尤其是当你卸载的插件插入过某段配置、而另一个还在用的插件恰好也依赖它的时候。

更新一个从 GitHub 装的插件

如果你安装插件时锁定了 commit(github:owner/repo#<sha>,我们在 GitHub 安装指南里推荐了这个做法),对它跑 update 不会悄悄把你带到更新的 commit 上,除非你自己去改这个锁定值。这正是锁定 commit 的意义所在——相比之下,对一个没有锁定的 github:owner/repo 引用执行更新,会拉取上游分支当前指向的任何内容,包括你没有审查过的代码。如果你要定期更新一个 GitHub 来源的插件,值得时不时去上游仓库亲自看一眼 diff,而不是相信 update 只是升了个版本号。

卸载之后的收尾

卸载一个插件会把它从 profile 的 bundle 列表和 node_modules 里删掉,但有几件事值得手动检查:

  • 它插入到别处的配置。 如果被卸载插件的补丁文件用 insert 添加过配置,而另一个仍在安装的插件(通过 inject)依赖着这段配置,那个依赖插件就会加载失败。卸载前后各跑一次 --dump-config 是发现这个问题最快的方法。
  • 它写到磁盘上的数据。 会持久化状态的插件(会话日志、记忆存储、缓存)一般不会在卸载时清理自己写下的文件——dsh 的卸载是"移除依赖",不是应用程序卸载器。如果插件的 README 记录了一个数据目录,想要彻底清理就得手动去处理。
  • 它用到的凭据。 如果插件需要一个存在 $DSH_HOME/.credentials.yaml 里或环境变量里的 API key,卸载插件并不会撤销或清理这个凭据。

有社区工具能帮上忙

生态里有几个插件专门用来让插件管理在 Web UI 里而不是 CLI 里变得更简单。dsh-updater-ui 在 Settings 页面加了一个自更新器,提供一键检查并拉取的流程。dsh-plugin-suite 里包含一个更新管理器,能检查更新、备份,并支持回滚一个插件。这些都是普通的第三方 dsh 插件,不是 dsh 本身的一部分——我们安全清单里对任何 dsh plugin add 对象适用的安装与信任考量,同样适用于它们。

FAQ

dsh plugin remove 能像应用卸载器那样干净地卸载一个插件吗?

大体可以,但不完全。它会移除包并停用其配置补丁,但插件写到磁盘上的任何数据(会话状态、缓存、记忆存储)会被留下,除非插件在文档里说明了数据目录、你再手动去清理。

能不卸载、只是禁用一个插件吗?

通过 dsh plugin 本身不行——没有一个独立于"未安装"之外的"已禁用"状态。一些社区插件(比如上面链接的那些)在此之上加了一层开关 UI,但那是插件自己在管理内部状态,不是 dsh 原生的功能。

如果更新一个插件之后出问题了怎么办?

核心 CLI 没有内置的回滚机制。如果你安装时锁定了 GitHub commit,可以重新锁定到之前已知可用的 commit 再重装。如果你是从 npm 安装的,可以在 add/update 命令里显式指定之前的版本号,跟任何 pnpm 管理的依赖一样操作。

更新或卸载插件之后需要重启 dsh 吗?

如果你开着热重载(用于本地插件开发的 @deepseek-ai/cordis-plugin-hmr 机制),改动可以不经过完整重启就生效。否则,重启这个 profile 才能确保新配置被加载。

我怎么查看一个插件当前的 dsh.profile.bundles 列表长什么样?

运行 dsh --profile <name> --dump-config 查看完整组合后、当前实际生效的配置——这反映的是任何更新或卸载之后的真实状态,而不只是某个文件里写的内容。

下一步

如果你还没装过第一个插件,先看如何安装 DeepSeek Harness 插件。对需要构建步骤的插件,从 GitHub 安装详细讲了 allowBuilds 提示。如果更新或安装时报了一个你不认识的错误,查一下插件安装错误与修复或更全面的排障指南