Codex + OpenSpec + Matt Pocock Skills 的项目初始化流程一键脚本
最近一段时间,我一直在使用:
Codex
+
OpenSpec
+
Matt Pocock Skills
做 AI Coding。
用得越多,越能感受到一个问题:
AI Coding 真正麻烦的地方,已经不只是“让 AI 把代码写出来”。
更容易出问题的是:
AI 不知道项目边界
AI 不知道当前做到哪一步
AI 不知道哪些文件不能乱改
AI 没有稳定的需求流程
AI 修 Bug 时容易开始猜
AI 写完代码后容易忘记测试和 Review
不同项目的 Codex 配置还不一致
每次创建一个新项目,我都要重复做一遍:
初始化 OpenSpec
安装 Skills
创建 AGENTS.md
创建 README
创建架构文档
创建 ADR
创建 PR Template
补开发规范
补测试规则
补 Git 规则
检查 Skills 是否安装正确
做了几次之后,我决定把这些东西直接固化下来。
于是有了这个脚本:
init-codex-project.sh
它的目标不是创建 React、Flutter、Electron 或 .NET 项目。
而是解决另外一个问题:
把一个普通代码仓库初始化成适合 Codex 持续开发的 AI Coding 工程。
一、这个脚本到底解决什么问题?
传统项目初始化通常关注的是技术栈。
比如:
npm create vite
或者:
flutter create
解决的是:
代码怎么开始写?
但使用 Codex 之后,我认为还需要解决另一层问题:
AI 应该怎么参与这个项目?
也就是说,一个项目除了:
src/
package.json
test/
之外,还应该存在一套 AI 能理解的工程上下文:
AGENTS.md
docs/PROJECT.md
docs/ARCHITECTURE.md
docs/adr/
openspec/
.agents/skills/
它们分别回答不同的问题。
例如:
AGENTS.md
→ AI 在这个仓库里应该遵守什么规则?
PROJECT.md
→ 这个产品到底是什么?
ARCHITECTURE.md
→ 项目当前真实架构是什么?
ADR
→ 为什么当初选择这个技术方案?
OpenSpec
→ 当前正在开发什么 change?
Skills
→ 遇到需求分析、Bug、TDD、Review 时应该执行什么工作流?
所以这个初始化脚本真正初始化的,其实不是代码。
而是:
AI 开发环境。
二、最终希望得到什么目录?
脚本执行完成后,项目大致会形成这样的工程结构:
project/
├── .agents/
│ └── skills/
│ ├── openspec-propose/
│ ├── openspec-apply-change/
│ ├── openspec-archive-change/
│ ├── grill-with-docs/
│ ├── domain-modeling/
│ ├── codebase-design/
│ ├── tdd/
│ ├── diagnosing-bugs/
│ ├── code-review/
│ └── writing-for-agents/
│
├── .github/
│ └── PULL_REQUEST_TEMPLATE.md
│
├── docs/
│ ├── adr/
│ │ └── README.md
│ ├── PROJECT.md
│ └── ARCHITECTURE.md
│
├── openspec/
│ ├── changes/
│ └── specs/
│
├── AGENTS.md
├── CHANGELOG.md
├── README.md
└── .editorconfig
我的思路是:
OpenSpec 管需求和 Change
Skills 管开发方法
AGENTS.md 管 Agent 行为
PROJECT.md 管产品边界
ARCHITECTURE.md 管技术边界
ADR 管长期技术决策
PR Template 管最终交付检查
几个东西各管一层,而不是全部堆进一个超级 AGENTS.md。
三、第一步:先检查环境,不满足条件就直接停
脚本第一件事并不是安装东西,而是检查运行环境。
主要检查:
node
npm
npx
git
其中 Node.js 会要求:
Node.js >= 20.19.0
这是因为当前 OpenSpec 官方要求 Node.js 20.19.0 或更高版本。
所以脚本不是简单执行:
npm install -g @fission-ai/openspec@latest
而是先判断环境。
类似:
for cmd in node npm npx; do
if ! command -v "$cmd" >/dev/null 2>&1; then
fail "Required command not found: $cmd"
fi
done
然后继续检查 Node 版本。
我比较喜欢这种处理。
因为初始化脚本最怕出现一种状态:
前面执行成功
↓
中间执行一半失败
↓
项目留下半套配置
↓
你也不知道哪些成功、哪些失败
所以脚本直接:
set -Eeuo pipefail
只要关键步骤出现异常,就停止执行。
同时还禁止直接在:
/
$HOME
运行。
目的也很简单:
尽量不要因为一次误操作,把初始化文件扔到错误目录。
四、OpenSpec 不再单独塞到 .codex/skills
这里是这版脚本我比较看重的一个调整。
以前给 Codex 配 OpenSpec,很容易形成:
.codex/skills/
然后安装其他第三方 Skills 又出现:
.agents/skills/
结果一个仓库里面存在两套 Skills。
所以这版直接使用:
openspec init . \
--tools agents \
--profile core \
--language "简体中文" \
--no-animation \
--no-copilot-cloud
统一使用:
.agents/skills/
当前 Codex 官方文档已经明确,仓库级 Skills 会从当前目录一路向 Repository Root 扫描 .agents/skills。
OpenSpec 当前 CLI 同样支持:
--tools agents
作为共享的 Agent Skills target。
因此我的项目里最终希望统一成:
.agents/skills/
├── openspec-*
├── tdd/
├── code-review/
├── diagnosing-bugs/
└── ...
而不是:
.codex/skills/
.agents/skills/
两套并存。
脚本甚至还专门检查旧项目是否存在:
.codex/skills/openspec-*
如果发现旧版本,只给出警告:
确认 .agents/skills 正常工作后
再考虑删除旧副本
但不会自动删除。
这一点也很重要。
因为初始化脚本应该:
尽量补东西,而不是擅自删用户已有文件。
五、第二层:给 Codex 安装一组工程化 Skills
只有 OpenSpec 还不够。
OpenSpec 更擅长解决:
这次要改什么?
为什么改?
影响哪些 Capability?
具体有哪些 Tasks?
但实际开发过程中,还会遇到:
需求本身还没想清楚
领域模型不知道怎么拆
复杂 Bug 不知道根因
核心逻辑需要 TDD
代码写完需要 Review
所以脚本继续安装了一组 Matt Pocock Skills。
安装方式类似:
npx --yes skills@latest add mattpocock/skills \
--skill setup-matt-pocock-skills \
--skill grill-with-docs \
--skill grilling \
--skill domain-modeling \
--skill codebase-design \
--skill tdd \
--skill diagnosing-bugs \
--skill code-review \
--skill writing-for-agents \
--agent codex \
--copy \
--yes
Matt Pocock Skills 官方目前也提供通过:
npx skills@latest add mattpocock/skills
给 Codex 等 Agent 安装 Skills 的方式。
skills CLI 本身支持:
--agent
--skill
--yes
--copy
这些参数。
我目前保留的 Skills 大致可以分成几类。
| Skill | 用途 |
|---|---|
setup-matt-pocock-skills | 初始化这一套 Skills 的项目配置 |
grill-with-docs | 需求不清楚时先把问题问透 |
grilling | 深入追问需求与设计 |
domain-modeling | 梳理领域概念和边界 |
codebase-design | 分析代码结构和设计 |
tdd | RED → GREEN → REFACTOR |
diagnosing-bugs | 系统化定位复杂 Bug |
code-review | 实现完成后的代码 Review |
writing-for-agents | 编写更适合 Agent 使用的文档 |
这里我没有选择:
所有 Skill 全装
而是只装当前工作流真正需要的一组。
原因也很现实:
Skill 不是越多越好。
Skill 太多以后,触发边界、职责和使用场景反而容易变得模糊。
六、OpenSpec 和 Skills 怎么配合?
这是整个方案里面最重要的一部分。
我的流程并不是:
需求
↓
Codex 写代码
而是:
需求
↓
$grill-with-docs
↓
$openspec-propose
↓
方案 Review
↓
$openspec-apply-change
↓
$tdd
↓
$code-review
↓
人工 Review
↓
验证
↓
归档 OpenSpec Change
不同工具负责不同阶段。
需求不清楚
先:
$grill-with-docs
不要急着写 Proposal。
因为一个错误的需求,如果直接进入 OpenSpec,只不过会得到一份:
结构非常完整的错误方案。
需求确定以后
再使用:
$openspec-propose
创建 Change。
让 Codex 输出:
proposal
design
specs
tasks
然后人工 Review。
确认方案以后
执行:
$openspec-apply-change
按照 Tasks 实施。
核心业务逻辑和 Bug 修复优先进入:
$tdd
遇到复杂 Bug
不是继续:
改一下试试
↓
还不行
↓
再改一下
而是:
$diagnosing-bugs
按照:
复现
↓
最小化
↓
提出假设
↓
验证 / 插桩
↓
确认根因
↓
修复
↓
回归测试
来处理。
最后
执行:
$code-review
然后再进行人工 Review。
也就是说:
AI Review 不是替代人工 Review,而是增加一道低成本检查。
七、为什么还要生成 AGENTS.md?
很多人装完 Skills,就觉得项目已经配置完成。
但我认为还缺一块:
项目自己的规则
Skill 更像:
怎么做 TDD
怎么排查 Bug
怎么 Review
而 AGENTS.md 解决的是:
这个项目允许怎么做?
所以脚本会生成一个 AGENTS.md 占位文件。
里面包括:
项目定位
技术栈
架构约束
OpenSpec 工作流
Bug 处理规则
TDD
Code Review
项目命令
完成标准
Git 规则
项目特殊约束
例如我会明确告诉 Codex:
不自动 push
不自动 archive OpenSpec change
不主动修改无关文件
不为了局部需求进行大规模重构
以及:
需求、影响范围或技术方案不明确时,
不要进行大范围修改。
我越来越觉得:
AGENTS.md 最重要的作用不是告诉 AI “应该做什么”,而是告诉它“不要擅自做什么”。
对于 Coding Agent 来说,这类边界非常重要。
八、我故意没有让脚本把项目文档写完整
脚本会创建:
AGENTS.md
README.md
CHANGELOG.md
docs/PROJECT.md
docs/ARCHITECTURE.md
但是这些文件刚生成的时候都会带:
PLACEHOLDER:REPLACE_ME
例如:
# <PROJECT_NAME>
> PLACEHOLDER:REPLACE_ME
<一句话说明项目是什么,以及解决什么问题>
为什么不让初始化脚本直接写?
因为:
脚本并不知道你的业务
如果强行生成:
项目目标
架构
模块边界
技术栈
Roadmap
很容易变成一堆看起来很专业,但其实是 AI 猜出来的内容。
所以我的原则是:
宁可明确留下 Placeholder,也不要伪造项目事实。
初始化结束以后,再让 Codex:
读取当前代码仓库
↓
分析真实项目
↓
补充这些文档
这样文档才有价值。
九、PROJECT.md 和 ARCHITECTURE.md 为什么分开?
以前我喜欢把所有内容全部写到 README。
后来发现对于 AI Coding 项目来说不太合适。
所以拆成了:
README.md
docs/PROJECT.md
docs/ARCHITECTURE.md
README
解决:
别人第一次进入项目应该知道什么?
例如:
项目是什么
技术栈
怎么启动
怎么测试
目录结构
开发流程
PROJECT.md
解决:
我们到底要做什么?
里面主要是:
背景
目标用户
核心目标
核心功能
当前阶段
Scope
Non-goals
产品原则
关键约束
尤其是:
Scope
Non-goals
我认为对 AI 很重要。
因为 AI Coding 一个非常常见的问题就是:
顺手多做。
ARCHITECTURE.md
解决:
代码应该怎么组织?
包括:
真实目录
模块边界
依赖方向
数据流
状态管理
错误处理
日志
测试策略
性能和兼容性
注意这里有一个关键词:
真实
不要为了画一个漂亮的架构图,把尚不存在的模块提前写进去。
十、再加一层 ADR
脚本还会创建:
docs/adr/
并准备一个 ADR 模板。
ADR 主要用来记录:
那些几年以后你还可能会问“当初为什么这么选”的决定。
比如:
为什么使用 MVVM?
为什么选择 MobX 而不是 Redux?
为什么本地存储选择 IndexedDB?
为什么桌面端选择 Electron?
为什么 API 层需要 Repository?
基本格式:
# ADR-0001: Use MVVM
## Status
Accepted
## Context
为什么需要做这个决策。
## Decision
最终决定。
## Alternatives
考虑过哪些方案。
## Consequences
收益、成本和限制。
但普通的:
这个函数叫什么名字
这个组件放哪个文件夹
没必要写 ADR。
否则很快就会进入另外一个极端:
文档比代码还多。
十一、PR Template 负责守最后一道门
AI Coding 还有一个特点:
写代码很快。
所以越到后面,越容易出现:
功能写完了
↓
看起来能跑
↓
直接提交
因此脚本准备了:
.github/PULL_REQUEST_TEMPLATE.md
要求至少检查:
Tests
Lint / Type Check
Build
git diff --check
openspec validate <change-id> --strict
openspec validate --all --strict
$code-review
人工 Review
无无关修改
其中我尤其看重:
无无关修改
因为 Coding Agent 很容易在实现一个功能的时候:
顺便重构一下
顺便换个写法
顺便整理几个文件
每一个单独看可能都没问题。
但最终 PR 会变得越来越难 Review。
所以我的原则一直是:
一次 Change 尽量只解决一次 Change 的问题。
十二、脚本最后还会进行一次“项目体检”
初始化完成并不代表成功。
所以脚本最后会验证:
OpenSpec 是否可读
OpenSpec Skills 是否存在
Matt Pocock Skills 是否存在
Placeholder 是否仍然存在
固定工程文件是否存在
然后输出项目状态。
例如:
STATUS: INITIALIZED, NOT READY FOR DEVELOPMENT
意思是:
工具已经初始化
但是项目文档还是 Placeholder
全部准备完成以后才应该达到:
STATUS: READY FOR DEVELOPMENT
我很喜欢这种设计。
因为:
初始化成功
和:
可以正式开发
其实并不是一个状态。
十三、怎么使用这个脚本?
脚本是 Bash,所以我主要在 macOS / Linux 环境使用,Windows 可以考虑 WSL 等 Bash 环境。
把:
init-codex-project.sh
放到项目根目录。
执行:
chmod +x init-codex-project.sh
./init-codex-project.sh
OpenSpec 当前官方要求 Node.js:
>= 20.19.0
因此旧 Node 环境需要先升级。
脚本跑完以后,不建议马上开始写业务代码。
十四、初始化之后,我通常还会让 Codex 做一次项目补全
第一步:
$setup-matt-pocock-skills
然后让 Codex读取真实仓库,把 Placeholder 文档补完整。
我通常会使用类似这样的 Prompt:
请分析当前仓库的真实代码、目录结构、依赖、配置、测试和已有文档。
补全以下项目初始化占位文件:
- AGENTS.md
- README.md
- CHANGELOG.md
- docs/PROJECT.md
- docs/ARCHITECTURE.md
要求:
1. 必须基于当前仓库真实实现,不要猜测不存在的模块。
2. 删除所有 PLACEHOLDER:REPLACE_ME。
3. README 面向项目使用者和开发者。
4. PROJECT.md 描述产品定位、核心能力、当前阶段、Scope 和 Non-goals。
5. ARCHITECTURE.md 描述真实目录、模块职责、依赖方向、数据流、状态管理、错误处理和测试策略。
6. AGENTS.md 作为 Codex 在本仓库中的开发规则入口。
7. CHANGELOG.md 只记录能够从 Git 和当前仓库确认的内容,不伪造历史版本。
8. 如果某项无法从仓库确认,明确标记待确认,不要自行编造。
9. 不修改业务代码。
10. 完成后检查仓库中是否还有 PLACEHOLDER:REPLACE_ME。
这样做完之后,一个真正适合 Codex 开发的项目环境才算基本完成。
十五、接下来才正式进入需求开发
假设我要开发一个比较复杂的新功能。
如果需求还很模糊:
$grill-with-docs
把需求问清楚。
然后:
$openspec-propose
建立 Change。
Review 完:
$openspec-apply-change
核心逻辑:
$tdd
遇到疑难 Bug:
$diagnosing-bugs
开发结束:
$code-review
最终:
人工 Review
↓
验证
↓
Commit / PR
↓
OpenSpec Archive
这就是我现在逐渐固定下来的 Codex 开发流程。
十六、为什么我要把它做成脚本?
因为 AI Coding 进入真正项目以后,我发现最值得自动化的并不是:
让 AI 多写一点代码
而是:
让每个项目从第一天开始就遵循同一套开发约束。
以前创建项目后,我可能需要半小时甚至更久整理:
OpenSpec
Skills
AGENTS.md
文档目录
ADR
PR Template
开发约束
而且不同项目还容易漏东西。
现在直接:
./init-codex-project.sh
先把骨架统一下来。
然后让 Codex 根据真实代码完成 Placeholder。
之后再进入:
需求澄清
→ OpenSpec
→ 实现
→ TDD
→ Review
→ 人工确认
写在最后
我现在越来越倾向于把 AI Coding 看成一种新的软件工程协作方式,而不是一个更强的代码补全工具。
如果只是:
写一个页面
写一个接口
写一个函数
其实不需要这么复杂。
但当项目开始持续迭代以后,真正决定 AI Coding 是否稳定的,往往不是某一次 Prompt 写得有多漂亮,而是项目里有没有长期存在的:
规则
上下文
规格
边界
验证
Review
所以这个脚本真正想解决的问题不是:
怎么一键安装 Codex 工具?
而是:
怎么让一个刚创建的仓库,从第一天开始就具备可持续的 AI Coding 工程结构?
这也是我目前使用:
Codex
+
OpenSpec
+
Matt Pocock Skills
+
AGENTS.md
+
项目文档
+
人工 Review
这套组合的主要原因。
后面我还准备继续把这套流程往下完善,比如:
项目规划阶段 Prompt
OpenSpec 标准 Change Prompt
Codex Commit / PR Skill
自动质量检查
CI 中的 OpenSpec Validation
不同技术栈的 AGENTS.md 模板
React / Electron / Flutter / .NET 项目初始化 Profile
最终目标不是做一个“大而全”的 AI Coding 框架。
而是把我自己反复使用、确定有效的工程习惯,逐步沉淀成:
可以直接复用的项目标准。