baozaotumao fb8761a546
docs-check / docs-sync (push) Has been cancelled
feat: 项目级 /coauthor 斜杠命令切换 Claude 署名开关
- template/.claude/commands/coauthor.md.jinja:生成项目自带 /coauthor on|off|status,
  薄包装调用 ./scripts/claude-attribution.sh,Claude Code 里打 / 即可发现
- 仅本项目生效,不装全局、不影响用户其它项目(install-skill.sh 未改)
- 两个脚本不变(开关 + 门禁);终端/CI 仍可直接用脚本
- README 署名章节补 /coauthor 用法 + 文件树补 coauthor.md.jinja

验证:仅后端/全栈两配置均生成 coauthor.md + 两脚本;命令体动作 off/on/status
读写 git config 正确;~/.claude/commands 未受影响;check-docs 通过。
2026-06-02 03:22:00 -07:00

scaffold · new-project skill

一个 Claude Code Skill:在任意项目里对 Claude 说一句"帮我新建项目",即可生成含完整质量门禁(pre-commit、CI、Docker、Claude 规则)的 FastAPI + React 工程骨架,并随选型自动裁剪规则文件。

🚀 安装(推荐)

一条命令装到全局,任意项目可用,无需克隆本仓库:

curl -fsSL https://raw.githubusercontent.com/baozaotumao2025/scaffold/main/scripts/install-skill.sh | bash

用法

安装后,在 Claude Code 中任选一种方式:

/new-project                          # 交互式问卷,逐步选服务/数据库
/new-project my-app                   # 指定项目名,其余交互确认
/new-project my-rules --preset principles   # 仅生成 10 个原理层规则,无服务代码

或者直接用自然语言——Claude 会自动识别并触发 skill

「帮我新建一个全栈项目,要 FastAPI + React,数据库用 postgresql」

可用 presetprinciples(仅规则)· fullstack · fullstack-ai · api-only

模板由 copier 从 GitHub 实时拉取。skill 目录 .claude/skills/new-project/ 自包含SKILL.md + scripts/verify.sh),安装即整目录拷贝,符合 skill 可移植惯例。


核心设计

两层规则体系

脚手架内置的 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 排除
────────────────────────────────────────────────────────────────────

四层质量护栏(左移,编码即查错)

同一套规则(ruff/mypy 读 pyproject.tomleslint/prettier 读各自配置)贯穿四层,越靠前越早发现,到 commit 时基本只是确认:

时机 机制 是否默认生成
1 编辑器 LSP 边打字 .vscode/settings.json + extensions.json:保存自动格式化/修复、实时标红 始终
2 watch 监听 一保存 .vscode/tasks.json:打开项目自动起 tsc --watch / ruff --watch 开关 vscode_auto_watch
3 pre-commit git commit .pre-commit-config.yamlruff/mypy/eslint/tsc/gitleaks 始终
4 CI push / PR .github/workflows/ci.yml 始终

关于 .vscode/

  • 只影响当前项目(工作区级),不碰你的 VSCode 全局配置;个人偏好(主题/字号)仍走全局。
  • 团队级规则,随 scaffold 演进——copier update 走 3-way 合并推送改进,仅改了同一行才提示冲突。
  • 首次用 watch 需在命令面板执行一次 "Tasks: Allow Automatic Tasks" 授权。

按规则生成功能:/new-feature

生成的项目自带一个 Claude Code 命令 /new-feature,把"按规则搭功能骨架"固化成一条标准提示词。

/new-feature 订单
/new-feature 用户认证

模式:纯结构 + 契约(不猜业务逻辑)。 Claude 现场阅读本项目的 .claude/rules,按六边形分层为该功能生成跨层的文件骨架

domain/(实体+值对象+端口 Protocol) → application/services → infrastructure/db(repository)
  → routers → 依赖注入;前端 types/schemas → store → hooks → components
  • 每个方法写完整签名 + docstring(前置/后置条件),方法体留 raise NotImplementedError
  • 接好依赖注入、注册路由、登记错误码
  • 不臆造业务逻辑、不写假设断言的测试——避免你去调试 AI 猜的代码
  • 自检只跑 ruff + mypy(验证结构能编译、类型自洽),不跑 pytest

命令按选型自动裁剪,只生成存在服务对应的层,末尾给出待填充 TODO 清单

分工:脚手架 copier 预生成完整架构基座(分层目录 + 横切层,确定性、能跑、过门禁,见下「架构基座」);/new-feature 引导 Claude 在基座上搭功能切片骨架;业务逻辑你按 testing-tdd.md(先测试后实现)自己填。


Claude 署名策略(每个生成项目自带)

控制提交信息里是否包含 Co-Authored-By: Claude 署名。默认 off(不含),由 commit-msg 门禁每次提交强制执行。仅本项目生效。

在 Claude Code 里(项目自带斜杠命令,打 / 即可找到):

/coauthor status   # 查看当前策略
/coauthor off      # 不含署名(默认)
/coauthor on       # 保留署名

或在终端直接用脚本(CI / 不用 Claude 时):

./scripts/claude-attribution.sh status   # 查看当前策略
./scripts/claude-attribution.sh off      # 不含署名(默认)
./scripts/claude-attribution.sh on       # 保留署名
  • 策略存于 git config scaffold.includeClaude(项目级),_tasks 生成时默认设为 false
  • 门禁check-claude-attribution.sh 挂在 pre-commit 的 commit-msg 阶段——策略 off 时自动剥除任何 Claude 署名行并提示,on 时保留
  • 即使有人/AI 在提交里带了署名,off 策略下也会被自动清掉,保证不入库

架构基座(每个生成项目自带,开箱即跑)

不加任何功能,生成的项目第一天就有完整分层结构 + 与业务无关的横切基础设施,三服务各自通过 ruff/mypy/build 门禁:

backend/src/                         agent/src/                      frontend/src/
├── domain/            (空层包)       ├── domain/  dag/  llm/         ├── components/ErrorBoundary
├── application/services/            ├── providers/ export/ storage/ ├── services/wsClient
├── infrastructure/db/ base(engine)  │     (空层包)                  ├── utils/logger
├── routers/  health + ws            ├── domain/exceptions           ├── App / main(ErrorBoundary
├── middleware/ request_id+access    ├── utils/ ids/files/concurrency│   + Toaster) + tailwind
├── exceptions/ AppException+handler ├── core/ config+logging        └── vite 类型
├── utils/ ids+files(防穿越)         └── main  health/ready + ws
└── core/ config+logging+deps
  • 横切层是确定性的(中间件、异常、DB 接线、日志、WS、错误边界规则里逐字给定)→ copier 预生成,永远一致、不漂移。
  • 运行时目录(日志 ~/{项目}/logs/、临时 ~/{项目}/{uuid}/)由代码按需创建,不入库。
  • 空层包(domain/services 等)等 /new-feature 或你按规则填业务。

脚手架内容

scaffold/
├── copier.yml                           ← 问卷变量 + 条件排除逻辑
├── README.md
├── .claude/skills/new-project/          ← 自包含 skill(拷了即用,符合惯例)
│   ├── SKILL.md                         ← skill 元数据 + 生成指令
│   └── scripts/verify.sh                ← skill 自带(与根 scripts/verify.sh 同步,CI 防漂移)
├── .github/workflows/docs-check.yml     ← scaffold 自身 CI:防文档/verify.sh 漂移
├── scripts/
│   ├── verify.sh                        ← 工具链合规检查(幂等只读,维护/retrofit 用)
│   ├── install-skill.sh                 ← 整目录拷贝安装 skill 到 ~/.claude/skills/
│   ├── check-docs.sh                    ← 校验 README 覆盖 template 架构基座目录
│   └── retrofit.sh                      ← 补装工具链到已有项目
└── template/
    ├── .copier-answers.yml.jinja        ← 记录模板版本+答案,供 copier update
    ├── .pre-commit-config.yaml.jinja    ← 按服务条件生成 hooks(含 gitleaks
    ├── .github/workflows/ci.yml.jinja   ← 按服务条件生成 CI jobs
    ├── .vscode/                         ← 编辑器实时护栏(始终生成)
    │   ├── settings.json.jinja          ← 保存自动格式化/修复(按服务裁剪)
    │   ├── extensions.json.jinja        ← 推荐扩展(ruff/eslint/mypy…)
    │   └── tasks.json.jinja             ← 自动 watch(仅 vscode_auto_watch=true
    ├── docker-compose.yml.jinja
    ├── CLAUDE.md.jinja                  ← 项目说明参数化
    ├── scripts/
    │   ├── claude-attribution.sh        ← 开关:本项目提交是否含 Claude 署名(默认 off
    │   └── check-claude-attribution.sh  ← commit-msg 门禁:按开关移除/保留署名
    ├── .claude/commands/
    │   ├── new-feature.md.jinja         ← 项目内命令:按规则引导生成功能分层代码
    │   └── coauthor.md.jinja            ← 项目内命令:/coauthor 切换 Claude 署名开关
    ├── .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 / Dockerfile / .env.example
    │   └── src/  架构基座:domain application infrastructure/db routers middleware
    │             exceptions utils core(详见上「架构基座」)
    ├── agent/    pyproject / Dockerfile / .env.example
    │   └── src/  架构基座:domain dag llm providers export storage utils core + WS
    └── frontend/ package.json / pnpm-workspace / tsconfig / tailwind / postcss / eslint / vite
        └── src/  架构基座:components(ErrorBoundary) services(wsClient) utils(logger) + 入口

进阶:不装 skill,直接用 copier

以下面向 CI、脚本,或不使用 Claude Code 的场景。日常使用推荐上面的 skill 方式。

前置依赖:

pip install copier        # 或 uv tool install copier

交互式问卷

copier copy git+https://github.com/baozaotumao2025/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
vscode_auto_watch bool false VSCode 打开项目自动启动 watch 任务(编码即时查错)

llm_provider 仅在 include_agent=true 时出现。

静默生成(CI / 脚本中)

# 全栈 + OpenAI API + PostgreSQL
copier copy git+https://github.com/baozaotumao2025/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/baozaotumao2025/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/baozaotumao2025/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/baozaotumao2025/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 my-scaffold
git init && git add . && git commit -m "chore: initial scaffold"

git remote add origin git@github.com:baozaotumao2025/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/baozaotumao2025/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%