今日开源[第44期]findskills项目skill解读

vercel-labs/skills 项目解读

仓库地址:https://github.com/vercel-labs/skills
一句话定位:The CLI for the open agent skills ecosystem(开放代理技能生态的命令行包管理器)
版本:v1.5.21(package.json)| 许可证:MIT | 语言:TypeScript / Node.js


一、项目概览:名称、作者、作用与背景

1.1 名称与作者

  • 项目名称skills(仓库名 vercel-labs/skills)。它是 Vercel Labs 开源的 Agent Skills CLI,相当于技能生态里的「npm/pip」包管理器。
  • 作者 / 组织:由 Vercel Labsvercel-labs 组织)主导维护,最新提交者 mlekhi。这是一个 社区驱动 项目(README 中能看到的贡献者遍布各 Agent 社区),本身没有单一「个人作者」,而是「Vercel 生态标准工具」。
  • 商标元素:CLI 启动时会打印 ASCII 字样的 skills Logo,并引导用户到 https://skills.sh 发现技能。

1.2 作用

skillsAgent Skills(由 SKILL.md 定义的、可复用的「给 AI 编码代理看的指令包」)变成一种可安装、可发现、可更新的「软件包」。它提供:

命令 作用
skills add <source> 从 GitHub / GitLab / 本地 / 直链安装技能到某个(或所有)Agent
skills use <source>@<skill> 免安装生成一段 prompt,或交互式拉起某个 Agent
skills list / ls 列出已安装技能(支持 --json 机器可读)
skills find [query] 交互式/关键字搜索技能
skills remove / rm 从 Agent 中移除技能
skills update 把已装技能更新到最新版本
skills init [name] 生成一个 SKILL.md 模板(用于自己写技能)
skills experimental_install / experimental_sync skills-lock.json 还原 / 从 node_modules 同步(实验性)

核心卖点:一个技能,可被 76+ 种编码代理复用(Claude Code、Cursor、Codex、OpenCode、CodeBuddy、Trae、Kiro、Roo Code、Windsurf 等),安装后通过 符号链接(symlink)指向同一份 canonical 副本,升级一次、处处生效。

1.3 背景

AI 编码代理(Coding Agent)在 2025–2026 年快速分化出几十种形态,各自都有「让用户塞一段系统指令/工作流」的能力,但格式互不兼容agentskills.io 提出了一份 Agent Skills 规范:一个目录里放一个带 YAML frontmatter 的 SKILL.mdname + description),即可被 Agent 加载。

vercel-labs/skills 就是这份规范的 参考实现 CLI

  • 解决「技能如何跨代理分发」的问题——把 SKILL.md 当源码,用包管理器的方式安装/升级;
  • 解决「去哪找技能」的问题——配套发现站 https://skills.sh(带安装量排行榜,能筛出「经过实战检验」的技能);
  • 解决「安装后的归属」问题——Agent 各自的 skills 目录五花八门(.claude/skills.cursor/skills.agents/skills…),CLI 用一张 Agent 注册表 把它们统一映射到 canonical 目录。

二、安装与使用教程、依赖条件

2.1 软件 / 硬件依赖

类别 要求
运行时 Node.js ≥ 22.20.0(强制门槛,低于此版本直接报错)
包管理器 开发用 pnpm@10.17.1;普通用户无需预装,靠 npx 即时拉取
运行时依赖 仅两个tar@^7.5.20(解档)、yaml@^2.8.3(解析 frontmatter)。零其他第三方运行时依赖,无原生编译
Git 非强制。优先走「archive 下载」(codeload / GitHub API / skills.sh blob API),需要克隆时才回退到系统 git(受 git transport allowlist 限制)
硬件 命令行工具,几乎无资源要求;能跑 Node 22 的任何机器即可
网络 安装远程技能需联网;skills use / local 源、skills init 可离线
操作系统 Linux / macOS / Windows 均支持(代码中专门处理 win32junction 软链、路径分隔符、APPDATA 等)

注意:simple-gitvitesthuskyprettier@vercel/detect-agent 等只出现在 devDependencies,不会被安装到最终用户环境。

2.2 安装(CLI 本身)

CLI 通过 npx 分发,无需预装

# 直接调用(首次会自动下载)
npx skills add vercel-labs/agent-skills

仅当你要二次开发时,才需要 clone + pnpm:

git clone https://github.com/vercel-labs/skills
cd skills && pnpm install && pnpm build

2.3 使用教程(常用范式)

(1) 安装一个技能仓库到所有已检测到的 Agent(项目级)

npx skills add vercel-labs/agent-skills

(2) 只装某个技能、装到指定 Agent、非交互(CI 友好)

npx skills add vercel-labs/agent-skills --skill frontend-design -g -a claude-code -y
  • -g 用户级(~/.claude/skills),不加则项目级(./.claude/skills);
  • -a 指定 Agent;-s 指定技能;--copy 用复制而非软链;--all 全装全 Agent。

(3) 支持多种源格式

npx skills add vercel-labs/agent-skills                 # GitHub 简写
npx skills add https://github.com/vercel-labs/agent-skills
npx skills add https://github.com/vercel-labs/agent-skills/tree/main/skills/web-design-guidelines
npx skills add https://gitlab.com/org/repo             # GitLab
npx skills add git@github.com:vercel-labs/agent-skills.git
npx skills add ./my-local-skills                        # 本地路径
npx skills add https://example.com/download/my-skill    # 直链(SKILL.md 或 .zip/.tar/.tgz)

(4) 免安装「即用」——生成 prompt 喂给 Agent

npx skills use vercel-labs/agent-skills@web-design-guidelines | claude
# 或交互式拉起某 Agent:
npx skills use vercel-labs/agent-skills --skill web-design-guidelines --agent claude-code

(5) 搜索 / 列出 / 更新 / 移除 / 初始化

npx skills find typescript --owner vercel     # 搜索
npx skills list -g --json                      # 列出(JSON 机器可读)
npx skills update -y                           # 更新
npx skills remove web-design-guidelines -y     # 移除
npx skills init my-skill                       # 生成 SKILL.md 模板

(6) 环境变量

变量 用途
INSTALL_INTERNAL_SKILLS=1 显示/安装标记为 metadata.internal: true 的内部技能
DISABLE_TELEMETRY / DO_NOT_TRACK 关闭匿名遥测(CI 中自动关闭)
SKILLS_DOWNLOAD_MAX_BYTES / SKILLS_EXTRACT_MAX_BYTES / SKILLS_EXTRACT_MAX_FILES 覆盖下载/解档大小与文件数上限

三、工作流程与执行步骤

3.1 命令总览(来自 src/cli.tsmain() 路由)

cli.ts 是入口,解析 process.argv,把命令分发到对应模块,并在退出前 flushTelemetry()

find/search/f → runFind
init           → runInit(生成 SKILL.md 模板)
experimental_install → runInstallFromLock
i/install/a/add → parseAddOptions + runAdd
use            → parseUseOptions + runUse
remove/rm/r    → parseRemoveOptions + removeCommand
experimental_sync → parseSyncOptions + runSync
list/ls        → runList
check/update/upgrade → runUpdate

设计细节:restArgs 里出现 --help/-h先短路打印帮助,避免误执行带副作用的命令(如 skills update --help 不应真的去更新)。

3.2 skills add 详细执行步骤(核心流程)

flowchart TD A[用户输入 skills add &lt;source&gt;] --> B[parseAddOptions 解析源与选项] B --> C[parseSource 归类源类型] C -->|owner/repo| D1[github 类型] C -->|完整 URL / tree 路径| D2[github/gitlab + ref/subpath] C -->|本地路径| D3[local] C -->|直链/归档| D4[download] C -->|其它 git URL| D5[git] C -->|HTTPS 非 Git 主机| D6[well-known] D1 & D2 & D4 & D5 & D6 --> E[download-source: 拉取并落地到临时目录] E --> F[发现 SKILL.md:深度遍历 skills/ 容器,支持 flat/catalog/plugin-manifest/root] F --> G[按 --skill 过滤(支持 '*')] G --> H[detectInstalledAgents 或 -a 指定的 Agent 列表] H --> I{对每个 Agent × 每个技能} I --> J[sanitizeName 防路径穿越 + isPathSafe 校验] J --> K[installSkillForAgent] K --> K1[写入 canonical: .agents/skills/&lt;name&gt;] K1 --> K2[软链/复制到 Agent 目录 如 .claude/skills/&lt;name&gt;] K2 --> L[写入 skills-lock.json] L --> M[flushTelemetry 上报(CI 自动关)]

关键步骤说明:

  1. 源归类(source-parser.tsparseSource:把任意输入归一化为 { type, url, ref?, subpath?, skillFilter?, localPath? }。支持 GitHub 简写、@skill 语法、#ref@skill fragment、gitlab:/github: 前缀、GitLab 子组(group/subgroup/repo)、GitHub Enterprise(GH_HOST)、直链归档、本地路径等。
  2. 源获取(download-source.ts / blob.ts / archive.ts:优先 archive 下载(codeloadraw.githubusercontentobjects.githubusercontent、skills.sh blob API),命中 isHostedArtifactUrl 时直接走 download 类型;否则走 git(受 git.ts 的 transport allowlist 约束)。
  3. 技能发现:在仓库内按约定目录(skills/skills/.curated/.claude/skills/.agents/skills/、各 Agent 目录…)深度 1(flat)/ 深度 2(catalog)SKILL.md--full-depth 额外搜 examples/tests/ 等。若存在 .claude-plugin/marketplace.json / plugin.json 则按清单发现。
  4. 安装(installer.tsinstallSkillForAgent
    • sanitizeName(小写、非 [a-z0-9._] 变连字符、去首尾点/杠、限 255 字符、空则 unnamed-skill)防目录穿越;
    • isPathSafe 二次校验目标路径在基准目录内;
    • 默认 symlink 模式:先把技能内容写到 canonical 目录.agents/skills/<name> 或全局 ~/.agents/skills/<name>),再为每个 Agent 建软链到其专属目录(如 .claude/skills/<name>);
    • 软链失败(createSymlink 返回 false,常见于不支持软链的文件系统)自动回退 copy 模式
    • Universal AgentskillsDir === '.agents/skills',如 Cline/Codex/Cursor/OpenCode 等)直接复用 canonical 目录,不重复建链,避免重复列出。

3.3 其它命令流程

  • skills use:解析源 → 把选中的单个技能写到临时目录 → 只把生成的 prompt 打到 stdout(可管道给 claude);带 --agent 时交互式拉起该 Agent。
  • skills listlistInstalledSkills 扫 canonical + 各已装 Agent 目录,parseSkillMd 解析 SKILL.md,按 scope:name 去重,返回含 agents[] 的安装清单;--json 输出机器可读。
  • skills find:交互式(fzf 风格)或关键字检索,可 --owner 限定 GitHub 组织。
  • skills remove:按名称/通配符从 Agent 目录删软链或副本;--all = 全清。
  • skills updateupdate-source.ts 重新拉取源并覆盖 canonical 副本(软链自动跟随,因此一次更新全 Agent 生效)。
  • skills init:在当前目录或子目录写一份带 frontmatter 模板的 SKILL.md
  • skills experimental_install:读取 skills-lock.json(由 local-lock.ts 记录),可重复还原安装;experimental_sync:从项目 node_modules 同步技能到 Agent 目录。

四、文件逐个解读(按目录)

4.1 根目录文件

文件 作用
package.json 包定义:bin 暴露 skillsadd-skillengines.node>=22.20dependenciestar+yamlpackageManager: pnpm@10.17.1keywords 列举了全部 80+ Agent
README.md 完整文档:命令、源格式、Agent 兼容表、Agent Skills 规范说明、环境变量、遥测
LICENSE MIT
ThirdPartyNoticeText.txt scripts/generate-licenses.ts 生成的三方许可声明
build.config.mjs obuild 构建配置(依赖打包,perf: bundle dependencies)
tsconfig.json TypeScript 配置
.prettierrc / .husky/ / .github/ 代码规范、Git hooks、CI 工作流(要求 Node 22.20+)
AGENTS.md 给 Agent 看的本仓库维护说明

4.2 bin/ — 分发入口

文件 作用
bin/cli.mjs 构建产物 CLI 入口(package.jsonbin 指向它)。dev 时则用 src/cli.ts 直接跑

4.3 src/ — 核心源码(TypeScript)

文件 作用
cli.ts 命令路由/main 入口:解析 argv、打印 Logo/横幅/帮助、分发到各命令、finally 中 flush 遥测
add.ts parseAddOptions + runAdd:实现 add 全流程(解析→获取→发现→过滤→安装→落锁)
use.ts parseUseOptions + runUse:免安装生成 prompt / 交互式拉起 Agent
list.ts runList:列出已装技能,--json 输出
find.ts runFind:交互/关键字搜索
remove.ts parseRemoveOptions + removeCommand:移除逻辑
update.ts runUpdate:升级已装技能
sync.ts runSync + parseSyncOptions:实验性 experimental_sync(从 node_modules 同步)
install.ts runInstallFromLock:实验性 experimental_install(从 lock 还原)
agents.ts Agent 注册表:76+ Agent 的 {name, displayName, skillsDir, globalSkillsDir, detectInstalled},并提供 detectInstalledAgents()getUniversalAgents()getEveSubagents() 等。这是跨 Agent 兼容的「地图」
installer.ts 安装引擎installSkillForAgent / installRemoteSkillForAgent / installWellKnownSkillForAgent / installBlobSkillForAgentcreateSymlink(含 ELOOP 处理、父子软链解析)、copyDirectorysanitizeNameisPathSafelistInstalledSkills
source-parser.ts 源解析parseSource 把任意输入归一化为结构化源;含 SOURCE_ALIASES(如 vercel-labs/vercel-skills → vercel-labs/agent-skills)、fragment ref(#ref@skill)、sanitizeSubpath(拒绝 .. 穿越)
frontmatter.ts Frontmatter 解析parseFrontmatter 仅支持 YAML(--- 分隔),刻意不实现 ---js 避免 gray-matter 式 eval RCE
skills.ts parseSkillMd:解析单个 SKILL.md 为技能对象
download-source.ts 把解析后的源拉取到本地临时目录(archive / git / blob)
archive.ts tar 归档下载与解档封装
blob.ts skills.sh blob 下载 API 封装(snapshot 格式 {path, contents}[]
github-host.ts GH_HOSTisGitHubHost 支持 GitHub Enterprise
git.ts git transport allowlist:限制可克隆的协议/主机,防供应链风险
plugin-manifest.ts 解析 .claude-plugin/marketplace.json / plugin.json 的技能清单
local-lock.ts 读写项目级 skills-lock.json(可重复安装)
skill-lock.ts lock 文件版本与一致性逻辑
update-source.ts 更新时重新解析并拉取最新源
constants.ts AGENTS_DIR.agents)、SKILLS_SUBDIRskills)等常量
telemetry.ts 匿名遥测(CI 自动禁用,DO_NOT_TRACK/DISABLE_TELEMETRY 可关)
detect-agent.ts isRunningInAgent:判断是否运行在 Agent 内(影响是否打印 Logo)
sanitize.ts 名称/路径清洗工具
types.ts 共享类型(AgentTypeParsedSourceSkillRemoteSkill 等)
providers/index.ts providers/registry.ts providers/types.ts providers/wellknown.ts 「知名源」提供方注册表:内置 vercel-labs/agent-skillsanthropics/skills 等官方源的发现与解析
prompts/search-multiselect.ts 交互式多选搜索的渲染(含视觉行/多选中测试)

附:agents.ts 注册表节选(CodeBuddy 与其它代表)

codebuddy: {
  name: 'codebuddy', displayName: 'CodeBuddy',
  skillsDir: '.codebuddy/skills',
  globalSkillsDir: join(home, '.codebuddy/skills'),
  detectInstalled: async () => existsSync(join(process.cwd(), '.codebuddy')) || existsSync(join(home, '.codebuddy')),
},
claude-code: { name:'claude-code', displayName:'Claude Code',
  skillsDir:'.claude/skills', globalSkillsDir: join(claudeHome,'skills'),
  detectInstalled: async () => existsSync(claudeHome) },
opencode: { name:'opencode', displayName:'OpenCode',
  skillsDir:'.agents/skills', globalSkillsDir: join(configHome,'opencode/skills'), ... },
// … 共 76+ 个,含 universal 组(skillsDir==='.agents/skills' 的 Cline/Codex/Cursor/... 共享 canonical 目录)

附:installer.ts 软链+防穿越节选

export function sanitizeName(name: string): string {
  const sanitized = name.toLowerCase()
    .replace(/[^a-z0-9._]+/g, '-')          // 非安全字符 → 连字符
    .replace(/^[.\-]+|[.\-]+$/g, '');       // 去首尾点/杠(防隐藏文件)
  return sanitized.substring(0, 255) || 'unnamed-skill';
}
// createSymlink 中:解析父目录软链、处理 ELOOP、win32 用 'junction';
// 软链失败 → 返回 false → 上层回退 copyDirectory。

附:source-parser.ts 源归一化节选

export function parseSource(input: string): ParsedSource {
  if (isLocalPath(input)) return { type:'local', url: resolve(input), localPath: resolve(input) };
  // ... 解析 fragment ref (#ref@skill)、SOURCE_ALIASES、github:/gitlab: 前缀
  // ... GitHub/GitLab tree+subpath、shorthand owner/repo@skill、well-known / git 回退
}

附:frontmatter.ts 安全解析节选

import { parse as parseYaml } from 'yaml';
// 仅支持 YAML 分隔符;刻意不支持 ---js / ---javascript,
// 以避免 gray-matter 内建 JS 引擎带来的 eval() RCE 风险。
export function parseFrontmatter(raw: string) {
  const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
  if (!match) return { data: {}, content: raw };
  const data = parseYaml(match[1]!) ?? {};
  return { data, content: match[2] ?? '' };
}

4.4 skills/ — 内置技能

文件 作用
skills/find-skills/SKILL.md CLI 自带的技能:当 Agent 用户问「怎么做到 X / 有没有做 X 的技能」时触发。它教 Agent 先查 skills.sh 排行榜、再 npx skills find、并按安装量/来源信誉/GitHub stars 校验质量后再推荐,最后可帮用户 npx skills add ... -g -y 安装。是「让技能生态自我发现」的范本

4.5 scripts/ — 维护脚本

文件 作用
generate-licenses.ts 生成 ThirdPartyNoticeText.txt
execute-tests.ts 测试执行编排
sync-agents.ts 同步 Agent 注册表(可能从各 Agent 官方文档刷新路径)
validate-agents.ts 校验 agents.ts 注册表一致性

4.6 tests/ — 测试套件

覆盖广泛,包含:archive/blob-fetch-tree-auth/blob-root-skillcross-platform-pathsdirect-download-addfull-depth-discoverygit-lfs-clonegit-transport-allowlistgrok-agent/eve-agent/kimchi-agent/minimax-code-agent/zcode-agentinstall/installer-copy/installer-symlinklocal-locknested-container-discoveryopenclaw-pathsplugin-manifest-discoveryremove-canonicalresolve-skills-to-removeroot-level-disk-install/root-level-lock-hashsanitize-name/sanitize-terminalsearch-multiselect-*skill-matching/skill-pathsource-parsersubpath-traversalsyncupdatewellknown-provider/wellknown-updatexdg-config-paths安全类测试(路径穿越、transport allowlist、subpath traversal)是重点


五、优势、不足、创新点与亮点

5.1 优势

  1. 真正的跨 Agent 一次编写、处处复用:76+ Agent 共享同一份 SKILL.md 源,canonical + 软链让「升级一次、全 Agent 生效」。
  2. 运行时依赖极简:仅 tar + yaml,无原生编译、无重型框架,分发体积小、启动快(bin/cli.mjs 还用了 module compile cache)。
  3. 安全优先的工程态度
    • frontmatter 只用 YAML 解析,刻意不实现 ---js 执行,规避 gray-matter 式 eval RCE;
    • sanitizeName + isPathSafe + sanitizeSubpath 三重防目录穿越;
    • 下载体积/文件数上限 + git transport allowlist 防供应链投毒;
    • archive 下载优先于 git clone,减少暴露面。
  4. 软链为主、复制兜底:默认 canonical 单副本 + 软链;文件系统在 Windows/某些场景不支持软链时自动回退 copy,体验不中断。
  5. 发现能力强:flat / catalog(.curated/.experimental/.system)/ plugin-manifest / root-level 多形态发现,--full-depth 兜底;配套 find-skills 内置技能与 skills.sh 排行榜。
  6. 工程成熟度:庞大的跨平台测试(含 Windows junction、Git LFS、各 Agent 路径)、husky + lint-staged + prettiervitest,质量门禁扎实。
  7. 可复现安装skills-lock.json + experimental_install 类似 package-lock,支撑团队/CI 一致性。
  8. 对 CodeBuddy 开箱即用:注册表已含 codebuddy(项目级 .codebuddy/skills、用户级 ~/.codebuddy/skills)。

5.2 不足

  1. 能力受 Agent Skills 规范落地程度限制allowed-toolsHookscontext: fork 等特性并非所有 Agent 都支持(README 兼容表显示仅 Claude Code 等少数支持 context: fork,Kiro/Antigravity 不支持 allowed-tools),技能作者需做兼容降级。
  2. Node ≥ 22.20 门槛偏新:部分老旧 CI / 嵌入式环境尚未上 22.20,直接使用会报错。
  3. 技能质量参差不齐:生态是社区驱动,质量靠人工/排行榜判断;find-skills 技能自己也强调「不要仅凭搜索结果推荐,要校验安装量与来源信誉」。
  4. 软链对部分 Agent 不友好:个别 Agent 不跟随软链时,需 --copy;而 copy 模式会复制多份,更新时需逐一处理。
  5. 中心化倾向:发现与 blob 下载依赖 Vercel 运营的 skills.sh,存在「事实标准由单一组织掌控」的治理隐忧。
  6. 实验性命令不稳定experimental_install / experimental_sync 明确标注 experimental,接口可能变动。
  7. 纯 CLI:对偏好 GUI 的用户不友好(需配合 skills.sh 网页或各 Agent 自带 UI)。

5.3 创新点与亮点

  1. Universal .agents/skills 约定:把 Cline/Codex/Cursor/OpenCode 等共享同一目录的 Agent 归为「universal 组」,安装时不为它们重复建链,优雅去重——getUniversalAgents() 的设计很有巧思。
  2. Canonical 单副本 + 多 Agent 软链的「包管理式」技能分发模型,把「提示词工程」提升到了「依赖管理」的成熟度。
  3. 安全即代码(security-by-construction):不是事后加固,而是在解析层就禁用 JS frontmatter、在路径层就做穿越校验、在网络层就做 transport 白名单,并用专门测试锁死这些行为。
  4. 源归一化极其完备parseSource 同时解决 GitHub 简写、@skill、fragment ref(#ref@skill)、GitLab 子组、GitHub Enterprise(GH_HOST)、本地路径、直链归档、well-known URL 等,并对 subpath 做 .. 拒绝。
  5. skills-lock.json 可复现安装:把「技能」当一等依赖纳入版本管理,呼应现代包管理器的可复现理念。
  6. 内置 find-skills 让生态自我发现:CLI 不只管理技能,还内置一个「帮用户找技能」的技能,形成发现→安装→使用的闭环。
  7. Agent 注册表即「兼容层」:用一张数据表(agents.ts)抽象掉 76+ Agent 的路径差异,新增 Agent 几乎零侵入,是该项目可快速扩张到 76+ Agent 的关键。
  8. 遥测克制:匿名、可关、CI 自动禁用,符合开发者工具的可信默认。

六、补充:与 CodeBuddy 的关系

vercel-labs/skills 的 Agent 注册表原生包含 codebuddy(项目级 .codebuddy/skills/、用户级 ~/.codebuddy/skills/),因此你可以直接用:

npx skills add vercel-labs/agent-skills -a codebuddy -y

把 Vercel 官方技能(React / Next.js / Web Design / Vercel 优化等)装到 CodeBuddy 中;也可用 npx skills find <关键词> --owner vercel 检索后一键安装。这意味着 WorkBuddy/CodeBuddy 用户能直接消费整个开放技能生态,无需等待平台官方逐个内置。


本文档基于仓库 main 分支(最近提交 2026-07-31,v1.5.21)的 README、package.jsonsrc/cli.tssrc/agents.tssrc/installer.tssrc/source-parser.tssrc/frontmatter.tsskills/find-skills/SKILL.md 解读整理。

posted @ 2026-07-31 18:24  zhang-yd  阅读(52)  评论(0)    收藏  举报