
dsh-skills-anywhere 0.9 在原有的单文件检查之外,加了一份有上限的技能目录清单(bundle manifest)。文档开头写明了原因:SKILL.md 没变,不代表它旁边的脚本和参考文件也没变。本文依据固定在 commit c011051 的 docs/BUNDLES.md 和 docs/MCP-COMPATIBILITY.md,讲怎样把这份清单用到技能审核里:生成和比较清单的命令,三个退出码,怎样在 MCP 加载时要求同一个目录身份,清单的格式与上限,以及摘要匹配证明不了什么。
本站的 Skills Anywhere:把各家 AI 工具里的 SKILL.md 汇成一个目录,经 dsh 或 MCP 按需加载 概述过这个项目及其文件检查与按哈希加载。下文描述的行为都来自项目文档([O],项目自述)。文档里的测试结果由项目报告,本站没有运行这些命令或测试。
为什么只核对 SKILL.md 不够
文档引用的 Agent Skills 规范(文档注明核对日期为 2026-09-14)把一个技能描述为 SKILL.md 加上可选的 scripts、references 和 assets。MCP 工具 open_skill 原有的 expected_sha256 只核对 SKILL.md。MCP-COMPATIBILITY.md 写明,这个哈希不覆盖被引用的脚本或其他文件,也不能确认作者身份。所以可能出现这种情况:审核时读过的 SKILL.md 一字未改,它让 agent 运行的脚本却已经换了。
目录清单记录所选目录下的每一个普通文件(regular file):相对路径、字节长度和 SHA-256,隐藏文件和二进制文件也算在内。文档还说明,这是项目自定的内容身份格式,并不声称属于 Agent Skills 规范。
在本地和 CI 里生成、比较清单
文档给出的两条命令如下,注释按原文保留:
# Keep both the review manifest and output logs outside the skill directory.
npx -y dsh-skills-anywhere@0.9.0 bundle /path/to/skill --json > reviewed-bundle.json
# Review the actual files, then retain the manifest in your review record.
npx -y dsh-skills-anywhere@0.9.0 bundle /path/to/skill \
--against reviewed-bundle.json --json
第一条注释的意思是:审核清单和输出日志都放在技能目录之外;第二条是:审核实际文件,然后把清单保留在审核记录里。第一条命令为审核时的目录生成清单;第二条用 --against 把当前目录与保存的清单比较。命令里写了包版本 @0.9.0,所以 npx 运行的工具版本由命令本身固定。这一节的标题是“Local review and CI”,但文档没有给出 CI 配置文件。
| 命令 | 退出码 | 文档写明的条件 |
|---|---|---|
| 生成清单 | 0 | 生成成功 |
比较(--against) | 0 | 文件路径和内容一致 |
比较(--against) | 1 | 有差异 |
比较(--against) | 2 | 输入无效、读取不稳定,或目录中有不支持的条目 |
文档没有写明生成清单失败时的退出码,本文不作推测。比较的 JSON 输出包含 added、removed、changed、两边的摘要和当前的 manifest。重命名表现为一个删除路径加一个新增路径。面向人的输出会对来自输入的路径做转义。两条命令都不会去发现其他技能根目录,不运行 Git,不同步仓库,也不执行技能代码。
清单放在哪里
保存的清单必须放在技能目录之外,否则它会变成自己的输入。shell 重定向可能在命令启动之前就创建好文件,所以要始终重定向到单独的审核目录。上面的命令把 reviewed-bundle.json 写在当前目录,也就是说,运行时当前目录不能位于技能目录之内。工具不会悄悄忽略任何文件:应传入技能自己的目录,而不是带缓存或 Git 元数据的整个应用检出。
一个假设的例子
下面是本站为说明而设的情形,不是运行结果。假设审核时目录里只有 SKILL.md 和 scripts/review.py,之后只有 scripts/review.py 被改过。按文档的约定,第二条命令以退出码 1 结束,scripts/review.py 出现在 changed 中。如果改动是把它改名为 scripts/check.py,结果会是 removed 里一个 scripts/review.py,added 里一个 scripts/check.py。如果目录里多了一个指向别处的符号链接,文档把它列为被拒绝的条目,按上表应得到退出码 2,而不是 1。
在浏览器里比较收到的清单
Hugging Face 上的演示页带一个作者编写的示例,其中只有 scripts/review.py 发生了变化;示例的两份清单在站点构建时由真实的文件系统读取器生成。可以下载其中任一份清单、恢复与之对应的文件,也可以打开自己的两份 JSON 清单查看差异。比较之前,浏览器会用与 CLI 相同的规范化方式重新计算每份清单的摘要。输入只留在页面内存中,不上传、不存储,也不写进分享链接;输入无效时清除对应结果;重置为示例时取消尚未完成的文件读取。这个页面比较的是已记录的清单,不能检查你的文件系统,也不能连接本地 MCP 服务器。
在 MCP 加载时要求同一个目录身份
审核通过后,调用 open_skill 时带上清单里的摘要:
{
"name": "your-discovered-skill-name",
"expected_bundle_sha256": "<manifest.sha256 from your reviewed bundle>"
}
open_skill在返回指令之前重新计算目录清单。只要有文件被新增、删除或修改,摘要就对不上,调用返回错误,不带指令正文。返回的bundle字段是这次核对用的清单。- 没有事先保存的摘要时,可以用
include_bundle: true查看当前清单。传了expected_bundle_sha256就隐含这个选项。 expected_sha256仍然只核对SKILL.md,两个摘要参数可以同时使用。在目录模式下,返回的指令和它的文件哈希,与目录清单用的是同一份字节。- 即使摘要匹配,作者当前设置的禁用选项仍然生效。
- 目录哈希只在独立 MCP 服务器的
open_skill工具上按需开启;默认的工具和资源加载,以及 dsh provider,行为不变。
MCP-COMPATIBILITY.md 报告了 0.9 的相关测试:同样的四种 SDK 配置(SDK 1.30.0,以及 SDK 2.0.0 的 legacy、auto 和固定 2026-07-28 三种协商方式)都用 expected_bundle_sha256 加载一次,然后只修改一个资源文件、保持 SKILL.md 不变,确认加载被拒绝。已安装的 npm 包也用两代 SDK 做了这项检查,CLI 操作在空的 PATH 下运行。这些是项目自己的测试记录。
清单格式与上限
格式 skills-anywhere-bundle-1 恰好有四个字段:schema、sha256、total_bytes 和 files;每个文件条目恰好有 path、bytes 和 sha256。各行按斜杠分隔的相对路径排序,用 JavaScript 字符串升序;路径不重复,一个路径也不能同时是另一个文件的父路径。不做 Unicode 规范化,也不用依赖区域设置的排序。目录摘要是下面这个 UTF-8 JSON 元组(不含空白)的 SHA-256:
["skills-anywhere-bundle-1",[["relative/path",byte_length,"file_sha256"],...]]
目录的绝对路径、包版本、时间戳和 JSON 排版都不属于这个身份,所以把相同的文件移到另一个目录,摘要不变。SKILL.md 必须存在且是合法的 UTF-8,但生成清单时不校验 frontmatter,解析结果要用 check 命令看;其他文件可以是二进制。
| 上限项 | 上限 |
|---|---|
| 文件数 | 512 |
| 目录条目总数 | 1,024 |
| 路径层级 | 12 |
SKILL.md | 128 KiB |
| 其他单个文件 | 16 MiB |
| 目录总量 | 32 MiB |
| 收到的单份清单 | 1 MiB |
| 单个相对路径 | 1,024 个 UTF-8 字节 |
路径中含控制字符、反斜杠、冒号、路径穿越段或 Unicode 替换字符时一律拒绝。如果安装根目录本身是符号链接,只解析一次;根目录之下的符号链接,以及管道这类特殊文件,都会被拒绝。文件读取、目录枚举和最后的元数据检查,都会发现检查过程中发生的变化。
局限 / 注意
- 摘要匹配只说明记录下来的文件路径和内容字节相同。它不认证作者,不判断代码是否安全,也不证明模型按指令做了。
- 空目录、权限、所有者、目录外的文件、已安装的包、解释器版本、远程 URL 和动态加载的内容,都不在摘要范围内。
- 它不推断也不认证 Git 修订版本。仓库来源重要时,要另外保留一个审核过的源码修订版本。
- 检查不会冻结目录,之后的资源读取或执行可能读到不同的内容。文档建议使用稳定、受控的检出,并在实际使用的地方执行自己的执行策略。这项功能只在加载或检查时发现目录变化,不是沙箱,也不是防御能力的基准测试。
- 默认的工具和资源加载不做目录哈希;不显式传参数就没有这项保护。
- MCP 兼容测试检验的是 SDK 层面的协议互通,不认证 Claude Code、Cursor、Codex 等具体应用的每个版本。文档在 0.8 的说明中写明该包通过 stdio 提供服务,0.8 没有加入 HTTP 传输、授权或远程托管。
- 本文依据 commit
c011051的文档,命令固定为 0.9.0;之后的版本在参数、字段或退出码上可能不同。
链接
- 目录清单契约:docs/BUNDLES.md(commit c011051)
- MCP 兼容矩阵与 0.9 目录测试:docs/MCP-COMPATIBILITY.md(commit c011051)
- 浏览器中比较清单:Hugging Face Space:dsh-skills-anywhere
- 技能目录结构:Agent Skills 规范
- 本站相关文章:Skills Anywhere:把各家 AI 工具里的 SKILL.md 汇成一个目录,经 dsh 或 MCP 按需加载



