DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

VCPr0j3k7 /

VCPr0j3k7/dsh-skill-manager

Verified

Skill manager UI for the DeepSeek Harness desktop shell — list, create, import, and open agent skills

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@679ed310

dsh-skill-manager

License: MIT Node.js

English | 简体中文

为 DeepSeek Harness (DSH) 桌面版提供 skill(技能)管理界面:列出宿主实际扫描的 skill 根目录、 标注每个 skill 的来源与有效性、新建 skill、从文件夹导入、在系统文件管理器中打开目录。

本插件以独立 bundle 形式装入 DSH profile,不接管官方 skill 的扫描与热加载。


目录

  • 问题背景
  • 环境要求
  • 安装
  • 卸载
  • 工作原理
  • 界面与操作
  • skill 的发现规则
  • 宿主接口
  • 启用条件
  • 测试
  • 已知限制
  • 许可

问题背景

官方桌面版已具备完整的 skill 能力,但没有任何可视化入口:

能力 提供方 是否随官方发行
扫描 skill 根、解析 frontmatter、热加载 @deepseek-ai/dsh-skill-filesystem 是
/ 唤起 skill @deepseek-ai/dsh-client-ui-skill 是
列出扫描到的根、标记无效文件、新建与导入 —— 否

因此当 frontmatter 写错、或 skill 没有被加载时,用户只能自己去翻目录与日志。

本插件补的就是这一层:它不参与加载,只在文件层面做增删查,并如实展示宿主扫描的根目录 与每个 skill 的来源。因此它与官方插件同时启用不会冲突 —— 一个负责装载,一个负责文件。

环境要求

项 要求
Node.js ^22.19.0 || >=24
DeepSeek Harness 官方桌面版
依赖 yaml(安装时自动装好)

安装

安装分两步:先装进 profile,再把包名登记进 bundle 层栈。

# 1. 进入桌面版的 profile 目录(Windows 默认:%USERPROFILE%\.dsh\profiles\desktop)
cd "<DSH_HOME>/profiles/desktop"

# 2. 用官方桌面版随包的 pnpm 装进 profile
pnpm add "file:<插件目录绝对路径>"
# 或者直接从 GitHub 装
pnpm add "github:VCPr0j3k7/dsh-skill-manager"

「随包的 pnpm」指 <安装目录>/resources/runtime/pnpm/bin/pnpm.cjs。若它不在 PATH 中, 用随包的 node 直接调用即可:

NODE="<安装目录>/resources/runtime/primary-runtime/dependencies/node/bin/node.exe"
PNPM="<安装目录>/resources/runtime/pnpm/bin/pnpm.cjs"

"$NODE" "$PNPM" add "file:<插件目录绝对路径>"
"$NODE" "$PNPM" add "github:VCPr0j3k7/dsh-skill-manager"

必须登记 bundle 层栈

pnpm add 只会写入 dependencies。DSH 只装载 dsh.profile.bundles 中列出的 bundle, 因此必须手动把包名追加进 profile 的 package.json:

{
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "dsh-skill-manager"        // ← 追加这一条
      ]
    }
  }
}

漏掉这一步的表现是:安装过程没有任何报错,依赖目录也在,但插件完全不加载 —— 界面上没有入口,日志里也没有记录。这是本项目最容易踩的一步。

dsh plugin --profile desktop add ... 会在 pnpm 结束后自动运行 reconcilePlugins(), 由它补上这一条。但官方桌面版通常不提供可直接调用的 dsh CLI, 走 pnpm add 的路径时就需要手动登记。

确认已登记:

cd "<DSH_HOME>/profiles/desktop" && cat package.json

安装完成后需重启桌面版。宿主只在启动时装配插件树,运行中的实例不会热更新。

卸载

cd "<DSH_HOME>/profiles/desktop"
"$NODE" "$PNPM" remove dsh-skill-manager

随后从 dsh.profile.bundles 中删除 "dsh-skill-manager" 一行。卸载后同样需要重启桌面版。

卸载不会删除任何 skill 文件:本插件只向 <DSH_HOME>/skills 写入,从不清理该目录。

工作原理

插件由两个半边组成,各自独立运行:

半边 运行位置 形态
宿主半边 DSH 宿主进程(Node.js) Cordis 插件,导出 name / inject / apply(ctx)
客户端半边 桌面版窗口(浏览器) React 页面,经 window.__ModuleLoader__.load({ id, factory }) 装载

宿主半边在 ctx.webServer 上注册一条 kind: 'prefix' 路由 /dsh-skill-manager/api,前缀内部的路由派发由 host/router.mjs 完成。 这样做的好处是注册点只有一处,卸载时由框架统一清理,不会在 webServer 中留下半张路由表。

所有响应统一为 { ok: true, data } 或 { ok: false, error },业务失败也返回 HTTP 200 —— 状态码只用于表达「路由不存在」这类传输层事实。

客户端半边在首次请求时探测宿主基址。页面的来源可能是宿主自身的 HTTP 地址、 外壳的自定义 scheme(dsh-app://app/),也可能是不透明来源(location.origin === "null")。 因此它按顺序尝试相对路径与官方虚拟主机名 http://dsh.internal,并以 /info 返回的 data.plugin 是否等于本插件 id 作为判定依据 —— 仅凭 HTTP 200 不够,SPA 的兜底路由 会把未知路径也返回 200 + HTML。选定后缓存复用。

共享配置:本插件与同系列的其他插件共用 <DSH_HOME>/dsh-extras.json, 通过 GET /config 读取、POST /config 深合并写回。本插件不定义自己的配置项, 但 GET /info 会带上其中的 appName 字段。

日志:宿主半边的日志写入 <DSH_HOME>/plugin-data/logs/dsh-skill-manager.log, 同时在内存中保留最近 2000 行环形缓冲。

界面与操作

侧边栏的「Skill 管理」入口打开面板,包含四项操作:

操作 行为
新建 Skill 表单生成 <DSH_HOME>/skills/<名称>/SKILL.md。名称需符合 kebab-case,description 与正文必填;同名目录已存在时拒绝写入
从文件夹导入 弹出系统目录选择器。若所选目录含 SKILL.md,整个目录按原目录名拷入用户 skill 根;否则把该目录下的平铺 .md 逐个拷入。目标已存在时跳过,不覆盖
打开 skill 目录 在系统文件管理器中打开用户 skill 根;点击某条 skill 的「打开位置」则定位到该文件
重新装回内置 skill 本插件中始终报告「不适用」,详见下文

面板同时展示:

  • 按 rank 分组的 skill 列表,每条显示名称、描述、何时使用、来源根、正文大小与正文预览;
  • 「随包内置」标记(依据记账文件判定,见下文);
  • 「被忽略的文件」列表,逐条给出 frontmatter 解析失败的原因;
  • 一张扫描根目录说明表(rank、路径、目录是否存在)。

关于「重新装回内置 skill」:本插件不适用

官方桌面版不随插件发行内置 skill:随包 skill 由运行时自行管理。因此宿主半边把 BUNDLED_DIR 固定为 null,POST /skills/restore-bundled 会明确返回:

官方桌面版不随插件发行内置 skill(随包 skill 由运行时自行管理),此项不适用

界面上的按钮保留,但点击后显示的就是上面这句话。列表中的「随包内置」一栏同样始终为空。

host/services/skills.mjs 中仍保留了一套完整的随包 skill 安装与记账实现 (installBundledSkills / restoreBundledSkills / bundledSkillNames, 记账文件为 <DSH_HOME>/bundled-skills/.installed.json),但在本插件中 bundledDir 恒为 null,这些函数不会安装任何内容。

skill 的发现规则

官方按 rank 顺序扫描以下根目录,同名的 skill 以 rank 较小者为准。每个根只扫描一层, 不支持嵌套的 SKILL.md:

rank 来源 路径 可写
100 当前项目(.dsh) <项目根>/.dsh/skills 是
200 当前项目(.agents) <项目根>/.agents/skills 是
400 桌面版用户目录 <DSH_HOME>/skills 是
500 共享 agent 目录 $DSH_AGENTS_HOME/skills(默认 ~/.agents/skills) 是
600 随包内置 官方 bundledSkillDir,本插件不涉及 否

「项目根」取最近的含 .git 的祖先目录(最多向上 24 层),没有则使用当前工作目录。

一个 skill 可以是:

  • 目录 bundle:<名称>/SKILL.md,可附带 references/、scripts/、assets/ 等资源;
  • 平铺文件:<名称>.md。

以 . 开头的条目会被跳过。SKILL.md 必须以 --- 包裹的 YAML frontmatter 开头:

字段 必填 说明
name 是 仅小写字母、数字与短横线(^[a-z0-9]+(?:-[a-z0-9]+)*$)
description 是 模型据此决定是否使用该 skill
whenToUse 否 何时使用
user-invocable 否 设为 false 时用户不可手动调用
disable-model-invocation 否 设为 true 时模型不可自动调用

布尔字段按严格布尔解析:接受 true / false,也接受 yes / no / on / off / 1 / 0 等字符串写法;其余值视为未设置(与官方一致)。

frontmatter 由 yaml 包解析,并且刻意使用运行时自带的那一份 —— 换用其他 YAML 库可能对边界写法给出不同结论,从而与宿主的判断不一致。

skill 是热生效的:新建或导入后无需重启宿主,官方 watcher 会在下一个模型步骤刷新目录。

宿主接口

所有接口挂在 /dsh-skill-manager/api 下。

插件自有路由

方法 路径 请求体 返回
GET /skills/list —— { roots, skills, invalid, home, userRoot, bundledDir }
POST /skills/create { input } { path, name }
POST /skills/import { sourceDir } { imported, skipped, root }
POST /skills/restore-bundled —— 恒为「不适用」错误
POST /skills/open-dir { target? } { opened },缺省打开用户 skill 根

公共路由

以下路由由 host/router.mjs 统一提供(本插件的页面只用到其中的一部分):

方法 路径 说明
GET /info 插件 id、宿主状态、运行时目录等;客户端以 data.plugin 判定基址是否可用
GET /config 读取 <DSH_HOME>/dsh-extras.json
POST /config 深合并写回该文件
POST /open-external 用系统默认程序打开 http/https 链接,其他协议一律拒绝
POST /pick-directory 系统目录选择器;优先使用官方 ctx.directoryPicker,否则在 Windows 上用 PowerShell 兜底
GET /restart-pending profile 的关键文件是否比宿主就绪时刻更新
POST /restart-host 恒定拒绝:插件无法重启承载自身的进程
GET /events 事件增量拉取(?since=<seq>),客户端每 300ms 轮询一次

启用条件

  • 宿主半边:包名出现在 profile package.json 的 dsh.profile.bundles 数组中, 且 profile 已重新装载(重启桌面版)。没有环境变量开关。
  • 客户端半边:页面由官方桌面版外壳提供。基址探测成功后界面可用;探测失败时界面仍会渲染, 但所有数据请求都会失败并显示错误信息。

测试

npm test
# 等价于 node test/check.mjs

test/check.mjs 是纯 Node 自检(35 项),不依赖 DSH 运行时,也不需要把插件装进 profile。 它使用临时 DSH_HOME 与临时 APPDATA,不会读写用户的真实目录。覆盖范围:

  • package.json 清单契约:dsh.bundle.patch、dsh.client.platform、exports 与 files 所指向的文件真实存在;
  • 宿主半边可被 import,导出 name / inject / apply,apply(ctx) 不抛并注册前缀路由;
  • 路由对齐:从 client.js 中提取全部 request("METHOD", "PATH") 调用(当前 10 条), 逐条打到真实路由表上,确认没有一条落到 404;同时校验两侧的路由前缀一致;
  • host/config.mjs 的默认值包含 githubToken 等字段,且配置文件路径落在当前 DSH_HOME 之下。

路由对齐是本项目的核心契约:客户端半边是构建产物,一旦它调用的路由在宿主侧不存在, 表现只是界面上某个按钮静默失败(宿主回 404,页面只显示一句笼统的错误)。

端到端验证:装入并重启桌面版后,侧边栏应出现「Skill 管理」入口,面板能列出 <DSH_HOME>/skills 下的 skill。

已知限制

  • 「重新装回内置 skill」不适用。 官方桌面版不随插件发行内置 skill,该操作恒定返回错误(详见上文)。
  • 宿主无法重启自身。 POST /restart-host 恒定拒绝;需要重启时请手动退出并重新打开桌面版。
  • 「打开 skill 目录」要求目录已存在。 若 <DSH_HOME>/skills 尚不存在(例如全新安装且从未创建过 skill),该操作会报「路径不存在」。先用「新建 Skill」或「从文件夹导入」创建一次即可。
  • 只扫描一层。 与官方一致,根目录下的子目录不会被递归查找,嵌套的 SKILL.md 不会被发现。
  • 不接管加载与卸载。 扫描、解析、热加载均由官方 dsh-skill-filesystem 负责;本插件只做 文件层面的增删查。界面上「有效 / 被忽略」的判断是对同一套规则的重演,不是另一套判定。
  • 导入不覆盖同名文件。 目标已存在时跳过并在结果中列出;需要覆盖请先手动删除。
  • client.js 是构建产物。 它由构建脚本从桌面版前端源码切片生成,其中包含若干本页未使用的 组件(安装进度环、README 抽屉、重启提示条、若干图标等,来自同一套切片的其他面板)。 这些组件不参与本插件的渲染;直接手工修改会在下次构建时被覆盖。
  • 界面文案为中文。 当前版本未做多语言。

许可

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 679ed3109691

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout