feat(skill): 技能治理 v0.2 —— 分桶/调用模式/校验/安全/清单/安装矩阵 #12

Merged
qiudl merged 4 commits from feat/skill-management into main 2026-10-31 14:18:15 +00:00
65 changed files with 1849 additions and 22 deletions
@@ -0,0 +1,19 @@
# 已拒绝:为某一种 harness 单开分支
- 状态:拒绝(长期有效)
- 日期:2026-10-31
## 想法
为 Codex / DSH / Claude 某一个客户端的特例,单独复制一份技能或加一个 harness 分支。
## 为什么拒绝
1. 复制出来的两份技能会立刻开始漂移,评测也要做两遍;
2. 客户端差异应交给安装器(目录、调用模式、字段映射)处理,不该写进技能内容;
3. 特例需求通常是个人的工作流调整,属于 `AGENTS.md` / `CLAUDE.md` 或 fork 的范围。
## 允许的替代路径
- 客户端差异 → 安装器加 target / 字段映射;
- 个人流程 → 个人目录或 fork。
+20
View File
@@ -0,0 +1,20 @@
# 已拒绝:新增「随手想到」的技能
- 状态:拒绝(长期有效)
- 日期:2026-10-31
## 想法
「我觉得应该有个技能做 X」——从想象出发新增技能,而不是从真实失败出发。
## 为什么拒绝
1. 技能目录是每次会话启动就要付的上下文预算,加一个就多一份;
2. 没有真实失败做依据的技能,写出来是泛泛而谈,实际触发率极低;
3. 技能之间会互相抢触发(description 相似),新增一个会稀释已有技能的准确率。
## 允许的替代路径
- 先用现有技能做一遍真实任务,记录卡点;
- 确实组合不出来,再按 `SCOPE.md` 门槛提,附真实失败证据;
- 只是个人偏好 → 放 `skills-personal/`,不进团队库。
+19
View File
@@ -0,0 +1,19 @@
# 已拒绝:把个人工作流调优塞进团队技能
- 状态:拒绝(长期有效)
- 日期:2026-10-31
## 想法
把某个人的偏好(提交信息格式、分支命名、审查语气、工具习惯)直接写进团队技能。
## 为什么拒绝
1. 团队技能要能被所有人用,个人偏好会变成隐式规训;
2. 一旦写进技能,改起来要走 PR,个人改不动;
3. 这类偏好本来就该放个人 `AGENTS.md` / `CLAUDE.md`。
## 允许的替代路径
- 个人偏好 → 个人配置文件或 `skills-personal/`;
- 如果是团队共识(不是个人偏好),走 `SCOPE.md` 门槛并附真实失败。
+25
View File
@@ -0,0 +1,25 @@
# Changelog
## Unreleased — 2026-10-31
### 新增
- 技能治理:`SCOPE.md` 收录门槛 + `.out-of-scope/` 拒绝档案。
- 生命周期分桶(`promoted` / `beta` / `deprecated`)与调用模式(`model-invoked` / `user-invoked`)。
- `scripts/validate-skills.py`:规范/大小/引用/调用模式/文档校验。
- `scripts/generate-catalog.py`:生成可审阅的 `catalog.json`。
- `scripts/scan-skill.sh` + `scripts/scan-allowlist.txt`:入库前安全扫描。
- 新技能(beta):`skill-creator`、`ai-proj-helper-entry`、`verification-before-completion`。
- `install-skills.sh`:`--agent dsh`、`--link`、`--audit`、`--include-beta`、`--no-validate`。
### 变更
- 18 个命令型技能转 `user-invoked`(biz/integration/dev-android|ios|pda/publish/发布链),目录预算减少 18 项。
- `dev-review`:增加「接收与响应评审意见」。
- `req-design`:增加「任务依赖边(blocking edges)」。
- `agent-swarm`:增加「并行编排流程」。
- `dev-test`:增加「TDD 循环」。
- `generate-marketplace.py`:只发布 `promoted`,beta/deprecated 不随 marketplace 分发。
- 按 SCOPE 降级两个无增量技能:`verification-before-completion`、`ai-proj-helper-entry`(规则已在用户级 AGENTS.md),入口路由内容转为 `docs/skill-routing.md`。
+7
View File
@@ -52,3 +52,10 @@ skills:
- `skills-personal/` 不被 Git 跟踪,用于存放个人配置和工具
- 其余 `skills-*` 目录均由 Git 版本控制
- 只有受 Git 跟踪的分类目录会被 `generate-marketplace.py` 扫描并加入公开 marketplace;`skills-personal/` 始终排除
## 技能治理规则
- 公开 marketplace 只发布 `status=promoted`;`beta`/`deprecated` 不进 marketplace(`generate-marketplace.py` 已按 status 过滤)。
- 每个 `plugin.json` 建议带 `status`,每个 `SKILL.md` 在 `metadata.invocation` 标 `model-invoked` / `user-invoked`。
- 任何技能增删改后,回改 `catalog.json` 与入口技能 `ai-proj-helper-entry`。
- 提交前依次跑:`python3 scripts/validate-skills.py`、`./scripts/scan-skill.sh`、`python3 scripts/generate-catalog.py`。
+15
View File
@@ -195,3 +195,18 @@ A: SSE 模式直连远程服务器,零依赖开箱即用(推荐)。stdio
- **管理员**:Donglin Lai (qiudl)
- **邮箱**:qiudl@zhiyuncai.com
- **仓库**:https://gitea.pipexerp.com/pipexerp/ai-proj-helper
## 技能治理(2026-10-31 起)
- **真相源**:本仓库。`~/.agents/skills`、`~/.claude/skills`、`$DSH_HOME/skills` 都只是安装产物。
- **收录门槛**见 [SCOPE.md](./SCOPE.md):只收「真实失败 + 组合不出来」,被拒的想法记在 `.out-of-scope/`。
- **生命周期**:`promoted`(默认安装)/ `beta`(需 `--include-beta`)/ `deprecated`(不安装);新技能一律先进 beta。
- **调用模式**:`model-invoked`(占模型目录预算)vs `user-invoked`(只由人触发,不占目录预算)。
- **安装**:
- Codex:`./install-skills.sh --agent codex`
- DSH:`DSH_HOME=<path> ./install-skills.sh --agent dsh --link`
- Claude(兼容):`./install-skills.sh --agent claude`
- 看漂移:`./install-skills.sh --audit`
- **校验 / 安全 / 清单**:`python3 scripts/validate-skills.py`、`./scripts/scan-skill.sh`、`python3 scripts/generate-catalog.py`
- **建技能**:走 `skill-creator` 技能(收录门槛、分桶、调用模式、evals、四段式文档、路由回改),不要手写。
- **路由表**:`docs/skill-routing.md`(什么任务用哪个技能,人读;由原 `ai-proj-helper-entry` 技能降级而来)。
+45
View File
@@ -0,0 +1,45 @@
# Scope — ai-proj-helper 技能的收录门槛
本仓库是团队每天在用的技能集,**不是技能收藏夹**。技能目录会在每次会话启动时占用模型的上下文预算,所以「多加一个」永远是有代价的。
## 门槛
新技能或改动**默认拒绝**,只有同时满足两条才进入评审:
1. **真实失败**:能说清在哪个真实任务/会话里出了问题——跑了什么、期望什么、实际什么。假设性的「这样会更好」不算。
2. **组合不出来**:用现有技能组合做不到。能组合的,改现有技能,不新增。
规模不重要:一个词的修改和一次重写按同一标准审。
## 分桶
| 桶 | 含义 | 安装 | 进 README / plugin.json |
| --- | --- | --- | --- |
| `promoted` | 已验证、日常在用 | 默认 | 必须 |
| `beta` | 公开试跑、收反馈 | `--include-beta` | 不进默认清单 |
| `deprecated` | 不再使用 | 不安装 | 只留文档,标弃用 |
新技能一律先进 `beta`;promoted 需要真实使用记录 + evals 通过。
## 调用模式
- `model-invoked`(默认):进模型目录,agent 自己判断何时用。
- `user-invoked`:只由人下命令触发,不占目录预算;必须写 `disable-model-invocation: true` + `metadata.invocation: user-invoked`。
判定:这件事是不是「人下命令才开始」?是 → user-invoked。
## 已经拒绝的想法
每个被拒概念一个文件,写在 [`.out-of-scope/`](./.out-of-scope/) 下,先读再提。当前已有:
- [`new-skills.md`](./.out-of-scope/new-skills.md)
- [`harness-specific-branches.md`](./.out-of-scope/harness-specific-branches.md)
- [`personal-workflow-tweaks.md`](./.out-of-scope/personal-workflow-tweaks.md)
## 提交流程
1. 先过 [`skill-creator`](./skills-core/skill-creator-plugin/skills/SKILL.md) 的收录门槛与质量门禁。
2. `python3 scripts/validate-skills.py` 通过。
3. `./scripts/scan-skill.sh` 无高危项。
4. `python3 scripts/generate-catalog.py` 更新 `catalog.json`。
5. 版本号 + CHANGELOG 更新,走 PR。
+21
View File
@@ -67,3 +67,24 @@ Claude Code 需要显式选择目标:
**如何移除技能?**
删除插件目录、重新生成 marketplace、提交变更。使用者随后执行 `./install-skills.sh --dry-run --cleanup`,确认后再去掉 `--dry-run`。
## 安装矩阵(2026-10 更新)
| agent | 安装目录 | 默认模式 | 状态文件 |
| --- | --- | --- | --- |
| `codex`(默认) | `~/.agents/skills` | copy | `~/.agents/.ai-proj-helper-installed-skills.json` |
| `dsh` | `$DSH_HOME/skills` | copy(开发机建议 `--link`) | `$DSH_HOME/.ai-proj-helper-installed-skills.json` |
| `claude`(兼容) | `~/.claude/skills` | copy | `~/.claude/.installed-skills.json` |
```bash
# 本机(DSH 开发机,改仓库即时生效)
DSH_HOME="<your DSH_HOME>" ./install-skills.sh --agent dsh --link
# 远程/其他机器
./install-skills.sh --agent codex
# 看谁落后了
./install-skills.sh --agent codex --audit
```
`beta` 技能默认不装:需要时加 `--include-beta`。`promoted/beta/deprecated` 见 `SCOPE.md`。
+685
View File
@@ -0,0 +1,685 @@
{
"repo": "ai-proj-helper",
"generated_at": "2026-10-31T14:18:10Z",
"total": 61,
"counts": {
"promoted/user-invoked": 18,
"deprecated/user-invoked": 1,
"promoted/model-invoked": 40,
"beta/user-invoked": 1,
"deprecated/model-invoked": 1
},
"skills": [
{
"name": "biz-contract",
"category": "biz",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "商务合同撰写。支持多种合同类型:软件订阅合同、软件定制开发合同、物流合同、销售服务合同、贸易合同等。当用户提到合同、协议、签约、合作协议相关任务时自动激活。",
"description_len": 78,
"path": "skills-biz/biz-contract-plugin/skills/SKILL.md",
"digest": "3d346d4a316590a3"
},
{
"name": "biz-ops",
"category": "biz",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "商务运营技能。支持商业计划书(BP)撰写和商务合同起草。当用户提到商业计划书、BP、融资计划、商业模式、合同、协议、签约等相关任务时自动激活。",
"description_len": 71,
"path": "skills-biz/biz-ops-plugin/skills/SKILL.md",
"digest": "aa5433074ba277d6"
},
{
"name": "biz-plan",
"category": "biz",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "商业计划书撰写。支持融资BP、战略规划、商业模式设计等。当用户提到商业计划书、BP、融资计划、商业模式、战略规划相关任务时自动激活。",
"description_len": 66,
"path": "skills-biz/biz-plan-plugin/skills/SKILL.md",
"digest": "f3bb159157441ca7"
},
{
"name": "finance",
"category": "biz",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "财务对账技能。支持银行对账、应收对账、应付对账、内部往来对账等。通过自然语言实现账单导入、差异分析、对账报告生成。当用户提到对账、银行流水、应收应付、账单核对、财务核销相关任务时自动激活。",
"description_len": 94,
"path": "skills-biz/finance-plugin/skills/SKILL.md",
"digest": "5191b5a91b34ecd6"
},
{
"name": "ai-proj-helper-entry",
"category": "core",
"version": "0.1.0",
"status": "deprecated",
"invocation": "user-invoked",
"description": "ai-proj-helper 技能库路由:告诉你有哪些技能、什么任务用哪个、以及「REQ released + PDV 通过才算交付」的强制口径。人在开始需求/开发/评审/发布任务前主动调用。",
"description_len": 96,
"path": "skills-core/ai-proj-helper-entry-plugin/skills/SKILL.md",
"digest": "41d39b76d4c71dbf"
},
{
"name": "ai-proj",
"category": "core",
"version": "2.0.1",
"status": "promoted",
"invocation": "model-invoked",
"description": "ai-proj 任务与需求管理。用于创建/查询/更新需求、任务、文档。当用户提到 ai-proj、任务管理、需求管理、REQ-XXX 相关操作时自动激活。",
"description_len": 77,
"path": "skills-core/ai-proj-plugin/skills/SKILL.md",
"digest": "f2ef00fdebb29034"
},
{
"name": "pm-ask",
"category": "core",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "基于 ai-proj MCP + git log 真实数据的项目问答。禁止编造。当用户说\"/ask\"、\"问一下\"、\"统计一下\"、\"最近多少\"、\"谁做了多少\"、\"本月进度\"等项目相关问题时自动激活。",
"description_len": 98,
"path": "skills-core/pm-ask-plugin/skills/SKILL.md",
"digest": "e5b69a0b56985472"
},
{
"name": "pm-risk",
"category": "core",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "三维度项目风险扫描(需求层/代码层/流程层)。当用户说\"/risk\"、\"风险扫描\"、\"有什么风险\"、\"哪些需求停滞了\"、\"分支健康\"时自动激活。",
"description_len": 72,
"path": "skills-core/pm-risk-plugin/skills/SKILL.md",
"digest": "928cfec76018329f"
},
{
"name": "publish",
"category": "core",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "发布 ai-proj-helper 技能市场更新并通知飞书群。用户说 /publish 时激活。",
"description_len": 48,
"path": "skills-core/publish-plugin/skills/SKILL.md",
"digest": "198c63f0dcb58d57"
},
{
"name": "skill-creator",
"category": "core",
"version": "0.1.0",
"status": "beta",
"invocation": "user-invoked",
"description": "团队技能的标准流程:收录门槛、分桶生命周期、调用模式、SKILL.md 规范、evals 全量、四段式文档、路由回改。当要新建技能、大改现有技能、或评审一个技能是否合格时使用。",
"description_len": 88,
"path": "skills-core/skill-creator-plugin/skills/SKILL.md",
"digest": "18f18c43c3fa56a6"
},
{
"name": "agent-browser",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "浏览器自动化技能。用于网页交互、E2E冒烟测试、需求验收验证、前端开发验证、截图对比。基于 Vercel agent-browser CLI。",
"description_len": 71,
"path": "skills-dev/agent-browser-plugin/skills/SKILL.md",
"digest": "f382bffe3d1c84b2"
},
{
"name": "agent-swarm",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "Multi-agent orchestration using OpenAI Swarm patterns. Coordinate specialized agents for complex development workflows with handoffs and context sharing.",
"description_len": 153,
"path": "skills-dev/agent-swarm-plugin/skills/SKILL.md",
"digest": "a0d8a329ab9468f5"
},
{
"name": "ai-chat",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "AI Chat 测试与管理。发送消息测试 AI Chat 工具调用链路,管理工具开关和 Provider 配置,支持 local/staging 环境切换。",
"description_len": 78,
"path": "skills-dev/ai-chat-plugin/skills/SKILL.md",
"digest": "97ce03993394605c"
},
{
"name": "ai-proj-cicd-release",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "Execute and audit the AI-Proj service CI/CD flow across Gitea gates, immutable image builds, staging verification, approved production release, rollback, and evidence capture. Use for AI-Proj CI status, release PRs, staging or production deployments, failed-release diagnosis, deployed commit/schema verification, and delivery-chain repair. Do not use for unrelated repositories or macOS application packaging.",
"description_len": 410,
"path": "skills-dev/ai-proj-cicd-release-plugin/skills/SKILL.md",
"digest": "49ef1b6865c2f1b3"
},
{
"name": "ai-proj-macos-release",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "Build, sign, notarize, publish, and verify the AI-Proj macOS Apple Silicon package through the repository's release chain. Use when asked to release, republish, update, or repair the downloadable macOS application, including Gatekeeper failures and download-manifest updates. Do not use for service deployments or unrelated applications.",
"description_len": 337,
"path": "skills-dev/ai-proj-macos-release-plugin/skills/SKILL.md",
"digest": "6f2496b941706137"
},
{
"name": "db-migration",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "数据库变更方案插件。Migration 脚本生成、数据迁移策略、回滚方案。挂载在 design 阶段,涉及数据库变更时由 req-design 推荐激活。",
"description_len": 77,
"path": "skills-dev/db-migration-plugin/skills/SKILL.md",
"digest": "f8d6ebbddbbf7a71"
},
{
"name": "defect-analysis",
"category": "dev",
"version": "1.1.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "系统性设计缺陷分析。对需求方案/代码架构进行多维度检查,发现隐藏的技术风险和设计漏洞。当用户提到缺陷检查、方案审查、设计审计时自动激活。",
"description_len": 68,
"path": "skills-dev/defect-analysis-plugin/skills/SKILL.md",
"digest": "23dfafda92d0c622"
},
{
"name": "deploy-rollback",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "回滚方案插件。部署后发现问题时的回滚策略和执行步骤。挂载在 deploy 阶段,部署出问题时激活。",
"description_len": 49,
"path": "skills-dev/deploy-rollback-plugin/skills/SKILL.md",
"digest": "75ebf66a3f74195a"
},
{
"name": "dev-android",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "Android 开发插件。Kotlin + Jetpack Compose + Hilt 依赖注入。当涉及 Android 开发任务时按需加载。",
"description_len": 72,
"path": "skills-dev/dev-android-plugin/skills/SKILL.md",
"digest": "fb058d1059b56cdd"
},
{
"name": "dev-arch",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "软件架构设计技能。用于系统设计、技术选型、架构评审、设计文档编写。当用户提到架构设计、系统设计、技术方案、API 设计相关任务时自动激活。",
"description_len": 69,
"path": "skills-dev/dev-arch-plugin/skills/SKILL.md",
"digest": "c9a419c83a307a11"
},
{
"name": "dev-cicd",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "CI/CD 流水线设计、优化与排查。适配 Gitea Actions + Go/Swift/Next.js/Docker 栈。当用户提到 CI、CD、流水线、pipeline、workflow、构建失败、runner 相关任务时自动激活。",
"description_len": 119,
"path": "skills-dev/dev-cicd-plugin/skills/SKILL.md",
"digest": "a763f0f140516411"
},
{
"name": "dev-coding",
"category": "dev",
"version": "2.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "软件编码开发技能。用于代码编写、功能实现、重构优化。集成 ai-proj CLI 进行任务管理和进度跟踪。核心支持 Go 后端 + Vue/React 前端开发。",
"description_len": 81,
"path": "skills-dev/dev-coding-plugin/skills/SKILL.md",
"digest": "1b754e668965132f"
},
{
"name": "dev-commit",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "智能 git commit — 分支保护 + 自动建功能分支 + Conventional Commits 生成。当用户说\"提交代码\"、\"commit\"、\"/commit\"、\"保存修改\"时自动激活。",
"description_len": 99,
"path": "skills-dev/dev-commit-plugin/skills/SKILL.md",
"digest": "1560658c4a30df45"
},
{
"name": "dev-deploy",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "应用部署技能。支持 iOS TestFlight、Docker 容器等多平台部署。当用户提到部署、发布、TestFlight、上架、build、archive 相关任务时自动激活。",
"description_len": 90,
"path": "skills-dev/dev-deploy-plugin/skills/SKILL.md",
"digest": "00873ab922fb1595"
},
{
"name": "dev-integration",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "前后端联调技能。API 契约验证、接口对接、联调报告生成。对应 req 流程 integration 阶段。纯后端需求自动跳过。",
"description_len": 64,
"path": "skills-dev/dev-integration-plugin/skills/SKILL.md",
"digest": "eff6be8eb57b7fef"
},
{
"name": "dev-ios",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "iOS 开发插件。Swift/SwiftUI + MVVM 架构,TestFlight 部署。当涉及 iOS 开发任务时按需加载。",
"description_len": 65,
"path": "skills-dev/dev-ios-plugin/skills/SKILL.md",
"digest": "44499e31f1abd5e2"
},
{
"name": "dev-mcp",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "MCP Bridge 开发插件。TypeScript MCP 服务开发,Token 管理,HTTP 客户端模式。当涉及 mcp-task-bridge 开发时按需加载。",
"description_len": 84,
"path": "skills-dev/dev-mcp-plugin/skills/SKILL.md",
"digest": "83d5912212fcfa4a"
},
{
"name": "dev-pda",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "PDA 应用开发插件。Android 原生 + 扫码枪集成 + 离线优先。当涉及 PDA/手持终端开发时按需加载。",
"description_len": 57,
"path": "skills-dev/dev-pda-plugin/skills/SKILL.md",
"digest": "2524f2ecd4f2a834"
},
{
"name": "dev-review",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "代码评审技能。六视角对抗性扫描法(含 Karpathy Scope 审计),用于 PR 代码审查、安全评审、质量检查。当执行 /req cr 或独立 PR review 时自动激活。",
"description_len": 91,
"path": "skills-dev/dev-review-plugin/skills/SKILL.md",
"digest": "a8a1ec79b85e3227"
},
{
"name": "dev-scaffold",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "模块脚手架插件。新建模块时自动生成分层代码骨架。挂载在 dev 阶段,新建模块时激活。",
"description_len": 43,
"path": "skills-dev/dev-scaffold-plugin/skills/SKILL.md",
"digest": "4044787b1e468302"
},
{
"name": "dev-test",
"category": "dev",
"version": "2.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "软件测试技能。用于单元测试、集成测试、E2E测试、测试用例设计。支持 Go、Vue、React、iOS、Android 等多平台测试。",
"description_len": 67,
"path": "skills-dev/dev-test-plugin/skills/dev-test/SKILL.md",
"digest": "a03536a478eabe6c"
},
{
"name": "executing-plans",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "Use when you have a written implementation plan to execute in a separate session with review checkpoints",
"description_len": 104,
"path": "skills-dev/executing-plans-plugin/skills/SKILL.md",
"digest": "8991a50091af83a4"
},
{
"name": "finishing-a-development-branch",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "Use when implementation is complete and all tests pass - verifies and creates PR",
"description_len": 80,
"path": "skills-dev/finishing-branch-plugin/skills/SKILL.md",
"digest": "1102047ccc060e60"
},
{
"name": "frontend-design",
"category": "dev",
"version": "1.0.1",
"status": "promoted",
"invocation": "model-invoked",
"description": "Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.",
"description_len": 234,
"path": "skills-dev/frontend-design-plugin/skills/SKILL.md",
"digest": "6bc30a1a562bae8c"
},
{
"name": "karpathy-guidelines",
"category": "dev",
"version": "1.0.1",
"status": "promoted",
"invocation": "model-invoked",
"description": "Karpathy 四原则编码行为守则。减少 LLM 常见编码错误:过度实现、静默假设、顺手重构、无验证标准。在任意编码场景激活。",
"description_len": 64,
"path": "skills-dev/karpathy-guidelines-plugin/skills/SKILL.md",
"digest": "a68f347031110d6a"
},
{
"name": "pull-request",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "Use when starting new development tasks, creating pull requests, reviewing code, or managing PR feedback cycles on Gitea. Triggers on /pr commands or when user mentions PR, pull request, code review, or branch creation.",
"description_len": 219,
"path": "skills-dev/pull-request-plugin/skills/SKILL.md",
"digest": "40dac0d290782bb5"
},
{
"name": "review-checklist",
"category": "dev",
"version": "1.1.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "项目级代码评审检查清单。按项目积累特定检查项,挂载在 dev-review 下自动加载。每次 CR 时触发。",
"description_len": 54,
"path": "skills-dev/review-checklist-plugin/skills/SKILL.md",
"digest": "5bae13b6a8d92650"
},
{
"name": "slark-cicd",
"category": "dev",
"version": "1.1.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "Slark 仓库 staging、生产和 Desktop 安装包的端到端 CI/CD 可执行 runbook。覆盖本地预推快检、PR 与内网 ci/internal-gate 门禁、合并 origin/main、生产前强制 staging 验收、审批式生产发布,以及在 m5max 构建签名、公证并上传 macOS/Windows Desktop 包到 OSS。当用户要在 slark(qiudl/qiu-slark)里发布/上线、部署到生产或 staging、发布 Desktop 安装包、盯 CI/合并 PR、复现或验证运行时行为、或排查发布链/推送路由问题时使用。",
"description_len": 285,
"path": "skills-dev/slark-cicd-plugin/skills/SKILL.md",
"digest": "2919c19d8a38dd23"
},
{
"name": "slark-dsh-cicd",
"category": "dev",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "DSH 插件包与 Slark 宿主补丁的发布 runbook。覆盖 npm run pack 双 tgz 双资产、无上游写权限时的 fork 发布、干净单提交与树一致性 gate、改指向后必须重新打包、draft→publish 节奏、GitHub HTTPS/SSH 与 fetch 卡死处置、发布后 SHA 核对、app.asar 完整性约束、ai-proj 发布状态对齐。当用户要发布或升级 DSH 插件(dsh-worktable 等)、发布/更新 Slark 宿主补丁、push 或下载 GitHub 失败、插件「检查更新」看不到新版本、需要 fork 发布、或排查 asar 完整性/签名问题时使用。",
"description_len": 306,
"path": "skills-dev/slark-dsh-cicd-plugin/skills/SKILL.md",
"digest": "44a1322e15d42845"
},
{
"name": "data-excel",
"category": "integration",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "Excel 数据处理与 BI 集成。通过自然语言操作 Excel 文件的读取、编辑、转换,并支持导入到 BI 系统(Metabase)进行可视化分析。当用户提到 Excel、表格处理、数据导入、BI 分析相关任务时自动激活。",
"description_len": 112,
"path": "skills-integration/data-excel-plugin/skills/SKILL.md",
"digest": "8dc4be8f88cfd866"
},
{
"name": "doubao-voice",
"category": "integration",
"version": "1.0.1",
"status": "promoted",
"invocation": "user-invoked",
"description": "豆包语音API调用。支持语音合成(TTS)和唱歌。当用户提到语音合成、文字转语音、唱歌、豆包语音相关任务时自动激活。",
"description_len": 58,
"path": "skills-integration/doubao-voice-plugin/skills/SKILL.md",
"digest": "7dc73d3b97e61fd2"
},
{
"name": "feishu-bitable",
"category": "integration",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "飞书多维表格操作。用于记录增删改查、批量操作、筛选排序、数据同步。当需要操作飞书多维表格时使用。",
"description_len": 48,
"path": "skills-integration/feishu-bitable-plugin/skills/SKILL.md",
"digest": "3bf37533007365a3"
},
{
"name": "feishu-docx",
"category": "integration",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "飞书云文档操作。用于创建、编辑云文档,插入内容块,会议纪要生成。当需要操作飞书云文档时使用。",
"description_len": 46,
"path": "skills-integration/feishu-docx-plugin/skills/SKILL.md",
"digest": "49d097bfa2c283ab"
},
{
"name": "feishu",
"category": "integration",
"version": "1.1.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "飞书文档与多维表格操作入口。当用户提到飞书、云文档、多维表格、Bitable 相关任务时自动激活。",
"description_len": 49,
"path": "skills-integration/feishu-plugin/skills/SKILL.md",
"digest": "973c6ac22104ee38"
},
{
"name": "siyuan",
"category": "integration",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "思源笔记 API 集成。通过自然语言创建、编辑、搜索笔记,管理笔记本和文档树。当用户提到思源笔记、SiYuan、笔记管理、知识库相关任务时自动激活。",
"description_len": 74,
"path": "skills-integration/siyuan-plugin/skills/SKILL.md",
"digest": "55f6175d81e7b524"
},
{
"name": "siyuan-to-feishu",
"category": "integration",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "将思源笔记导出为 PDF 并发送到飞书群。当用户提到\"发送笔记\"、\"导出PDF发飞书\"、\"/siyuan send\"、\"分享到飞书\"相关任务时自动激活。",
"description_len": 76,
"path": "skills-integration/siyuan-to-feishu-plugin/skills/SKILL.md",
"digest": "998dace910c1eb7a"
},
{
"name": "wecom",
"category": "integration",
"version": "1.0.0",
"status": "promoted",
"invocation": "user-invoked",
"description": "企业微信集成。通过自然语言发送消息、管理群机器人、操作审批流程、管理通讯录。当用户提到企业微信、微信工作、群机器人、企业号、wecom相关任务时自动激活。",
"description_len": 77,
"path": "skills-integration/wecom-plugin/skills/SKILL.md",
"digest": "cec289b67805389d"
},
{
"name": "req-audit",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "部署后审计。运行时日志检查 + 静态缺陷分析 + 设计偏移检测。可独立调用或由 /req done 自动触发。",
"description_len": 55,
"path": "skills-req/req-audit-plugin/skills/SKILL.md",
"digest": "ff2e6197bbb059c6"
},
{
"name": "req-compare",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "对比式需求分析插件。系统平移、竞品借鉴、版本升级时使用参考对象对比法编写 PRD。挂载在 analysis 阶段,需要对比分析时由 req-prd 推荐激活。",
"description_len": 79,
"path": "skills-req/req-compare-plugin/skills/SKILL.md",
"digest": "3428e3f37ef9e9e8"
},
{
"name": "req-design",
"category": "req",
"version": "2.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "需求开发设计技能。用于 PRD 到开发设计的转换:API 契约定义、数据模型变更方案、变更文件清单、开发任务拆分、技术风险评估。当用户执行 /req doc 或需要编写开发设计文档时自动激活。",
"description_len": 96,
"path": "skills-req/req-design-plugin/skills/SKILL.md",
"digest": "8ec85838666b5cc5"
},
{
"name": "req-dev",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "需求开发计划编写技能。用于 PRD 到代码转换、代码库分析、开发任务拆分、技术方案设计。当用户执行 /req doc 或需要编写开发计划时自动激活。",
"description_len": 74,
"path": "skills-req/req-dev-plugin/skills/SKILL.md",
"digest": "3b0dd9396df3c236"
},
{
"name": "req-lookback",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "回归测试。部署后自动验证变更涉及的功能是否正常。可独立调用或由 /req done 自动触发。",
"description_len": 47,
"path": "skills-req/req-lookback-plugin/skills/SKILL.md",
"digest": "cc6bff614a8f7bf4"
},
{
"name": "req",
"category": "req",
"version": "2.1.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "需求工作流管理。用于 /req 命令使用、需求全生命周期管理(创建→PRD→评审→开发→测试→部署→归档)。当用户提到需求管理、/req 命令、REQ-XXX 相关任务时自动激活。",
"description_len": 90,
"path": "skills-req/req-plugin/skills/SKILL.md",
"digest": "bdb1fab4d3d8c3d2"
},
{
"name": "req-prd",
"category": "req",
"version": "2.3.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "产品设计与需求管理。用于 PRD、需求分析、用户故事、功能设计和原型规划,并将正式需求文档双写到本地仓库与 ai-proj Task Document。",
"description_len": 76,
"path": "skills-req/req-prd-plugin/skills/SKILL.md",
"digest": "0e5b16fcef3105bd"
},
{
"name": "req-prototype",
"category": "req",
"version": "2.2.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "原型生成与关联。生成可交互 HTML、上传到 ai-proj OSS 并关联 Requirement/PRD iframe,也支持 Stitch AI 视觉探索。",
"description_len": 81,
"path": "skills-req/req-prototype-plugin/skills/SKILL.md",
"digest": "7e362f4f895fb50a"
},
{
"name": "req-research",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "需求调研插件。代码审计、数据库分析、现有功能调研、技术可行性评估。挂载在 analysis 阶段,需要深度调研时由 req-prd 推荐激活。",
"description_len": 71,
"path": "skills-req/req-research-plugin/skills/SKILL.md",
"digest": "a94924f53bd4c80e"
},
{
"name": "req-retro",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "复盘总结。自动采集数据、计算质量评分、跨需求模式识别、技能自动进化。可独立调用或由 /req done 自动触发。",
"description_len": 57,
"path": "skills-req/req-retro-plugin/skills/SKILL.md",
"digest": "636b7099d85e9549"
},
{
"name": "req-review",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "PRD 评审方法论。用于需求评审、PRD 文档审查、评审意见编写。当执行 /req review 或需要评审 PRD 文档时使用。",
"description_len": 65,
"path": "skills-req/req-review-plugin/skills/SKILL.md",
"digest": "cd1a5181d72f35f4"
},
{
"name": "req-test-gate",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "测试与质量门禁制度。覆盖需求级测试(Gates 1-5)、部署级验证(Deploy Gates)、持续回归(Regression)、Harness Engineering 工程约束方法论(Ratchet、约定建立、门禁层级)。当用户提到质量门禁、架构约束、约定检查、ratchet、harness 相关任务时自动激活。",
"description_len": 159,
"path": "skills-req/req-test-gate-plugin/skills/SKILL.md",
"digest": "0eba060fa456885d"
},
{
"name": "req-workflow",
"category": "req",
"version": "1.0.0",
"status": "promoted",
"invocation": "model-invoked",
"description": "需求完整工作流。用于从创建到归档的完整流程、Hook 自动同步、测试环境流程。当需要了解需求完整生命周期或同步策略时使用。",
"description_len": 61,
"path": "skills-req/req-workflow-plugin/skills/SKILL.md",
"digest": "87499da3817d162d"
},
{
"name": "verification-before-completion",
"category": "req",
"version": "0.1.0",
"status": "deprecated",
"invocation": "model-invoked",
"description": "汇报「完成/修好/通过」或关闭任务、提交 PR、宣布 REQ 完成之前,必须先运行验证命令并附证据;没有证据不得声称完成。当准备说完成、关闭任务、或汇报交付前使用。",
"description_len": 82,
"path": "skills-req/verification-before-completion-plugin/skills/SKILL.md",
"digest": "7c23649f4a0a8798"
}
]
}
+38
View File
@@ -0,0 +1,38 @@
# 技能路由表(人读)
> 由原 `ai-proj-helper-entry` 技能降级而来:内容属于「索引」而不是「规则」,做成文档即可,不占技能目录、不用维护技能生命周期。
## 交付终点(强制)
开发任务交付终点是:需求按 REQ 流程推进到具备发布条件并完成上线(`delivery_stage=released` + PDV 验收通过)。
写代码、过单测、提 PR、合并都只是过程节点;任务 `completed` ≠ 需求完成。
## 主流程
讨论(`req`) → PRD(`req-prd`) → 评审(`req-review`) → 设计(`req-design`) → 开发(`dev-coding`/`karpathy-guidelines`) → 测试(`dev-test`+`req-test-gate`) → 代码评审(`dev-review`) → 发布(`slark-cicd`/`slark-dsh-cicd`/`publish`) → PDV 验收 → released
## 按任务选技能
| 任务 | 技能 |
| --- | --- |
| 讨论 / 调研 / 对比 | `req`、`req-research`、`req-compare` |
| PRD / 原型 | `req-prd`、`req-prototype` |
| PRD 评审 | `req-review` |
| 设计 / 拆任务 | `req-design`、`dev-arch`、`db-migration` |
| 编码 | `dev-coding`、`karpathy-guidelines` |
| 测试 | `dev-test`、`req-test-gate` |
| 代码评审 | `dev-review`、`review-checklist` |
| 发布(Slark 仓库/Desktop) | `slark-cicd` |
| 发布(DSH 插件/宿主补丁) | `slark-dsh-cicd` |
| 发布(ai-proj 服务 / macOS 包) | `ai-proj-cicd-release`、`ai-proj-macos-release` |
| 回滚 | `deploy-rollback` |
| 部署后审计 / 回归 | `req-audit`、`req-lookback` |
| 复盘 | `req-retro` |
| 项目管理 | `project-management`、`pm-risk`、`pm-ask` |
| 建/改技能 | `skill-creator` |
## 红线
- 不得自审批;不得绕过门禁(测试 Gate / 发布 Gate / 归档 Gate)
- 不得把「某步骤完成」当结束;不得无证据声称完成
- 不得把凭据/内网地址/绝对路径写进技能或文档
+8
View File
@@ -96,6 +96,14 @@ def scan_plugins(directory, source_prefix, disabled):
with open(manifest_path) as f:
manifest = json.load(f)
# Lifecycle buckets: only promoted plugins ship in the public
# marketplace. beta/deprecated must be installed with --include-beta.
import os
status = manifest.get("status", "promoted")
if status in ("beta", "deprecated") and os.environ.get("ALLOW_BETA") != "1":
print(f" ⊘ {plugin_name} (status={status}, not shipped)")
continue
category, keywords = get_category_and_keywords(plugin_name)
plugins.append({
+94 -4
View File
@@ -5,7 +5,11 @@
# ./install-skills.sh [options]
#
# Options:
# --agent <agent> Install target: codex (default) or claude
# --agent <agent> Install target: codex (default), dsh, or claude
# --link Symlink skills from the repo instead of copying (dev machines)
# --audit Show installed vs repo versions for the selected target
# --include-beta Also install skills whose plugin.json status=beta
# --no-validate Skip scripts/validate-skills.py before installing
# --dry-run Preview changes without writing anything
# --category <cat> Only install plugins in dir_category=<cat>
# Valid values: biz, core, dev, integration, personal, req
@@ -30,6 +34,10 @@ FORCE=false
CLEANUP=false
LIST_ONLY=false
INSTALL_ACTION=false
LINK_MODE=false
AUDIT_ONLY=false
INCLUDE_BETA=false
NO_VALIDATE=false
# ── Colour helpers ─────────────────────────────────────────────────────────────
GREEN='\033[0;32m'
@@ -48,9 +56,13 @@ dry() { echo -e "${YELLOW}[dry]${RESET} $*"; }
while [[ $# -gt 0 ]]; do
case "$1" in
--agent)
[[ $# -ge 2 ]] || { error "--agent requires codex or claude"; exit 1; }
[[ $# -ge 2 ]] || { error "--agent requires codex, dsh or claude"; exit 1; }
AGENT_TARGET="$2"; shift ;;
--dry-run) DRY_RUN=true ;;
--link) LINK_MODE=true ;;
--audit) AUDIT_ONLY=true ;;
--include-beta) INCLUDE_BETA=true ;;
--no-validate) NO_VALIDATE=true ;;
--force) FORCE=true ;;
--cleanup) CLEANUP=true ;;
--list) LIST_ONLY=true ;;
@@ -77,13 +89,21 @@ case "$AGENT_TARGET" in
SKILLS_DIR="${AI_PROJ_HELPER_SKILLS_DIR:-${HOME}/.agents/skills}"
STATE_FILE="${AI_PROJ_HELPER_STATE_FILE:-${HOME}/.agents/.ai-proj-helper-installed-skills.json}"
;;
dsh)
if [[ -z "${DSH_HOME:-}" ]]; then
error "--agent dsh requires DSH_HOME (or set AI_PROJ_HELPER_SKILLS_DIR explicitly)"
exit 1
fi
SKILLS_DIR="${AI_PROJ_HELPER_SKILLS_DIR:-${DSH_HOME}/skills}"
STATE_FILE="${AI_PROJ_HELPER_STATE_FILE:-${DSH_HOME}/.ai-proj-helper-installed-skills.json}"
;;
claude)
SKILLS_DIR="${AI_PROJ_HELPER_SKILLS_DIR:-${HOME}/.claude/skills}"
COMMANDS_DIR="${AI_PROJ_HELPER_COMMANDS_DIR:-${HOME}/.claude/commands}"
STATE_FILE="${AI_PROJ_HELPER_STATE_FILE:-${HOME}/.claude/.installed-skills.json}"
;;
*)
error "Unsupported agent: $AGENT_TARGET (expected codex or claude)"
error "Unsupported agent: $AGENT_TARGET (expected codex, dsh or claude)"
exit 1
;;
esac
@@ -281,8 +301,19 @@ install_plugin() {
effective_install_type="skill"
fi
local status
status="$(read_field "$json_path" status)"
status="${status:-promoted}"
if [[ "$LIST_ONLY" == true ]]; then
echo " [$dir_category] $effective_install_type:$install_name v$version"
echo " [$dir_category] $status $effective_install_type:$install_name v$version"
return
fi
if [[ "$status" == "deprecated" ]]; then
return
fi
if [[ "$status" == "beta" && "$INCLUDE_BETA" != true ]]; then
return
fi
@@ -305,6 +336,21 @@ install_plugin() {
return
fi
# Dev machines may symlink instead of copying: repository edits apply at once.
if [[ "$LINK_MODE" == true && "$effective_install_type" != "command" ]]; then
if [[ "$DRY_RUN" == true ]]; then
dry "$install_name → symlink $target_path → $src_dir"
else
mkdir -p "$SKILLS_DIR"
rm -rf "$target_path"
ln -sfn "$src_dir" "$target_path"
state_set "$install_name" "$version" "symlink" "$(content_digest "$src_dir")"
ok "$install_name → symlink (v$version)"
fi
INSTALL_ACTION=true
return
fi
# A recorded content digest distinguishes repository updates from user edits.
# Legacy state is adopted automatically only when the target is missing or
# already identical to the repository source.
@@ -415,6 +461,38 @@ cleanup_removed() {
done < <(state_all_names)
}
# ── Audit ──────────────────────────────────────────────────────────────────────
audit_target() {
python3 - "$REPO_DIR" "$STATE_FILE" "$AGENT_TARGET" "$SKILLS_DIR" <<'PYEOF'
import json, sys, pathlib
repo, state_file, agent, skills_dir = sys.argv[1:5]
root = pathlib.Path(repo)
state = {}
if pathlib.Path(state_file).is_file():
try: state = json.loads(pathlib.Path(state_file).read_text())
except Exception: state = {}
rows = []
for pj in sorted(root.glob('skills-*/*-plugin/.claude-plugin/plugin.json')):
try: meta = json.loads(pj.read_text())
except Exception: continue
name = meta.get('install_name')
if not name: continue
status = meta.get('status', 'promoted')
want = meta.get('version', '')
got = state.get(name, {}).get('version', '')
itype = state.get(name, {}).get('install_type', '')
drift = '' if got == want else ('missing' if not got else 'stale')
rows.append((name, status, want, got or '-', itype or '-', drift))
drift_rows = [r for r in rows if r[5]]
print(f'audit agent={agent} skills_dir={skills_dir}')
print(f'{"name":34} {"status":10} {"repo":8} {"installed":9} {"mode":8} drift')
for r in rows:
print(f'{r[0]:34} {r[1]:10} {r[2]:8} {r[3]:9} {r[4]:8} {r[5]}')
print(f'\n{len(rows)} 个技能,{len(drift_rows)} 个漂移(未安装/版本落后)')
raise SystemExit(1 if drift_rows else 0)
PYEOF
}
# ── Main ───────────────────────────────────────────────────────────────────────
main() {
if [[ "$LIST_ONLY" == true ]]; then
@@ -429,7 +507,19 @@ main() {
return
fi
if [[ "$AUDIT_ONLY" == true ]]; then
audit_target
return
fi
info "Installing skills for $AGENT_TARGET from: $REPO_DIR"
if [[ "$NO_VALIDATE" != true && -f "$REPO_DIR/scripts/validate-skills.py" ]]; then
if ! python3 "$REPO_DIR/scripts/validate-skills.py" >/tmp/ai-proj-helper-validate.log 2>&1; then
error "validate-skills.py 未通过,修复后再装(或加 --no-validate 跳过)"
tail -20 /tmp/ai-proj-helper-validate.log >&2 || true
exit 1
fi
fi
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no files will be written"
[[ -n "$CATEGORY_FILTER" ]] && info "Category filter: $CATEGORY_FILTER"
+106
View File
@@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""Generate catalog.json — the reviewable list of every skill in this repo.
Usage: python3 scripts/generate-catalog.py [--check]
(default) write catalog.json
--check fail if catalog.json is out of date (for CI)
"""
from __future__ import annotations
import hashlib
import json
import re
import sys
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
CATALOG = ROOT / "catalog.json"
def frontmatter(text: str) -> dict:
if not text.startswith("---"):
return {}
end = text.find("\n---", 3)
if end == -1:
return {}
data: dict = {}
metadata: dict = {}
key = None
for line in text[3:end].splitlines():
if not line.strip():
continue
m = re.match(r"^([A-Za-z0-9_-]+):\s*(.*)$", line)
if m:
key = m.group(1)
data[key] = m.group(2).strip().strip('"').strip("'")
continue
m = re.match(r"^\s+([A-Za-z0-9_-]+):\s*(.*)$", line)
if m and key == "metadata":
metadata[m.group(1)] = m.group(2).strip().strip('"').strip("'")
if metadata:
data["metadata"] = metadata
return data
def build() -> dict:
skills = []
for plugin_json in sorted(ROOT.glob("skills-*/*-plugin/.claude-plugin/plugin.json")):
plugin_dir = plugin_json.parent.parent
meta = json.loads(plugin_json.read_text(encoding="utf-8"))
skill_files = sorted((plugin_dir / "skills").rglob("SKILL.md"))
if not skill_files:
continue
skill_md = skill_files[0]
fm = frontmatter(skill_md.read_text(encoding="utf-8", errors="replace"))
desc = fm.get("description", "")
body = skill_md.read_text(encoding="utf-8", errors="replace")
skills.append(
{
"name": meta.get("install_name") or fm.get("name"),
"category": meta.get("dir_category"),
"version": meta.get("version"),
"status": meta.get("status", "promoted"),
"invocation": (fm.get("metadata") or {}).get("invocation", "model-invoked"),
"description": desc,
"description_len": len(desc),
"path": str(skill_md.relative_to(ROOT)),
"digest": hashlib.sha256(body.encode("utf-8")).hexdigest()[:16],
}
)
counts: dict = {}
for skill in skills:
key = f"{skill['status']}/{skill['invocation']}"
counts[key] = counts.get(key, 0) + 1
return {
"repo": "ai-proj-helper",
"generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"total": len(skills),
"counts": counts,
"skills": skills,
}
def main() -> int:
catalog = build()
text = json.dumps(catalog, ensure_ascii=False, indent=2) + "\n"
if "--check" in sys.argv:
if not CATALOG.is_file():
print("catalog.json 不存在,请运行 python3 scripts/generate-catalog.py")
return 1
current = json.loads(CATALOG.read_text(encoding="utf-8"))
current.pop("generated_at", None)
fresh = dict(catalog)
fresh.pop("generated_at", None)
if current != fresh:
print("catalog.json 已过期,请重新生成")
return 1
print("catalog.json 是最新的")
return 0
CATALOG.write_text(text, encoding="utf-8")
print(f"写入 {CATALOG.relative_to(ROOT)}:{catalog['total']} 个技能 {catalog['counts']}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+5
View File
@@ -0,0 +1,5 @@
# 安全扫描允许清单(人工确认过的误报)
# 格式:<路径子串>::<匹配文本中的特征串>
# 例:某技能文档把危险命令当作“禁止清单”引用,而非真的要执行。
skills-dev/slark-cicd-plugin::NEVER_AUTO
skills-dev/slark-cicd-plugin::destructive
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
# scan-skill.sh — security scan before a skill enters the team library.
#
# Usage: ./scripts/scan-skill.sh [plugin-dir ...]
# With no arguments scans every skills-*/*-plugin directory.
# Exit 0 = clean (warnings allowed), 1 = high severity finding.
set -uo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
HIGH=0
WARN=0
# High severity: destructive, remote-code-execution, secret material.
HIGH_PATTERNS=(
'rm[[:space:]]+-[a-zA-Z]*r[a-zA-Z]*[[:space:]]+/($|[[:space:]])'
'curl[^|]*\|[[:space:]]*(ba|z)?sh'
'wget[^|]*\|[[:space:]]*(ba|z)?sh'
'chmod[[:space:]]+777'
'BEGIN (RSA|OPENSSH|EC|DSA) PRIVATE KEY'
'sk-[A-Za-z0-9]{16,}'
'AKIA[0-9A-Z]{16}'
'ghp_[A-Za-z0-9]{20,}'
)
# Warnings: machine-specific paths, plain http endpoints.
WARN_PATTERNS=(
'/Users/[A-Za-z0-9._-]+/'
'http://[A-Za-z0-9.-]+'
'password[[:space:]]*=[[:space:]]*[^$]'
)
targets=("$@")
if [[ ${#targets[@]} -eq 0 ]]; then
while IFS= read -r dir; do
targets+=("$(dirname "$(dirname "$dir")")")
done < <(find "$ROOT" -path "*/skills-*/*-plugin/.claude-plugin/plugin.json" | sort)
fi
ALLOWLIST="$ROOT/scripts/scan-allowlist.txt"
is_allowlisted() {
# is_allowlisted <abs_path> <matched_line>
local path="$1" line="$2" entry sub needle
[[ -f "$ALLOWLIST" ]] || return 1
while IFS= read -r entry; do
[[ -z "$entry" || "$entry" == \#* ]] && continue
sub="${entry%%::*}"
needle="${entry#*::}"
if [[ "$path" == *"$sub"* && "$line" == *"$needle"* ]]; then
return 0
fi
done < "$ALLOWLIST"
return 1
}
for dir in "${targets[@]}"; do
rel="${dir#"$ROOT"/}"
for pattern in "${HIGH_PATTERNS[@]}"; do
while IFS= read -r hit; do
abs="${hit%%:*}"
detail="${hit#*:}"
if is_allowlisted "$abs" "$hit"; then
echo "[allow] $rel: $detail"
continue
fi
echo "[HIGH] $rel: $detail"
HIGH=$((HIGH + 1))
done < <(grep -rnE --include='*.md' --include='*.sh' --include='*.py' --include='*.js' --include='*.ts' --include='*.json' -- "$pattern" "$dir" 2>/dev/null | cut -c1-200)
done
for pattern in "${WARN_PATTERNS[@]}"; do
while IFS= read -r hit; do
echo "[warn] $rel: ${hit%%:*}:${hit#*:}"
WARN=$((WARN + 1))
done < <(grep -rnE --include='*.md' --include='*.sh' --include='*.py' --include='*.js' --include='*.ts' -- "$pattern" "$dir" 2>/dev/null | cut -c1-200)
done
done
echo ""
echo "扫描完成:${#targets[@]} 个插件,$HIGH 个高危,$WARN 个警告"
if [[ "$HIGH" -gt 0 ]]; then
echo "存在高危项,禁止入库,除非逐条确认并记录原因。"
exit 1
fi
exit 0
+161
View File
@@ -0,0 +1,161 @@
#!/usr/bin/env python3
"""Validate plugins and SKILL.md files against the Agent Skills spec + team rules.
Usage: python3 scripts/validate-skills.py [--strict]
Exit 0 = pass, 1 = errors found.
"""
from __future__ import annotations
import json
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
ALLOWED_FRONTMATTER = {
"name", "description", "license", "compatibility", "metadata",
"allowed-tools", "disable-model-invocation", "version",
}
NAME_RE = re.compile(r"^[a-z0-9][a-z0-9-]{0,63}$")
BODY_MAX_BYTES = 20 * 1024
DESC_MIN, DESC_MAX = 30, 1024
STATUSES = {"promoted", "beta", "deprecated"}
INVOCATIONS = {"model-invoked", "user-invoked"}
REQUIRED_PLUGIN_FIELDS = ("install_name", "install_type", "dir_category", "version")
errors: list[str] = []
warnings: list[str] = []
def parse_frontmatter(text: str):
"""Return (frontmatter dict, body text). Supports one level of nesting."""
if not text.startswith("---"):
return {}, text
end = text.find("\n---", 3)
if end == -1:
return {}, text
raw, body = text[3:end], text[end + 4:]
data: dict = {}
metadata: dict = {}
key = None
for line in raw.splitlines():
if not line.strip():
continue
m = re.match(r"^([A-Za-z0-9_-]+):\s*(.*)$", line)
if m:
key = m.group(1)
data[key] = m.group(2).strip().strip('"').strip("'")
continue
m = re.match(r"^\s+([A-Za-z0-9_-]+):\s*(.*)$", line)
if m and key == "metadata":
metadata[m.group(1)] = m.group(2).strip().strip('"').strip("'")
elif key:
data[key] = (data.get(key, "") + " " + line.strip()).strip()
if metadata:
data["metadata"] = metadata
return data, body
def check_plugin(plugin_json: Path):
plugin_dir = plugin_json.parent.parent
rel = plugin_dir.relative_to(ROOT)
try:
meta = json.loads(plugin_json.read_text(encoding="utf-8"))
except Exception as exc: # noqa: BLE001
errors.append(f"{rel}: plugin.json 解析失败: {exc}")
return
for field in REQUIRED_PLUGIN_FIELDS:
if not meta.get(field):
errors.append(f"{rel}: plugin.json 缺少 {field}")
status = meta.get("status", "")
if status and status not in STATUSES:
errors.append(f"{rel}: status 非法 {status!r}(应为 {sorted(STATUSES)})")
install_name = meta.get("install_name", "")
if install_name and not NAME_RE.match(install_name):
errors.append(f"{rel}: install_name 不合规 {install_name!r}")
skills_dir = plugin_dir / "skills"
skill_files = sorted(skills_dir.rglob("SKILL.md")) if skills_dir.is_dir() else []
if not skill_files:
errors.append(f"{rel}: 没有找到 skills/**/SKILL.md")
return
for skill_md in skill_files:
check_skill(rel, skill_md, meta)
def check_skill(rel: Path, skill_md: Path, meta: dict):
text = skill_md.read_text(encoding="utf-8", errors="replace")
fm, body = parse_frontmatter(text)
where = f"{rel}/{skill_md.name}"
name = fm.get("name", "")
if not name:
errors.append(f"{where}: frontmatter 缺少 name")
elif not NAME_RE.match(name):
errors.append(f"{where}: name 不合规 {name!r}(小写字母/数字/连字符,≤64)")
desc = fm.get("description", "")
if not desc:
errors.append(f"{where}: frontmatter 缺少 description")
elif not (DESC_MIN <= len(desc) <= DESC_MAX):
warnings.append(f"{where}: description 长度 {len(desc)},建议 {DESC_MIN}-{DESC_MAX}(决定是否被触发)")
for key in fm:
if key == "metadata":
continue
if key not in ALLOWED_FRONTMATTER:
warnings.append(f"{where}: 非标准 frontmatter 字段 {key!r},建议移入 metadata")
body_bytes = len(body.encode("utf-8"))
if body_bytes > BODY_MAX_BYTES:
warnings.append(f"{where}: 正文 {body_bytes} 字节,超过 20KB 预算,建议拆 references/")
metadata = fm.get("metadata") or {}
invocation = metadata.get("invocation", "")
if invocation and invocation not in INVOCATIONS:
errors.append(f"{where}: metadata.invocation 非法 {invocation!r}")
disable_model = str(fm.get("disable-model-invocation", "")).lower() == "true"
if invocation == "user-invoked" and not disable_model:
errors.append(f"{where}: user-invoked 技能必须设置 disable-model-invocation: true")
if invocation == "model-invoked" and disable_model:
errors.append(f"{where}: model-invoked 技能不应设置 disable-model-invocation: true")
status = meta.get("status", "")
if status == "promoted":
docs = ROOT / "docs" / "skills" / f"{meta.get('install_name', name)}.md"
if not docs.is_file():
warnings.append(f"{where}: promoted 技能缺少四段式文档 docs/skills/{docs.name}")
# Relative links must resolve.
for target in re.findall(r"\]\((\.[^)\s]+|[A-Za-z0-9_-]+/[^)\s]+)\)", body):
if target.startswith(("http://", "https://", "#")):
continue
if not (skill_md.parent / target).exists():
warnings.append(f"{where}: 引用的相对路径不存在: {target}")
def main() -> int:
strict = "--strict" in sys.argv
plugins = sorted(ROOT.glob("skills-*/*-plugin/.claude-plugin/plugin.json"))
if not plugins:
print("未找到任何 plugin.json", file=sys.stderr)
return 1
for plugin_json in plugins:
check_plugin(plugin_json)
for warning in warnings:
print(f"[warn] {warning}")
for error in errors:
print(f"[error] {error}")
print(f"\n检查 {len(plugins)} 个插件:{len(errors)} 个错误,{len(warnings)} 个警告")
if errors:
return 1
if strict and warnings:
print("--strict 模式下,警告视为失败")
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -7,5 +7,6 @@
},
"install_name": "biz-contract",
"install_type": "skill",
"dir_category": "biz"
"dir_category": "biz",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: biz-contract
description: 商务合同撰写。支持多种合同类型:软件订阅合同、软件定制开发合同、物流合同、销售服务合同、贸易合同等。当用户提到合同、协议、签约、合作协议相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 商务合同撰写技能 (biz-contract)
@@ -7,5 +7,6 @@
},
"install_name": "biz-ops",
"install_type": "skill",
"dir_category": "biz"
"dir_category": "biz",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: biz-ops
description: 商务运营技能。支持商业计划书(BP)撰写和商务合同起草。当用户提到商业计划书、BP、融资计划、商业模式、合同、协议、签约等相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 商务运营 (biz-ops)
@@ -7,5 +7,6 @@
},
"install_name": "biz-plan",
"install_type": "skill",
"dir_category": "biz"
"dir_category": "biz",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: biz-plan
description: 商业计划书撰写。支持融资BP、战略规划、商业模式设计等。当用户提到商业计划书、BP、融资计划、商业模式、战略规划相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 商业计划书撰写技能 (biz-plan)
@@ -7,5 +7,6 @@
},
"install_name": "finance",
"install_type": "skill",
"dir_category": "biz"
"dir_category": "biz",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: finance
description: 财务对账技能。支持银行对账、应收对账、应付对账、内部往来对账等。通过自然语言实现账单导入、差异分析、对账报告生成。当用户提到对账、银行流水、应收应付、账单核对、财务核销相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 财务对账技能
@@ -0,0 +1,13 @@
{
"name": "ai-proj-helper-entry-plugin",
"description": "技能库路由:列出技能、什么任务用哪个、交付终点口径。由人主动调用,不占模型目录 token。",
"version": "0.1.0",
"author": {
"name": "qiudl"
},
"install_name": "ai-proj-helper-entry",
"install_type": "skill",
"dir_category": "core",
"status": "deprecated",
"invocation": "user-invoked"
}
@@ -0,0 +1,77 @@
---
name: ai-proj-helper-entry
description: ai-proj-helper 技能库路由:告诉你有哪些技能、什么任务用哪个、以及「REQ released + PDV 通过才算交付」的强制口径。人在开始需求/开发/评审/发布任务前主动调用。
metadata:
invocation: user-invoked
owner: qiudl
disable-model-invocation: true
---
# ai-proj-helper 入口(路由器)
## 0. 这个技能是什么
一个**纯人触发**的路由器:人问「该用哪个技能 / 从哪开始」,就读这里。它不进模型目录,所以不占每次会话的目录 token;代价是必须由人主动喊。
> 路由规则:**任何技能增、删、改名、改行为后,必须回改本文件**。一个没提到新技能、或还指向已删技能的路由器,就是假的路由器(见 `skill-creator` §9)。
## 1. 交付终点(强制,优先于路由)
开发任务的交付终点是:需求按 REQ 流程推进到具备发布条件并完成上线(`delivery_stage=released` + PDV 验收通过)。
- 写代码、过单测、提 PR、过 internal gate、合并代码,都是过程节点,**不得当作交付终点**;
- 任务 `completed` ≠ 需求完成;REQ 未 `released` 不得报完成;
- 汇报格式:**当前 REQ 阶段 + 下一个要做的节点**;
- 只有必须由人拍板/授权的阻塞(生产发布授权、密钥权限、需求变更、无法自动修复的失败)才停下来问,并写清卡点与下一步。
## 2. 主流程:需求 → 上线
```
讨论(req) → PRD(req-prd) → 评审(req-review) → 设计(req-design)
→ 开发(dev-coding / karpathy-guidelines) → 测试(dev-test + req-test-gate)
→ 代码评审(dev-review) → 发布(publish / slark-cicd / slark-dsh-cicd) → PDV 验收 → released
```
| 阶段 | 技能 |
| --- | --- |
| 讨论/调研 | `req`、`req-research`、`req-compare` |
| PRD | `req-prd`、`req-prototype` |
| 评审 | `req-review` |
| 设计/拆任务 | `req-design`、`dev-arch`、`db-migration` |
| 编码 | `dev-coding`、`karpathy-guidelines` |
| 测试 | `dev-test`、`req-test-gate` |
| 代码评审 | `dev-review`、`review-checklist` |
| 发布 | `publish`、`slark-cicd`、`slark-dsh-cicd`、`deploy-rollback` |
| 部署后 | `req-audit`、`req-lookback` |
| 复盘 | `req-retro` |
| 项目管理 | `project-management`、`pm-risk`、`pm-ask` |
| 建/改技能 | `skill-creator` |
| 汇报完成前 | `verification-before-completion` |
## 3. 按任务类型的旁路
- 「这个 bug 很难查」→ `diagnosing-bugs`(先建红循环再推理)
- 「帮我审这个 PR」→ `dev-review`
- 「发版」→ 对应 `*-cicd` runbook,不是通用 `dev-deploy`
- 「不确定该用哪个」→ 读到这里就够了,别猜
## 4. 红线
- 不得自审批(提交人不能批自己的 REQ)
- 不得绕过门禁(测试 Gate、发布 Gate、归档 Gate)
- 不得把「某步骤完成」当结束
- 不得无证据声称完成(见 `verification-before-completion`)
- 不得把凭据/内网地址/绝对路径写进技能或文档
## 5. 技能从哪来
- 用户级:`~/.agents/skills/`(Codex)、`$DSH_HOME/skills/`(DSH)
- 项目级:项目根 `.agents/skills/`
- **真相源**:`ai-proj-helper` 仓库;本机目录是安装产物,不要直接改
- 个人技能:`skills-personal/`(不入库、不发布)
## 6. 维护检查
- `./install-skills.sh --audit` 漂移数 > 0 → 先同步再干活
- 技能有增删改 → 本文件 + `catalog.json` 必须同 PR 回改
- 每季度人工过一遍本路由,删掉不再用的技能引用
@@ -0,0 +1,24 @@
{
"skill_name": "ai-proj-helper-entry",
"skill_version": "0.1.0",
"evals": [
{
"id": 1,
"kind": "happy_path",
"prompt": "我要给 qiu-slark 做个新功能,从哪开始",
"expected_output": "给出 req → req-prd → req-review → req-design 的路径,并声明交付终点是 released + PDV,不是写完代码"
},
{
"id": 2,
"kind": "edge_case",
"prompt": "我已经把单测跑过了,这个需求可以算完成了吗",
"expected_output": "否定:单测只是过程节点,REQ 未 released 不算完成;给出当前阶段与下一节点"
},
{
"id": 3,
"kind": "failure_recovery",
"prompt": "你说的那个技能我机器上没装,怎么办",
"expected_output": "说明技能真相源在 ai-proj-helper 仓库、本机目录是安装产物;给出 install-skills.sh 安装/审计命令"
}
]
}
@@ -7,5 +7,6 @@
},
"install_name": "publish",
"install_type": "skill",
"dir_category": "core"
"dir_category": "core",
"invocation": "user-invoked"
}
@@ -2,6 +2,9 @@
name: publish
description: 发布 ai-proj-helper 技能市场更新并通知飞书群。用户说 /publish 时激活。
user_invocable: true
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# publish - 技能市场发布与通知
@@ -0,0 +1,13 @@
{
"name": "skill-creator-plugin",
"description": "团队技能创建与维护的标准流程:收录门槛、分桶生命周期、调用模式、evals、四段式文档、路由回改。",
"version": "0.1.0",
"author": {
"name": "qiudl"
},
"install_name": "skill-creator",
"install_type": "skill",
"dir_category": "core",
"status": "beta",
"invocation": "user-invoked"
}
@@ -0,0 +1,127 @@
---
name: skill-creator
description: 团队技能的标准流程:收录门槛、分桶生命周期、调用模式、SKILL.md 规范、evals 全量、四段式文档、路由回改。当要新建技能、大改现有技能、或评审一个技能是否合格时使用。
metadata:
invocation: user-invoked
owner: qiudl
disable-model-invocation: true
---
# 技能创建(团队标准流程)
## 0. 一句话
先有真实失败,再写技能;没有 evals 的技能不算完成;**技能目录是预算,不是收藏夹**。
## 1. 何时用
- 新建技能
- 大改现有技能(改 description、改核心流程、改门禁)
- 评审别人提上来的技能
- 判断某个想法「该不该做成技能」
何时不用:只改错别字/格式 → 直接改;一次性个人偏好 → 放个人技能,不进团队。
## 2. 收录门槛(先过这一关,再谈怎么写)
新技能**默认拒绝**,只有同时满足两条才立项:
1. **真实失败**:能说出在哪个真实任务/会话里出了问题——跑了什么、期望什么、实际什么。假想改进(「这样会更好」)不算。
2. **组合不出来**:用现有技能组合做不到;能组合的,就改现有技能,不新增。
被拒的想法记进仓库 `.out-of-scope/<概念>.md`,写清理由,避免下次重复讨论。
## 3. 分桶与生命周期
| 桶 | 含义 | 是否安装 | 是否进 README / plugin.json |
| --- | --- | --- | --- |
| `promoted` | 已验证、日常在用 | 默认安装 | 必须出现 |
| `beta` | 公开试跑,收反馈 | 需 `--include-beta` | 不进默认清单 |
| `deprecated` | 不再用 | 不安装 | 留文档,标弃用 |
- 新技能一律先进 `beta`,跑够真实使用 + evals 通过才 `promoted`。
- 只有 `promoted` 能进模型目录;beta 不占目录预算。
## 4. 调用模式(省目录 token 的关键)
每个技能二选一,写进 frontmatter:
- **`model-invoked`**(默认):进模型目录,agent 自己判断何时用。
- **`user-invoked`**:只由人下命令触发,**不进模型目录**;必须同时写 `disable-model-invocation: true` 和 `metadata.invocation: user-invoked`。
判定口径:这件事是不是「人下命令才开始」?是 → user-invoked。典型:publish、retro、triage、发布 runbook、建技能。
## 5. SKILL.md 硬约束(Agent Skills 规范)
- 目录:`SKILL.md` + 可选 `scripts/`、`references/`、`assets/`
- frontmatter 必填:`name`(小写字母/数字/连字符,≤64)、`description`(≤1024,写清「做什么 + 何时用」)
- 可选:`license`、`compatibility`、`metadata`、`allowed-tools`
- **非标准字段**一律进 `metadata`
- 正文 ≤20KB(约 5000 token),细节拆 `references/`
- 只写 agent 不知道的东西:项目约定、边界、坑;不写通用常识
## 6. 正文结构模板
```
# 名称
## 0. 一句话
## 1. 何时用 / 何时不用
## 2. 步骤(可执行、有顺序)
## 3. 硬约束与红线
## 4. 常见坑(gotchas)
## 5. 验证清单
## 6. 参考(references/ 链接)
```
## 7. evals(强制、全量)
- 路径:`evals/evals.json`;至少 3 条:正常路径 / 边界输入 / 失败恢复
- 跑「有技能 / 无技能」对比,结果存 `iteration-<N>/`,按 rubric 打分,PR 附结果
## 8. 四段式文档(每个 promoted 技能一篇)
`docs/skills/<name>.md`,四节固定顺序:
1. **What it does**
2. **When to reach for it**
3. **Common questions**
4. **It's working if**(必须给可验证证据,不许写「感觉对了」)
beta 不写文档;弃用保留文档并标 archived。
## 9. 路由回改(硬规则)
所有技能增、删、改名、改行为后,**必须同步回改入口技能 `ai-proj-helper-entry` 和 `catalog.json`**。一个没提到新技能、或还在路由到已删技能的路由器,就是假的路由器。
## 10. 质量门禁(提 PR 前逐条打勾)
- [ ] 过了收录门槛(真实失败 + 组合不出来)
- [ ] 桶与调用模式已标,`beta` 不得出现在默认清单
- [ ] `name`/`description` 合规,description 含「何时用」
- [ ] 正文 ≤20KB,细节已拆 references
- [ ] evals ≥3 条,有「有/无技能」对比
- [ ] 四段式文档已写(promoted 才需要)
- [ ] 入口路由与 `catalog.json` 已回改
- [ ] `plugin.json` 已登记 `install_name`/`install_type`/`dir_category`/`status`/版本号
- [ ] `python3 scripts/validate-skills.py` 通过
- [ ] `./scripts/scan-skill.sh` 无高危项
- [ ] 版本号与 CHANGELOG 已更新
- [ ] 无绝对路径、无凭据、无内网地址
## 11. 反模式
- 一次写 800 行「大全」,什么都想覆盖
- description 写成「各种任务都能用」
- 没有 evals 就提 PR;没有四段式文档就 promoted
- 直接复制外部技能,不改写成我们的 REQ/ai-proj 语境
- 把临时排障步骤固化成团队技能(这类放 personal)
- 技能改名后忘了回改路由
## 12. 评审别人技能时看什么
1. 收录门槛过没过(有没有真实失败)
2. description 能不能让模型判断「何时用」
3. 桶与调用模式是否正确(该 user-invoked 的别占目录)
4. 和现有技能是否重复(先查 `catalog.json`)
5. evals 是否覆盖失败路径、文档是否有「It's working if」
6. 是否触碰红线(自审批、绕过门禁、绝对路径、凭据)
@@ -0,0 +1,24 @@
{
"skill_name": "skill-creator",
"skill_version": "0.1.0",
"evals": [
{
"id": 1,
"kind": "happy_path",
"prompt": "我想加一个新技能,用来在每次部署后自动跑一遍冒烟",
"expected_output": "先问真实失败场景(哪次部署出过问题、跑了什么、期望什么),再判断现有 req-lookback/req-audit 能否组合;给出 bucket/调用模式/evals 计划"
},
{
"id": 2,
"kind": "edge_case",
"prompt": "直接帮我把这个想法写成 SKILL.md:一个能自动优化代码风格的技能",
"expected_output": "拒绝直接写,指出没有真实失败证据,要求先给案例;若无证据则建议放个人技能"
},
{
"id": 3,
"kind": "failure_recovery",
"prompt": "技能有 evals 但 validate-skills.py 报了 name 不合规,怎么处理",
"expected_output": "说明 name 规则(小写/数字/连字符、≤64),给出改名步骤,并提示要同步 install_name、catalog、入口路由"
}
]
}
@@ -404,3 +404,14 @@ ssh melbourne "cd /Users/coolbuy-dev/coding/new-ai-proj && \
- [OpenAI Swarm 文档](https://github.com/openai/swarm)
- [Multi-Agent Systems 设计模式](https://arxiv.org/abs/2308.00352)
- [Claude Code Skills 文档](https://docs.anthropic.com/claude-code/skills)
## 并行编排流程
把大任务拆给多个子 agent 时按这个顺序:
1. **先划写入边界**:每个子 agent 拥有互不重叠的目录/文件;共享文件(锁文件、入口文件)由编排者最后统一改。
2. **子 agent 必须新上下文**:不要 fork 父上下文,否则它继承了本该甩掉的包袱。
3. **每个子任务给验收标准 + 回报格式**:三句话(结果 / 证据路径 / 下一步)。
4. **子 agent 不做合并与发布**:只交分支或补丁,合并由编排者做。
5. **汇总时先跑集成验证**,再回报;冲突由编排者解,不让子 agent 互改。
6. 两个子 agent 不得写同一文件;不确定时先串行。
@@ -7,5 +7,6 @@
},
"install_name": "ai-proj-cicd-release",
"install_type": "skill",
"dir_category": "dev"
"dir_category": "dev",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: ai-proj-cicd-release
description: Execute and audit the AI-Proj service CI/CD flow across Gitea gates, immutable image builds, staging verification, approved production release, rollback, and evidence capture. Use for AI-Proj CI status, release PRs, staging or production deployments, failed-release diagnosis, deployed commit/schema verification, and delivery-chain repair. Do not use for unrelated repositories or macOS application packaging.
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# AI-Proj CI/CD release
@@ -7,5 +7,6 @@
},
"install_name": "ai-proj-macos-release",
"install_type": "skill",
"dir_category": "dev"
"dir_category": "dev",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: ai-proj-macos-release
description: Build, sign, notarize, publish, and verify the AI-Proj macOS Apple Silicon package through the repository's release chain. Use when asked to release, republish, update, or repair the downloadable macOS application, including Gatekeeper failures and download-manifest updates. Do not use for service deployments or unrelated applications.
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# AI-Proj macOS release
@@ -7,5 +7,6 @@
},
"install_name": "dev-android",
"install_type": "skill",
"dir_category": "dev"
"dir_category": "dev",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: dev-android
description: Android 开发插件。Kotlin + Jetpack Compose + Hilt 依赖注入。当涉及 Android 开发任务时按需加载。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# Android 开发插件 (dev-android)
@@ -7,5 +7,6 @@
},
"install_name": "dev-ios",
"install_type": "skill",
"dir_category": "dev"
"dir_category": "dev",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: dev-ios
description: iOS 开发插件。Swift/SwiftUI + MVVM 架构,TestFlight 部署。当涉及 iOS 开发任务时按需加载。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# iOS 开发插件 (dev-ios)
@@ -7,5 +7,6 @@
},
"install_name": "dev-pda",
"install_type": "skill",
"dir_category": "dev"
"dir_category": "dev",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: dev-pda
description: PDA 应用开发插件。Android 原生 + 扫码枪集成 + 离线优先。当涉及 PDA/手持终端开发时按需加载。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# PDA 应用开发插件 (dev-pda)
@@ -303,3 +303,13 @@ mcp__ai-proj__link_tasks_to_requirement({
4. **严重度准确** — 不要所有问题都标 High,按实际影响分级
5. **建议可操作** — 每个发现必须附带具体修复建议
6. **关注变更** — 评审范围是 diff,不要对未变更的代码提意见(除非变更引入了对旧代码的新风险)
## 接收与响应评审意见
评审不是单向输出,收到意见后按这套来:
1. **先分类**:阻断项(必须修)/ 建议项(可讨论)/ 澄清项(问题理解不一致)。
2. **先复述再回应**:用自己的话重述意见,确认理解一致,再给证据或修改。
3. **不辩解**:用证据说话(代码、测试、日志),不用语气词反驳。
4. **逐条回评**:每条写「已修(commit)/ 不修(理由)/ 需澄清(具体问题)」,不得默默跳过。
5. **阻断项没修完不得合并**;建议项不修要记录原因,进 PR 描述。
@@ -215,3 +215,11 @@ AI 根据需求变更范围动态生成 Playwright spec,模板见 `templates/p
若 git diff 显示同一功能的 `handlers/`、`middleware/`、`routes/` 文件均有变更(通过命名模式识别,如 `impersonation_handler.go` + `impersonation_middleware.go` + `impersonation_routes.go`),则除单元测试外**额外生成** `backend/tests/` 下的集成测试。
识别方式:提取文件名中的功能前缀(如 `impersonation`),若在三个目录中均出现,则触发集成测试生成。
## TDD 循环(红 → 绿 → 重构)
1. **一次只做一个行为**:写一个小测试,先确认它**失败**,并确认失败原因就是你要修的那件事(不是编译错误/环境问题)。
2. **最小实现让它变绿**,不做顺手重构。
3. **绿了再重构**,重构期间测试保持绿。
4. 禁止先写实现再补测试;补的测试要能证明它真的会红(临时改坏一次验证)。
5. 交付时附:测试命令、通过/失败数、以及「曾经红过」的证据(日志或截图记录)。
@@ -7,5 +7,6 @@
},
"install_name": "data-excel",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: data-excel
description: Excel 数据处理与 BI 集成。通过自然语言操作 Excel 文件的读取、编辑、转换,并支持导入到 BI 系统(Metabase)进行可视化分析。当用户提到 Excel、表格处理、数据导入、BI 分析相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# Excel 数据处理与 BI 集成 Skill
@@ -7,5 +7,6 @@
},
"install_name": "doubao-voice",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: doubao-voice
description: 豆包语音API调用。支持语音合成(TTS)和唱歌。当用户提到语音合成、文字转语音、唱歌、豆包语音相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 豆包语音API技能
@@ -7,5 +7,6 @@
},
"install_name": "feishu-bitable",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: feishu-bitable
description: 飞书多维表格操作。用于记录增删改查、批量操作、筛选排序、数据同步。当需要操作飞书多维表格时使用。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 飞书多维表格 (Bitable)
@@ -7,5 +7,6 @@
},
"install_name": "feishu-docx",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: feishu-docx
description: 飞书云文档操作。用于创建、编辑云文档,插入内容块,会议纪要生成。当需要操作飞书云文档时使用。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 飞书云文档 (Docx)
@@ -7,5 +7,6 @@
},
"install_name": "feishu",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: feishu
description: 飞书文档与多维表格操作入口。当用户提到飞书、云文档、多维表格、Bitable 相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 飞书集成
@@ -7,5 +7,6 @@
},
"install_name": "siyuan",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: siyuan
description: 思源笔记 API 集成。通过自然语言创建、编辑、搜索笔记,管理笔记本和文档树。当用户提到思源笔记、SiYuan、笔记管理、知识库相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 思源笔记 API 集成 Skill
@@ -7,5 +7,6 @@
},
"install_name": "siyuan-to-feishu",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: siyuan-to-feishu
description: 将思源笔记导出为 PDF 并发送到飞书群。当用户提到"发送笔记"、"导出PDF发飞书"、"/siyuan send"、"分享到飞书"相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# siyuan-to-feishu Skill
@@ -7,5 +7,6 @@
},
"install_name": "wecom",
"install_type": "skill",
"dir_category": "integration"
"dir_category": "integration",
"invocation": "user-invoked"
}
@@ -1,6 +1,9 @@
---
name: wecom
description: 企业微信集成。通过自然语言发送消息、管理群机器人、操作审批流程、管理通讯录。当用户提到企业微信、微信工作、群机器人、企业号、wecom相关任务时自动激活。
metadata:
invocation: user-invoked
disable-model-invocation: true
---
# 企业微信集成技能
@@ -474,3 +474,13 @@ PRD 说「做什么」(用户故事、业务规则、验收标准),设计
| V1.0 | 2026-01-26 | 初始版本(原名 req-dev) |
| V2.0 | 2026-04-06 | 重构为 req-design:移除架构指南和编码规范,聚焦 API 契约 + 任务拆分 |
| V2.1 | 2026-04-16 | 新增 Memory 隔离规则(REQ-20260416-0017) |
## 任务依赖边(blocking edges)
拆子任务时,每个任务必须显式声明依赖,而不是只给层级:
- 每个任务写 `blockers: [任务编号...]`,没有依赖就写 `blockers: []`;
- **被阻塞的任务不得先开工**,即使它看起来更简单;
- 依赖图落进需求的任务描述,供 ai-proj / PM 检查;
- 出现循环依赖直接拒绝拆分方案,重新设计边界;
- 验收时检查:所有 blockers 是否 completed,再开自己。
@@ -0,0 +1,13 @@
{
"name": "verification-before-completion-plugin",
"description": "汇报完成/关闭任务/提交 PR 前必须先跑验证并附证据;没有证据不得声称完成。",
"version": "0.1.0",
"author": {
"name": "qiudl"
},
"install_name": "verification-before-completion",
"install_type": "skill",
"dir_category": "req",
"status": "deprecated",
"invocation": "model-invoked"
}
@@ -0,0 +1,55 @@
---
name: verification-before-completion
description: 汇报「完成/修好/通过」或关闭任务、提交 PR、宣布 REQ 完成之前,必须先运行验证命令并附证据;没有证据不得声称完成。当准备说完成、关闭任务、或汇报交付前使用。
metadata:
invocation: model-invoked
owner: qiudl
---
# 完成前验证
## 0. 一句话
**没有证据的「完成」不算完成。**
## 1. 何时用
- 准备说「搞定了 / 修好了 / 通过了 / 可以发了」
- 准备把任务标 `completed`、关 issue、提 PR
- 准备宣布 REQ 完成或可发布
- 收到「你确认一下」这类要求时
何时不用:还在探索阶段、明确记录的是中间发现(这时要写「未验证」而不是「完成」)。
## 2. 证据三件套
1. **命令**:原样可复制,别人能重跑
2. **输出关键行**:可读文本,不要只看截图
3. **判定**:退出码 / 通过数 / 失败数
格式:`验证:<命令> → <结果>(通过 N / 失败 M),证据:<日志路径或输出片段>`
## 3. 按类型的验证清单
| 改动类型 | 必须验证 |
| --- | --- |
| 代码改动 | 构建 + 单测 + 类型检查(有则跑) |
| bug 修复 | 先复现(证明坏)→ 修复 → 同一用例再跑(证明好) |
| 需求级交付 | 验收标准逐条打勾 + PDV 验收通过 |
| 发布/部署 | 健康检查 + E2E + 回滚预案可用 |
| 配置/文档 | 生效验证(如 `--dump-config` 结果、命令输出) |
| 数据变更 | 变更前后数据抽查 + 回滚脚本验证 |
## 4. 反模式
- 「应该可以」「本地没问题」「理论上过了」
- 只贴成功截图,不贴命令
- 跳过失败用例不说明
- 把「编译通过」当成「功能可用」
- 把「测试跑了一部分」说成「全部通过」
## 5. 与 ai-proj 对接
- 任务标 `completed` 前,把证据挂到该任务文档;
- REQ 未 `released` 时不得报需求完成(见 `ai-proj-helper-entry` 的交付终点);
- 证据缺失时,正确做法是状态写 `in_progress` 并说明「还差哪项验证」。
@@ -0,0 +1,24 @@
{
"skill_name": "verification-before-completion",
"skill_version": "0.1.0",
"evals": [
{
"id": 1,
"kind": "happy_path",
"prompt": "我改完了登录接口,可以提交了吗",
"expected_output": "要求给出构建/单测命令与结果、失败数;附证据路径后再提交"
},
{
"id": 2,
"kind": "edge_case",
"prompt": "测试环境没有依赖装不上,先合了吧,本地我手动看过没问题",
"expected_output": "拒绝以「手动看过」作为证据;说明缺失依赖要记录为未验证项,状态保持 in_progress"
},
{
"id": 3,
"kind": "failure_recovery",
"prompt": "测试跑过了 10 个,还有 2 个没跑,能说全部通过吗",
"expected_output": "不能:必须写明通过 10 / 未跑 2 及原因,不得声称全部通过"
}
]
}