DeepSeek Harness 插件

xiaxi626/dsh-skills-nexus

Star 数 ★ 2 下载量(近 30 天) 1,569 分类 技能包 收录于 2026-08-28 npm dsh-skills-nexus

通用 skill 适配器,将含 SKILL.md 的 GitHub 仓库克隆并 symlink 到官方 skills 根目录,注册为 DSH skill。

安装

# npm 包(预构建)

dsh plugin --profile web add dsh-skills-nexus

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

dsh plugin --profile web add github:xiaxi626/dsh-skills-nexus

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

CI

English | 中文

⭐ 如果项目对你有帮助,欢迎 Star 支持!

通用 DSH skill 适配器。安装一次,就可以把任意包含 SKILL.md 的 git 仓库注册为 DSH skill——一条命令添加一个仓库。skill 仓库本身保持纯净:不需要 Cordis 插件代码,不需要 package.json,也不需要 cordis.patch.yml。

nexus 将 SKILL.md 仓库克隆到本地 ~/.dsh/skills-nexus/repos/ 目录,然后在 DSH 官方 skills 根目录(~/.dsh/skills/)中创建符号链接(symlink)。官方 filesystem provider 会自动发现、监听并加载这些 skill——不再需要自定义 provider,也不再需要在运行时扫描目录。

为什么需要它

dsh plugin --profile <name> add "github:owner/repo" 转发给 pnpm,且只有声明了 dsh.bundle.patch 的包才会被激活为 profile layer。一个只含 SKILL.md + references/ + scripts/ 的内容仓库没有 Cordis 封装,走不通这条路。dsh-skills-nexus 填补了这个缺口:

命令 安装的是什么 需要 dsh.bundle.patch?
dsh plugin add github:owner/dsh-skills-nexus nexus 本身(仅一次) 是
dsh-skills-nexus add github:owner/any-skill 纯 SKILL.md 内容仓库 否

不确定自己的仓库该用哪个命令? 请看 nexus 与 dsh plugin——什么时候用哪个。 一句话版:仓库里有 SKILL.md → 用 nexus;是纯插件(cordis.patch.yml / dsh.bundle.patch,无 SKILL.md)→ 用 dsh plugin;两者都有 → 自己选(nexus = 要内容,plugin = 要代码)。

安装 nexus

可选:注册为 DSH 插件

如果需要将 nexus 注册到 DSH 的 web profile,可执行(其他 profile 请替换 web):

dsh plugin --profile web add "github:xiaxi626/dsh-skills-nexus"

在 web 会话中,这一步会带上 Skills Nexus 设置面板及其 /skills-nexus/* HTTP 路由;非 web 宿主里该层保持沉默。它仍然不会提供全局 CLI 命令,也不是下面 CLI 安装的前置条件——只用 CLI 管理 skill 的话可以跳过。

全局安装 CLI

全局安装 CLI——只有这一步才会把 dsh-skills-nexus 命令放进你的 shell PATH(前提是 npm 全局命令目录已在 PATH 中):

**npm 12:**确认信任仓库及其依赖后,显式允许本次安装获取 Git 依赖:

npm install -g --allow-git=all github:xiaxi626/dsh-skills-nexus

**较旧的 npm(未禁止 Git 依赖时):**可使用原命令;两条安装命令按版本和策略选一条执行即可:

npm install -g github:xiaxi626/dsh-skills-nexus
遇到 EALLOWGIT 怎么办?

如果原命令报错:

npm error code EALLOWGIT
npm error Fetching packages of type "git" have been disabled

这是 npm 的 Git 依赖获取策略在下载前拦截了安装,不是 Nexus 没装,也不是仓库构建失败。npm 12 起,allow-git 默认从允许改为 none;github:owner/repo 属于 Git 依赖,因此需要显式放行。可用 npm --version 查看版本;npm 12 可用 npm config get allow-git 查看当前策略。

默认收紧是为了降低供应链风险:Git 依赖会访问远程仓库,并可能引入项目无法控制的配置。这个错误不代表 npm 检测到了 Nexus 的恶意代码,也不表示 Nexus 与 npm 12 不兼容。 不必为此重装 DSH 插件或降级 npm;确认信任来源后,使用上面带 --allow-git=all 的命令即可解除这一项拦截,后续下载和安装仍需满足其他条件。

--allow-git=all 仅对本次调用生效,不会永久修改 npm 配置;它会放行本次安装中的所有 Git 依赖(包括传递依赖),不代表这些依赖已经过安全验证。不建议全局永久设置 allow-git=all。dsh plugin add 使用 pnpm,其配置与 npm 独立;插件安装成功不会改变 npm 的策略。

lib/ 编译产物已随仓库提交,无需构建,安装即用。

如果只需 npm registry 上的已发布版本(当前为 0.3.0),也可改用下面的命令:

npm install -g dsh-skills-nexus

这是 registry 包安装,不属于 Git 依赖,无需为 Nexus 本身设置 --allow-git=all;已发布版本与 GitHub 最新代码可能不同。

插件层是可选的。 它把包装进 profile 的 node_modules,并在宿主为 DSH web 会话时注册Web 面板与 HTTP 路由。但 skill 发现本身从不依赖该层:技能靠 nexus 在 ~/.dsh/skills/ 建的 symlink + 官方 filesystem provider 被发现与加载;全局 CLI 则来自上面的 npm 安装(开发期也可用 npm link)。

使用

# 注册一个 skill 仓库(克隆到 ~/.dsh/skills-nexus/repos/<name>/ 下)
dsh-skills-nexus add github:owner/repo
dsh-skills-nexus add github:owner/repo#dev          # 指定分支 / tag
dsh-skills-nexus add https://github.com/owner/repo
dsh-skills-nexus add https://gitlab.com/group/project  # 任意 git 主机
dsh-skills-nexus add owner/repo                     # 简写(仅限 GitHub)
dsh-skills-nexus add github:owner/a github:owner/b  # 一次安装多个仓库
dsh-skills-nexus add github:owner/repo --yes         # 跳过"包装型仓库?"确认
dsh-skills-nexus add github:owner/repo --subdir skills/foo   # 只安装集合仓库里的某个子目录
dsh-skills-nexus add github:owner/repo --subdir skills --name owner-skills   # 自定义条目名(条目名回退链:--name > subdir 末段 > 仓库名)

# 查看 / 维护
dsh-skills-nexus list                               # 列出所有条目(含来源、commit、subdir、显式锁、状态)
dsh-skills-nexus list --filter <query>              # 按名称、URL 或 subdir 模糊匹配缩小范围
dsh-skills-nexus list --json                        # …或输出同内容的带版本号 JSON 报告
dsh-skills-nexus update [name]                      # 刷新(分支 pin 拉取;tag/commit pin 校验)
dsh-skills-nexus switch-version <name> <ref> [--type <branch|tag|commit>]  # 把克隆切到另一个 ref(fetch、checkout、重归一化、重建链接)
dsh-skills-nexus enable  <name>...                  # 创建 symlink(默认开启);可一次给多个名字
dsh-skills-nexus disable <name>...                  # 删除 symlink 但不删克隆
dsh-skills-nexus remove <name>...                   # 删除克隆 + symlink + 注销(可一次给多个名字)
dsh-skills-nexus remove 'theme-*'                   # …或用 * / ? 通配符匹配 skill 名
dsh-skills-nexus doctor [--json] [--updates] [--quiet]  # 只读体检 nexus 全量状态(退出码 0/1/2)
dsh-skills-nexus purge  [--yes] [--json]                # 清理积累产物(默认 dry-run)
dsh-skills-nexus completions --shell <bash|zsh|fish|powershell>  # 输出对应 shell 的补全脚本

# 跨机器搬运 skill——包携带来路,绝不携带 .git
dsh-skills-nexus export --all -o migrate.zip        # 打包全部条目(含禁用条目)
dsh-skills-nexus export <name>... -o one.zip        # …或只打包其中几个
dsh-skills-nexus import migrate.zip --dry-run       # 逐条目预览:真克隆还是落快照;零副作用
dsh-skills-nexus import migrate.zip                 # 按记录的 ref 重建条目
dsh-skills-nexus import migrate.zip --locked        # 恢复各条目记录的精确 commit
dsh-skills-nexus adopt <name> --url github:owner/repo   # 给无 git 源的条目补回来路

取值型选项(--name、--ref、--subdir)也支持 --flag=value 写法(如 --subdir=skills/foo、--name=owner-skills);布尔选项 --yes 不接受值。

给脚本用时,--json 可把 add、list、update、remove、enable、disable、purge 变成机器接口:stdout 只输出一份 version 1 报告、诊断走 stderr,退出码语义不变 (0 成功 / 1 有错误或部分失败 / 2 用法错误)。报告描述的是「刚才做了什么」 ——安装落在哪个 commit、更新的 before→after、批量里哪个名字没找到:

$ dsh-skills-nexus add github:owner/repo --json | jq '.results[0]'
{ "spec": "github:owner/repo", "status": "added", "name": "repo",
  "commit": "…", "ref": "main", "links": ["repo"] }

--json 运行不会提示,交互式运行会问的步骤请显式传 --yes。完整契约与明确的 「不承诺」清单见 在 nexus 之上构建。

add 可接受多个仓库 spec,remove 可接受多个名字与 */? 通配符;每个目标独立处理,任一失败则退出码非零。由于 --name/--ref/--subdir 是每仓库级选项,不能与多个 add spec 同时使用——要分别定制请分开跑多条 add。remove 的通配符若匹配到多个 skill,会先列出待删清单并要求确认(加 --yes 跳过);通配符请加引号('theme-*'),以免被 shell 提前展开。

支持的仓库格式:github:owner/repo[#ref]、完整 https:// URL(任意 git 主机——GitLab、Gitee、Bitbucket、自建 GitLab;含 /tree/<ref>/... 子路径)、git+https://、git@/ssh://、以及裸写 owner/repo 简写(仅限 GitHub——解析到 github.com)。其他平台请写完整 URL。

add 会在注册前检查克隆下来的仓库类型:

  • 纯 SKILL.md 仓库:直接注册。
  • SKILL.md + DSH 薄包装层:询问是否忽略包装层、按普通 SKILL.md 仓库管理。输入 y 继续,输入 n 中止并建议按 DSH 插件方式安装。使用 --yes 可跳过确认。
  • 纯 DSH 插件(没有 SKILL.md):提示请按该仓库自己的 DSH 插件安装方式安装,不建议用 nexus 管理,然后退出,不注册。
  • 两者都不是:提示未找到 SKILL.md 或 DSH 插件标记,报错退出。
  • 集合仓库(skills/<name>/SKILL.md 布局,如 trae-community/trae-skills):整个仓库安装时根目录没有可安装的 skill,nexus 会拒绝并提示改用 --subdir <path> 指定子目录;一次安装解析出超过 20 个 skill 时会弹确认提示(--yes 跳过)。

跨机器搬运 skill:export / import

包是搬运容器,不是安装方式。export 写出技能文件外加一份 nexus-package.json 标签,记录每个条目的来路;import 在另一台机器上按这份标签把条目重建出来——也可以用来收取别人打给你的包。

  • 包内绝不含 .git,也不含任何凭据。它携带的是技能和它们的来路:每个条目的 url / gitUrl / ref / commit / subdir、启用状态与链接名。export --all 连禁用条目一起打包,因此整机迁移能还原出原机的样子。
  • import 优先重新克隆:标签里记录的远端此刻可达时,走与 add 同一条安装路径——真浅克隆,可 update、可 switch-version。只有在没有来源、或远端不可达时才落成快照;即便如此,原机的状态也会被还原:在那边禁用的技能到这里仍然禁用,链接名也原样保留。
  • --locked 精确恢复导出时的版本:只接受 selected entry 含安全 gitUrl、非空 ref 与 40–64 位完整 commit SHA 的 labelled package。nexus 跳过可达性探测,对该 commit 执行 depth-1 fetch 和 detached checkout,并在 manifest 中标记显式锁。只有远端明确报告「commit 不可获取」才回退包内快照;网络、认证和含糊的 Git 错误仍会失败。裸包不支持 --locked,且该选项不能与 --no-remote 或 --no-net-check 同用。
  • --dry-run 先看后动,零副作用,逐条目打印四种判定之一:will clone from <url> (<ref>)、will import as snapshot (<url> unreachable)、will import as snapshot (<url> check timed out)(5 秒探测——网络慢绝不能被写成"仓库没了"),以及无标签包的 will import as snapshot (source unknown)。别人打的 zip 就属于最后这种:它的技能靠更宽容的扫描找到;层级太深时用 --subdir <path> 显式指定根。
  • 包是用来跨机器的,不是用来安装的:有网就直接 add,export / import 负责整体搬迁(或接收别人交付的技能)。--no-net-check 完全跳过探测(离线零等待)、--no-remote 一律落快照、--each 每个技能一个条目(与 --locked 合用时,每个技能各有一份锁在记录 commit 的独立 clone)、--force 替换同名已注册条目。list 的 LOCK 列显示显式 package lock;doctor --updates 会将其与普通 detached tag/commit pin 区分。成功执行 switch-version 后显式锁被清除。

把冻结条目救回来:adopt

快照不能 update、也不能 switch-version——它没有历史可取。等你查到它当初来自哪个仓库,把身份接上:

dsh-skills-nexus adopt daily-trend-writer --url github:owner/repo
dsh-skills-nexus adopt daily-trend-writer --url github:owner/repo --subdir skills/daily-trend-writer

adopt 不改条目名、也不改它的 subdir 身份,只把该仓库克隆进 repos/<name>/ 并重建链接,于是该条目与 add 装出来的完全同质。原目录会保留为 repos/<name>.pre-adopt-<ts>(用 --prune 删除);若新来源暴露的技能集合不同,默认拒绝,除非显式 --force;任一步失败都会把目录、链接与 manifest 还原回操作前。

Web 面板(插件侧,可选)

当 nexus 运行在 DSH web 会话里——无论是通过 dsh plugin add 注册,还是用本地测试步骤里的 --patch overlay 挂载——设置页都会出现一个 Skills Nexus 段。面板与 CLI 驱动同一份 manifest、同一批克隆与同一套跨进程文件锁,两边可以随意混用(一边正在操作的 skill,另一边会收到 busy / locked)。

面板使用与 DSH 设置页同源的界面组件——状态点、开关、标签、折叠行、终端输出块等——配色自动跟随宿主的亮/暗主题,看起来就是设置页原生的一部分,而非第三方拼凑的界面。

在面板里你可以:

  • 浏览条目卡片——链接名、启用状态、固定的 commit、no source / linked directory / disabled 等状态标签,以及分支跟踪条目的「有更新」徽标;
  • 在工具栏过滤列表——搜索框按名字或 url 匹配;右侧的徽标在有待更新条目时显示待更新数量,并常驻显示已注册技能总数;
  • 按 git url 添加 skill——可在折叠区填写可选项 name(覆盖条目名)、ref、subdir(monorepo 内的目录)——与 CLI 同一条安装流水线,含 frontmatter 归一化;
  • 导入包——选好文件后先看逐条目判定(与 import --dry-run 同一套措辞:真克隆还是落快照、以及为什么),确认后才真正导入。上传走裸 body、文件名放在旁边,没有 multipart 端点;
  • 给快照接上来源——adopt 动作只出现在无 git 源的条目上,仓库 url 由你填(永不猜测);
  • 启用 / 禁用、更新、切换到其他 ref、删除条目——破坏性操作会展示服务端的后果说明,确认接受后才带确认重发;
  • 导出全部条目为 zip——面板以服务端正路径作为可复制的 notice 展示,文件留在服务器上(没有下载按钮);
  • 观看长操作(克隆 / 导入 / adopt / 更新 / 切换)流式进度并带取消按钮——最近 3 条已结束的操作(done / failed / cancelled)会留在「recent operations」区——以及对全部条目检查更新;
  • 在底部独立区块运行健康检查:点一下 run check,状态点加一行摘要即展示错误、警告与可更新数量。

面板底部一行文字指向宿主自带的 Skill Manager,用于查看其他工具管理的本地技能——本面板只列出 nexus 安装的条目。

热加载。 链接变化由官方 filesystem provider 的 watcher 拾取,面板操作在稳定窗口内即对运行中的宿主生效——无需重启。宿主未启用 watcher 时,面板会明说该变更在下次宿主启动时生效。

HTTP 接口(内部)。 面板与 /skills-nexus/* 路由通信——GET 为 ping / list / doctor / job 轮询;POST 为 add / import / adopt / remove / update / check-updates / switch-version / toggle / export / job cancel。成功返回 { data, hotReload },长操作以 202 { data: { jobId } } 受理,所有变更路由均做同源校验(remove 额外仅接受 loopback)。这些路由是面板自身的管道——不属于在 nexus 之上构建承诺的稳定机器接口;工具开发者请继续 shell out 调 CLI。

Shell 补全

dsh-skills-nexus completions --shell <bash|zsh|fish|powershell> 输出对应 shell 的补全脚本——补子命令、每个命令的 flag,以及已安装的 skill 名(通过 dsh-skills-nexus list --names 取数)。在你用的 shell 里装载一次即可:

# bash(~/.bashrc)
eval "$(dsh-skills-nexus completions --shell bash)"

# zsh(~/.zshrc,需在 compinit 之后)
eval "$(dsh-skills-nexus completions --shell zsh)"

# fish(一次性装载,或保存为 ~/.config/fish/completions/dsh-skills-nexus.fish)
dsh-skills-nexus completions --shell fish | source
# PowerShell($PROFILE)
dsh-skills-nexus completions --shell powershell | Out-String | Invoke-Expression

卸载:从配置文件里删掉装载行,并在当前会话里撤销注册;若从未写进配置 文件,直接开一个新终端即可(新会话天然干净):

# bash
complete -r dsh-skills-nexus
unset -f _dsh_skills_nexus

# zsh
compdef -d dsh-skills-nexus
unfunction _dsh_skills_nexus

# fish
complete -c dsh-skills-nexus -e
# PowerShell——用空脚本块重新注册以移除补全器
Register-ArgumentCompleter -Native -CommandName dsh-skills-nexus -ScriptBlock $null

命令名本身的补全不需要任何脚本——shell 会从 PATH 里补可执行文件名, 只要 npm 全局 bin 在 PATH 中即可自动生效;上面的脚本补的是该命令的 参数。逐 shell 的完整验证流程见 验证命令补全。

卸载

分两个层级,按需选择:

卸载单个 skill

# 查看已注册的 skill
dsh-skills-nexus list

# 删除一个(删除 symlink、克隆目录并注销)
dsh-skills-nexus remove <skill-name>

# 一次删除多个——按名字,或用 * / ? 通配符(记得加引号)
dsh-skills-nexus remove <name1> <name2>
dsh-skills-nexus remove 'theme-*' --yes

下次 DSH 重载后该 skill 从目录中消失,不影响其他已注册的 skill。

卸载 nexus 本身

nexus 会留下三个互相独立的东西,用不同的命令清理——清掉一个不会连带清掉其他。下面这段带注释的命令逐条清理,只跑你需要的那几行即可。

最容易踩的坑——先读这条。 你在终端里敲的 dsh-skills-nexus,只来自下面的第 3 项(npm link 或 npm install -g)。--patch 只把 layer 挂进当前这个 DSH 进程、dsh plugin add 只写 profile 的 node_modules,两者都不会把命令放进你的 shell PATH。所以「装了 GitHub 版却还在跑本地逻辑」= 你敲的命令走的是第 3 项里 npm link 指向的本地工作区,跟 GitHub 装进第 2 项的那份毫无关系。想真正切到远程:先 npm uninstall -g dsh-skills-nexus,再按安装 nexus中的版本与策略说明全局安装 GitHub 版(npm 12 需显式加 --allow-git=all)。

# 1. skill 数据——~/.dsh/skills-nexus/ 下的克隆 + 清单(是数据,不是命令本身)
dsh-skills-nexus remove '*' --yes          # '*' 匹配所有已注册 skill

# 2. DSH profile 插件层——仅当你用过 dsh plugin add(--patch 不写这里)
dsh plugin --profile web remove dsh-skills-nexus

# 3. 全局 CLI 命令——你在终端敲的 dsh-skills-nexus 就是它!
npm uninstall -g dsh-skills-nexus

# (可选)删除第 1 项残留的数据目录
#    macOS / Linux:
rm -rf ~/.dsh/skills-nexus
#    Windows PowerShell:
# Remove-Item -Recurse -Force ~/.dsh/skills-nexus

重启 DSH profile。插件层、CLI 命令与所有已管理的 skill 都会消失。

切勿用裸相对路径 Remove-Item -Recurse -Force dsh-skills-nexus 来「清理」:它的效果完全取决于当前目录——在 npm 全局前缀目录下跑会删掉 CLI 的 bin shim(命令突然变成「not found」),在你克隆的父目录下跑会删掉你的源码树。若确实要丢弃本地克隆,请用明确的完整路径删除。

兜底——手动删除(仅当 npm uninstall -g 不可用时)。 先删 bin shim,再删链接。删除链接时绝不加 -Recurse:它是指向你克隆的 junction/符号链接,加 -Recurse 会顺着链接删进你的源码树。

# Windows PowerShell
Remove-Item -Force "$(npm prefix -g)\dsh-skills-nexus*"               # bin shim
Remove-Item -Force "$(npm prefix -g)\node_modules\dsh-skills-nexus"   # 链接——不加 -Recurse

Git Bash / macOS / Linux 请直接用 npm uninstall -g dsh-skills-nexus,不要手动删链接(对目录型链接用 rm 不安全)。

本地测试步骤

不需要推 GitHub、不需要发 npm,按以下五步在本机完整验证。

第一步:把项目编译出来

在 dsh-skills-nexus/ 目录下:

cd dsh-skills-nexus
npm install
npm run build      # 生成 lib/ 目录

如果改了代码想先确认类型无误再编译,可以跑 npm run typecheck(只检查类型,不生成产物)。

第二步:创建本地 overlay

在项目根目录下新建 overlay.yml(注意:不要提交到 git,它是本地开发专用的):

# overlay.yml
- insert:
    - id: dsh-skills-nexus
      # 相对路径以 overlay.yml 所在目录为锚
      name: './lib/index.js'

overlay.yml 放在项目根目录时,'./lib/index.js' 即 <项目>/lib/index.js——相对路径以 overlay.yml 所在目录为锚,Windows / macOS / Linux 通用同一写法。如需绝对路径,请改用 file:/// 形式,例如 'file:///C:/dev/dsh-skills-nexus/lib/index.js';旧写法 '/C:/...'(盘符前加 /)在当前 dsh 上不再可用——会被解析成 C:\C:\...。

也可以用命令一键生成(确保已 cd 到项目目录;Git Bash / macOS / Linux 通用):

cat > overlay.yml <<EOF
- insert:
    - id: dsh-skills-nexus
      name: './lib/index.js'
EOF

生成的文件不嵌入任何本机绝对路径——不需要 pwd / pwd -W,之后移动项目文件夹也依然有效。

执行后项目根目录会自动生成正确的 overlay.yml。

第三步:用 patch 模式启动 DSH

npx @deepseek-ai/dsh web --patch overlay.yml

这只把 nexus 作为临时 layer 挂载进当前这个 DSH 进程——进程一停 layer 就消失,不会写进 profile。插件侧构建好之后,本次会话的 web 设置页还会出现 Skills Nexus 面板。注意它不会把 dsh-skills-nexus 命令放进你的 shell PATH;shell 里的命令来自第四步的 npm link。每次改了代码重新 npm run build 后,重启 DSH 生效。

第四步:用 CLI 加一个 skill 测试

注意:本地测试过程中不要移动项目文件夹。如果你在 npm link 之后移动了项目位置,再次 npm link 会报 EEXIST: file already exists——因为全局里还留着旧位置的链接。处理方法见下文。

另开一个终端:

# 先把 CLI 链到全局,方便直接用 dsh-skills-nexus 命令
cd dsh-skills-nexus
npm link

# 加一个真实的 skill 仓库试试
dsh-skills-nexus add github:xiaxi626/theme-port-skill

# 查看是否注册成功
dsh-skills-nexus list

# 检查官方根目录中是否创建了 symlink
ls -la ~/.dsh/skills/

如果移动过文件夹,npm link 报 EEXIST 的处理方法:

方案 A — 用 --force 直接覆盖(最简单,全平台通用):

npm link --force

方案 B — 用 npm 移除旧的全局链接,再重新链接(全平台通用):

npm uninstall -g dsh-skills-nexus
npm link

优先用 npm uninstall -g,而不是手动去 npm 全局目录删文件:它会一次性安全地移除 bin shim 和链接,避免对符号链接的全局包误用 Remove-Item / rm 踩坑。

第五步:在 DSH 里验证

第三步启动的 DSH 进程确实是在第四步加 skill 之前就跑起来的——但默认配置下不需要重启:官方 filesystem provider 一直在监听 ~/.dsh/skills/,CLI 刚建的 symlink 会在稳定窗口内被拾取。在运行中的 DSH 会话里开一个新对话,问一句「你有哪些 skill」,theme-port-skill 应当出现在列表里。

如果你的宿主没启用 filesystem watcher(或 skill 迟迟不出现),退回重启兜底:回到第三步的终端按 Ctrl+C 停掉进程,重新跑一遍 npx @deepseek-ai/dsh web --patch overlay.yml,DSH 会在启动时重新扫描 skills 根目录。

本地测试后的清理

--patch 不写 profile,所以没有插件要移除。本地测试只留下两样——skill 数据与 npm link——按卸载 nexus 本身的第 1、3 项清理即可(先 dsh-skills-nexus remove '*' --yes,再 npm uninstall -g dsh-skills-nexus);跳过第 2 项(dsh plugin remove),这里用不上。


更轻的验证(不启动 DSH 也能测核心逻辑)

如果只想验证「clone + symlink 创建 + list」这条链路是否正常,不需要启动整个 DSH,直接用 CLI 即可:

# 加一个 skill
dsh-skills-nexus add github:xiaxi626/theme-port-skill

# 查看注册结果
dsh-skills-nexus list

# 检查 symlink 是否创建成功
ls -la ~/.dsh/skills/

如果 list 显示了预期的 skill、ls -la 显示了指向 repos/ 目录的 symlink,说明整个 clone + symlink 链路正常。


注意事项与限制

  • add 后是否立即可见:默认配置下官方 filesystem provider 监听 skills 根目录,新添加的 skill 会在稳定窗口内出现在运行中宿主的新对话里——无需重载。未启用 watcher 的宿主则要等下次重扫/重启;web 面板会以「下次宿主启动」提示标注这种情况。
  • 版本固定与更新:用 #分支名、#tag名 或 #commit-hash 固定 ref。安装时 manifest 会记录实际解析到的 commit(commit 字段)——一个轻量锁,list 会显示它。update 只对分支 pin 的 skill 做快进拉取(并打印 commit 变化);tag/commit pin 的 skill 是固定点:只校验当前 checkout 是否仍等于 pin(漂移则自动恢复),不做 pull——被固定的版本永远不会静默漂移。不加 #ref 时,CLI 会通过 git ls-remote --symref 自动探测远程默认分支(探测失败回落到 main)。
  • 仅用于 skill 内容仓库:这不是 dsh plugin add 的替代品。如果仓库本身就有 dsh.bundle.patch,请用正常方式安装——nexus 是给那些没有封装的仓库用的。完整决策指南见 nexus 与 dsh plugin——什么时候用哪个。
  • 集合仓库与 --subdir:skill 藏在子目录的集合仓库用 --subdir <path> 按需安装——每次安装是一个独立条目、独立克隆(独立克隆设计,P1/P2 权衡见 docs/subdir-design.md)。新装的 --subdir 条目在 Git 和远端支持时为稀疏检出:部分克隆加 cone 模式 sparse-checkout(安装输出里报 checkout: sparse),无关 skill 目录不落盘——远端支持 blob 过滤时通常可减少下载与磁盘占用,实际收益取决于仓库布局(无硬性流量上限:cone 会保留仓库根与祖先目录的直属文件;远端忽略 filter 时可能整仓下载,nexus 会给出可见警告)。想退出稀疏:git -C <克隆目录> sparse-checkout disable(会把剩余内容全部拉取检出;后续 update 不会重新强制稀疏);稀疏流程需要 Git 2.35+(更旧的 Git 其 sparse-checkout set 不提供 --cone),本机 Git 缺少该能力时,会在警告后把同一克隆补成整仓检出,不重复下载。不带 --subdir 全量安装时,根目录无可用 skill 会被拒绝;超过 20 个 skill 会弹确认提示。从同一仓库挑装的多个条目各自保留独立克隆,但 list 会显示 SOURCE 列(来源 owner/repo),同一仓库挑出的条目一眼可辨。
  • 平铺 md 过滤:没有 frontmatter name 且没有 description 的平铺 *.md 不会被当作 skill——集合仓库的文档(README.zh-CN.md、CONTRIBUTING.md、community-leaderboard.md 等)永远不会被"假装安装"。发现阶段的跳过名单也按前缀模式覆盖 readme*、contributing*、license*、changelog*、code-of-conduct*、security*。
  • 同名不消歧:DSH 按名称索引 skill,后安装的同名 skill 会覆盖前者。用 --name 区分条目,或用 --subdir 只装需要的。--subdir 安装时显式传入的 --name 若归一化后与默认条目名(subdir 末段)相同,安装成功后会提示可省略该参数。enable/disable 按条目(即按安装的 subdir)生效,remove 删除整个条目的克隆及其所有 symlink。
  • skill 名校验:DSH 要求 skill 名是小写 kebab-case([a-z0-9]+ 段,用单个 - 分隔)。frontmatter name 不合法(如 CurriculumDesigner)会导致 DSH 拒绝该 skill,因此 nexus 会在安装时归一化这类名称(转为 kebab-case),并在 add 时以 ⚠ 警告。
  • 构建脚本:由于 nexus 自己 clone 内容仓库(不走 pnpm),它完全绕开了 pnpm 的 allowBuilds 拦截。
  • Windows 链接:nexus 在 Windows 上创建目录联接(junction,symlink(..., 'junction'))、在其他平台上创建普通目录软链——均不需要开发者模式或管理员权限。

给工具开发者

想在 nexus 之上构建工具——GUI 面板、同步守护进程、CI 任务、或更上层的、把 git 上 SKILL.md 仓库装进 DSH 的安装器?nexus 已经把跨平台的琐碎部分全部解决(spec 解析、带重试的克隆、ref 固定、frontmatter 归一化、集合仓库 --subdir、Windows junction 软链),并对外暴露稳定、可依赖的机器接口: dsh-skills-nexus list --names(枚举已安装 skill)、dsh-skills-nexus doctor --json (带版本号的健康报告),以及 add / list / update / remove / enable / disable 的 --json(描述「刚才做了什么」的带版本号报告)。请 shell out 调 CLI—— 绝不要 import 包内部、也不要读 manifest.json。完整契约、生态边界、以及 没有承诺的接口清单,见 在 nexus 之上构建——面向工具开发者的机器接口。

改完浏览器半段后怎么验

lib/client.js 由 npm run build:client 生成,而 CI 刻意不跑它(它要求 Node ≥ 22.18,测试矩阵从 20 起),浏览器模块表也不在类型检查范围内——loader 答不出的 require 是运行时抛错,构建期没有任何症状。所以改 src/client/** 或模块表后 必须手跑一次:

  1. npm run build && npm run build:client,并提交 lib/。

  2. 确认产物里的 require 全在宿主模块表内:

    $ node -e "const s=require('fs').readFileSync('lib/client.js','utf8');\
      console.log([...new Set([...s.matchAll(/require\(\"([^\"]+)\"\)/g)].map(m=>m[1]))].sort())"
    [ '@deepseek-ai/dsh-client-ui-primitives', 'react', 'react/jsx-runtime' ]
    

    出现其它 specifier 就是 loader 会拒绝的请求。

  3. dsh web --profile <名字>,把这个检出装进该 profile,打开 设置 → Skills Nexus:确认面板渲染、技能行的状态点正确,并跑通一个动作 (切一次启停即可)。

  4. desktop profile 由 Electron 应用独占管理,第 3 步请用一次性 profile; dsh plugin --profile desktop … 会被直接拒绝。

文档

参与贡献

欢迎各种形式的贡献。想参与的话,先看看 CONTRIBUTING.zh-CN.md,里面有项目布局、本地开发和质量检查的完整说明。

发现 bug 或有想法?直接 提交 issue,我们有 issue 模板。

许可证

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。