把分散在多个 AI agent (Claude Code / Codex / CodeBuddy / WorkBuddy / agents-personal) 的重复 skill 合并到 ~/.skillhub/ 单一权威拷贝,原 agent 路径替换为目录级 symlink。一处更新,所有 agent 生效。
> ℹ️ 本 Skill 是 skillhub CLI 的扩展子命令 normalize,由 scripts/skills_normalize.py 实现 + scripts/skillhub.sh 包装脚本驱动(安装后改名为 ~/.skillhub/skillhub,保持用户的 alias 习惯)。规范化只读模式默认输出,--apply 才动磁盘,所有改动 tar 全量备份后才落盘。
| 用户想做的事 | 是否触发本 Skill |
|---|---|
| --- | --- |
| 把 ~/.claude / ~/.codex / ~/.codebuddy 的同一个 skill 合并 | ✅ |
| 统一所有 AI agent 的 skill 数据源 | ✅ |
| 算一下 skill 重复占了多少空间 | ✅(用 --scan-only + --status) |
| 加新 agent (Cursor / Aider / Continue) 的扫描支持 | ✅(写 ~/.skillhub/.normalize-adapters.json,见 references/adapters.md) |
| 安装新 skill / 搜索 skillhub 商店 / 升级单个 skill | ❌(用 skillhub install / search / upgrade,不是本 Skill) |
| Linux / Windows 上跑 | ❌(本 Skill 仅 macOS 适配) |
skill 装到 ~/.skillhub/skill-normalize/ 之后,需要做一次性的 shell 集成。直接跑包内的安装脚本:
~/.skillhub/skill-normalize/scripts/install.sh
这一步会做:
scripts/skills_normalize.py 软链到 ~/.skillhub/skills_normalize.py(与 skills_store_cli.py 同级)。scripts/skillhub.sh 软链到 ~/.skillhub/skillhub(去掉 .sh,保持用户 alias 习惯)。python3 skills_normalize.py --bootstrap 把 normalize 子命令插进 skills_store_cli.py。alias skillhub='~/.skillhub/skillhub'(可选;脚本会问)。之后每次 CLI self-upgrade 时如果 skills_store_cli.py 被替换,包装脚本会在每次调用前自动重打补丁,对用户透明。
skillhub normalize --scan-only # 列出每个 agent 装了多少 skill、多少已是 symlink
skillhub normalize --status # 列出已归一化的 skill + 反向链接数
skillhub normalize # 计算 plan 写到 ~/.skillhub/.normalize-plan.json,不动磁盘
skillhub normalize --apply --dry-run # 打印所有 mv / ln -s / cache invalidate 操作但不执行
skillhub normalize --apply # 真跑,备份在 ~/.skillhub/.normalize-backup/<ts>/
skillhub normalize --rollback <ts> # 从备份还原;ts 用 ls ~/.skillhub/.normalize-backup/ 看
回滚做三件事:解 tar 还原 agent 原路径 → 删 ~/.skillhub/ 权威副本 → 清 .skills_store_lock.json 里这次 apply 加的条目。
| Adapter | 扫描路径 | 加载机制 |
|---|---|---|
| --- | --- | --- |
claude | ~/.claude/skills/ | fs scan |
claude-plugins | ~/.claude-internal/plugins/cache/ | installed_plugins.json 注册 |
codex | ~/.codex/vendor_imports/skills/skills/.curated/ | skills-curated-cache.json |
codex-internal | 同 codex 但在 ~/.codex-internal/ | 同 codex |
codebuddy | ~/.codebuddy/plugins/marketplaces//{plugins,external_plugins}//skills/ | marketplace cache |
workbuddy | ~/.workbuddy/connectors/skills/ | MCP connector |
agents-personal | ~/.agents/skills/ | 用户手动归一化目录 |
新 agent 通过 ~/.skillhub/.normalize-adapters.json 加,无需改代码。schema 见 references/adapters.md。
每个 skill 的 frontmatter 由 parse_frontmatter 取出后,按下表分类:
| Frontmatter 字段 | 处理 |
|---|---|
| --- | --- |
仅 name / description / shortDescription / icon* / repoPath / version / author / source | ✅ 归一化候选 |
含 allowed-tools(CodeBuddy 工具授权专属) | ❌ skipped,原样保留 + 写 reason |
含 connector(WorkBuddy MCP 连接器 ID 专属) | ❌ skipped |
含 disable(WorkBuddy 启用标志专属) | ❌ skipped |
把 CodeBuddy 的 allowed-tools skill 拷到 Codex 下不会出错,但工具授权会失效;把 WorkBuddy 的 connector skill 拷到 Claude 下没有 MCP server 它就废了。所以这类 skill 保留原样并标 reason,不归一化。
按 lowercase basename 分组后,组内 sha256:
canonicalize action(合并)conflict action(同名不同内容,写到 plan 但 apply 跳过)冲突常见来源:不同 agent vendor 了不同版本的同名 skill(比如 pdf 在 codex 和 codebuddy 里 hash 不一样)。看到 conflict 后用户可以:
v1 不自动选——错的合并代价比保留重复大得多。
每次 --apply:
~/.skillhub/.normalize-backup// ,再 os.rename 权威源到 ~/.skillhub// ,再建 symlink。中途 crash → 备份完整可回滚。~/.skillhub// 的组在 plan 阶段被过滤,所以 apply 是幂等的。| 子命令 | 谁负责 |
|---|---|
| --- | --- |
skillhub install | 不是本 Skill:从 metadata.json 配置的云端仓库下载 zip 装到 ~/.skillhub/ |
skillhub search | 不是本 Skill:调 skills_search_url 找云端 skill |
skillhub upgrade [ | 不是本 Skill:根据每个 skill config.json 里的 update URL 升级 |
skillhub list | 不是本 Skill:读 .skills_store_lock.json 列已装 |
skillhub normalize | 本 Skill:扫描本地各 AI agent 的 skill 目录、合并重复、symlink 归一 |
skillhub self-upgrade | 不是本 Skill:升级 CLI 自身 |
normalize 写到 lockfile 时 source 字段标 agent-import(区别于 skillhub 这个 install source),所以后续 list 和 upgrade 看得到这些条目,但不会去云端找它们的更新(云端没这些 slug,因为它们是从本地 agent 目录"逆向"来的)。
跑完 skillhub normalize --apply 之后,验证三个独立 agent 路径下的 algorithmic-art 全部指向同一个权威拷贝:
for p in \
~/.claude-internal/plugins/cache/anthropic-agent-skills/document-skills/*/skills/algorithmic-art \
~/.claude-internal/plugins/cache/anthropic-agent-skills/example-skills/*/skills/algorithmic-art \
~/.claude-internal/plugins/cache/anthropic-agent-skills/claude-api/*/skills/algorithmic-art ; do
echo "$p -> $(readlink -f "$p")"
done
# 期望:3 行 readlink -f 输出全是 ~/.skillhub/algorithmic-art
references/architecture.md — 数据流图、operation 序列、单事务保证references/adapters.md — 自定义 adapter schema + 加新 agent 的步骤references/troubleshooting.md — 常见问题 + 调试命令共 1 个版本