0017-community-skills.md 3.3 KB

ADR-0017 第三方技能:skills.sh 目录 + GitHub 固定提交,两个引擎共用

  • 状态:Accepted · 日期:2026-10-23 · 补充 ADR-0016

背景

官方技能仓库只覆盖少量场景。skills.sh 是社区技能目录,收录 GitHub 仓库中的 SKILL.md 技能,提供搜索接口(GET https://skills.sh/api/search?q=…,返回 source=owner/repo、skillId、installs)。第三方技能是通用格式,两个引擎都能用。

决策

  • 一个目录,两个引擎:第三方技能安装在 <dataDir>/managed-skills/community(服务可写的数据目录;在沙箱中单独开放只读),采用 Claude 插件格式(.claude-plugin/plugin.json,name = community-skills;技能在 skills/<name>/)。
    • Claude:运行时按路径作为本地插件加载
    • Codex:通过 skills/extraRoots/set 加入。已验证(codex 0.164):Codex 会读取上级目录的 plugin.json,技能名显示为 community-skills:<name>
    • 两个引擎的技能 ID 一致:community-skills:<name>
  • 流程:搜索 → 预览 → 安装
    • 搜索走 skills.sh
    • 预览时服务端取仓库默认分支的最新提交(GitHub API commits/HEAD),下载该提交的压缩包(≤ 50 MB,缓存在 data/skill-catalogs/github/<owner>__<repo>/<sha>,每个仓库只保留最新快照),定位技能目录,返回 SKILL.md 全文、文件列表、许可证与是否含脚本
    • 后台必须勾选"已阅读"才能安装
    • 安装使用预览时的提交号,不会装上未看过的内容;更新也是重新预览后再安装
  • 定位技能:在仓库中(深度 ≤ 6)查找 SKILL.md。优先 frontmatter name 等于 skillId 的目录,其次目录名相同的目录,多个匹配时取路径最短的。安装目录名取 SKILL.md 的 name,这样 Claude 与 Codex 的技能名一致。
  • 许可:只允许开源许可,其余拒绝安装。
    • 识别顺序:技能目录中的 LICENSE 文件 → SKILL.md 的 license 字段(SPDX)→ 仓库根目录的 LICENSE
    • 接受的许可:MIT、Apache、BSD、ISC、MPL、Unlicense、CC0 等
    • 拒绝:专有许可、"governed by …"类第三方条款,以及无法识别的许可
  • 官方仓库不走这里:anthropics/skills、openai/skills 在搜索结果中标记为不可安装,提示到各自引擎的页面安装(官方技能不交叉使用,ADR-0016)。
  • 默认不启用:Profile 选择"全部技能"时不包含第三方技能,必须取消"全部"后单独勾选。
    • Claude:resolveSkills 跳过 optIn 插件
    • Codex:skillsToDisable 在 all 时禁用 community-skills:*
  • 文件安全:
    • 安装只复制普通文件,跳过符号链接,防止仓库中的链接指向服务器上的文件
    • 单个技能最多 500 个文件、20 MB
    • owner/repo 严格校验,不能以 . 开头
    • 技能目录在两个引擎的沙箱中只读可见,脚本与其他命令一样受沙箱限制

后果

  • 第三方技能未经审核,风险由管理员在预览时判断;审计日志记录来源、提交号、路径和许可证
  • 不依赖 npx skills CLI,也不执行仓库中的任何安装脚本
  • 部分仓库只在 README 中说明许可、没有 LICENSE 文件,这类技能无法安装(宁缺毋滥)