feat: init

This commit is contained in:
2026-07-02 23:57:59 +08:00
commit ea3621a065
7 changed files with 759 additions and 0 deletions
+282
View File
@@ -0,0 +1,282 @@
# Agent Skills 仓库
自研 Agent Skills 的单一事实来源(SSOT)。Skill 内容在本仓库维护;安装与管理由 [skiff](https://git.yumee.top/laily/skiff) CLI 负责。
| 仓库 | 地址 | 职责 |
|------|------|------|
| **skills**(本仓库) | https://git.yumee.top/laily/skills | skill 内容与规范 |
| **skiff** | https://git.yumee.top/laily/skiff | 安装、symlink、健康检查 |
---
## 快速开始
```bash
# 1. 克隆并关联
git clone https://git.yumee.top/laily/skills.git ~/code/gitea/skills
git clone https://git.yumee.top/laily/skiff.git ~/code/gitea/skiff
cd ~/code/gitea/skiff && ./install.sh
skiff setup ~/code/gitea/skills
# 2. 全局安装 skill
skiff install declarative-openspec-loop
# 3. 查看状态
skiff list
skiff status
```
---
## 仓库结构
```
skills/
├── _template/ # 新建 skill 的脚手架
├── declarative-openspec-loop/ # 自研 skill
│ ├── SKILL.md
│ └── reference.md
registry.yaml # 外部 Git skill 来源目录
AGENTS.md # 本文档
```
**本仓库包含**`skills/``registry.yaml``AGENTS.md`
**本仓库不包含**:CLI 代码、各项目的 skill 启用清单
---
## Skill 目录
### 自研(Owned
| Skill | 说明 |
|-------|------|
| [declarative-openspec-loop](skills/declarative-openspec-loop/SKILL.md) | 声明式编程循环:用户提供校验方式,Agent 自动 propose/apply/校验并迭代直到通过 |
新建 skill:复制 `skills/_template/``skills/<name>/`,编辑 `SKILL.md`,在本仓库 commit。
### 外部(External Git
`registry.yaml` 中注册,通过 skiff 拉取安装:
| Skill | 来源 |
|-------|------|
| superpowers | https://github.com/obra/superpowers |
```bash
skiff fetch superpowers
skiff install-external superpowers
```
### 社区(External NPM / GitHub
推荐使用 Vercel CLI 安装第三方 skill
```bash
npx skills add vercel-labs/agent-skills -g -y
npx skills find typescript
```
---
## 设计原则
1. **SSOT** — 自研 skill 只存在于 `skills/<name>/`,不在 Agent 目录直接创建
2. **项目自治** — 每个项目自己维护 `.skills.yaml`,本仓库不维护项目清单
3. **软链优先** — 通过 symlink 映射到 Agent 目录,改 skill 即改 SSOT
4. **仓库分离** — skill 内容与 CLI 工具分仓库,互不影响更新
---
## 架构
```
skills 仓库(本仓库) skiff CLI
skills/<name>/ ←── skiff install / enable
registry.yaml ←── skiff add / fetch
~/.skillssymlink
┌────┴────┐
▼ ▼
~/.cursor/skills/ project/.agents/skills/
~/.claude/skills/ project/.claude/skills/
~/.codex/skills/ project/.skills.yaml
```
### Skill 三层分类
| 层级 | 位置 | 维护方式 |
|------|------|---------|
| **Owned** | `skills/<name>/` | 本仓库 commit |
| **External Git** | `~/.local/share/skills/externals/` | `skiff fetch` |
| **External NPM** | `node_modules/` | `npx skills add` / `skills-npm` |
### 多 Agent 路径
| Agent | 全局 | 项目 |
|-------|------|------|
| Cursor | `~/.cursor/skills/` | `.agents/skills/` |
| Claude Code | `~/.claude/skills/` | `.claude/skills/` |
| Codex | `~/.codex/skills/` | `.agents/skills/` |
---
## 项目级启用
每个项目**自己维护** `.skills.yaml`,不由本仓库管理:
```yaml
# .skills.yaml(在项目根目录)
skills:
- declarative-openspec-loop
- name: superpowers
source: registry
ref: main
targets: # 可选,默认 all
- cursor
- claude
- codex
```
| 概念 | 类比 |
|------|------|
| skills 仓库 | npm registry |
| `.skills.yaml` | `package.json` dependencies |
| `skiff enable` | `npm install` |
| `skiff sync` | `npm ci` |
项目级命令(skiff 待实现):
```bash
cd ~/code/my-app
skiff enable declarative-openspec-loop
skiff disable declarative-openspec-loop
skiff sync
```
---
## skiff 命令
详见 [skiff README](https://git.yumee.top/laily/skiff)。
### 已实现
| 命令 | 说明 |
|------|------|
| `skiff setup <path>` | 关联 `~/.skills` 到本仓库 |
| `skiff list` | 列出所有 skill |
| `skiff status` | 安装状态总览 |
| `skiff install <name>` | 全局安装(symlink |
| `skiff uninstall <name>` | 移除 symlink |
| `skiff add / fetch / install-external` | 外部 Git skill |
### 待实现
| 命令 | 说明 |
|------|------|
| `skiff enable / disable` | 项目级启用/关闭 |
| `skiff sync` | 按 `.skills.yaml` 重建 symlink |
| `skiff create` | 从 `_template/` 脚手架创建 skill |
| `skiff doctor` | symlink 健康检查 |
---
## Skill 编写规范
遵循 [Agent Skills 开放标准](https://agentskills.io)
```
skill-name/
├── SKILL.md # 必需
├── reference.md # 可选
├── examples.md # 可选
└── scripts/ # 可选
```
### Frontmatter
```yaml
---
name: skill-name
description: >-
做什么、何时触发。description 是 Agent 决定是否加载的唯一依据,务必写清触发关键词。
---
```
### 命名
- 目录名 = frontmatter `name`
- 小写 + 连字符:`security-review`
- 禁止 camelCase、空格、下划线
### 新建流程
1. `cp -r skills/_template skills/my-skill`
2. 编辑 `skills/my-skill/SKILL.md`
3. `skiff install my-skill --target cursor` 验证
4. 在本仓库 commit
5. 各项目 `skiff enable my-skill`(待实现)
**禁止**在 `~/.cursor/skills/` 或项目 Agent 目录直接创建非 symlink 的 skill。
---
## Skill 修改回流
symlink 正确时,Agent 在项目里改 skill 文件 = 直接改 SSOT
```
project/.agents/skills/foo/SKILL.md
→ ~/.skills/skills/foo/SKILL.md
→ 在本仓库 commit
```
---
## Claude Code 注意事项
Claude Code 对 symlink 支持不稳定:可能无法发现 skill,或写入时将 symlink 替换成普通文件。
| 场景 | 建议 |
|------|------|
| Cursor / Codex | symlink,正常 |
| Claude Code | symlink 单个 skill 目录,不要 symlink 整个 `~/.claude/skills/` |
| symlink 被替换 | `skiff doctor`(待实现)→ 重建 symlink |
---
## 工具分工
| 场景 | 工具 |
|------|------|
| 自研 skill 安装/管理 | **skiff** |
| 社区 skill 安装 | **Vercel `npx skills add`** |
| NPM 包内 skill | **skills-npm** / **skill-indexer** |
| 搜索发现 | **npx skills find** / [skills.sh](https://skills.sh) |
---
## 日常速查
| 我要… | 命令 | 在哪 |
|-------|------|------|
| 首次 setup | `skiff setup ~/code/gitea/skills` | 任意 |
| 新建 skill | 复制 `_template/` → 编辑 → commit | 本仓库 |
| 全局启用 | `skiff install <name>` | 任意 |
| 项目启用 | `skiff enable <name>` | 项目目录 |
| 看状态 | `skiff status` | 任意 |
| 装社区 skill | `npx skills add owner/repo -g -y` | 任意 |
| 更新外部 skill | `skiff fetch <name>` | 任意 |
---
## 参考
- [Agent Skills 开放标准](https://agentskills.io)
- [skiff CLI](https://git.yumee.top/laily/skiff)
- [Vercel skills CLI](https://github.com/vercel-labs/skills)
- [skills.sh](https://skills.sh)
- [Cursor Skills 文档](https://cursor.com/docs/context/skills)
+20
View File
@@ -0,0 +1,20 @@
schema: spec-driven
# Project context (optional)
# This is shown to AI when creating artifacts.
# Add your tech stack, conventions, style guides, domain knowledge, etc.
# Example:
# context: |
# Tech stack: TypeScript, React, Node.js
# We use conventional commits
# Domain: e-commerce platform
# Per-artifact rules (optional)
# Add custom rules for specific artifacts.
# Example:
# rules:
# proposal:
# - Keep proposals under 500 words
# - Always include a "Non-goals" section
# tasks:
# - Break tasks into chunks of max 2 hours
+17
View File
@@ -0,0 +1,17 @@
# External skills registry
# Format:
# <name>:
# repo: <git-url>
# ref: <branch|tag> (default: main)
# path: <subpath> (default: .)
#
# Example:
# superpowers:
# repo: https://github.com/obra/superpowers
# ref: main
# path: .
superpowers:
repo: https://github.com/obra/superpowers
ref: main
path: .
View File
+30
View File
@@ -0,0 +1,30 @@
---
name: skill-name
description: >-
简要描述 skill 做什么、何时触发。Include trigger keywords so agents can match automatically.
---
# Skill 名称
一句话说明这个 skill 的用途。
---
## 何时使用
- 触发场景 1
- 触发场景 2
---
## 步骤
1. 第一步
2. 第二步
3. 第三步
---
## 注意事项
- 约束或边界条件
+237
View File
@@ -0,0 +1,237 @@
---
name: declarative-openspec-loop
description: 声明式编程循环 - 用户提供校验方式,Agent 自动 propose/apply/校验并迭代直到通过。Use when the user provides expectations or a verification method and wants the agent to implement, verify, and iterate until expectations pass. Triggers on 声明式编程、按预期循环、做到校验通过、declarative loop.
---
# 声明式 OpenSpec 循环
用户提供**判断结果是否符合预期的方式**,Agent 按 OpenSpec 流程 propose → apply → 校验,不通过则分析原因并迭代,直到通过。通过后输出变更点与思路。
**前置**:需要 openspec CLI 及三个子 skill。预期/校验写法的详细说明和端到端示例见 [reference.md](reference.md)。
---
## 何时使用
- 用户说「按我给的预期/校验方式做,做到通过为止」
- 用户提供了校验命令、预期文档、校验清单或自由描述,并希望自动迭代
- 用户提到「声明式编程」「按预期循环」「做到校验通过」
---
## 输入:预期与校验方式
用户必须提供**如何判断结果符合预期**(可组合):
| 形式 | 示例 |
| -------- | --------------------------------------------- |
| 校验命令 | `make test-one2`,退出码 0 即通过 |
| 预期文档 | `docs/tmp/expect_desc.md` 中的校验项表格 |
| 校验清单 | 日志须含 `阶段2 圆弧起点``阶段3 右边竖边` … |
| 自由描述 | 「拟合轮廓与 PLY 逆时针顺序一致」 |
若用户未给清,**必须先问**。详细格式说明见 [reference.md § 预期/校验方式](reference.md#预期校验方式的写法)。
---
## 如何调用子 skill(关键)
本 skill 编排三个子 skill,每次调用子 skill 时**必须先读取对应 SKILL.md 并遵循其中的完整步骤**:
| 步骤 | 子 skill | 读取路径 |
| ---- | --------------------- | ----------------------------------------------- |
| 探索 | openspec-explore | `.cursor/skills/openspec-explore/SKILL.md` |
| 提案 | openspec-propose | `.cursor/skills/openspec-propose/SKILL.md` |
| 实现 | openspec-apply-change | `.cursor/skills/openspec-apply-change/SKILL.md` |
**不要凭记忆执行子 skill 的流程**,每次都读取最新的 SKILL.md 再做。
---
## 主流程
```
用户输入:目标 + 校验方式
1. 初始化:change 名称 + docs/tmp/<name>/ + expectation.md
2. [可选] explore:目标复杂/模糊时先探索
3. propose:生成 proposal / design / tasks(任务带验收标准)
4. apply:按 tasks 实现
5. 校验 ──通过──▶ 6a. 完成:输出变更与思路
不通过
6b. 分级处理(见下)──▶ 回到 4 或 3
```
---
## 迭代分级:失败后怎么做
校验不通过时,**根据失败根因选择不同路径**,避免小 bug 也走完整提案流程:
### Level 1:代码小修复(最常见)
**触发**:编译错误、运行时 bug、坐标写反、off-by-one、日志格式不对等实现层面问题。
**动作**
1. 定位出错代码,直接修复
2. 重新编译(若适用)
3. 回到**步骤 5 校验**
不需要 explore,不需要修改 proposal/design/tasks。
### Level 2:任务遗漏或不完整
**触发**:某个校验项没有对应的 task、task 描述模糊导致实现偏差。
**动作**
1. 分析缺失的校验项对应什么工作
2.`tasks.md` 中**补充或修正** task
3. 回到**步骤 4 apply** 执行新增/修正的 task → **步骤 5 校验**
### Level 3:设计级问题(最少见)
**触发**:整体方向错误、架构不合适、预期理解有偏差、多个校验项系统性失败。
**动作**
1. 读取子 skill **openspec-explore** 并执行:基于校验结果 + 当前 proposal/design 分析根因
2. 将分析写入 `docs/tmp/<change-name>/iteration_<N>.md`
3. 修订 proposal.md / design.md / tasks.md(在原有 change 上修改,不新建)
4. 回到**步骤 4 apply** → **步骤 5 校验**
### 判断依据
| 信号 | Level |
| ---------------------------------------- | ------ |
| 编译报错 | 1 |
| 运行崩溃 / 段错误 | 1 |
| 单个校验项不通过,其余都通过 | 1 或 2 |
| 多个校验项不通过,但原因各异 | 2 |
| 多个校验项不通过,原因相同(方向性错误) | 3 |
| 校验项全部不通过 | 3 |
---
## 最大迭代次数
- 默认上限:**5 轮**(一轮 = 一次 apply + 一次校验)。
- 到达上限后**暂停并询问用户**:展示当前进度、未通过的校验项、已尝试的修复方向,让用户决定是否继续。
- 用户可在初始化时指定不同的上限(如「最多跑 3 轮」「不限轮次」)。
- Level 1 的小修复(如编译错误修复后重新编译)**不计入**轮次,仅 apply+校验 计一轮。
---
## 编译失败处理
对于需要编译的项目(C/C++、Rust、Go 等):
1. apply 完成后、运行校验命令前,**先编译**(或校验命令本身触发编译)。
2. 若编译失败:属于 **Level 1**,直接修复编译错误,重新编译,不计入迭代轮次。
3. 若编译成功但校验不通过:按正常分级处理。
4. 编译错误的修复**不需要** explore 或修订 proposal。
---
## 重复失败检测
若连续 **2 轮**校验结果中,**同一个校验项以相同原因失败**
1. 停止自动迭代
2. 向用户报告:哪个校验项、什么错误、已尝试的两次修复各做了什么
3. 请用户给出新方向或手动介入
避免 Agent 在同一个坑里反复打转。
---
## 恢复 / 续接
对话中断后重新进入时:
1. 检查 `docs/tmp/<change-name>/` 下已有的 `iteration_*.md` → 确定当前轮次
2. 检查 `openspec/changes/<name>/tasks.md``[x]` / `[ ]` → 确定 task 进度
3. 读取最近一轮的 `iteration_<N>.md``check_result_<N>.txt` → 了解上次失败原因
4. 从上次中断的步骤继续,不从头开始
---
## TodoWrite 跟踪
整个循环过程中用 **TodoWrite** 跟踪进度:
```
示例 todo 列表:
- [x] 初始化 change + expectation.md
- [x] propose: 生成 proposal/design/tasks
- [in_progress] 第 1 轮 apply + 校验
- [ ] 校验通过 → 输出变更摘要
```
每轮 apply + 校验 为一个 todo;校验不通过时更新 todo 内容(如「第 1 轮:3/8 校验项通过,Level 2 修复中」)。
---
## 过程数据存储
根目录:`docs/tmp/<change-name>/`
| 文件 | 内容 |
| ------------------------ | -------------------------------------------------- |
| `expectation.md` | 校验方式摘要(或引用路径) |
| `iteration_<NNN>.md` | 每轮:apply 要点、校验结果、失败项、分级、修复动作 |
| `check_result_<NNN>.txt` | 校验命令原始输出 |
| `iteration_final.md` | 通过后的最终摘要(可选) |
`docs/tmp` 不存在,先创建。
---
## 输出模板(校验通过时)
```markdown
## 声明式循环完成
**Change:** <change-name>
**校验方式:** <摘要>
**迭代轮次:** N
### 变更摘要
- <文件 1><改动>
- <文件 2><改动>
### 思路
<设计取舍、与预期的对应、关键实现要点>
### 过程数据
`docs/tmp/<change-name>/`
```
---
## Guardrails
- **未提供校验方式时**:不进入循环,先问用户。
- **每轮校验结果必须落盘**:至少记录通过/不通过与未满足项。
- **优先复用同一 change**:修订 proposal/design/tasks,不盲目新建。
- **任务带验收标准**propose 时每个 task 尽量带可执行的验证步骤。
- **explore 只分析不改代码**:改代码通过 apply 或 Level 1 直接修复。
- **最大轮次到达时停下问用户**:不自动放弃也不无限跑。
- **重复失败时升级**:同一错误连续 2 轮 → 停下问用户。
- **用户可随时中断**:暂停并汇报当前状态。
@@ -0,0 +1,173 @@
# 声明式 OpenSpec 循环 - 参考
## 预期/校验方式的写法
### 校验命令
用户直接给命令,成功 = 退出码 0(或约定输出内容):
```
"跑 make test-one2,通过就行"
"运行 pytest tests/test_foo.py,全部 green 即符合预期"
"make build && ./run_check.sh,输出里必须包含 ALL PASSED"
```
Agent 收到后在 `expectation.md` 中记录:命令、成功条件(退出码 / 输出关键字)。
### 预期文档(含校验项)
文档里有「校验项」或「预期说明」,Agent 按此检查输出/日志/文件。推荐文档结构:
```markdown
## 整体预期描述
<这个功能/轮廓/接口应该怎样>
## 详细说明
<按顺序的几何/行为描述>
## 校验项
| 序号 | 检查点 | 预期说明 | 日志/输出关键字 |
| ---- | ------ | -------- | --------------- |
| 1 | ... | ... | ... |
```
本仓库示例:`docs/tmp/expect_desc.md` — 描述弧顶七字形轮廓几何,末尾有 8 项校验表。
### 校验清单(条目化)
用户列几条「必须满足」的条件:
- 日志中必须出现:`阶段2 圆弧起点(左上角)``阶段3 右边竖边: 上端=...`
- 生成文件 `out/result.json``status` 必须为 `ok`
- 拟合轮廓 2D PLY 点数 > 100
### 自由描述
由 Agent 归纳为可执行检查步骤并在 `expectation.md` 中记录归纳结果,执行前向用户确认理解是否正确。
---
## 迭代日志模板 `iteration_<NNN>.md`
每轮写入 `docs/tmp/<change-name>/iteration_<NNN>.md`,推荐结构:
```markdown
# 第 N 轮
## apply 要点
- 执行了哪些 task / 修复了什么
## 校验结果
- 命令:`make test-one2`
- 退出码:1
- 通过项:1, 2, 3, 5, 6
- 未通过项:4(底边端点偏差 > 2mm)、7(右下斜边日志缺失)、8(左侧竖边未闭合)
## 分级
Level 2task 2.3 缺少右下斜边独立成段的验证
## 下一步
- 在 tasks.md 补充 task 2.3 的验证步骤
- 修改 sampleArcTopSevenShape2D 中右下斜边的端点取值
```
---
## 端到端示例(基于本项目)
以下是一个完整循环的示例,基于「弧顶七字形拟合与 expect_desc 对齐」场景。
### 用户输入
```
目标:让弧顶七字形拟合结果与 docs/tmp/expect_desc.md 描述一致
校验方式:
1. 运行 make test-one2
2. 拟合日志中应包含 expect_desc.md「校验项」表的 8 项(各段端点 world 坐标与 PLY 一致,容差 2mm)
```
### 第 0 步:初始化
```
mkdir -p docs/tmp/arc-top-seven-expect-align/
```
`docs/tmp/arc-top-seven-expect-align/expectation.md`
```markdown
## 校验方式
1. 命令:`make test-one2`,退出码 0
2. 文档:`docs/tmp/expect_desc.md`「校验项」表 8 项全部通过(world 坐标容差 2mm)
```
### 第 1 步:propose
读取 openspec-propose SKILL.md → 执行:
```bash
openspec new change "arc-top-seven-expect-align"
```
生成 proposal.md、design.md、tasks.md。tasks 中每个 task 带验收标准,例如:
```markdown
- [ ] 2.3 运行 make test-one2,对比拟合日志中各段端点与 expect_desc 表;不符则修改后重复
```
### 第 2 步:apply(第 1 轮)
读取 openspec-apply-change SKILL.md → 逐 task 实现。
### 第 3 步:校验(第 1 轮)
```bash
make test-one2 2>&1 | tee docs/tmp/arc-top-seven-expect-align/check_result_001.txt
```
结果:编译通过,但校验 8 项中 5 项通过、3 项不通过(底边端点、右下斜边、左侧竖边)。
→ 写 `iteration_001.md`
### 第 4 步:分级 → Level 1(代码小修复)
底边端点偏差原因:`sampleArcTopSevenShape2D` 中取错了变量。直接修复,重新编译运行。
### 第 5 步:校验(第 2 轮)
6/8 通过,右下斜边和左侧竖边仍不对。
→ 写 `iteration_002.md`,分析发现 tasks 中缺少右下斜边独立成段的 task。
### 第 6 步:分级 → Level 2(补 task
在 tasks.md 中补充 taskapply 新 task。
### 第 7 步:校验(第 3 轮)
8/8 通过。
→ 输出变更摘要与思路,写 `iteration_final.md`
---
## 过程数据目录结构示例
```
docs/tmp/arc-top-seven-expect-align/
├── expectation.md # 校验方式
├── iteration_001.md # 第 1 轮:5/8 通过
├── check_result_001.txt # make test-one2 第 1 轮原始输出
├── iteration_002.md # 第 2 轮:6/8 通过,Level 2 补 task
├── check_result_002.txt # 第 2 轮原始输出
├── iteration_003.md # 第 3 轮:8/8 通过
├── check_result_003.txt # 第 3 轮原始输出
└── iteration_final.md # 最终摘要
```