From f42633bbd22938d06d90d55c0d755954bccc9f6f Mon Sep 17 00:00:00 2001 From: baozaotumao Date: Tue, 2 Jun 2026 02:56:02 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20Claude=20=E7=BD=B2=E5=90=8D=E5=BC=80?= =?UTF-8?q?=E5=85=B3=20+=20commit-msg=20=E9=97=A8=E7=A6=81=EF=BC=88?= =?UTF-8?q?=E7=94=9F=E6=88=90=E9=A1=B9=E7=9B=AE=E8=87=AA=E5=B8=A6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - template/scripts/claude-attribution.sh:一条命令切换本项目是否含 Claude 署名 (on|off|status,存于 git config scaffold.includeClaude,默认 off) - template/scripts/check-claude-attribution.sh:commit-msg 门禁逻辑,off 时自动 - .pre-commit-config 增加 commit-msg 阶段 local 钩子调用门禁 - copier.yml _tasks 默认 git config scaffold.includeClaude false - 修复:template/scripts/*.sh 补可执行位(否则生成项目直接运行报 permission denied) - README 加「Claude 署名策略」章节 + 文件树补 template/scripts/ 验证:开关 on/off/status、门禁直接调用、经 pre-commit(language:system) 调用均生效, off 剥除 / on 保留,copier 生成 rc=0、脚本可执行、门禁已挂载。 scaffold 仓库自身亦已装本地 commit-msg 钩子,保证本仓库今后不含 Claude 署名。 --- README.md | 19 ++++++++++++++++ copier.yml | 2 ++ scripts/retrofit.sh | 2 +- template/.pre-commit-config.yaml.jinja | 9 ++++++++ template/scripts/check-claude-attribution.sh | 18 +++++++++++++++ template/scripts/claude-attribution.sh | 24 ++++++++++++++++++++ 6 files changed, 73 insertions(+), 1 deletion(-) create mode 100755 template/scripts/check-claude-attribution.sh create mode 100755 template/scripts/claude-attribution.sh diff --git a/README.md b/README.md index e61ff4c..6af713c 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,22 @@ domain/(实体+值对象+端口 Protocol) → application/services → infrastru --- +## Claude 署名策略(每个生成项目自带) + +控制提交信息里是否包含 `Co-Authored-By: Claude` 署名。**默认 off(不含)**,由 commit-msg 门禁每次提交强制执行。 + +```bash +./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 门禁: @@ -158,6 +174,9 @@ scaffold/ │ └── 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 ← 项目内命令:按规则引导生成功能分层代码 ├── .claude/rules/ diff --git a/copier.yml b/copier.yml index 32897d0..c5b1c72 100644 --- a/copier.yml +++ b/copier.yml @@ -43,6 +43,8 @@ _exclude: _tasks: - command: git init + # 默认不在提交中包含 Claude 署名(commit-msg 门禁据此剥除);改用 ./scripts/claude-attribution.sh on 保留 + - command: "git config scaffold.includeClaude false" - command: git add . - command: "git commit -m 'chore: initialize project from scaffold'" - command: uv sync diff --git a/scripts/retrofit.sh b/scripts/retrofit.sh index a047b07..a7c169c 100755 --- a/scripts/retrofit.sh +++ b/scripts/retrofit.sh @@ -14,7 +14,7 @@ set -euo pipefail # ── 默认值 ──────────────────────────────────────────────────────────────────── -SCAFFOLD_URL="${SCAFFOLD_URL:-git+https://github.com/your-org/scaffold.git}" +SCAFFOLD_URL="${SCAFFOLD_URL:-git+https://github.com/baozaotumao2025/scaffold.git}" TARGET="." DRY_RUN=0 FORCE=0 diff --git a/template/.pre-commit-config.yaml.jinja b/template/.pre-commit-config.yaml.jinja index 0be158f..1613581 100644 --- a/template/.pre-commit-config.yaml.jinja +++ b/template/.pre-commit-config.yaml.jinja @@ -24,6 +24,15 @@ repos: - id: conventional-pre-commit stages: [commit-msg] + # Claude 署名门禁:按 scaffold.includeClaude 策略移除/保留(默认移除) + - repo: local + hooks: + - id: claude-attribution-gate + name: Claude 署名门禁 + entry: bash scripts/check-claude-attribution.sh + language: system + stages: [commit-msg] + {%- if include_backend or include_agent %} # Python(ruff 同时做 lint + format) diff --git a/template/scripts/check-claude-attribution.sh b/template/scripts/check-claude-attribution.sh new file mode 100755 index 0000000..61c9730 --- /dev/null +++ b/template/scripts/check-claude-attribution.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# commit-msg 门禁:按 scaffold.includeClaude 策略处理 Claude 署名。 +# 由 pre-commit 在 commit-msg 阶段调用,参数 $1 为提交信息文件。 +# off(默认):剥除 Co-Authored-By: Claude 行 +# on :保留(./scripts/claude-attribution.sh on) +set -euo pipefail + +msg_file="${1:?用法: check-claude-attribution.sh }" +include="$(git config --get scaffold.includeClaude 2>/dev/null || echo false)" +[ "$include" = "true" ] && exit 0 + +if grep -qiE 'co-authored-by:.*claude' "$msg_file"; then + tmp="$(mktemp)" + grep -viE 'co-authored-by:.*claude' "$msg_file" >"$tmp" + mv "$tmp" "$msg_file" + echo "🛡 已移除 Claude 署名(scaffold.includeClaude=false;保留请运行 ./scripts/claude-attribution.sh on)" +fi +exit 0 diff --git a/template/scripts/claude-attribution.sh b/template/scripts/claude-attribution.sh new file mode 100755 index 0000000..acf8bfa --- /dev/null +++ b/template/scripts/claude-attribution.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# 设置本项目提交是否包含 Claude 署名(Co-Authored-By: Claude)。 +# 策略存于 git config scaffold.includeClaude,由 commit-msg 门禁强制执行。 +# 用法:./scripts/claude-attribution.sh on|off|status +set -euo pipefail + +case "${1:-status}" in + on) + git config scaffold.includeClaude true + echo "✓ 本项目提交将【保留】Claude 署名" + ;; + off) + git config scaffold.includeClaude false + echo "✓ 本项目提交将【移除】Claude 署名(默认)" + ;; + status) + v="$(git config --get scaffold.includeClaude 2>/dev/null || echo 'false(默认,未显式设置)')" + echo "scaffold.includeClaude = $v" + ;; + *) + echo "用法: $0 on|off|status" >&2 + exit 2 + ;; +esac