Chuyển đến nội dung chính

dsh-skill-console

Đã xác minh

dsh-skill-console · v0.1.1 · MIT · Giao diện web

DeepSeek Harness 技能控制台:在 Web GUI 里浏览全部本地技能、一键启用/停用、删除到可恢复回收站,以及从本地路径或 GitHub 仓库导入技能。

Cài đặt

dsh plugin add dsh-skill-console

Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.

Mã nguồn

Thẻ

Tác giả

Readme

dsh-skill-console

English | 中文

CI License: MIT Node

DeepSeek Harness 的技能管理插件。 在 Web GUI 的「设置 → 技能」里浏览全部本地技能、一键启用停用、删除到可恢复的回收站、从本地目录或 GitHub 仓库导入——不用再手动去命令行里搬文件。

技能控制台

为什么要有这个

dsh 的技能注册表在设计上就是只读的:provider 只负责 list() 和 get(),官方接口里没有任何写入路径。对一个注册表来说这是对的,但代价是每天都会遇到的操作——「这个先关一阵」「这个不用了删掉」「把那个仓库里的技能拿过来」——全都得回到终端手动改文件。

这个插件把这块补上,全程只用官方 SDK:不改 dsh 源码,不打补丁,不引入影子状态。

功能

浏览 全部本地技能,按发现来源分组(项目 / 自定义 / 用户 / 内置 / 运行时),支持搜索和启用状态筛选
启用 / 停用 一键切换。靠重命名技能的 SKILL.md 实现,重启后依然有效,且与磁盘状态始终一致
删除 移入各根目录下的 .trash,可恢复,另有单独的「彻底删除」
加载 技能页上的文件夹选择:直接选目录,勾选里面扫出来的技能,装上
导入 扫描本地目录或 GitHub 仓库,勾选后装进任一用户级根目录
诊断 列出那些永远进不了技能目录的文件,并说明原因
详情 渲染 SKILL.md 正文(标题、加粗、代码、表格),并显示 whenToUse、路径和附带文件

环境要求

  • Node ^22.19.0 || >=24.0.0
  • DeepSeek Harness,SDK 0.1.x(rc.7 及以上)

安装

从 npm 安装

包发布之后:

dsh plugin --profile web add dsh-skill-console

重启 dsh web,打开「设置 → 技能」。

从源码安装

git clone https://github.com/wendaokeliu-sys/dsh-skill-console.git
cd dsh-skill-console
pnpm install
pnpm build
npm link

dsh plugin --profile web add dsh-skill-console

免构建直接放置

编译产物没有任何运行时依赖,除了你 profile 本来就有的 dsh SDK——js-yaml 在构建期已经打进 bundle。所以把编译好的包直接放到 dsh 能解析到的位置就行:

<dsh home>/profiles/node_modules/dsh-skill-console/
  package.json
  lib/index.js
  lib/client.js

然后往 profile 的 cordis.patch.yml(<dsh home>/profiles/<profile>/cordis.patch.yml)里加一行:

- insert:
    - id: skill-console
      name: 'dsh-skill-console'

<dsh home> 在 macOS / Linux 上是 ~/.dsh,Windows 上是 C:\Users\<你>\.dsh,也可能是 DSH_HOME 指向的位置。

注意:手工放进 node_modules 的目录,可能被这个 profile 后续的 pnpm install 清掉。这条路适合试用,不适合长期安装。

开发模式

直接挂源码,不用打包:

dsh web --patch ./cordis.patch.yml

使用

全部功能在设置 → 技能一个页面上:技能列表、一个【加载技能】按钮、一个搜索框。其他东西不常驻——诊断提示条和回收站只在里面有内容时才出现。

列表

技能按发现来源分组:

来源 目录
project-dsh <项目>/.dsh/skills
project-agents <项目>/.agents/skills
custom customSkillDirs 指定的目录
user-dsh <dsh home>/skills
user-agents ~/.agents/skills
bundled 随包分发的技能
  • 加载技能是唯一的添加入口,本机文件夹和 GitHub 仓库都走它。
  • 左边的开关控制启用停用。项目级、内置和运行时技能的开关是灰的——它们在这里只读(见安全边界)。
  • 点技能名打开详情:正文、whenToUse、绝对路径、以及这个技能包里附带的资源文件。
  • 删除二次确认后移入回收站。
  • 右侧两个小圆点是调用策略:绿色 = 模型可调用,蓝色 = 用户可调用,灰色 = 关闭。
  • 搜索框匹配名称和描述;旁边的分段控件按启用状态筛选。

回收站

删除会把技能移进回收站,只要里面还有东西,列表下方就会出现一个回收站区块。恢复把技能搬回原位——如果原来的位置已经被同名新技能占了,它会拒绝而不是覆盖。彻底删除不可逆。

加载技能

一个按钮,两种来源。

本机文件夹会打开系统的目录选择框。选一个目录,里面所有能导入的技能就列出来给你勾选安装。没有原生选择框的主机(多为远程部署)会退回成手填绝对路径。

GitHub 仓库支持 owner/repo、owner/repo@分支、普通 URL,以及带子目录的浏览地址(https://github.com/owner/repo/tree/main/skills)。

两种来源都是同一套流程:选目标根目录 → 扫描 → 勾选 → 导入所选。目标里已存在同名技能的候选项会被标出来并且默认不勾选;想覆盖就勾上覆盖同名技能。

GitHub 匿名调用 API 每小时 60 次,扫大仓库容易用完。启动 dsh 之前设一下 GITHUB_TOKEN(或 GH_TOKEN)可以提高配额:

GITHUB_TOKEN=ghp_xxx dsh web

诊断

当用户级目录里有文件永远进不了技能目录时,列表上方会出现一条提示,告诉你有几个、分别为什么:缺 description、名字不是 kebab-case、SKILL.md 里的 name 和目录名对不上、文件读不了,或者描述太短。没有提示条就说明一切正常。

配置

配置存在 dsh 自己的 settings 服务里,命名空间是 dsh-skill-console:

字段 默认 作用
enabled true 总开关。关掉后 provider 卸载、写接口返回 503,目录接口仍可读
announceToAgent true 往 system prompt 里加一段说明,让 agent 知道有这个插件、能做什么
allowNetworkImport true 是否允许仓库导入

实现原理

启用停用不引入影子状态

官方 filesystem provider 只认两种发现形状:目录包的 <name>/SKILL.md,和扁平文件 <name>.md。停用就是把文件改名成 SKILL.md.disabled——文件还在原地,provider 扫不到,状态自然跨重启保持。GUI 之所以还能列出被停用的技能,是因为本插件自己扫盘时把 .disabled 文件也收进来并打上标记。

好处是不需要侧车状态文件。你手动改名、用 git 回滚、把目录同步到另一台机器,插件报告的永远是磁盘上的真实情况,不可能出现「配置说启用了、文件却不在」的错位。

删除

删除是 rename 到 <root>/.trash/<名字>-<时间戳>。.trash 是点开头的,官方 provider 本来就跳过点开头的条目,所以被删的技能对所有消费者天然不可见,不需要额外记账。恢复时从回收站条目的名字里读回原路径。

目录视图从哪来

dsh web app 里,宿主层的 skill-filesystem 行是故意关掉的——agent preset 各自往自己的 scope 层挂 provider。直接查全局层会是空的,所以本插件往那一层注册了一个自己的只读 provider,专供管理视图使用。

agent 会话不受影响:preset 层比全局层更近,同名技能永远是 preset 自己的 provider 胜出。

安全边界

  • 只有用户级技能可写——<dsh home>/skills 和 ~/.agents/skills。项目级、内置和运行时技能只读展示,控件禁用。每次写入在执行任何 syscall 之前先过一道根目录检查。项目级技能属于它所在的仓库,应该跟着 git 走,不该被 GUI 悄悄改掉。
  • 接口只走回环。 远端地址必须是 loopback 字面量,Host 头必须指向 loopback,跨站请求一律拒绝。就算你把 dsh web 绑到 0.0.0.0,局域网里的人也够不到这些接口。
  • 导入有硬上限。 目录深度、候选数量、单文件大小、单包文件数都设了上限。把导入器指向一个巨大的 monorepo 只会慢,不会失控。
  • 仓库导入可以整个关掉,通过 allowNetworkImport。

开发

pnpm install
pnpm typecheck    # tsc --noEmit
pnpm test         # 44 个测试
pnpm build        # 类型声明 + 两个 bundle
src/
  protocol.ts    宿主端和浏览器端共享的线上类型 + 路由表
  skillfs.ts     所有碰文件的操作:扫描、frontmatter 解析、启停、回收站
  import.ts      导入来源(本地目录 / GitHub 仓库)以及落盘
  provider.ts    注册进 ctx.skills 全局层的只读 provider
  routes.ts      /api/skill-console 路由族及其请求闸门
  index.ts       宿主端 apply:settings、provider、routes、system prompt
  client/
    api.ts       路由的类型化客户端
    locales.ts   中英文案(locale 服务强制双语对齐)
    index.tsx    浏览器端 apply:注册 settings.section 槽位
    panel/       控制台页面

测试覆盖:按官方 provider 语义解析 frontmatter、写入闸门、停用 → 删除 → 恢复 → 彻底删除的完整生命周期、仓库地址解析、本地导入落盘,以及在真实 HTTP 服务器上跑的整套路由测试(含回环闸门和总开关)。

常见问题

「技能」分区没出现。 看 dsh web 的启动日志里有没有 skill-console 的报错,以及浏览器控制台里有没有 dsh-skill-console 加载失败。最常见的原因是包名从 profile 里解析不到——确认 <dsh home>/profiles/node_modules/dsh-skill-console 存在,或者 npm link 确实成功了。

装的技能找不到。 打开诊断页。如果那里也没列出来,多半是文件层级太深了——发现过程不递归,技能必须是技能根目录的直接子项。

导入报 403。 GitHub 限流,设 GITHUB_TOKEN。

开关提示「只读」。 那个技能在项目级或内置根目录里。去它所在的地方改,或者先复制一份到用户级根目录。

贡献

欢迎提 issue 和 PR,见 CONTRIBUTING.md。

许可

MIT