1. 项目概述:技能同步工具 skill-sync

如果你和我一样,日常开发中重度依赖各种AI编程助手(Agent),比如Cursor、Codex、Claude Code,那你肯定也遇到过这个痛点:每个工具都有自己的技能(Skill)安装目录,而你的技能源码却分散在各个本地项目仓库里。手动为每个工具创建软链接、检查更新、处理冲突,简直是场噩梦。 skill-sync 这个CLI工具,就是为解决这个“技能管理碎片化”问题而生的。它本质上是一个智能的、安全的同步引擎,能自动扫描你的本地项目,发现 SKILL.md 文件,并将它们以符合各个AI助手原生要求的方式,“安装”到对应的技能目录中,同时保持源码的单一真实来源。

简单来说,它让你可以像管理代码依赖一样管理你的AI技能。你只需要在项目里维护一个 SKILL.md 文件, skill-sync 会负责处理跨多个AI工具的分发、版本同步和冲突检测。它特别适合那些技能源码存放在本地Git仓库,而非通过 npm 等包管理器分发的场景。无论是独立开发者维护一套私有技能库,还是团队内部共享工具链, skill-sync 都能将你从繁琐的重复劳动中解放出来,确保你在任何AI助手环境里,使用的都是最新、最一致的技能版本。

2. 核心设计理念与架构解析

2.1 为什么需要 skill-sync:超越 npx skills

官方或社区通常推荐使用 npx skills 来安装和管理技能。这个工具非常优秀,但它主要面向的是“包管理”范式:技能作为一个独立的npm包发布,你通过 npx 拉取并安装。然而,在实际开发工作流中,很多技能并非独立的包,而是与特定项目代码库深度绑定。例如,一个用于生成项目特定API客户端代码的技能,其 SKILL.md 文件很可能就放在该API服务项目的根目录下,与业务逻辑一同迭代。

skill-sync 解决的是另一个维度的问题: 源码本地化 。它的设计基于以下几个核心假设:

  1. 技能即代码 :技能是项目的一部分,应该与项目代码一同进行版本控制。
  2. 单一真实来源 :一个技能只应有一个权威的源码位置(通常是项目仓库)。
  3. 多环境分发 :开发者可能同时使用多个AI编程环境(如Codex写注释,Cursor写业务代码),技能需要在所有环境中可用。
  4. 安全与可控 :任何同步操作必须是可预测、可回滚的,不能静默覆盖用户手动创建的内容。

因此, skill-sync 的架构围绕“发现-计划-执行”模型构建。它首先在你的配置的项目根目录(如 ~/_dev )中发现技能源文件,然后根据每个目标AI工具(它称之为“Harness”,即套具)的原生布局规则,生成一个同步计划,最后在用户确认后安全地执行。

2.2 核心工作流程与数据模型

skill-sync 的内部逻辑可以拆解为以下几个关键阶段:

1. 源发现 (Source Discovery) 工具会递归扫描你配置的所有项目根目录。它不仅仅查找顶层的 SKILL.md ,还支持两种常见的组织模式:

  • 嵌套技能目录 <项目根>/skills/<技能名>/SKILL.md 。这种结构适合在一个仓库内管理多个相关技能。
  • 子仓库技能 :对于项目根下的一级子目录(本身是Git仓库),如果其包含 SKILL.md skills/ 目录,也会被识别。这对应了Monorepo或项目集合的场景。

发现过程中,它会解析每个 SKILL.md 文件的YAML Frontmatter,提取技能名称 ( name )、描述等元数据。技能的“slug”(用于安装目录的名称)默认由 name 字段生成(经过slugify处理),如果没有 name ,则回退到目录名。

2. 套具识别与状态检测 (Harness Detection & State Inspection) skill-sync 内置了主流AI工具的技能根目录映射(如Codex对应 ~/.codex/skills )。它会检查这些目录的当前状态:哪些技能已经安装?是工具原生的、 skill-sync 管理的,还是用户手动创建的?它通过检查目录结构和元数据(如特殊的标记文件或符号链接的指向)来区分。

3. 冲突与漂移分析 (Conflict & Drift Analysis) 这是安全性的核心。工具会比较“源状态”和“套具状态”,计算出需要执行的操作:

  • 新增 :源中存在,但某个套具中未安装。
  • 更新 :源文件内容已变更,需要同步到套具。
  • 冲突 :套具中已存在一个技能,但其来源并非当前 skill-sync 管理的源(例如用户手动创建或来自其他源)。 skill-sync 会标记此类冲突,默认不会覆盖。
  • 孤儿项 :套具中存在 skill-sync 管理的安装,但其对应的源文件已不存在。这可能是源文件被删除或移动了。
  • 错误 :源文件Frontmatter格式错误、YAML无效、符号链接断裂等。这些会导致AI工具无法正确索引技能,因此被视作阻塞性错误。

4. 计划与执行 (Planning & Execution) 基于分析结果, skill-sync 生成一个详细的变更计划。执行阶段,它会:

  • 为支持的套具创建符合其预期的目录结构。对于大多数工具,这是一个包装目录,内含一个指向源 SKILL.md 的符号链接。
  • 对于Codex的“本地技能”,则采用物化目录(复制文件)的方式安装。
  • 对于需要在Codex中共享可见的技能,会通过物化的 ~/.agents/skills 桥接条目进行路由,避免在IDE中重复列出。
  • 自动修剪套具根目录下可能导致解析器错误(如OpenCode)的顶级目录符号链接。
  • 在执行任何破坏性操作前,可选地创建备份。

2.3 安装布局策略详解

skill-sync 根据套具类型,采用不同的安装策略,这是其能无缝集成各工具的关键:

  1. 包装目录与符号链接 (Wrapper Directory & Symlink) 这是对大多数套具(如Claude Code, Cursor, Hermes)的默认策略。假设技能 my-linter 的源在 ~/dev/tools/my-linter/SKILL.md ,安装到Cursor后,目录结构如下:

    ~/.cursor/skills/
    └── my-linter/          # 包装目录
        └── SKILL.md -> ~/dev/tools/my-linter/SKILL.md  # 符号链接指向源
    

    这样做的好处是:AI工具看到一个标准的技能目录结构,而实际内容始终指向单一源码。任何对源文件的修改都会立即在所有套具中生效。

  2. Codex的物化目录 (Materialized Directory for Codex-local) Codex对本地技能的处理方式略有不同。 skill-sync 会为Codex创建一个物化的技能目录,将 SKILL.md 文件内容复制进去。这是为了兼容Codex内部可能对技能文件的读取方式。但同时,它通过 ~/.agents/skills 桥接来管理共享技能,确保Codex能正确识别来自其他套具的技能,而不会在插件列表中重复显示。

  3. 作用域控制 (Scope Control) 技能源可以通过Frontmatter中的 skill-sync-scope skill-sync-install-on 字段精细控制其分发范围。

    • skill-sync-scope: local-only :该技能仅安装在它所在的套具根目录对应的工具中。例如,一个专门为Codex调试设计的技能,可以设为仅安装在Codex中。
    • skill-sync-install-on: [codex, cursor] :明确指定只同步到Codex和Cursor。
    • skill-sync-scope: global :显式声明为全局技能,同步到所有套具。 默认情况下,供应商特定的套具根目录(如 ~/.codex/skills )被视为“本地仅限”,而共享根目录(如 ~/.agents/skills )则默认为全局。这个设计避免了意外地将一个工具的私有技能泄露到所有其他工具。

3. 从安装到实战:完整操作指南

3.1 环境准备与初始化

首先,你需要通过npm全局安装 skill-sync 。建议使用Node.js 16或更高版本。

npm install -g @light-merlin-dark/skill-sync

安装后,系统会添加 skill-sync 和其快捷命令 ss 。接下来进行初始化配置:

# 初始化配置文件,通常位于 ~/.skill-sync/config.json
skill-sync config init

这个命令会创建一个默认配置。最重要的配置项是项目根目录。默认是 ~/_dev ,但你可以添加任意多个路径。

# 查看当前配置的根目录
skill-sync roots list
# 添加一个新的项目根目录
skill-sync roots add /path/to/your/projects
# 移除一个根目录
skill-sync roots remove /path/no/longer/needed

实操心得 :我习惯将我的所有Git仓库都克隆到 ~/dev 目录下,所以我直接将其添加为根目录。如果你使用类似 ~/Projects ~/workspace 的目录,记得在这里添加。 skill-sync 会扫描这些目录下所有直接子仓库(一级深度),所以请确保你的项目结构是扁平的,或者使用 skills/ 子目录结构。

3.2 技能源文件规范与编写

skill-sync 的核心是 SKILL.md 文件。它本质上是一个Markdown文件,但必须在文件开头包含有效的YAML Frontmatter块,用于定义技能元数据。

一个最基本的 SKILL.md 文件示例如下:

---
name: TypeScript Interface Generator
description: Generates TypeScript interfaces from JSON samples or API responses.
author: Your Name
version: 1.0.0
skill-sync-scope: global # 可选,默认可根据位置推断
---

# TypeScript Interface Generator

This skill helps you quickly create TypeScript interface definitions.

## Instructions
1. Provide a JSON object or an API endpoint response.
2. The skill will analyze the structure and generate corresponding TypeScript interfaces.
3. You can specify optional properties, nested types, and export statements.

## Examples
**Input:**
```json
{
  "id": 123,
  "name": "Alice",
  "email": "alice@example.com",
  "profile": {
    "age": 30,
    "city": "New York"
  }
}

Output:

export interface User {
  id: number;
  name: string;
  email: string;
  profile: Profile;
}

export interface Profile {
  age: number;
  city: string;
}

**Frontmatter 关键字段说明:**
- `name` (**必需**):技能的名称。这将被用于生成技能的slug(目录名)。请使用清晰、描述性的名称。
- `description`:技能的简短描述,会在AI工具的技能列表中显示。
- `author`, `version`:可选,用于信息记录。
- `skill-sync-scope`: 控制技能分发范围,可选值为 `global`, `local-only`。
- `skill-sync-install-on`: 一个数组,明确指定技能应安装到哪些套具,例如 `[codex, cursor]`。

> **注意事项**:
> 1.  **YAML有效性**:Frontmatter必须是合法的YAML。常见的错误包括缩进使用Tab(应用空格)、字符串值未加引号导致特殊字符被解析、或数组格式错误。`skill-sync doctor` 会严格检查这一点,无效的YAML会导致同步被阻止。
> 2.  **name字段必填**:如果没有 `name` 字段,`skill-sync` 将无法为技能生成一个确定的slug,这会导致安装失败。务必确保每个 `SKILL.md` 都有 `name`。
> 3.  **文件编码**:建议使用UTF-8编码,避免特殊字符出现问题。

### 3.3 核心命令详解与日常使用

`skill-sync` 的命令设计遵循“检查先行,安全执行”的原则。以下是日常高频命令的深度解析。

**1. 诊断与检查 (`doctor`, `check`, `stabilize`)**
在执行任何写操作前,务必先进行检查。

```bash
# 基础诊断:显示发现的技能源、套具状态、漂移和冲突
skill-sync doctor
# 详细信息:显示每个技能条目的详细计划,包括孤儿安装项
skill-sync doctor --verbose
# 机器可读输出:供其他脚本或工具处理
skill-sync doctor --json

doctor 命令是安全网。它会告诉你:

  • 发现了多少个技能源。
  • 每个技能在每个套具中的状态(OK, 缺失, 过期, 冲突)。
  • 是否存在源错误(如无效YAML)。
  • 是否存在重复的技能slug(在不同项目源中同名)。
  • 是否存在可能污染解析器的危险符号链接。

skill-sync stabilize 是一个更强大的“预执行”命令。它默认以安全模式(dry-run)运行,执行一系列修复操作的计划预览,例如修复断裂的源符号链接、修剪危险的套具根目录链接等。加上 --execute 参数才会实际执行。

2. 执行同步 ( execute , sync ) doctor 显示一切正常或你已审查完计划后,就可以执行同步。

# 执行同步计划
skill-sync execute
# 或使用别名
skill-sync sync

这两个命令是等价的,它们会应用 doctor stabilize 计算出的变更计划:创建新安装、更新已过期的、移除孤儿项(如果源已删除)。 关键点 :对于“冲突”(套具中已存在非 skill-sync 管理的同名技能),默认操作是 报告而非覆盖 。这保护了你手动安装或来自其他渠道的技能。

如果你确认要覆盖冲突(例如,你手动安装的旧版本可以被新管理的源替换),可以使用 --continue-on-conflict 参数。但请谨慎使用,并建议先备份。

3. Codex专项审计 ( codex-audit ) Codex由于其复杂的缓存和会话机制,有时会出现技能“安装了但不可见”的问题。 codex-audit 命令专门用于诊断此类问题。

# 基础审计:检查配置、路径、运行时和工作区可见性
skill-sync codex-audit
# 修复配置问题(如错误的 skills.config 路径)
skill-sync codex-audit --fix-config
# 严格运行时检查:只考虑近2小时内活跃的会话快照
skill-sync codex-audit --strict-runtime --runtime-max-age-hours 2

这个命令会检查多个层面:

  • 配置层 ~/.codex/skills.config 文件是否正确引用了技能目录。
  • 磁盘层 :技能文件是否实际存在于Codex的技能目录中。
  • 运行时层 :当前活跃的Codex会话线程中,技能列表是否包含了已安装的技能。这里涉及会话快照的匹配, skill-sync 能通过时间戳和rollout-id精确匹配,避免误报。
  • 工作区层 :通过模拟查询Codex的应用服务器API,检查技能是否真的出现在IDE的“Plugins > Skills”列表中。

如果遇到Codex技能不显示的问题, codex-audit 通常是第一步。

4. 备份与恢复 ( backup ) 在进行任何可能修改套具目录的操作(尤其是 execute clean )之前,创建备份是一个好习惯。

# 创建备份(备份存储在 ~/.skill-sync/backups/)
skill-sync backup create
# 列出所有备份
skill-sync backup list
# 预览恢复操作(dry-run)
skill-sync backup restore 2024-06-15T10-30-00-000Z --dry-run
# 执行恢复
skill-sync backup restore 2024-06-15T10-30-00-000Z

备份机制非常可靠。它不仅备份符号链接的目标,还会快照 SKILL.md 文件内容本身。这意味着即使原始源文件后来被删除或移动,你仍然可以从备份中恢复出技能的内容。

3.4 高级配置与自定义

skill-sync 的配置文件 ~/.skill-sync/config.json 提供了丰富的自定义选项。

自定义套具 (Harness) 虽然工具内置了主流AI工具的路径,但你可以添加自定义的套具。

{
  "harnesses": {
    "my-custom-ide": "/path/to/ide/skills/dir"
  }
}

或者通过命令行添加:

skill-sync harness add my-custom-ide /path/to/ide/skills/dir

控制源发现 你可以忽略某些路径,或优先选择某些路径,这在你有多个项目源包含同名技能时很有用。

{
  "discovery": {
    "ignorePathPrefixes": [
      "/Users/me/dev/experimental/old-skill-clone"
    ],
    "preferPathPrefixes": [
      "/Users/me/dev/official/skills-repo"
    ]
  }
}

当同一个技能slug在多个源中被发现时, preferPathPrefixes 列表中的路径拥有更高优先级。这解决了“哪个源是权威”的问题。

自定义技能命名 你可以覆盖默认的slug生成规则,为特定技能在特定套具中指定不同的安装名称。

{
  "installNameOverrides": {
    "/Users/me/dev/tools/ts-gen/SKILL.md": {
      "global": "typescript-helper", // 在所有套具中使用此名
      "codex": "ts-gen-codex" // 仅在Codex中使用此名
    }
  }
}

4. 故障排查与实战经验

即使工具设计得再完善,在实际复杂的环境中也会遇到各种边界情况。以下是我在长期使用中总结的常见问题与解决方案。

4.1 技能在AI工具中不显示或不可用

这是最常见的问题。请按以下步骤排查:

  1. 运行 skill-sync doctor :首先确认 skill-sync 本身是否认为技能已正确安装到目标套具。如果状态是“OK”,则问题可能出在AI工具侧。
  2. 运行 skill-sync codex-audit (针对Codex) :这是诊断Codex问题的利器。它会逐层检查。如果 codex-audit 报告“runtime missing”或“workspace missing”,但“disk”是“OK”的,那问题就是Codex的缓存或会话状态。
    • 解决方案 :尝试 skill-sync cache-bust --harness codex 。这个命令会触摸已安装的 SKILL.md 文件,并尝试清除Codex的相关缓存文件,触发重新索引。
    • 有时需要完全重启Codex IDE。
  3. 检查技能文件格式 :确保 SKILL.md 的Frontmatter是 有效的YAML 。一个常见的陷阱是在描述中使用了冒号 : 而未加引号,导致YAML解析错误。 skill-sync doctor 会捕获此类错误。
  4. 检查符号链接 :对于使用符号链接的套具,确保链接没有断裂。可以手动进入套具的技能目录(如 ~/.cursor/skills/<skill-name> ),检查 SKILL.md 是否是一个有效的符号链接,并指向正确的源文件路径。
  5. 查看AI工具日志 :某些AI工具(如Cursor)有开发者控制台或日志文件,里面可能包含技能加载失败的错误信息。

4.2 处理“冲突”状态

doctor 显示某个技能在某个套具中处于“冲突”状态时,意味着该套具的对应目录已存在,但不是由当前 skill-sync 管理的(例如,可能是你之前手动创建的,或是通过 npx skills 安装的)。

决策流程:

  1. 保留现有 :如果你需要保留现有的非托管技能,可以忽略此冲突。 skill-sync 不会动它。你可以考虑将你的本地源技能重命名(修改Frontmatter中的 name )以避免冲突。
  2. 用本地源替换 :如果你确认要用你的本地源版本替换现有的,有两个方法:
    • 手动清理 :先手动删除套具中的那个冲突目录(例如 rm -rf ~/.cursor/skills/conflicting-skill ),然后再次运行 skill-sync execute
    • 强制覆盖 :使用 skill-sync execute --continue-on-conflict 务必谨慎 ,建议先执行 skill-sync backup create
  3. 合并内容 :有时你可能想合并两者。这种情况下,你需要手动处理:将现有技能的内容备份,然后用你的本地源覆盖,再将需要保留的部分手动添加回你的本地 SKILL.md 源文件中。之后, skill-sync 会将合并后的版本同步到所有套具。

4.3 性能与扫描优化

如果你在 ~/_dev 下有非常多的项目, skill-sync 的扫描可能会稍慢。你可以通过配置来优化:

  • 精简项目根目录 :只添加确实包含技能的项目目录,而不是整个开发目录。
  • 使用 .skill-syncignore 文件(如果未来版本支持)或配置忽略 :在项目根目录下创建 .skill-syncignore 文件,语法类似 .gitignore ,可以忽略某些子目录。目前可以通过 config.json 中的 ignorePathPrefixes 实现类似效果。
  • 缓存 skill-sync 内部有状态缓存。如果怀疑缓存过期导致显示状态不对,可以运行 skill-sync cache-bust (不带 --harness 参数)来清除所有内部缓存。

4.4 在CI/CD或自动化脚本中使用

skill-sync --json 输出模式使其非常适合集成到自动化流程中。例如,你可以在团队的Post-commit钩子或CI流水线中运行它,确保共享技能库的变更能自动同步到所有成员的开发环境配置中(假设环境已配置好套具路径)。

# 在脚本中检查状态,如果有变更则执行同步
if skill-sync doctor --json | jq -e '.summary.changes > 0' > /dev/null; then
    echo "Skills out of sync, updating..."
    skill-sync execute
else
    echo "Skills are in sync."
fi

重要提示 :在自动化环境中执行 execute 前,务必确保环境是受控的,并且你理解将要发生的变更。可以考虑先执行 skill-sync stabilize --execute 来进行安全的自动修复,它比完整的 execute 攻击性更小。

4.5 与 npx skills 的协作

skill-sync npx skills 并非互斥,而是互补。我的个人工作流是:

  • 公共/通用技能 :使用 npx skills install <skill-name> 。这些技能通常来自社区,作为npm包管理,更新方便。
  • 私有/项目特定技能 :在本地项目仓库中创建 SKILL.md ,使用 skill-sync 进行管理。
  • 隔离 skill-sync 默认不会去触碰 npx skills 安装的技能(因为它们通常不在其管理的项目根目录下),反之亦然。两者可以和平共存于同一套具目录中。 skill-sync doctor 会将其它来源的技能标记为“冲突”或“外部”,让你一目了然。

5. 项目开发与贡献指南

skill-sync 本身是一个用TypeScript编写的Node.js CLI工具。如果你对其内部机制感兴趣,或想为其添加对新AI工具(套具)的支持,可以参与贡献。

本地开发环境设置:

# 克隆仓库
git clone https://github.com/light-merlin-dark/skill-sync.git
cd skill-sync
# 安装依赖 (项目使用 bun,但 npm/yarn 也可)
bun install
# 运行测试
bun test
# 直接运行开发版本的CLI
bun run src/index.ts doctor --home /tmp/test-home # 使用临时目录避免污染真实配置

添加对新套具的支持: 主要工作是在源代码中定义新套具的根目录路径和可能的安装布局策略。你需要研究目标AI工具是如何加载本地技能的(通常是读取某个固定目录下的 SKILL.md 文件或特定结构的目录)。然后,在 skill-sync 的套具注册逻辑中添加一个新的条目。由于项目代码结构清晰,这部分工作对于熟悉Node.js和文件系统操作的开发者来说并不复杂。

发布流程: 项目使用 make release 命令进行一键发布,它会自动完成版本号提升、更新变更日志、运行测试、构建、发布到npm以及创建GitHub Release等一系列操作,非常规范。

6. 总结与最佳实践建议

经过一段时间的深度使用, skill-sync 已经成为了我AI辅助开发工作流中不可或缺的一环。它带来的最大价值是 “心智负担的卸载” 。我不再需要记住哪个技能在哪个工具里,是否更新了。我的技能库现在就是我的代码库的一部分,享受同样的Git工作流:修改、提交、推送,然后一键同步。

给新用户的几条最佳实践建议:

  1. 始于检查,终于备份 :养成 skill-sync doctor 先行的习惯。在执行任何 execute clean 操作前,运行 skill-sync backup create 。这为你提供了回滚的安全网。
  2. 清晰的技能命名 :在 SKILL.md 的Frontmatter中使用独特且描述性的 name 。避免使用过于通用或容易冲突的名称。
  3. 利用作用域控制 :不要把所有技能都设为 global 。仔细思考每个技能的使用场景。如果是Codex专用的调试技能,就用 skill-sync-scope: local-only skill-sync-install-on: [codex] 把它限制在Codex中。这能保持各个工具的技能列表整洁。
  4. 项目结构扁平化 :尽量将包含技能的项目直接放在配置的根目录下。如果使用Monorepo,考虑将技能统一放在仓库根目录的 skills/ 子目录中,这样 skill-sync 的发现逻辑最清晰。
  5. 将配置纳入版本控制 :你的 ~/.skill-sync/config.json 文件定义了技能源和套具映射。可以考虑将此文件也放入一个Git仓库,方便在新机器上快速恢复你的技能管理环境。
  6. 结合自动化 :如果你在团队中推广使用,可以考虑编写一个简单的安装后脚本,为新成员自动配置 skill-sync 并同步基础技能集。

最后,工具是死的,工作流是活的。 skill-sync 提供了一套强大而灵活的机制,但如何将其融入你的日常,还需要你根据自己的习惯进行微调。开始时不妨保守一些,只同步一两个关键技能,熟悉了整个流程和故障排查方法后,再逐步将你的整个技能库迁移过来。当你发现所有AI助手都能即时访问你最新、最强大的自定义技能时,那种流畅感会让你觉得这一切的配置都是值得的。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐