npm package: @maxlee/skm
Description: Claude/Cursor Skills global manager with symlink + lock + security hardening
Latest version: 1.0.0

# OpenSkill.dev CLI

OpenSkill.dev 是一个面向多代理工作流的 Skills 全局管理器，核心目标是把技能仓库统一存储在全局目录，通过项目映射（symlink/copy）实现多项目复用与版本一致。

## 产品概览

- 定位：Skills 全局管理 + 项目映射 + lock 元数据跟踪
- 当前支持代理：skills.sh 规范 41 agents（见“多代理说明”）
- 当前支持模式：`symlink`、`copy`（可通过 `--no-symlink` 强制 copy）
- 当前实现命令：`init/link/unlink/update/add/del/list/browse/search/doctor external/repo add/outdated/repair/config set/completion`
- 运行时要求：Node.js `>=18`，项目为 ESM（`"type": "module"`）

## 安装与升级

### 安装

发布版全局安装：

```bash
npm install -g @maxlee/skm
```

本地源码调试安装：

```bash
npm install
npm link
```

安装后可用以下命令确认：

```bash
skm --version
skm --help
```

说明：`skm` 是主入口，`openskill` 仍可作为兼容别名使用。

### 升级（本地源码方式）

```bash
git pull
npm install
npm test
npm link
```

## 快速开始（5 分钟）

以下示例使用临时目录隔离全局数据，避免污染真实环境。

```bash
mkdir -p /tmp/openskill-quickstart
cd /tmp/openskill-quickstart
export OPENSKILL_HOME=/tmp/openskill-home

# 1) 初始化全局目录（会创建 ~/.openskill/config.json、~/.openskill/openskill.json）
skm init --preset dev

# 2) 添加一个技能源
skm add https://github.com/coreyhaines31/marketingskills/tree/main/skills/seo-audit

# 3) 将全局技能映射到当前项目
skm link --agent claude-code

# 4) 更新全局技能并刷新 lock
skm update

# 5) 检查是否落后远端
skm outdated --agent claude-code

# 6) 修复失效映射
skm repair --agent claude-code
```

预期结果：

- 全局目录出现 `~/.openskill/skills/<skill>`（若设置 `OPENSKILL_HOME` 则在该目录下）
- `~/.openskill/openskill.json` 记录全局技能清单
- `openskill-lock.json` 记录 commit SHA 与状态（`ok/broken/outdated`）

说明：`npx skills ...` 同步受 `externalSyncMode` 控制，默认 `best-effort`（失败告警但继续）；外部 CLI 默认钉住 `skills@1.4.4`。

## 核心概念

### 1) 全局存储

所有技能统一保存在：

- `~/.openskill/skills/<skill>`

### 2) 项目映射

项目内只保存映射结果目录：

- `.claude/skills/*`、`.agent/skills/*`、`.agents/skills/*`、`skills/*` 等（按 agent 映射，symlink 或 copy）

### 3) 全局技能索引

`~/.openskill/openskill.json` 记录已安装技能列表与来源，供 `link/del/search` 等命令读取。

### 4) Lock 元数据

`~/.openskill/openskill-lock.json` 记录来源、SHA、状态与更新时间。

### 5) Symlink 与 Copy

- 默认：Linux/macOS 使用 symlink，Windows 默认 copy
- 强制 copy：`--no-symlink`

### 6) Agent 路由

`link/outdated/repair` 可通过 `--agent/-a` 指定代理；未指定时使用 `config.defaultAgent`。

### 7) 错误处理行为

- 参数校验失败会立即退出（非 0）
- `--help` 与 `--version` 退出码为 `0`
- `npx skills ...` 外部同步可配置：`best-effort`（默认）失败告警不中断，`strict` 失败即中断，`off` 跳过外部同步
- `OPENSKILL_DEBUG=1` 可输出外部命令与 API 调用的结构化调试日志

## 命令总览

| 命令 | 说明 |
| --- | --- |
| `skm init` | 初始化全局目录，可选按 preset 安装 |
| `skm link` | 将全局技能索引中的技能映射到当前项目 |
| `skm unlink` | 解除当前项目的技能映射 |
| `skm update` | 更新全局技能并刷新 lock |
| `skm add` | 添加技能源到全局 |
| `skm del` | 从全局与项目移除技能（支持 `--all`） |
| `skm list` | 列出当前全局已安装技能及其本地状态 |
| `skm browse` | 交互式选择并安装技能（不自动 link） |
| `skm search` | 从 lock/repo/preset/repo-index/registry 检索技能 |
| `skm doctor external` | 检查外部 `skills` CLI、API 与缓存目录健康状态 |
| `skm repo add` | 注册仓库来源 |
| `skm outdated` | 检查技能是否落后远端 |
| `skm repair` | 修复失效链接或映射 |
| `skm config set` | 设置全局配置项 |
| `skm completion` | 输出 bash/zsh 补全脚本 |

## 按命令详解

### init

用途：初始化全局 OpenSkill 目录，按预设安装技能（不执行项目映射）。

参数：

- `--preset <name>`：预设名（当前内置 `dev`）

示例：

```bash
skm init --preset dev
```

常见失败：

- 预设不存在：`Unknown preset`
- 远端仓库不可达或 clone 失败

### link

用途：按 `~/.openskill/openskill.json` 把全局技能映射到当前项目。

说明：

- `symlink` 模式为目录级软链：`.<agent>/skills -> ~/.openskill/skills`
- 因此新增全局 skill 后，在已 link 的项目中会自动可见（通常不需要再次执行 `link`）
- `copy` 模式仍是静态复制，新增 skill 后需要再次执行 `link`

参数：

- `--agent <agent>`
- `--no-symlink`
- `--force`

示例：

```bash
skm link --agent cursor --no-symlink
```

常见失败：

- 全局技能目录缺失（本次 link 计入 failures；lock 在 `update/outdated/repair` 时刷新）

### unlink

用途：移除当前项目内由 OpenSkill 创建的技能映射，不删除全局 skills。

说明：

- `unlink` 只清理当前项目下指定 agent 的映射目录。
- 若当前项目使用的是整目录 symlink，会移除该 agent 对应的 skills 根链接。
- 若当前项目使用的是 copy 模式，只会删除 registry 管理的 skill 目录；同目录下的其他自定义内容会保留。

参数：

- `--agent <agent>`

示例：

```bash
skm unlink
skm unlink --agent cursor
```

常见结果：

- 未找到可移除映射：`No project skill links found to unlink.`

### update

用途：拉取全局技能最新版本并刷新 lock SHA。

说明：

- `update` 为全局更新，不区分 agent。
- 若误传旧参数 `--agent/-a/-t`，会给出提示并自动忽略。
- 更新时会输出分阶段进度；同仓库同 ref 的 GitHub tree source 会合并刷新，减少重复 sparse checkout。
- git 拉取包含超时与重试，避免长时间无响应。

示例：

```bash
skm update
```

常见失败：

- 网络不可达导致远端 fetch/pull 失败

### add

用途：添加技能源到全局技能目录。

参数：

- `<source>`：仅支持 URL（`https://...(.git)` 或 `git@...`）
- `<query>`：skill 名称（如 `frontend-design`），优先通过 `skills.sh` 搜索 API 解析来源，失败时回退到 `npx skills find <query>`
- `--no-cache`：对 query 解析跳过本地 `skills.sh` API 缓存
- 也支持 GitHub tree URL：
  - 单个 skill：`https://github.com/<owner>/<repo>/tree/<ref>/skills/<skill-name>`，直接安装
  - skills 目录：`https://github.com/<owner>/<repo>/tree/<ref>/skills`，进入交互式多选安装
- GitHub 仓库根 URL（如 `https://github.com/<owner>/<repo>` 或 `.git`）会先探测 `tree/<ref>/skills`：
  - 若存在则进入与 `browse` 一致的交互式多选安装
  - 若不存在则中断，并提示使用完整 tree URL
- 目录 URL 的交互模式快捷键：`a` 全选，`i` 反选，`q/esc` 取消，`enter` 提交

示例：

```bash
skm add https://github.com/coreyhaines31/marketingskills
skm add https://github.com/coreyhaines31/marketingskills.git
skm add frontend-design
skm add frontend-design --no-cache
skm add https://github.com/coreyhaines31/marketingskills/tree/main/skills/seo-audit
skm add https://github.com/coreyhaines31/marketingskills/tree/main/skills
```

常见失败：

- source 格式非法
- source 含危险 shell 元字符
- tree URL 路径不存在，或目标目录下未找到 `SKILL.md`
- 仓库根 URL 未检测到 `skills` 目录（需改用完整 tree URL）

### del

用途：移除全局技能、项目登记及映射目录。

说明：

- 不传参数时进入交互式删除，展示本地已安装 skills 列表，多选后需要二次确认。
- 交互模式快捷键：`a` 全选，`i` 反选，`q/esc` 取消，`enter` 提交。
- `--all` 继续保留为直接删除所有已安装技能的非交互路径。

参数：

- 无参数：交互式选择需要删除的技能
- `<name>`：技能名（仓库名）
- `--all`：移除所有已安装技能（全局目录 + lock + registry + 各 agent 项目映射）

约束：

- `<name>` 与 `--all` 二选一；两者都不传时进入交互式删除。

示例：

```bash
skm del
skm del codex
skm del --all
```

常见失败：

- 无可交互删除技能：`No installed skills available to remove.`
- 交互删除取消：`Delete cancelled, no changes were made.`
- 单个目标不存在：`No matching skill to remove: <name>`
- `--all` 且无可移除技能：`No skills found to remove.`

### browse

用途：交互式勾选技能后批量安装到全局目录。

说明：

- `browse` 不接收 agent 参数。
- `browse` 默认会对 GitHub tree 目录展开结果做短时缓存，加快重复打开速度；使用 `--refresh` 可跳过缓存。
- 安装完成后不会自动执行 `link`，如需映射到当前项目请手动执行 `skm link`。
- 候选列表来源：`global-lock`、`repos`、`preset`、`repo-index`（不包含 `global-registry`）。

参数：

- `--refresh`：跳过 tree 展开缓存，强制重新读取远端目录

示例：

```bash
skm browse
skm browse --refresh
```

常见失败：

- 交互中断（Ctrl+C）：会优雅取消，不写入状态

### list

用途：显示当前全局已安装技能列表，以及它们基于本地 metadata 和全局目录推导出的状态。

说明：

- `list` 只读取本地状态，不执行网络请求。
- `list` 不刷新 lock，也不写入任何文件。
- 输出列固定为 `NAME`、`STATUS`、`SOURCE`。
- `list` 不接收 agent 参数。

参数：

- 无（仅支持 `-h/--help`）

示例：

```bash
skm list
```

状态说明：

- `ok`：lock 存在且全局技能目录存在
- `outdated`：lock 标记为落后且全局技能目录存在
- `broken`：lock 或 registry 记录存在，但全局技能目录缺失
- `untracked`：全局技能目录存在，但缺少 lock 记录

### search

用途：检索技能索引（全局 lock、repo、preset、repo-index、全局技能索引）。

参数：

- `<query>`

示例：

```bash
skm search codex
```

常见失败：

- 无匹配时返回空表，不报错

行为说明：`search` 为只读索引查询，不会初始化或改写全局 config/lock 文件。

### repo add

用途：注册仓库来源到全局配置。

参数：

- `<gitUrl>`
- `--untrusted`

输入说明：

- 接受 `https://...`、`git@...`、`github:owner/repo`、`owner/repo`。
- 按规范化后的仓库 URL 去重（已存在会返回 `already exists`）。

示例：

```bash
skm repo add https://github.com/org/skills-catalog.git
```

常见失败：

- URL/source 格式非法

### outdated

用途：检查本地技能是否落后远端。

参数：

- `-a, --agent <agent>`
- `--refresh`：跳过 GitHub tree HEAD 缓存，强制重新查询远端 SHA

示例：

```bash
skm outdated --agent claude-code
skm outdated --agent claude-code --refresh
```

常见失败：

- 本地目录损坏或不是 git 仓库

### repair

用途：修复缺失或失效的映射路径。

参数：

- `-a, --agent <agent>`
- `--no-symlink`

示例：

```bash
skm repair --agent cursor
```

常见失败：

- 全局 source 丢失（会标记为 `broken`，无法修复）

### config set

用途：设置全局配置。

参数：

- `<key>`：`defaultAgent`、`symlinkMode`、`externalSyncMode`、`externalSkillsVersion`、`skillsSearchCacheMode` 或 `skillsSearchCacheTtlSec`
- `<value>`：
  - `defaultAgent`: 41 个规范 agent 名（见下文“多代理说明”）
  - `symlinkMode`: `symlink|copy`
  - `externalSyncMode`: `best-effort|strict|off`
  - `externalSkillsVersion`: `latest` 或精确版本（如 `1.4.4`）
  - `skillsSearchCacheMode`: `disk|off`
  - `skillsSearchCacheTtlSec`: 正整数秒数

示例：

```bash
skm config set defaultAgent claude-code
skm config set symlinkMode copy
skm config set externalSyncMode strict
skm config set externalSkillsVersion 1.4.4
skm config set skillsSearchCacheMode disk
skm config set skillsSearchCacheTtlSec 900
```

常见失败：

- key 不支持
- value 不在允许范围

### doctor external

用途：检查外部 `skills` CLI、`skills.sh` API 和缓存目录可用性。

示例：

```bash
skm doctor external
```

输出列：

- `CHECK`
- `STATUS`
- `DETAILS`

### completion

用途：输出补全脚本。

参数：

- `<shell>`：`bash|zsh`

示例：

```bash
skm completion zsh
```

常见失败：

- shell 参数非法

## 配置文件

### 全局配置 `~/.openskill/config.json`

```json
{
  "version": 1,
  "defaultAgent": "claude-code",
  "symlinkMode": "symlink",
  "externalSyncMode": "best-effort",
  "externalSkillsVersion": "1.4.4",
  "skillsSearchCacheMode": "disk",
  "skillsSearchCacheTtlSec": 900,
  "repos": [
    {
      "name": "skills-catalog",
      "url": "https://github.com/org/skills-catalog.git",
      "trusted": true
    }
  ]
}
```

字段说明：

- `defaultAgent`：默认代理
- `symlinkMode`：默认映射模式
- `externalSyncMode`：外部 `npx skills` 同步策略（`best-effort|strict|off`）
- `externalSkillsVersion`：外部 `skills` CLI 版本（默认 `1.4.4`）
- `skillsSearchCacheMode`：`skills.sh` API 搜索缓存模式（`disk|off`）
- `skillsSearchCacheTtlSec`：搜索缓存 TTL，单位秒
- `repos`：仓库来源列表

### 全局 lock `~/.openskill/openskill-lock.json`

```json
{
  "version": 1,
  "skills": {
    "codex": {
      "source": "https://github.com/openai/codex",
      "commitSha": "abc123...",
      "lastUpdated": "2026-03-05T10:00:00.000Z",
      "status": "ok"
    }
  }
}
```

状态语义：

- `ok`：本地与记录正常
- `broken`：路径缺失、映射损坏或来源不可用
- `outdated`：落后远端

迁移说明：

- 旧版 lock 若使用 `agent:skill` 作为键（如 `claude:codex`），新版本在读取时会自动迁移为 `skill` 键（如 `codex`）。
- 旧版 config 若 `defaultAgent` 为 `claude`，读取时会自动静默迁移为 `claude-code` 并回写（不额外打印迁移提示）。

### 全局技能索引 `~/.openskill/openskill.json`

```json
{
  "version": 1,
  "skills": [
    {
      "name": "codex",
      "source": "https://github.com/openai/codex"
    }
  ]
}
```

## 多代理说明

- 当前内置 41 个规范 agent：
  `amp, antigravity, augment, claude-code, openclaw, cline, codebuddy, codex, command-code, continue, cortex, crush, cursor, droid, gemini-cli, github-copilot, goose, junie, iflow-cli, kilo, kimi-cli, kiro-cli, kode, mcpjam, mistral-vibe, mux, opencode, openhands, pi, qoder, qwen-code, replit, roo, trae, trae-cn, windsurf, zencoder, neovate, pochi, adal, universal`
- 映射目录：
  - `claude-code -> .claude/skills`
  - `openclaw -> skills`
  - `antigravity -> .agent/skills`
  - `universal/cursor/codex/opencode/... -> .agents/skills`
- 全局目录不区分 agent，统一为 `~/.openskill/skills/<skill>`
- 涉及项目映射/状态检查（`link/unlink/outdated/repair`）时建议显式传 `--agent`，避免默认代理引起误操作。

## 补全配置

### zsh

```bash
mkdir -p ~/.zfunc
skm completion zsh > ~/.zfunc/_skm
# 确保 ~/.zfunc 在 fpath 中
```

### bash

```bash
skm completion bash > ~/.skm-completion.bash
source ~/.skm-completion.bash
```

## 常见故障排查

### 1) `Command failed after ... npx skills ...`

原因：外部命令不可用、网络问题或 npm/npx 环境异常。

建议：

- 确认 `npm -v`、`npx -v` 可用
- 检查网络连通性
- 重试命令，必要时先运行 `skm update`

### 2) `Path conflict ... exists and is not a symlink`

原因：目标目录已有真实文件夹。

建议：

- 使用 `--force` 覆盖
- 或手工备份后重试

### 3) `Unsupported add source`

原因：`add` 输入既不是 URL，也不是 skill 名称，或 `npx skills find <query>` 无法解析出可安装来源。

建议：

- 使用更精确的 query（如完整 skill 名）
- 或直接使用 `https://...git` / `git@...`

### 4) `Repository URL does not contain a valid skills directory`

原因：你传入的是 GitHub 仓库根 URL，但该仓库在默认分支下未检测到 `skills` 目录。

建议：

- 改用完整 tree URL，例如：
  - `https://github.com/<owner>/<repo>/tree/main/skills`
  - `https://github.com/<owner>/<repo>/tree/main/skills/<skill-name>`

### 5) 交互中断

`browse` 中 Ctrl+C 会安全取消，不写入状态。

## 安全说明

- source 输入会校验并拒绝危险 shell 元字符
- 外部命令执行使用 `spawn(..., { shell: false })`
- 项目映射路径做目录越界保护
- JSON 持久化采用原子写（tmp + rename）

## 已知限制

- `repo` 当前仅实现 `repo add`，未实现 `list/remove/sync`
- `npx skills` 外部同步仍受外部命令可用性与网络状态影响（可用 `externalSyncMode` 控制策略）
- 尚未提供性能基准报告（`<8s`）与自动化压测
- Windows 端到端验证和文档仍需加强

## 跨平台代理建议

- Linux/macOS：优先使用 symlink（默认）
- Windows：建议 copy 模式（默认），必要时显式 `--no-symlink`
- CI 或无交互终端：spinner 会自动退化为普通输出