ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

一键初始化脚本:整合Codex、OpenSpec与TypeScript Skills的AI开发工作流

一键初始化脚本:整合Codex、OpenSpec与TypeScript Skills的AI开发工作流 最近在搭建新项目的时候我给自己写了套一键初始化脚本把 Codex、OpenSpec 和 Matt Pocock Skills 这三样东西一次性配好。以前每开一个新仓库我得先装 CLI、登录认证、配置模型、初始化规范目录、再手动把 skill 文件复制进去至少折腾半小时现在跑一条命令三分钟左右就能进入“直接跟 AI 对话开工”的状态。这个流程解决的核心问题很简单AI 编程工具越来越强但“让 AI 在正确规范下干活”这件事手动配置起来又碎又容易漏。Codex 负责执行OpenSpec 负责流程约束Matt Pocock Skills 负责给模型注入 TypeScript 领域的编码最佳实践——三样东西单独用都不难难的是每次新建项目都把它们正确地拼在一起。这篇文章我把脚本的设计思路、完整实现和踩坑记录都写出来适合正在用 Codex 做项目、或者想在团队里统一 AI 开发流程的开发者参考。1. 为什么要把初始化流程做成脚本1.1 三个工具各自解决什么问题这个组合看起来名字很多其实分工非常清楚。CodexOpenAI 出的命令行编程代理可以在本地终端里读代码、改代码、执行命令、跑测试。它相当于你的“AI 协作者”但它本身只提供协作能力并不知道你的项目应该按什么规范来。OpenSpec一套规范驱动的 AI 开发工作流。要求你在动手写代码之前先把要做的功能写成一个 spec需求说明再由 spec 生成 plan实施计划最后才进入编码。这个流程能避免 AI 一上来就乱改代码、改完发现方向错了。Matt Pocock SkillsMatt Pocock 是 TypeScript 社区的知名教育者他维护了一套给 AI 编程工具用的 skills。skills 本质上是一些 Markdown 文件SKILL.md里面写清楚了在某种场景下应该遵守的编码习惯、常见陷阱、检查清单。对 TypeScript/React 项目帮助尤其明显。三者组合之后等价于你拿到了一名“知道代码库情况、按规范推进、并且懂 TypeScript 最佳实践”的 AI 工程师。这句话听起来很玄其实拆开看每个环节都很朴实Codex 负责动手OpenSpec 负责控制节奏Skills 负责补充领域知识。少了任何一个另外两个都会打折扣。为了验证这个判断我自己做过 AB 对比同样的需求“给博客加一个标签归档页”直接让 Codex 改它可能会直接开始在 pages 下面新建文件而先走 OpenSpec 的 spec → plan 流程它会把数据结构、路由设计、页面入口先在文档里说清楚再动手。后者虽然多花了五分钟在文档上但后面几乎没有返工。1.2 手动初始化到底痛在哪很多人以为“初始化”就是装个 CLI 那么简单实际远不止。第一流程步骤多且顺序敏感。你得先装好 Codex 并登录认证然后才能用它OpenSpec 要在项目根目录初始化才会生成 openspec 目录Skills 文件要放进 Codex 能扫描到的目录通常是.codex/skills放错位置等于白放。步骤一多人就会漏。第二配置漂移。上个月用 Codex 的时候可能还只需要指向某个默认模型就够了下个月你又给项目加了 OpenSpec还需要在配置里开启 skills 支持。每个人的全局配置、每个项目的局部配置经常不一样团队里十个人就有十种环境光“把环境对齐”这件事就能耗掉大半天。第三新手上手成本高。如果你的团队来了个新人你给他一份 README里面写“先装 Codex再跑 openspec init然后把 skills 克隆到 .codex/skills最后把 codex.json 改成 XXX”。他大概率会在某个环节卡住尤其在认证、模型选择这些地方反复纠结。而一个脚本把所有这些判断都包进去他只管执行。所以当我连续手动初始化了五六个项目之后我确定了一件事这个流程值得做成脚本。不是因为我懒而是因为“可重复的手工劳动”本身就是技术债会持续吃掉我和队友的时间。1.3 自动化之后的收益我做了一个简单对比手动做一套流程和脚本一键做一套差异如下对比维度手动操作一键脚本耗时20-40 分钟2-3 分钟一致性靠记忆容易漏步骤固定流程每次一致可审计不知道当时配了什么日志完整可追溯可传播需要口头/文档教学脚本即文档出问题恢复手工排查、重来重新执行脚本即可这个表格我实际用了两个月目前感觉收益最明显的是“可传播”。脚本本身就成了项目的 onboarding 入口新人拉完仓库先跑一下脚本环境就绪剩下的只需要读 PROMPT.md。对个人开发者来说这个收益可能没有团队场景那么明显但半年后你回头再维护这个仓库时脚本能帮你快速恢复“当时是怎么搭起来”的记忆。2. 脚本设计思路与整体拆解2.1 脚本要完成的五步流程我在设计脚本的时候把整个初始化过程抽象成了五个步骤并且严格控制顺序检查依赖环境确认 Node.js、OpenSpec CLI、Codex CLI 是否安装版本是否满足要求。缺了就给出安装命令提示而不是直接报错退出。写入 Codex 配置生成项目级 codex.json指定模型、审批策略、skills 目录等。初始化 OpenSpec调用 openspec init 生成目录结构同时创建一个初始的 project 文档。安装 Matt Pocock Skills将技能文件同步到.codex/skills目录。生成启动上下文把项目名、规范说明、推荐工作流写进 PROMPT.md方便每次启动 Codex 时直接引用。为什么是这个顺序因为每一步都依赖前一步的产物。Codex 是执行引擎必须先能跑OpenSpec 是工作流约束必须在写代码前就位Skills 是领域知识要放进 Codex 的扫描范围最后生成 PROMPT.md 是为了把前三步串成“人怎么开始用”的入口。如果先装 Skills 再初始化 OpenSpecOpenSpec 初始化过程理论上不会碰 skills 目录但如果你连续跑多次脚本顺序不固定就会导致状态不可预期。2.2 目录结构与约定脚本执行完项目根目录应该长这样your-project/ ├── .codex/ │ ├── config.json │ └── skills/ │ ├── typescript/ │ │ └── SKILL.md │ └── react/ │ └── SKILL.md ├── openspec/ │ ├── projects/ │ │ └── initial-plan.md │ └── specs/ ├── AGENTS.md └── PROMPT.md这里有几个细节必须说明。.codex/config.json是 Codex CLI 的项目级配置。放在项目里比写进用户全局配置更好因为不同项目可能用不同模型、不同 skills 组合项目内部配置文件可以跟着仓库走团队其他人 clone 下来就自然继承。openspec/是 OpenSpec 初始化生成的目录projects/下面放当前进行中的计划specs/下面放已经确认的需求文档。这个结构不要乱改OpenSpec 的 CLI 会依赖这个约定。AGENTS.md是给 AI 代理看的项目说明文件Codex 会优先读取这个文件来了解项目规则。脚本会把最基础的项目语言、代码风格、命令约定写进去。PROMPT.md是启动提示词它不是给 AI 看的系统文件而是给人看的“接下来怎么用”。我习惯在里面写清楚第一步先让 Codex 读 openspec/ 下的计划第二步让 Codex 按计划执行第三步跑测试验证。这样新上手的人也知道怎么跟 AI 协作。2.3 幂等与安全设计脚本最大的敌人是“重复执行后状态变乱”。所以我做了几点设计脚本开头加set -euo pipefail。这个组合的意思分别是遇到错误立即退出、使用未定义变量时退出、管道中任一命令失败则失败。它能避免脚本在某个命令失败后继续乱跑。每个步骤都做“存在性检查”。比如.codex/config.json已经存在时先问用户要不要覆盖skills 目录里已有同名 skill 时跳过而不是覆盖openspec 目录已经初始化过就不再重复执行 init。设计临时文件清理机制。比如初始化过程中生成的临时 plan 草稿用trap ... EXIT在脚本退出时清理。这样就算中间报错也不会在项目里留下一堆垃圾文件。这些看着都是小细节但恰恰是脚本能“反复跑、放心跑”的关键。我见过太多一键脚本只能在干净环境跑一次第二次就各种报错就是因为没有做幂等处理。3. 核心实现一步步写出脚本3.1 环境检查与依赖引导脚本第一步是检查依赖。我写了一个通用函数check_cmd() { local cmd$1 local hint$2 if command -v $cmd /dev/null 21; then echo [OK] $cmd 已安装 else echo [MISSING] 缺少 $cmd echo 提示: $hint exit 1 fi } check_cmd node 请先安装 Node.js 18推荐用 nvm 安装。 check_cmd codex 请先安装 Codex CLI参照官方安装文档。 check_cmd openspec 请先安装 OpenSpec CLI参照官方文档。command -v是 shell 里最可靠的可执行文件检测方式比which兼容性更好。我故意把安装提示写成“指引你去官方文档”而不是在脚本里偷偷安装。原因很简单安装方式是全局环境的事脚本不应该替用户做修改全局 PATH 或安装全局包的决定。如果脚本发现了 Mac 上缺 Homebrew最好的做法是提示而不是直接把它装上。如果你还需要某个最低版本可以在检测后追加版本比较。比如 OpenSpec 要求 Node 18可以这样node_major$(node -p process.versions.node.split(.)[0]) if [ $node_major -lt 18 ]; then echo Node.js 版本过低需要 18当前 $node_major exit 1 fi这个细节对实际使用很重要因为很多旧项目环境装的是 Node 14 或 16Codex CLI 和 OpenSpec 跑不起来报错信息又不好懂。3.2 写入 Codex 配置Codex 项目的配置其实有两种承载方式一是用户全局配置~/.codex/config.toml二是项目级配置。我在脚本里选择生成项目级codex.json理由刚才说过——项目配置跟着仓库走方便团队共享。配置内容大概长这样{ model: gpt-5.6-sol, approval_policy: on-request, skills: { enabled: true, directories: [.codex/skills] } }这份 JSON 我按最小可用原则来写字段含义说明一下model指定 Codex 后端跑的模型。不同账号、不同订阅能访问的模型不一样报错“the gpt-5.6-sol model is not supported”时通常就是账号没权限可以改成你有权限的模型名。approval_policy审批策略。on-request表示涉及敏感操作时征求你同意适合日常开发如果你希望 AI 全自动跑测试和命令可以改成never或对应放行策略。skills启用 Codex 的技能系统并把目录指向项目内的.codex/skills。这里要注意不同版本的 Codex 配置字段命名可能不同我用的这个skills.directories是当前版本里比较常见的写法。如果你用的版本字段不一样以官方文档为准。还有一个经常被忽略的点Codex 除了读项目配置还会读项目根的AGENTS.md。这个文件对代理的行为影响非常大我会在脚本里生成一份最基础的模板# AGENTS.md ## 项目说明 这是一个 TypeScript 项目使用 Node.js 22 pnpm 管理依赖。 ## 命令 - 安装依赖pnpm install - 开发启动pnpm dev - 测试pnpm test ## 编码约定 - 遵循 Matt Pocock 的 TypeScript 最佳实践。 - 修改前先阅读 openspec/ 下的对应 spec。有了这个文件Codex 一进项目就知道“该用什么包管理器、测试怎么跑、代码风格偏好”这些信息如果只写在 PROMPT.md 里你可能每次都要手动粘贴放在 AGENTS.md 里就是自动加载。3.3 OpenSpec 初始化OpenSpec 我理解为“给 AI 开发加的一道流程约束”。它的核心思路很朴素人先想清楚要什么把它写成 spec再把 spec 拆成 plan最后才让代理去执行。脚本里初始化 OpenSpec 的步骤大概是这样# 如果 openspec 目录不存在再初始化 if [ ! -d openspec ]; then echo 初始化 OpenSpec 目录... openspec init else echo 检测到 openspec 目录已存在跳过 init。 fi # 确保初始计划文件存在 mkdir -p openspec/projects if [ ! -f openspec/projects/initial-plan.md ]; then cat openspec/projects/initial-plan.md EOF # 当前计划 这个文件用于记录当前 AI 正在执行的计划。 每次新任务开始前先在这里更新你的 plan。 ## 任务目标 待补充 ## 执行步骤 1. 先阅读 openspec/specs/ 下的需求说明。 2. 拆解为实现步骤。 3. 完成编码后运行测试验证。 EOF fi这里有一个容易踩的坑openspec init在某些版本里是交互式命令会问你问题。在脚本里直接跑如果它等待输入脚本就会卡住。我试过两种处理方式用管道喂一个换行echo | openspec init有时能跳过默认选项。显式传参跳过交互openspec init --yes或--no-interactive不同版本参数不一样。如果你的 OpenSpec 版本不支持非交互参数最简单稳妥的做法是不调用 init而是手动创建openspec/{projects,specs}目录并放一个初始文件。因为 OpenSpec 的核心是目录结构约定只要目录结构对了绝大多数子命令都能正常工作。这个方案虽然“土”一点但在脚本里最不容易翻车。3.4 接入 Matt Pocock SkillsMatt Pocock Skills 本质上就是一组 SKILL.md 文件。你要做的只有两件事把它放到 Codex 能扫到的地方确保 SKILL.md 的格式符合 Codex 的 skill 解析规则。脚本里我采用的策略是先确认远端仓库的最新版本再把它 clone 到临时目录然后把需要的技能复制到.codex/skills下。简化后的脚本逻辑是这样的SKILLS_SOURCE${1:-$HOME/.cache/ai-skills} if [ -d $SKILLS_SOURCE ]; then echo 使用本地 skills 缓存: $SKILLS_SOURCE else echo 克隆 Matt Pocock Skills 仓库... git clone --depth 1 https://github.com/mattpocock/ai-skills.git $SKILLS_SOURCE fi mkdir -p .codex/skills for skill_dir in $SKILLS_SOURCE/skills/*/; do skill_name$(basename $skill_dir) if [ -f $skill_dir/SKILL.md ]; then cp -R $skill_dir .codex/skills/$skill_name echo 已安装 skill: $skill_name else echo 跳过 $skill_name缺少 SKILL.md fi done这里有个很重要的设计只复制包含 SKILL.md 的目录。因为 Codex 的 skill 加载机制是扫描目录下的 SKILL.md 文件如果目录里没有这个文件复制过去也不会被加载还会干扰 Codex 的目录扫描。你也许想问为什么不直接用软链接指向克隆下来的仓库我实际试过软链接在本地跑没问题可一旦你把仓库同步到 CI 或者换一台机器链接就断了而且在 Windows 上创建软链接经常需要管理员权限。所以脚本里我坚持用“复制”虽然会占用一点磁盘空间但胜在稳定。关于仓库地址、目录布局不同作者维护的版本可能有差异使用前建议先看一眼仓库结构。Matt Pocock 的这套 skills 核心是 TypeScript/React 方向文件结构就是典型的skills/name/SKILL.md形式所以脚本按这个约定来扫基本没问题。如果你要接入其他 skills 集合改一下for skill_dir的路径就行。3.5 生成启动提示词 PROMPT.md最后一步是为“人机协作”准备一个入口。我习惯生成一个 PROMPT.md里面写清楚三件事这个项目是什么。接下来开发时遵循哪个流程先 spec 再 plan 再编码。第一个任务从哪里开始。脚本生成的初始版本类似# 项目启动提示词 你是一名资深 TypeScript 工程师。请遵循以下工作流 1. 先阅读 AGENTS.md 和 openspec/ 下的计划与说明。 2. 如果有新需求先按 OpenSpec 格式新增 spec再拆 plan。 3. 开始编码前先调用合适的 skill如 typescript、react。 4. 改完代码后运行测试并说明改动影响。 当前第一个任务为项目初始化一个可运行的 hello-world 入口 同时跑通 pnpm dev 和 pnpm test。这个文件在脚本里用 heredoc 写入。写完之后脚本会打印一段使用说明告诉你下一步可以直接在终端运行codex让它先读PROMPT.md。我在实际使用时会先把PROMPT.md内容粘贴进第一轮 Codex 对话或者把文件路径告诉 Codex让它先读。这样能显著减少第一轮对话的“磨叽”直接进入干活状态。4. 常见问题与排查技巧实录4.1 codex 认证与模型不可用这个组合里Codex 的登录认证和环境配置是最容易出问题的一环。我自己遇到并帮别人排查过这些第一类是登录态丢失或认证失败。表现是运行codex时提示需要登录或者 OAuth 流程在浏览器里转一圈回来后还是失败。处理方式通常可以先把本地已有的凭证目录备份并清理掉再重新登录。注意不同操作系统这个目录位置不一样不要乱删。第二类是模型不可用报错尤其是报the gpt-5.6-sol model is not supported when using codex with a chatgpt account。这句报错字面意思是“你用的是 ChatGPT 账号但这个模型不允许你这么用”。这里核心问题是Codex 可以用 ChatGPT 订阅账号登录也可以用 API Key 认证但两者能用的模型集合不一样。如果你没权限用默认模型最简单的办法是改配置里model字段换成一个当前账号可用的模型名。第三类是希望能接入第三方兼容端点的情况。如果你手头没有官方 API但想用其他提供兼容接口的服务可以在配置里指定base_url之类的方式指向兼容端点。具体能不能用取决于你选的模型服务是否兼容 Codex 的请求格式。这块涉及各家服务商的配置方式不同建议在对应用户手册里查看配置思路其实跟改model是一样的。4.2 OpenSpec 在脚本里卡交互这是脚本化最常遇到的坑。openspec init在交互式终端里很友好但在脚本里会卡住。前面说了两种解法我再补充一个细节如果实在没有非交互参数可以先printf n\n | openspec init之类的管道喂字符但是不同版本的问题数量不同这种喂法很不稳定。我的最终建议是脚本里不调用 init手动创建目录结构即可。OpenSpec 本身对目录结构的要求非常明确你只要按约定的目录结构创建空目录和初始文件后续openspec子命令基本都能正常工作。还有个相关的小坑OpenSpec 的 spec 文件是 Markdown 格式里面 frontmatter 有时包含id、status等字段。如果你手动创建初始文件最好保留 frontmatter 模板否则后续工具解析可能报错。把模板写死在脚本里比每次手动敲一遍靠谱得多。4.3 Skills 加载不掉明明已经把 skills 复制到.codex/skills下了但 Codex 好像完全没反应。我先列一下我排查过的可能性目录放错了。Codex 扫描的是项目级.codex/skills不是你自己建的skills/。如果两者名字相似很容易搞混。SKILL.md 格式不对。Codex 对这种文件有解析要求如果 frontmatter 里缺了必要字段整个 skill 会被跳过。复制完之后可以手动打开一个 SKILL.md 看看。配置没开 skills。也就是 codex.json 里skills.enabled为false或者没配置directories。这种情况下你复制多少文件都没用。改了配置没重启。Codex CLI 通常启动时会加载配置如果你在它运行的过程中改了 skills 目录当前会话不会自动生效退出重进就好了。我见过最坑的一种情况用户把 skills 放到了全局的.codex/skills又同时在项目里放了另一套同名 skill两边冲突时行为就变得很难预测。所以我的建议是同一时刻只在一个位置维护 skills脚本里固定用项目级目录更符合项目自包含的原则。4.4 跨平台脚本差异这个脚本按“bash Unix 工具链”写的在 macOS 和 Linux 上直接跑没问题。但如果你在 Windows 上开发建议用 Git Bash 或者 WSL 来执行不要直接依赖 CMD 或 PowerShell因为脚本里用了cp -R、command -v这类 Unix 风格命令。还有两个跨平台细节值得注意macOS 自带的sed -i和 Linux GNU sed 的写法不同。如果脚本里要做文本替换建议用sed -i.bak这种带备份后缀的写法两端兼容。read交互在 Windows 的 Git Bash 里有时表现不同。如果你脚本里要跟用户交互建议把交互选项做成环境变量判断默认值给好用户可以直接回车跳过别强制等待输入。我的脚本里其实只保留了极少量的read交互检测到已有配置时问一句“是否覆盖”。其他地方全部无交互这样放到 CI 环境里也不会卡住。4.5 问题速查表最后整理一张速查表方便大家直接对着查现象可能原因解决办法codex提示未登录凭证缺失或过期重新执行登录流程报错模型不支持账号权限、模型名不对修改model字段openspec 命令卡住交互式命令在脚本中等待输入手动创建目录或传非交互参数skill 老是不生效目录位置/格式/配置问题按 4.3 检查清单逐项排查脚本在非 Unix 环境报错使用了 Unix 命令用 Git Bash 或 WSL 执行二次运行报目录已存在脚本没有做存在性判断加上如果存在就跳过的逻辑这张表不是完整的排障手册但覆盖了我自己踩过的绝大部分问题。如果你在实战中遇到新问题我的建议是先看日志输出再对照每一步脚本在做什么通常很快能定位到是环境问题还是配置问题。5. 结束与扩展方向脚本我放在自己的 dotfiles 仓库里每次新项目只用两条命令一条从仓库拉下来一条执行初始化。半年下来我大概跑了十几次最大的体会是这个东西的价值不在于“自动化”本身而在于它把一套容易漏步骤、靠记忆维护的流程变成了可版本管理、可团队复制的约定。AI 开发工具更新很快配置项会变、指令格式会变但“先检查环境、再写配置、再建约束、再注入技能、最后给上下文”这个骨架是稳定的值得你为它写一次脚本。如果你也想做类似的工具我最后再给一个建议脚本保持小和弱依赖不要把所有配置都塞进去。它只需要负责“把目录、配置、技能文件放到位”剩下真正复杂的逻辑交给 Codex 和 OpenSpec 本身去处理。后续想扩展的话可以考虑把它做成pnpm create模板、加一个 CI 检查步骤来验证配置是否有效或者针对不同技术栈生成不同的 skills 子集。先跑通再变重这个顺序比一上来追求大而全要稳得多。
返回列表