@lxchinesszz/sks
v0.1.2
Published
SKS - AI Skills 包管理器,GitHub-based registry + symlink projection system
Maintainers
Readme
SKS — AI Skills 包管理器
GitHub-based AI Skill Registry + Symlink Projection System
SKS 是一个统一管理 AI Skills 的命令行工具。它的本质是:把 AI 能力当成软件包来管理。
- 从 GitHub Registry 一键安装 Skill
- 通过 symlink 自动同步到 Claude / Codex / Cursor
- 零服务器、纯本地、可离线使用
目录
安装
环境要求:Node.js 22+、git
# 从项目目录安装到全局
npm install -g .
# 验证安装
sks --version如果暂时不想全局安装,可以用
node dist/bin/sks.js替代sks运行所有命令。
快速开始
场景一:安装并使用 Registry 中的 Skill
# 搜索你感兴趣的 Skill
sks search java
# 安装 Skill(自动同步到 AI 工具)
sks install java-expert
# 查看已安装的 Skills
sks list场景二:开发自己的 Skill
# 创建新 Skill 目录
mkdir my-skill && cd my-skill
# 交互式初始化
sks init
# 编辑 prompt.md,填入你的 AI 指令内容
# ...
# 链接到本地 SKS(开发模式)
sks link .
# 同步到 AI 工具
sks sync
# 准备好后,发布到 Registry
sks login
sks publish核心概念
Skill
一个 Skill 就是一个目录,至少包含两个文件:
sks.yaml:描述文件(名称、版本、同步目标等)prompt.md:Skill 的核心提示词内容
AI 工具(Claude、Codex、Cursor)会读取 prompt.md 来加载 Skill 的能力。
Registry
SKS 使用 GitHub 作为唯一的 Skill 注册表,无需自建服务器。Registry 本质是一个 GitHub 仓库中的 index.json 文件:
{
"java-expert": {
"repo": "https://github.com/user/java-expert",
"latest": "1.0.0",
"description": "Java 高级开发专家"
}
}Symlink Projection(核心机制)
SKS 不复制文件,而是用 symlink 把 ~/.sks/skills/ 中的 Skill 投影到各 AI 工具的目录:
~/.sks/skills/java-expert/ ← 实体(source of truth)
↓ symlink
~/.claude/skills/java-expert ← Claude 看到的
~/.codex/skills/java-expert ← Codex 看到的
~/.cursor/skills/java-expert ← Cursor 看到的这意味着:更新一次 ~/.sks/skills/java-expert/,所有 AI 工具立即生效。
Link(开发模式)
当你本地开发一个 Skill 时,不需要安装到 skills/,而是在 links/ 里建一个 symlink 指向你的工作目录:
~/.sks/links/my-skill → /Users/you/workspace/my-skilllinks 的优先级高于 skills:同名时,link 版本覆盖已安装版本,适合开发调试。
命令参考
用户侧命令
sks install <skill>
从 GitHub Registry 下载并安装 Skill,安装完成后自动执行 sync。
别名:sks i
sks install java-expert
sks install java-expert --force # 强制重装(覆盖旧版本)
sks install java-expert --no-sync # 安装后不自动 sync选项
| 选项 | 说明 |
|------|------|
| -f, --force | 强制重新安装,覆盖已安装版本 |
| --no-sync | 安装完成后不自动执行 sync |
流程
读取 Registry index.json
↓
git clone 到临时目录
↓
校验 sks.yaml + prompt.md
↓
移动到 ~/.sks/skills/<skill>/
↓
自动执行 sks sync输出示例
安装 Skill: java-expert
✔ 从 Registry 下载 java-expert...
✔ 已安装 [email protected]
路径: /Users/you/.sks/skills/java-expert
描述: Java 高级开发专家
目标: claude, codex
✔ 同步 symlinks...
ℹ Symlinks 已同步sks list
列出所有本地已安装的 Skills(包含 skills/ 和 links/ 两个来源)。
别名:sks ls
sks list输出示例
本地 Skills
NAME VERSION TYPE TARGETS DESCRIPTION
─────────────────────────────────────────────────────────────────────────
java-expert 1.0.0 registry claude, codex Java 高级开发专家
my-skill 0.1.0 link claude 我的自定义 SkillTYPE为registry:Skill 已安装到~/.sks/skills/TYPE为link:Skill 来自~/.sks/links/(本地开发模式)
sks search [keyword]
从 GitHub Registry 搜索 Skill。不带关键词时列出 Registry 全部 Skills。
别名:sks s
sks search java # 搜索关键词
sks search # 列出全部
sks search java --refresh # 强制刷新缓存后搜索选项
| 选项 | 说明 |
|------|------|
| -r, --refresh | 强制忽略缓存,从 Registry 重新拉取 |
输出示例
搜索结果(共 3 个)
NAME VERSION INSTALLED DESCRIPTION TAGS
─────────────────────────────────────────────────────────────────────────
java-expert 1.0.0 ✔ Java 高级开发专家 java, spring
spring-boot 2.1.0 Spring Boot 专家 java, spring
mybatis 1.3.0 MyBatis 开发专家 java, orm
运行 `sks install <name>` 安装 Skill注意:搜索结果有 1 小时本地缓存(默认值),无需每次都请求网络。
sks remove <skill>
删除已安装的 Skill,同时清理所有 AI 工具目录中的对应 symlink。
别名:sks rm
sks remove java-expert
sks remove java-expert --yes # 跳过确认提示选项
| 选项 | 说明 |
|------|------|
| -y, --yes | 跳过删除确认 |
注意:
remove只能删除skills/中的已安装 Skill。如果要移除开发链接,请使用sks unlink。
sks sync
核心命令。扫描所有本地 Skills,计算与 AI 工具目录的差异,创建/修复/清理 symlinks。
sks sync
sks sync --prune # 同时删除孤立的(多余的)symlinks选项
| 选项 | 说明 |
|------|------|
| --prune | 删除 AI 工具目录中存在、但本地已无对应 Skill 的孤立 symlinks |
输出示例
SKS Sync — Symlink Reconciliation
✔ 扫描并同步 Skills...
已创建的 Symlinks:
+ [claude] java-expert
~/.claude/skills/java-expert
→ ~/.sks/skills/java-expert
已修复的 Broken Links:
~ [codex] old-skill
✔ Sync 完成: 1 已创建, 2 已跳过, 1 已修复sync 是幂等的:反复执行结果相同,已正确的 symlinks 会直接跳过,不会重复创建。
冲突处理策略
| 场景 | 处理方式 |
|------|----------|
| symlink 已正确指向目标 | 跳过 |
| symlink 是 broken link | 自动修复(重新创建) |
| symlink 指向旧路径 | 自动更新(删旧建新) |
| 目标路径是普通文件 | 备份(加 .bak.时间戳 后缀)后创建 symlink |
开发者侧命令
sks init
在当前目录交互式初始化一个新 Skill,生成 sks.yaml 和 prompt.md。
mkdir my-java-skill && cd my-java-skill
sks init交互示例
初始化新 Skill
按 Enter 接受括号内的默认值
? Skill name (my-java-skill): java-expert
? Version (1.0.0):
? Description: Java 高级开发专家
? Author (yourname): tongzhi
? Tags (逗号分隔,如 java,backend): java,spring,backend
? Targets (逗号分隔,如 claude,codex,cursor): claude,codex
✔ Skill "java-expert" 初始化完成
sks.yaml ✔
prompt.md ✔
ℹ 下一步:
1. 编辑 prompt.md 填写 Skill 内容
2. 运行 `sks link .` 链接到本地 SKS
3. 运行 `sks sync` 同步到 AI 工具
4. 准备好后,运行 `sks publish` 发布到 Registry生成的 sks.yaml
name: java-expert
version: 1.0.0
description: Java 高级开发专家
author: tongzhi
tags:
- java
- spring
- backend
targets:
- claude
- codex生成的 prompt.md(模板,需自行填写)
你是一个 java-expert 专家。
## 能力
- 在此描述你的核心能力
## 工作方式
- 在此描述你的工作方式sks link <path>
将本地 Skill 目录链接到 SKS,用于开发和调试。链接后,修改本地文件会立即对 AI 工具生效(无需重新 sync)。
sks link . # 链接当前目录
sks link ~/workspace/my-skill # 链接指定目录
sks link /absolute/path/to/skill # 绝对路径效果
~/.sks/links/java-expert → /Users/you/workspace/java-expert输出示例
✔ 已链接: java-expert
~/.sks/links/java-expert → /Users/you/workspace/java-expert
版本: 0.1.0
ℹ 运行 `sks sync` 将 Skill 同步到 AI 工具注意:link 只是在
~/.sks/links/里建了一个 symlink,不会复制文件。Skill 名称取自sks.yaml中的name字段。
sks unlink <skill>
移除本地 Skill 的链接。只删除 ~/.sks/links/ 中的 symlink,不删除你的实际文件。
sks unlink java-expert输出示例
✔ 已取消链接: java-expert
已移除: ~/.sks/links/java-expert
原指向: /Users/you/workspace/java-expert
本地文件未被删除。运行 `sks sync` 更新 AI 工具的 symlinks。sks login
登录 GitHub,获取 publish 命令所需的权限。
sks login认证流程
- 优先检测是否已登录(
gh auth token或config.json中的 token) - 如果已登录,直接显示当前用户名
- 如果 gh CLI 已安装,调用
gh auth login - 如果没有 gh CLI,提示手动输入 Personal Access Token(需要
repo权限)
Token 保存在 ~/.sks/config.json 中。
输出示例
GitHub 认证
✔ 检查认证状态...
✔ 已登录为: tongzhisks publish
将当前目录的 Skill 发布到 Registry(通过 GitHub Pull Request)。
sks publish
sks publish --dry-run # 仅校验,不实际发布选项
| 选项 | 说明 |
|------|------|
| --dry-run | 只做结构校验,不创建 fork 和 PR |
发布流程
读取并校验 sks.yaml + prompt.md
↓
获取当前目录的 git remote URL(作为 repo 地址)
↓
Fork sks-hub/sks-registry
↓
更新 fork 中的 index.json(追加/更新当前 Skill 条目)
↓
向 sks-hub/sks-registry 提交 Pull Request
↓
输出 PR 地址输出示例
发布 Skill 到 Registry
✔ 校验 Skill 结构...
名称: java-expert
版本: 1.0.0
描述: Java 高级开发专家
✔ 提交 PR 到 Registry...
✔ 发布成功!
PR:
https://github.com/sks-hub/sks-registry/pull/42
PR 需要 Registry 维护者审核后才会生效
通常在 1-3 个工作日内处理前提:当前目录必须是 git 仓库,且已设置
originremote 指向 GitHub 仓库。
系统命令
sks doctor
全面检查 SKS 系统健康状态,包括目录结构、工具依赖、AI 工具适配器、broken symlinks 等。
sks doctor检查项目
| 检查项 | 说明 |
|--------|------|
| ~/.sks 目录结构 | skills、links、cache 目录是否存在 |
| config.json | 配置文件是否存在且有效 |
| Registry 缓存 | 是否存在且未过期 |
| git 命令 | install 需要 |
| gh CLI | login / publish 的可选依赖 |
| Claude 适配器 | ~/.claude 是否存在,skills/ 是否可写 |
| Codex 适配器 | ~/.codex 是否存在,skills/ 是否可写 |
| Cursor 适配器 | ~/.cursor 是否存在,skills/ 是否可写 |
| Broken symlinks | ~/.sks/links/ 中是否有失效的链接 |
输出示例
SKS Doctor — 系统健康检查
AI 工具 Adapters:
检查结果:
✔ ~/.sks 目录存在
✔ ~/.sks/skills 目录存在
✔ ~/.sks/links 目录存在
✔ config.json 存在
✔ Registry 缓存有效 (12min 前更新)
✔ git 已安装
⚠ gh CLI 未找到 — publish 命令的可选依赖
✔ claude: 目标目录可写
⚠ codex: 未检测到 AI 工具 — ~/.codex 不存在
⚠ cursor: 未检测到 AI 工具 — ~/.cursor 不存在
✔ 没有 broken symlinks
⚠ 一切正常,但有 3 个警告退出码:有 fail 项时退出码为 1,否则为 0。
sks config
查看或修改 SKS 配置(~/.sks/config.json)。
sks config # 等同于 sks config list
sks config list # 列出所有配置项
sks config get <key> # 获取单个配置项
sks config set <key> <value> # 修改配置项示例
# 查看所有配置
sks config list
# 查看 Registry 地址
sks config get registryUrl
# 修改缓存有效期为 2 小时
sks config set cacheMaxAge 7200
# 设置 GitHub Token
sks config set githubToken ghp_xxxxxxxxxxxx
# 切换到自定义 Registry
sks config set registryUrl https://raw.githubusercontent.com/my-org/my-registry/main/index.jsonSkill 结构规范
每个 Skill 是一个目录,必须包含以下两个文件:
skill-name/
├── sks.yaml # 必须
├── prompt.md # 必须
├── README.md # 推荐
└── tools/ # 可选(附加工具定义)sks.yaml 完整说明
# Skill 的唯一标识,建议使用 kebab-case
name: java-expert
# 遵循语义化版本规范
version: 1.0.0
# 简短描述(展示在 search 结果中)
description: Java 高级开发专家
# 作者名
author: tongzhi
# 用于搜索的标签列表
tags:
- java
- spring
- backend
# 同步目标:决定 sync 时将 Skill 投影到哪些 AI 工具
# 可选值:claude、codex、cursor
targets:
- claude
- codex字段说明
| 字段 | 必填 | 类型 | 说明 |
|------|------|------|------|
| name | ✅ | string | Skill 唯一名称,与目录名保持一致 |
| version | ✅ | string | 语义化版本,如 1.0.0 |
| description | ✅ | string | 简短描述,展示在搜索结果 |
| author | ✅ | string | 作者名称 |
| tags | ❌ | string[] | 搜索标签,可为空 |
| targets | ❌ | string[] | 同步目标,默认 ["claude"] |
本地目录结构
~/.sks/
│
├── skills/ # 实体 Skill 存储(source of truth)
│ ├── java-expert/
│ │ ├── sks.yaml
│ │ ├── prompt.md
│ │ └── README.md
│ └── react-expert/
│ ├── sks.yaml
│ └── prompt.md
│
├── links/ # 本地开发 Skill 的 symlinks
│ └── my-skill -> /Users/you/workspace/my-skill
│
├── cache/ # Registry 缓存
│ └── index.json # 从 GitHub 拉取的 Registry 索引
│
├── adapters/ # 适配器目录(预留)
│
└── config.json # SKS 配置文件AI 工具目录(由 sks sync 自动创建和维护):
~/.claude/skills/ # Claude 读取的 Skills
│ └── java-expert -> ~/.sks/skills/java-expert
│
~/.codex/skills/ # Codex 读取的 Skills
│ └── java-expert -> ~/.sks/skills/java-expert
│
~/.cursor/skills/ # Cursor 读取的 Skills
└── java-expert -> ~/.sks/skills/java-expertsync 机制详解
sks sync 是整个系统的核心,它实现的是一个 Symlink Reconciliation Engine(符号链接调解引擎)。
工作流程(四阶段)
Phase 1 构建 SkillGraph
─────────────────────────────────────────
扫描 ~/.sks/skills/ → source: "registry"
扫描 ~/.sks/links/ → source: "link"
同名时 links 覆盖 skills(开发优先)
Phase 2 计算期望状态(desired state)
─────────────────────────────────────────
对每个 Skill,读取 targets 字段
生成期望存在的 symlink 集合:
{ adapter, skillName, symlinkPath, targetPath }
Phase 3 读取当前状态(current state)
─────────────────────────────────────────
枚举各 AI 工具 skills 目录的现有 symlinks
记录每个 symlink 的当前指向路径
Phase 4 三路 Diff + 执行
─────────────────────────────────────────
to_create = desired - current → 创建缺失的 symlinks
to_fix = broken current links → 修复 broken links
to_skip = already correct → 跳过
to_remove = current - desired → 仅 --prune 时删除为什么 sync 是幂等的?
每次执行都完整地对比期望状态和当前状态,只处理差异部分。已正确的 symlink 直接跳过,不会重复创建或删除。
配置参考
配置文件路径:~/.sks/config.json
| 配置项 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| registryUrl | string | https://raw.githubusercontent.com/sks-hub/sks-registry/main/index.json | Registry 的 index.json URL |
| githubToken | string | — | GitHub Personal Access Token(publish 用) |
| syncTargets | string[] | ["claude", "codex", "cursor"] | 全局启用的同步目标(单个 Skill 的 targets 优先) |
| cacheMaxAge | number | 3600 | Registry 缓存有效期(秒),3600 = 1 小时 |
| registryRepo | string | sks-registry | Registry 仓库名(publish 用) |
| registryOwner | string | sks-hub | Registry 仓库 owner(publish 用) |
示例:使用私有 Registry
sks config set registryUrl https://raw.githubusercontent.com/my-org/skills-registry/main/index.json
sks config set registryOwner my-org
sks config set registryRepo skills-registry环境变量:设置 SKS_HOME 可覆盖默认的 ~/.sks 目录,用于多环境隔离:
SKS_HOME=/tmp/test-sks sks doctor权限说明
| 命令 | 需要网络 | 需要 GitHub 登录 |
|------|----------|------------------|
| install | ✅ | ❌ |
| search | ✅(首次或缓存过期) | ❌ |
| list | ❌ | ❌ |
| sync | ❌ | ❌ |
| link | ❌ | ❌ |
| unlink | ❌ | ❌ |
| remove | ❌ | ❌ |
| init | ❌ | ❌ |
| login | ✅ | — |
| publish | ✅ | ✅ |
| doctor | ❌ | ❌ |
| config | ❌ | ❌ |
常见问题
Q: sks sync 后 Claude 没有看到 Skill?
检查 ~/.claude/skills/ 目录是否存在该 Skill 的 symlink:
ls -la ~/.claude/skills/同时检查 Skill 的 sks.yaml 中 targets 是否包含 claude:
cat ~/.sks/skills/<skill-name>/sks.yamlQ: 出现 broken symlink 怎么办?
通常是因为 sks unlink 后没有重新 sync,或 links 指向的目录被移动了。运行:
sks sync # 自动修复 broken links如果需要同时清理孤立 symlinks:
sks sync --pruneQ: 如何同时使用多个版本的同一 Skill?
目前不支持同名多版本并存。如需测试新版本,建议:
sks link <new-version-path>链接新版本(会覆盖已安装版本)- 测试完成后
sks unlink <skill>移除,sks sync恢复已安装版本
Q: publish 失败,提示找不到 git remote URL?
确保当前目录是 git 仓库并已配置 GitHub remote:
git remote add origin https://github.com/your-username/skill-nameQ: 如何搭建私有 Registry?
- 创建一个 GitHub 仓库,在根目录放
index.json(参考上文格式) - 修改 SKS 配置:
sks config set registryUrl https://raw.githubusercontent.com/your-org/your-registry/main/index.json
sks config set registryOwner your-org
sks config set registryRepo your-registryQ: sks install 提示没有 git?
install 命令需要 git 来克隆仓库。如果系统没有安装 git,SKS 会自动 fallback 到通过 GitHub tarball API 下载(需要网络)。
建议安装 git:brew install git(macOS)。
