baozaotumao 29d60fbd0a first commit
2026-06-01 20:28:07 -07:00
2026-06-01 20:28:07 -07:00

scaffold

基于 Copier 的工程脚手架,一键生成含完整质量门禁的 FastAPI + React 项目,并随选型自动定制 Claude Code 约束规则。


核心设计

两层规则体系

脚手架内置的 Claude Code 规则文件分为两层,职责不同:

层级 规则文件 加载方式 说明
原理层 architecture.md / ddd.md / design-discipline.md 等 10 个 全局恒加载 六边形架构、DDD、SOLID、TDD 等通用原则,换项目不变
落地层 backend*.md / agent*.md / frontend*.md paths 按需加载 原理在本项目具体服务中的落地约束,随选型生成

落地层规则根据问卷答案动态生成或选择,而非固定复制:

问卷选择                           生成的落地层规则
────────────────────────────────────────────────────────────────────
include_agent=true
  llm_provider=gemini-cli     →  agent.md + agent-concurrency.md
                                 + agent-llm-pty.mdPTY/CLI 规范)
  llm_provider=openai-api     →  agent.md + agent-concurrency.md
                                 + agent-llm-api.mdAPI 流式规范)
  llm_provider=anthropic-api  →  同上(agent-llm-api.md

include_agent=false            →  所有 agent*.md 全部排除

database=sqlite                →  backend-db.mdSQLite + WAL 模式)
database=postgresql            →  backend-db.mdasyncpg + 连接池 + pg 迁移注意)

include_backend=false          →  所有 backend*.md 排除
include_frontend=false         →  所有 frontend*.md 排除
────────────────────────────────────────────────────────────────────

脚手架内容

scaffold/
├── copier.yml                           ← 问卷变量 + 条件排除逻辑
├── README.md
├── scripts/
│   ├── verify.sh                        ← 工具链合规检查(幂等只读)
│   └── retrofit.sh                      ← 补装工具链到已有项目
└── template/
    ├── .pre-commit-config.yaml.jinja    ← 按服务条件生成 hooks
    ├── .github/workflows/ci.yml.jinja   ← 按服务条件生成 CI jobs
    ├── docker-compose.yml.jinja
    ├── CLAUDE.md.jinja                  ← 项目说明参数化
    ├── .claude/rules/
    │   ├── # 原理层(10 个,静态,始终复制)
    │   ├── architecture.md / ddd.md / design-discipline.md ...
    │   │
    │   ├── # 落地层:静态但条件复制(按服务选择)
    │   ├── agent-dag.md                 ← DAG 模式(不随 LLM 选型变)
    │   ├── agent-extension-points.md    ← 扩展点模式(不随 LLM 选型变)
    │   ├── agent-llm-pty.md             ← LLM CLI/PTY 规范(仅 gemini-cli
    │   ├── agent-llm-api.md             ← LLM API/SDK 规范(非 gemini-cli
    │   ├── backend.md / backend-concurrency.md
    │   ├── frontend.md / frontend-runtime.md
    │   ├── communication-catalog.md / error-codes.md / observability.md
    │   │
    │   └── # 落地层:动态渲染(.jinja,内容随选型变化)
    │       ├── agent.md.jinja           ← 技术栈表 / 依赖 / 目录 / 配置 / 测试
    │       ├── agent-concurrency.md.jinja  ← PTY 并发节 vs API 并发节
    │       └── backend-db.md.jinja      ← SQLite 配置 vs PostgreSQL 配置
    ├── backend/  pyproject.toml / Dockerfile / .env.example / src/
    ├── agent/    同上
    └── frontend/ package.json / tsconfig / eslint / prettier / vitest / vite

前置依赖

pip install copier        # 或 uv tool install copier

生成新项目

交互式问卷(推荐首次使用)

copier copy git+https://github.com/your-org/scaffold.git my-new-project

问卷包含以下选择:

变量 类型 默认 说明
project_name str My Awesome Service 项目显示名称
project_slug str 自动派生 snake_case 包名
org_name str my-org GitHub 组织名
description str 一行项目描述
include_backend bool true 包含 FastAPI backend
include_agent bool false 包含 LLM Agent 服务
include_frontend bool true 包含 React + Vite 前端
backend_port int 8000 Backend 端口
agent_port int 8001 Agent 端口
frontend_port int 5173 前端端口
python_version choice 3.12 3.11 / 3.12 / 3.13
database choice sqlite sqlite / postgresql
node_version choice 22 20 / 22
llm_provider choice gemini-cli gemini-cli / openai-api / anthropic-api / custom

llm_provider 仅在 include_agent=true 时出现。

静默生成(CI / 脚本中)

# 全栈 + OpenAI API + PostgreSQL
copier copy git+https://github.com/your-org/scaffold.git my-project \
  --data project_name="My Service" \
  --data include_backend=true \
  --data include_agent=true \
  --data include_frontend=true \
  --data database=postgresql \
  --data llm_provider=openai-api

# 仅 APIbackend onlySQLite
copier copy git+https://github.com/your-org/scaffold.git my-api \
  --data include_backend=true \
  --data include_agent=false \
  --data include_frontend=false

# 本地模板调试
copier copy ./scaffold /tmp/test-project

模板更新(推送给已有项目)

cd my-existing-project

# 复用上次答案,自动三路合并
copier update --defaults

# 修改某个答案(如切换数据库)
copier update --data database=postgresql

# 查看更新预览(不实际写入)
copier update --defaults --pretend

.copier-answers.yml 由 Copier 自动维护,记录模板版本和答案,不要手动修改


工具脚本

verify.sh — 合规检查

检查项目工具链配置是否符合 scaffold 规范。只读幂等,不修改任何文件,可重复运行。

用法:./scripts/verify.sh [OPTIONS] [PROJECT_PATH]

选项:
  -h, --help      显示帮助信息
  -v, --verbose   详细输出(显示所有通过项和跳过项)
  -s, --strict    严格模式:警告(△)也视为失败,退出码 1

退出码:
  0  全部通过(严格模式下无警告)
  1  存在失败项
  2  参数错误
# 检查当前目录
./scripts/verify.sh

# 详细模式(显示每项通过/跳过的路径)
./scripts/verify.sh -v

# 严格模式(CI 中使用,警告也阻断)
./scripts/verify.sh -s /path/to/project

# 详细 + 严格(组合简写)
./scripts/verify.sh -vs .

智能检查内容:

  • 自动读取 .copier-answers.yml 获取 llm_providerdatabase 配置
  • 按存在的目录(backend/ / agent/ / frontend/)决定检查哪些服务
  • LLM 驱动规则互斥验证gemini-cli 时检查 agent-llm-pty.md 存在且 agent-llm-api.md 不存在(反之同理),两个同时存在时输出 WARN
  • Claude 规则文件完整性检查(全局规则 + 对应落地层规则)
  • 工具链可用性检查(uv / pnpm / pre-commit / copier 版本)

汇总输出示例:

═══════════════════════════════════════════════════════════════
分类                   通过   警告   失败
根目录                    6      1      0
Backend                   8      0      0
Agent                     7      0      0
Frontend                  9      0      0
Pre-commit 钩子           4      0      0
Claude 规则文件          18      0      0
工具链可用性              4      0      0
───────────────────────────────────────────────────────────────
合计                     56      1      0
═══════════════════════════════════════════════════════════════
✓ 核心检查全部通过  △ 1 项警告(建议修复)

retrofit.sh — 补装工具链到已有项目

对未经 copier 创建的已有项目,叠加 scaffold 模板。全部步骤幂等,重复运行安全。

用法:./scripts/retrofit.sh [OPTIONS] [PROJECT_PATH]

选项:
  -h, --help          显示帮助信息
  -n, --dry-run       预览所有操作,不实际执行任何命令
  -f, --force         强制覆盖配置文件(移除 _skip_if_exists 保护,慎用)
      --no-deps       跳过依赖安装,仅运行 copier copy
      --scaffold URL  指定 scaffold 来源(覆盖 $SCAFFOLD_URL

环境变量:
  SCAFFOLD_URL        scaffold 来源(默认:git+https://github.com/your-org/scaffold.git
# 补装工具链到当前目录
./scripts/retrofit.sh

# 先预览将执行哪些步骤(不实际运行)
./scripts/retrofit.sh --dry-run /path/to/project

# 使用本地 scaffold(开发调试)
SCAFFOLD_URL=./scaffold ./scripts/retrofit.sh /path/to/project

# 使用远程 scaffold,仅运行 copier(跳过 uv/pnpm
./scripts/retrofit.sh --scaffold git+https://github.com/your-org/scaffold.git --no-deps .

# 补装后立即验证
./scripts/retrofit.sh . && ./scripts/verify.sh .

幂等性保证:

步骤 幂等机制
Copier 模版叠加 _skip_if_exists 保护 src/ 代码不被覆盖
uv sync --frozen 保证锁文件一致;已安装时仅校验,不重装
pnpm install --frozen-lockfile 保证锁文件一致
Pre-commit 安装 检测 .git/hooks/pre-commit 已存在时 SKIP--force 才重装

步骤汇总输出示例:

═══════════════════════════════════════════════════════════════
Retrofit 步骤汇总: /path/to/project
───────────────────────────────────────────────────────────────
步骤                           状态
Copier 模版叠加                ✓ 完成
Backend uv sync                ✓ 完成
Agent uv sync                   跳过
Frontend pnpm install          ✓ 完成
Pre-commit 钩子                – 跳过(已安装,幂等)
───────────────────────────────────────────────────────────────
完成: 3  跳过: 2  警告: 0  失败: 0
═══════════════════════════════════════════════════════════════

后续步骤:
  • 运行 ./scripts/verify.sh /path/to/project 验证最终结果

典型组合示例

# 1. 全栈 AI 项目(默认 gemini-cli PTY 模式)
copier copy ./scaffold /tmp/test-full \
  --data include_backend=true --data include_agent=true --data include_frontend=true

# 2. 全栈 AI 项目(OpenAI API 模式,生成 agent-llm-api.md 而非 agent-llm-pty.md
copier copy ./scaffold /tmp/test-openai \
  --data include_backend=true --data include_agent=true --data include_frontend=true \
  --data llm_provider=openai-api --data database=postgresql

# 3. 仅 API 服务(无前端,无 agent)
copier copy ./scaffold /tmp/test-api \
  --data include_backend=true --data include_agent=false --data include_frontend=false

# 4. 验证生成结果(详细模式)
./scripts/verify.sh -v /tmp/test-full

发布到团队

cd /Users/maxta/Downloads/scaffold
git init && git add . && git commit -m "chore: initial scaffold"

git remote add origin git@github.com:your-org/scaffold.git
git push -u origin main

# 打版本 tagcopier update 按 tag 追踪)
git tag v1.0.0 && git push --tags

之后团队成员只需:

pip install copier
copier copy git+https://github.com/your-org/scaffold.git my-project

贡献模板

  1. 修改 template/ 下的 .jinja 文件或静态规则文件
  2. 本地测试:copier copy . /tmp/test && cd /tmp/test && pre-commit run --all-files
  3. verify.sh 验证生成项目合规性:./scripts/verify.sh -v /tmp/test
  4. 打 semver taggit tag v1.1.0 && git push --tags
  5. 已有项目运行 copier update --defaults 三路合并收到更新

添加新的 LLM provider 支持

  1. copier.ymlllm_provider.choices 中增加新选项
  2. template/.claude/rules/agent.md.jinja 中添加对应 {% elif llm_provider == '...' %} 分支
  3. template/.claude/rules/agent-concurrency.md.jinja 中视需要添加分支
  4. 若新 provider 使用不同机制(非 API SDK),按需新建对应规则文件并在 copier.yml_exclude 中添加互斥条件
  5. 更新 scripts/verify.shagent/pyproject.toml 的 SDK 包名检查

添加新的数据库支持

  1. copier.ymldatabase.choices 中增加新选项
  2. template/.claude/rules/backend-db.md.jinja 中添加对应 {% elif database == '...' %} 分支
  3. scripts/verify.shlocal_driver 映射中添加新数据库的驱动包名
S
Description
No description provided
Readme 159 KiB
Languages
Shell 49.7%
Jinja 40.1%
Python 7.5%
TypeScript 2.4%
JavaScript 0.2%