sklink 0.2.1

Install skills into platform directories via a local store and symlinks
## sklink

将仓库中的 `skills/` 目录下各 skill(子目录)通过软链接安装到不同平台/Agent 的配置目录中,避免复制带来的漂移。

### 术语与目录

- skill:一个目录(例如 `skills/software-engineer/`),目录名即 skill 名
- repo skills dir:仓库中的 `./skills/` 目录(或在 `skills/` 目录内运行时的当前目录)
- local store:本机持久化技能仓库,默认 `~/.config/sklink/skills`
- target dir:某个平台下的一个安装目标目录(来自 `config.toml`
### 配置

默认读取:`~/.config/sklink/config.toml`

本机技能仓库(持久化存储):`~/.config/sklink/skills`

初始化(推荐):

```bash
sklink init
```

默认会生成如下平台配置:

```toml
[platforms.kimi]
targets = [
  { dir = "~/.kimi/skills" },
]

[platforms.trae]
targets = [
  { dir = "~/.trae/skills" },
]
```

配置结构(TOML):

```toml
[platforms.<platform_name>]
targets = [
  { dir = "<target_dir>" },
]
```

- `<platform_name>`:平台名(`-p/--platform` 传入的值)
- `<target_dir>`:目标目录路径,支持 `~`,也支持相对路径(相对当前运行目录解析)

### 用法

```bash
# 初始化配置
sklink init

# 查看可用技能列表(优先从 ./skills 或当前 skills/ 目录发现;否则回退到本机技能仓库)
sklink list

# 查看已安装到哪里(读取 config.toml 中的 targets 并扫描目标目录)
sklink list --installed

# 生成补全脚本(以 zsh 为例)
sklink completions zsh > _sklink

# 在仓库根目录运行:默认使用 ./skills 作为 skills 目录
# 在 skills/ 目录内运行:默认使用当前目录作为 skills 目录
# 安装指定技能到指定平台(-i 可重复;既支持 skill 名,也支持路径)
sklink -i software-engineer -i legal-counsel -p kimi

# 使用长选项安装(等价于 -i)
sklink --install software-engineer -p kimi

# 也可以传路径(便于在任意目录运行;shell 展开后的 ./skills/* 也能工作)
sklink -i ./skills/software-engineer -p kimi

# 安装到配置中全部平台
sklink -p all

# 不传 -p 时默认 all
sklink

# 若本机技能仓库中已存在同名 skill,必须显式 --force 才允许覆盖(覆盖会先备份旧目录再写入)
sklink --force -i software-engineer -p kimi
```

### 安装模式(默认动作)

不带子命令时执行安装流程:

```bash
sklink [-i|--install SKILL|PATH ...] [-p|--platform PLATFORM|all] [--force]
```

- `-i, --install <SKILL|PATH>`:可重复
  - 传 skill 名:会在 local store / repo skills dir 中解析
  - 传路径:必须指向一个目录,skill 名取目录名
- `-p, --platform <PLATFORM|all>`:不传默认 `all`
- `--force`
  - 允许覆盖 local store 中的同名 skill(覆盖前会备份)
  - 影响部分解析优先级(见“skill 解析与优先级”)

### 开发运行(cargo run)

```bash
# 注意:cargo run 需要用 `--` 分隔 cargo 参数与 CLI 参数
cargo run -- --help
cargo run -- list
cargo run -- list --installed
cargo run -- -p all
```

### 行为说明

- skills 会先复制到 local store `~/.config/sklink/skills/<skill>`,再从 target dir 创建软链接
- 若 target dir 不存在或不可用:跳过并输出 warning(不会自动创建)
- 若 local store 中已存在同名 skill:
  - 批量安装(不传 `-i`)时:默认直接使用 store 版本(不报错),除非指定 `--force` 才会用当前来源覆盖 store
  - 指定安装(传 `-i`)时:默认报错;仅在指定 `--force` 时才允许覆盖(覆盖会先将旧目录备份到 `~/.config/sklink/backups/`- 若链接不存在:创建软链接 `<target_dir>/<skill> -> <local_store>/<skill>`
- 若已存在且为正确软链接:跳过并输出 `skipped`
- 若已存在但不是正确软链接(普通文件/目录/指向其他目标):报错退出(避免误删用户文件)

### skill 解析与优先级

当 `-i` 传入的是“skill 名”(不是路径)时:

- 同名 skill 在 local store 存在:默认使用 local store
- local store 不存在但 repo skills dir 可用:使用 repo skills dir
- 同名 skill 同时在 local store 与 repo skills dir 存在:
  - 当前实现:带 `--force` 时优先 repo skills dir;不带 `--force` 时优先 local store

当 `-i` 传入的是“路径”时:

- 支持 `~``./relative/path`、包含 `/` 的路径
- 该路径必须是目录;skill 名取该目录的最后一段名称

### `list` 输出说明

- `sklink list`:输出可用 skill 名列表(每行一个)
- `sklink list --installed`:扫描配置中的 target dir,并按树形展示内容:
  - `[L]`:软链接
    - `ok`:软链接指向 local store 下的同名 skill
    - `outside-store`:软链接存在但不指向 local store 下的同名 skill
    - `unknown-store`:无法确定 local store(例如 canonicalize 失败)
    - `broken:<err>`:软链接损坏或无法解析
  - `[D]`:目录
  - `[F]`:普通文件
  - `[?]`:未知类型或读取失败

### 常见问题

- 为什么安装时提示 `warning: target dir not found (skipped)`  - 目标目录不存在或不可访问时会跳过,不会自动创建目录;请先手动创建并确保权限正确
- 为什么提示“已存在但不是正确软链接”就直接失败?
  - 这是刻意的安全边界:工具不会删除/覆盖用户已有文件或目录,避免误操作

### 平台与系统限制

- 当前使用 Unix 软链接实现(macOS/Linux)

### 发布

发布到 crates.io 的流程已固化为脚本,见 [scripts/README.md](file:///Users/norman/workspace/zhimingcool/chore/scripts/README.md)