DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-skill-mini-manager

r

dsh-skill-mini-manager

Manifest valid
UI (client)hasBundlePatch

dsh-skill-mini-manager · skill 极简管理

English | 中文

DSH Web 设置里的一页 skill 管理器:把当前 DSH 装的全部 skill 列出来,展示每个 skill 自己的简介,并且可以逐个移除。

  • 插件 id:dsh-skill-mini-manager
  • 中文名:skill 极简管理
  • 英文名:Skill Mini Manager

它的位置与内置的「插件」分区同级——设置面板左侧同一层导航里的独立一页, 不是「插件」里的一个标签页。

它显示什么

每一行是一个 skill,显示:

字段来源
名称skill frontmatter 的 name
简介skill frontmatter 的 description(skill 自己写的那段路由说明,原样展示)
使用时机可选的 whenToUse
来源user-dsh / user-agents / project-dsh / project-agents / custom / bundled
可调用面模型可调用 / 用户可调用(对应 disable-model-invocation、user-invocable)
占用skill 目录的绝对路径、文件数、总字节数
提供给哪些预设(或全局层)会把这个 skill 交给 agent

页面顶部有搜索框(按名称 / 简介 / 使用时机过滤)、刷新按钮和计数,底部是回收站。

skill 存在哪一层(重要)

DSH 的 skill 注册表是 host + 按 scope 分层的:部署级 provider 注册进全局层, 而每个 agent 预设自己的 skill-filesystem 行注册进那个预设的层。关键在于 dsh-web-app 的补丁显式禁用了宿主机上的 skill-filesystem 行(原注释写明 「presets own local discovery」),所以全局层在标准 web profile 上是空的, 所有用户 skill 都活在预设层里——只读全局层会得到一份空目录。

因此本插件逐个读取:全局层 + roster 里每个预设的层,然后按名称合并。预设的读取用 AgentPresets.standingKeyFor(id) 取该预设的 standing scope key,这正是 DSH 为 「没有 agent 的宿主读取者」提供的读取 scope。读不通的预设会明确报在页面上, 而不是静默少列几个 skill。

于是每个 skill 会标出它被哪些预设提供(例如 提供给 预设 standard · 预设 code); 预设自带 skills/ 目录里的私有 skill(例如内置 cordis 预设的两个)只标它自己。 同名 skill 在不同预设里指向不同文件时,页面会列出它但标为不可移除(ambiguous)。

内容完全来自宿主真实运行的 ctx.skills 注册表:每次打开或刷新都现场读取,没有缓存, 所以页面上看到的就是模型此刻能加载的东西。

移除是怎么做的

点「移除」会进入二次确认,确认框里会显示将要移动的确切路径。确认后:

  1. 宿主机把整个 skill 目录(或扁平 skill 的那一个 .md 文件)移动到 <DSH_HOME>/.skill-mini-manager/trash/<时间戳>-<名称>-<随机串>/payload,并在同目录写入 meta.json 记录原始路径。
  2. 该位置在所有 skill 根目录之外,所以文件系统 provider 的一层发现再也看不到它—— skill 立刻从模型目录里消失(provider 自带的 watcher 会触发失效)。
  3. 页面底部的回收站列出已移除的 skill,每项都有恢复按钮,会把它移回原路径。 清空回收站是插件里唯一不可逆的操作,同样需要二次确认。

什么不能被移除

移除在宿主侧做了一组硬性拒绝,页面会显示拒绝原因而不是给出按钮:

原因含义
bundled-sourceDSH 内置打包的 skill(DSH_BUNDLED_SKILL_DIR),属于发行物而不是用户资产
runtime-provider由插件在运行时注册的 skill,根本没有文件
system-owned位于系统保留的 .system 目录内
not-on-disk定义里没有文件路径
outside-skill-roots不在任何已知 skill 根目录内
unsupported-layout既不是 <name>/SKILL.md,也不是 <name>.md
missing目录还在但 SKILL.md 已经不见了
ambiguous同名 skill 在不同预设层里指向不同文件;页面只发名称,没有唯一目标就不猜

再加两条结构性保证:

  • 浏览器永远不传路径。 页面只发 skill 名称(remove)或回收站条目 id(restore/purge), 宿主每次都用自己的规则重新解析目标路径。被篡改的页面无法让这个插件去删任意文件。
  • 删除目标永远不会是 skill 根目录本身。 一个直接躺在根目录里的 SKILL.md 会被拒绝, 而不是把整个 skills/ 目录移走。

宿主接口

宿主半侧在 webServer 上挂四条 exact 路由,全部只接受同源请求(Origin 与 Host 不一致即 403):

方法路径作用
GET/dsh-skill-mini-manager/api/catalogskill 列表 + 回收站 + 根目录状态
POST/dsh-skill-mini-manager/api/remove{"name":"<skill>"}
POST/dsh-skill-mini-manager/api/restore{"id":"<回收站条目>"}
POST/dsh-skill-mini-manager/api/purge清空回收站

安装

本插件是一个标准的 DSH bundle(声明了 dsh.bundle.patch 与 dsh.client), 把包装进 profile 并重启即可。

从 GitHub 直接装

dsh plugin --profile web add github:runcat-tommy/dsh-skill-mini-manager

需要本机有 git。仓库没有提交构建产物、也没有 prepare 脚本,所以通常不会触发构建审批; 若 DSH 要求批准,按提示同意即可。更新就是重跑同一条命令。

从本地目录装

git clone https://github.com/runcat-tommy/dsh-skill-mini-manager.git
dsh plugin --profile web add D:\path\to\dsh-skill-mini-manager

dsh plugin 是 pnpm 的转发壳:它会在 profile 目录里跑 pnpm add,然后按装载后的真实状态 对齐 dsh.profile.bundles。所以也可以用 pnpm add link:<路径> 手工挂载,此时需要自己把包名 加进 dsh.profile.bundles(pnpm add 不会自动加):

{
  "dsh": {
    "profile": {
      "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-skill-mini-manager"]
    }
  }
}

更新走 git pull 后重跑 add。

三条路都必须重启一次 dsh web:宿主半侧在启动时挂载路由。只刷新页面的话, 页面会明确提示「插件的主机半侧没有响应」。

卸载用 dsh plugin --profile web remove dsh-skill-mini-manager(移除 skill 是另一回事, 本插件不会碰包依赖)。

装箱内容

文件作用
lib/index.js宿主半侧:四条 HTTP 路由、回收站、全部拒绝规则
lib/catalog.js纯函数核心:根目录解析、planRemoval、回收站命名校验
lib/client.js浏览器半侧:手写的 __ModuleLoader__ bundle,注册 settings.section
test/51 个测试:纯规则、宿主半侧(真实临时目录 + 分层读取)、浏览器半侧结构
scripts/inspect-live-catalog.mjs只读探针:用本机已装的 skill 跑一遍目录读取与移除规划

浏览器半侧不需要构建步骤:它只 require("react") 这一颗平台种子,其余全部用 同源 fetch 与宿主半侧对话。文案通过 locale 服务注册中英双语,跟随 DSH 界面语言。

开发

node --test "test/*.test.mjs"          # 全部 51 个测试
node scripts/inspect-live-catalog.mjs  # 用本机真实 skill 做只读验证

模型体验

无。 本插件不注册提示词、工具、消息或提供方请求。它唯一对模型的可见影响是间接的: 移除一个 skill 之后,文件系统 provider 会让该 skill 从模型目录中消失——这正是「移除」 的本意,而目录本身由 @deepseek-ai/dsh-tool-skill 渲染。

KV Cache 影响

移除会触发 provider 失效,从而使目录消费方在既有请求历史后追加一份替换目录。 浏览这一页不会增加任何模型 token。

已知限制与暂缓事项

  • 只列用户级 skill。 设置面板没有工作区,所以目录读取不带 cwd:项目根下的 .dsh/skills 与 .agents/skills 不会出现。要管理项目 skill,需要一个带工作区上下文的入口。
  • 判据是路径形状,而不是 provider 自述。 自定义根目录只要目录名不是 skills, 就会被 outside-skill-roots 拒绝——这是有意的保守选择,代价是这类部署需要显式声明根目录。
  • 移除是「移走」而不是「卸载」。 插件不碰 package.json、registry 或插件装配; 它只搬动 skill 自己的目录。
  • 回收站不会被自动清理。 需要用户显式清空。
  • 每条路由都现场重算目录。 skill 数量很大时每次刷新都会重读一遍全部定义; 「极简」在这里意味着不做缓存,而不是省这一次读取。

Comments

Loading…