# Skill 开发规范

本文档是 SophClaw Skill 开发的完整规范，供 `sophclaw-skill-creator` 在第二步（方案对齐）和第三步（校验）中参考。

---

## 硬规则（必须遵守）

1. **description = 功能 + 触发场景** — LLM 匹配 skill 的唯一依据
2. **SKILL.md 只写用法，不写实现细节** — 实现放 scripts/
3. **用 `uv run` 启动 Python 脚本** — 不用 `python`
4. **路径用运行时路径** — `{baseDir}/scripts/xxx.py`，不含 `src/`
5. **不提及其他 skill** — 保持独立性
6. **SKILL.md 不含 `version` 字段** — 版本号由 skill.json 唯一管理
7. **store 类型必须有中文 displayName 和 description**
8. **pyproject.toml version 与 skill.json version 一致**
9. **Python 兼容 3.8+** — 用 typing.Optional/List/Dict，pathlib，encoding="utf-8"

---

## 一、分离原则

**SKILL.md 只写"怎么用"，实现细节放在 scripts/ 里。**

| 文件类型 | 职责 | 内容 |
|---------|------|------|
| SKILL.md | 接口文档 | 功能描述、调用步骤、输出格式、注意事项 |
| scripts/*.py | 具体实现 | 业务逻辑、API 调用、数据处理 |

**理由**：SKILL.md 保持简洁，LLM 阅读成本低；实现变更不影响接口文档；清晰边界让 skill 更易维护。

---

## 二、Skill 类型

| type | CLI 可见 | 适用场景 | 特殊要求 |
|------|---------|---------|---------|
| builtin | 是 | 系统内置，默认可用 | 无 |
| store | 是 | 商店可安装 | **必须**有中文 displayName 和 description |
| private | 否 | 内部使用 | CLI list/download 隐藏 |
| tmp | 否 | 临时/未分类 | CLI list/download 隐藏 |

---

## 三、目录结构

### 仓库结构（开发时）

```
skill-name/
├── skill.json              # 必需：元信息
├── design.md               # 开发留存：需求+方案+测试用例（不参与打包）
├── src/                    # 打包时会被拉出
│   ├── SKILL.md            # 必需：skill 接口文档
│   ├── pyproject.toml      # 推荐：Python 项目配置
│   ├── scripts/            # 可选：Python 脚本
│   │   └── __init__.py
│   ├── references/         # 可选：参考文档
│   └── assets/             # 可选：静态资源
```

### 运行时结构（打包后）

```
skill-name/
├── SKILL.md                # src/ 被拉出到根目录
├── scripts/
├── references/
└── assets/
```

**关键**：SKILL.md 中写路径时必须用运行时路径（`{baseDir}/scripts/xxx.py`），不能带 `src/`。

---

## 四、skill.json 规范

```json
{
  "name": "skill-name",
  "version": "1.0.0",
  "types": ["store"],
  "displayName": "中文名称",
  "description": "中文描述",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-05-25",
      "changes": ["变更说明"]
    }
  ],
  "createdAt": "2026-05-25",
  "updatedAt": "2026-05-25"
}
```

- `name`：与目录名一致，kebab-case
- `version`：语义化版本号；**每次代码变更必须 bump 并添加 changelog 条目**
- `types`：数组，元素为 builtin/store/private/tmp
- `displayName` / `description`：store 类型必填，使用中文
- `createdAt` / `updatedAt`：ISO 日期格式

---

## 五、SKILL.md 编写规范

### frontmatter

```yaml
---
name: skill-name
description: 功能 + 触发场景（一句话；LLM 匹配的唯一依据）
---
```

- **不包含 `version` 字段**（版本号由 skill.json 管理）
- description 是 LLM 匹配 skill 的唯一依据，必须清楚表达功能和触发场景

### description 公式

```
功能 + 触发场景 = 好的 description
```

正例：
```yaml
# ✅ 言简意赅，功能+触发场景
description: 生成证件照。当用户上传人物照片并要求生成证件照、换底色、制作一寸/二寸照片时使用。
```

反例：
```yaml
# ❌ 冗长模糊
description: 这是一个用于处理图片的工具，可以帮助用户进行各种图片相关操作

# ❌ 只有功能，无触发场景
description: 图片压缩

# ❌ 包含实现细节
description: 使用 Pillow 库压缩图片，支持调整质量参数
```

### body 内容

- 功能描述
- 调用命令示例（使用 `uv run`，路径为 `{baseDir}/scripts/...`）
- 输出格式
- 注意事项
- 不写实现细节、不写代码逻辑、不提及其他 skill

---

## 六、脚本编写规范

### 入口脚本模板

```python
#!/usr/bin/env python3
"""
Skill 描述：一句话说明功能
"""

import argparse
import sys

def main():
    parser = argparse.ArgumentParser(description="功能描述")
    parser.add_argument("--input", required=True, help="输入参数")
    args = parser.parse_args()

    # 业务逻辑

    print("STATUS=succeeded")
    print("OUTPUT_PATH={}".format(output_path))

if __name__ == "__main__":
    main()
```

### 输出规范

脚本输出结构化的键值对，便于 LLM 解析：

```
STATUS=succeeded
OUTPUT_PATH=/path/to/result
ERROR_MESSAGE=（失败时）
```

### Python 兼容性

- 目标 Python 3.8+
- 使用 `typing.Optional`、`typing.List`、`typing.Dict`（不用 `X | Y`、`list[X]`）
- 文件 I/O 指定 `encoding="utf-8"`
- 优先使用 `pathlib` 而非字符串拼接路径

---

## 七、执行规范

```bash
# ✅ 正确
uv run {baseDir}/scripts/xxx.py --args

# ❌ 错误
python {baseDir}/scripts/xxx.py --args
```

`uv` 自动管理依赖和虚拟环境，执行更快更可靠。

---

## 八、pyproject.toml 规范

```toml
[project]
name = "skill-name"
version = "1.0.0"
description = "Skill description"
requires-python = ">=3.8"
```

- `version` 必须与 `skill.json` 保持一致
- `name` 与 skill 名称一致

---

## 九、三方加载机制

Skill 采用渐进式披露设计，LLM 按需加载内容：

1. **Metadata（name + description）** — 始终在上下文中，LLM 根据 description 决定是否触发
2. **SKILL.md body** — 触发后才加载，包含调用指令、输出格式、注意事项
3. **Bundled resources（scripts/references/assets）** — 按需执行或加载，不占用上下文

**关键**：description 是触发的唯一依据，不要期望 body 里的说明能帮助匹配。

---

## 十、design.md 规范

design.md 在 skill 创建阶段由 LLM 产出，放在 skill 根目录（与 skill.json 同级），不参与打包。

### 结构

```markdown
# <skill-name> 设计文档

## 一、需求说明
- 功能描述
- 触发场景（用户怎么说话会触发）
- 输入/输出约定
- 上线平台及 type 选择理由

## 二、方案设计
- 目录结构
- 是否需要脚本及理由
- SKILL.md 关键设计决策
- 注意事项

## 三、测试用例
| 编号 | 测试场景 | 触发语句 | 预期匹配 | 预期行为 | 预期输出 |
```

### 用途

- 记录设计决策，供后续维护者参考
- 测试用例覆盖正常/边界/不触发场景
- 不被打包，仅仓库内留存

---

## 十一、检查清单

开发完成后逐项检查：

### 结构检查
- [ ] skill.json 存在且字段齐全
- [ ] name 一致性（目录名 = skill.json.name = SKILL.md frontmatter.name）
- [ ] types 值合法
- [ ] store 类型有中文 displayName 和 description
- [ ] src/SKILL.md 存在且 frontmatter 格式正确
- [ ] SKILL.md frontmatter 无 version 字段
- [ ] src/pyproject.toml 存在
- [ ] pyproject.toml version == skill.json version

### 内容检查
- [ ] description 简短精准：功能 + 触发场景
- [ ] 命令示例用 `uv run`，不用 `python`
- [ ] 路径为运行时路径（不含 `src/`）
- [ ] 未提及其他 skill
- [ ] SKILL.md 中无实现细节（大段代码、API 调用逻辑）
- [ ] 脚本输出结构化、可解析（STATUS=... 格式）

### 变更管理
- [ ] 代码变更后 skill.json version 已 bump
- [ ] changelog 已追加条目

---

*本文档基于 `sophclaw-skill-creator` 的需求整理，持续迭代。*