我把 Codex + OpenSpec + Matt Pocock Skills 的项目初始化流程做成了一键脚本

8 阅读9分钟

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分析代码结构和设计
tddRED → 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 框架。

而是把我自己反复使用、确定有效的工程习惯,逐步沉淀成:

可以直接复用的项目标准。