بنقرة واحدة
sync-project-config
把 claude-code-global 仓库管理的"跨项目共享开发配置模板"的最新变化同步进当前项目;含 adopt 模式(无 marker 老项目首次接入)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
把 claude-code-global 仓库管理的"跨项目共享开发配置模板"的最新变化同步进当前项目;含 adopt 模式(无 marker 老项目首次接入)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | sync-project-config |
| description | 把 claude-code-global 仓库管理的"跨项目共享开发配置模板"的最新变化同步进当前项目;含 adopt 模式(无 marker 老项目首次接入) |
| disable-model-invocation | false |
用户调用此 skill 表示要把仓库的模板(~/.claude/templates/<stack>/)变化反映到当前项目。两种模式:
.agent-template.yml marker → 计算 diff → AI 智能 merge 提议 → 用户批量决策 → 执行三种项目形态(本轮均支持),差异只在生效模板源:
len >= 2):前端 / 后端正交叠加(如 python-uv 落根 + react-vite 落 frontend/),各 stack 按各自 path 落点 + _common 一并参与len == 1):<stack> + _common 两源参与len == 0):仅 _common,适用于模板源仓库本身(claude-code-global)或所有 stack 都不合身、但仍想复用 _common stack-无关资源(issue templates、labels.yml、.prettierrc 等)的项目各 stack 的 path 来自 marker(bootstrap / adopt 按 stack.yml default_path 写入:python-uv→.、react-vite→frontend)。
三态收敛约定(下文统一遵循、不再逐处复述):凡「遍历 stacks」对每条 stack 各跑一遍;len == 1 退化为单条、行为与旧单 stack 完全一致;len == 0 走「仅 _common」分支。skipped 读写位置随形态而定——len >= 1 用 stacks[].skipped(_common 归 stacks[0]),len == 0 用 marker 顶层 skipped(不为 _common 造虚拟 stack 条目,以免破坏「_common 不进 stacks 列表」约定)。
详细 schema / 设计决策:~/.claude/global-repo/docs/11-跨项目共享模板与sync-skill/(SCHEMA.md / PROMPT.md / PLAN.md)
按顺序,任一失败立即停止并报告原因:
git rev-parse --is-inside-work-tree 返回 true~/.claude/templates/ 必须存在且至少含一个 stack 子目录~/.claude/global-repo/ 必须存在且为指向本仓库的软链~/.claude/global-repo/ 内必须能跑 git rev-parse HEAD(即仓库未损坏)任一失败 → 提示用户重跑 bash ~/.claude/global-repo/install.sh 并退出。
marker 文件名在 round 22 由 .cc-template.yml 改为 .agent-template.yml。读 marker 前先做一次迁移检查:
.cc-template.yml 且不存在新名 .agent-template.yml → 用 git mv .cc-template.yml .agent-template.yml 重命名(前置检查已确保是 git 仓库),并明确告知用户「检测到旧版 marker 文件名,已自动迁移为 .agent-template.yml」。需求管理已改为「云端 issue 单一真源、无本地索引文件」(见 GLOBAL_AGENTS.md「需求管理」章)。老项目本地可能仍遗留 docs/BACKLOG.md——它与云端 open issues 是双写副本,正是新约定要消除的 drift。sync 是「把约定变更落地到老项目」的天然承载点,故在此做一次性迁移(做完即删文件、后续幂等无操作,类比上文「旧名 marker 自动迁移」)。
探测:项目根 docs/BACKLOG.md 是否存在。
git rm,然后继续正常 sync:
docs/BACKLOG.md,分出两类条目:
## P0/P1/P2 段里的行,每行本就带一个云端 issue 链接);## 已完成 / 不再追踪 段里的行,每条带原因)。python3 $HOME/.claude/scripts/platform_issue.py issue-view <N>)。都在 → 无需动作(云端已是真源,删文件不丢信息);若某行没有 issue 链接(极老的裸文本条目)→ 提示用户先 /backlog 把它补成云端 issue,再继续。wontfix 的 closed issue(与 /finish Step 2 同一手法):逐条 issue-create --title "刻意不做:<一句话>" --body-file <tmp> --label wontfix --label type:docs --label area:<Y> --label priority:P2(body 保留原因文字),建完 gh issue close <N> -r "not planned"(GitLab 用 glab issue close <N>)。wontfix label 缺失先补进 .github/labels.yml 并 sync。label 契约见 ~/.claude/scripts/platform_issue.md。git rm docs/BACKLOG.md,告知用户「已废弃本地 BACKLOG.md,open 项速览改用 saved query(按 priority 过滤 open issues),刻意不做项已归档为 wontfix closed issue」。读项目根 .agent-template.yml:
直接 Read 文件、按 YAML 语义读字段。需要:
template_commit(旧 commit hash)stacks 列表(0、1 或多条);每条读 stack(名)、path(落点)、skipped(数组)、variants(map: 变体落地目标名 → 选中 key,可缺省,缺省视作空 map —— 老项目 bootstrap 时还没这机制)len == 0 时改读 marker 顶层 skipped(数组,可缺省视作空数组)校验:
stacks 各条的 path 用其声明值(如 python-uv→.、react-vite→frontend),不再强制 path == .stack 名或重复 path,若有 → 报错并请用户手动修(后续 2.x / 6.x 的「遍历 stacks」「<stack>」按顶部「三态收敛约定」处理。)
NEW_COMMIT=$(git -C ~/.claude/global-repo rev-parse HEAD)
如果 working copy 有未提交修改:
git -C ~/.claude/global-repo status --porcelain templates/
非空 → 警告用户「~/.claude/global-repo 的 templates 有未提交修改,sync 仅基于 HEAD 进行,未提交内容不会同步」。
扫的模板源 = marker 里每个 stack 的 templates/<stack>/ + 始终自动应用的 _common/。把所有生效源作为 pathspec 一次性 diff:
# 例:marker 有 python-uv + react-vite 两条
git -C ~/.claude/global-repo diff --name-status <old>..<new> -- \
templates/python-uv/ templates/react-vite/ templates/_common/
len == 1:templates/<stack>/ templates/_common/(等价旧单 stack)len == 0:仅 templates/_common/⚠️ 不要省略 pathspec:git diff 不传路径会扫全 templates、误把项目未接入的其他 stack 的变更带进来。pathspec 只列 marker 里实际有的 stack。
输出形如:
M templates/python-uv/__root__/.gitignore(修改,来源 stack)A templates/_common/__root__/.github/ISSUE_TEMPLATE/feat.md(新增,来源 _common)D templates/python-uv/__subpath__/configs/old.json(删除)若输出为空 → 报告「模板自上次同步起未变化」,再继续走 skipped 重检(2.5)。
对应到项目侧路径(先按 diff 路径 templates/<source>/... 判定该文件来源是哪个 stack 或 _common):
__root__/<rel> → 项目根的 <rel>(任何来源都落根)__subpath__/<rel> → 该来源 stack 的 <path>/<rel>(python-uv path . → 项目根;react-vite path frontend → frontend/<rel>)_common 理论上不应出 __subpath__/ 内容(设计约束:_common 只承载 stack-无关、根级资源);若违反,按项目根 <rel> 兜底 + 输出警告不同 stack 的 __subpath__ 落到各自 path 子树、天然不撞;__root__ 内容各 stack 与 _common 共贡献到根,不应有同名冲突(设计约束);万一有,stack 优先。
读取 3 份内容做对比(<source> 是 <stack> 或 _common):
git -C ~/.claude/global-repo show <old>:templates/<source>/<scope>/<rel>~/.claude/templates/<source>/<scope>/<rel>四象限:
| 模板侧 | 项目侧 | 默认建议 |
|---|---|---|
| 修改 | 与旧模板一致(未自定义) | take 新模板(clean update) |
| 修改 | 与旧模板不一致(已自定义) | AI 智能 merge:保留用户修改语义 + 引入模板新内容 |
| 新增 | 不存在 | 创建 |
| 新增 | 已存在(罕见) | 询问 take / 保留 / 智能 merge |
| 删除 | 仍存在 | 询问删除 / 保留(用户可能仍需要) |
特殊:变体组文件(凡文件名形如 <target>.variant.<key>)永远不直接写同名文件——同一 <target> 的多个 .variant.<key> 是「一组互斥变体」,只有一个落地为 <target>(去 .variant.<key> 后缀,落该来源 stack 的落点)。normal sync 遇到某变体组文件有 diff(M/A/D)时,先看 marker 里该 stack 的 variants[<target>] 记没记选择:
variants[.gitlab-ci.yml] == shell)→ 只处理选中 key(shell)那份变体与项目侧已落地 <target> 的四象限(模板旧版 / 新版都取 .variant.shell,项目侧取 <target>);其余 key 的变体文件 diff 一律忽略(用户没在用、不落地)。选中变体新增了 job / 改了脚本 → 按四象限(多半「模板改 + 项目侧已自定义或一致」)提议 take / merge 进项目侧 <target>。variants 字段或缺该 target)→ 该变体组标记「需补选」,进 TODO;第 5 节决策时问用户选一个 key(展示各变体人话说明,key 说明由 skill 按已知 key 硬编码给,同 bootstrap Step 3.3.7),选后:① 用选中变体与项目侧 <target> 做四象限落地;② 把选择写回 marker 对应 stack 的 variants[<target>](6.1 持久化)。.variant.<key> 从模板消失)→ 若正是当前选中 key,提示用户「所选变体已从模板移除,需改选其他变体」;非选中 key 则静默忽略。各变体的人话说明(当前唯一变体组
.gitlab-ci.yml):docker→ "Docker executor runner";shell→ "本地 shell runner(无 docker executor,脚本装 uv)"。与 bootstrap Step 3.3.7 同一份,改动时两处同步。
特殊:fragment 文件(凡文件名以 .fragment 结尾)永远不直接写同名文件,去掉 .fragment 后缀得目标相对路径(始终落项目根),按目标类型合并。当前两类:
(a) pyproject.toml.<section>.fragment(TOML 段合并)
<section> 用 - 分隔层级(如 ruff → [tool.ruff]、uv → [tool.uv]、uv-index → [[tool.uv.index]]、uv-workspace → [tool.uv.workspace]、pytest → [tool.pytest.ini_options];以 fragment 内实际表头为准)。[[tool.uv.index]]):按 name 字段 union(项目侧已有同名条目则跳过,避免重复注册)。pyproject.toml:
python-uv stack → 标记为「待 4.4 完成 uv init 后合并」python-uv-workspace stack → 直接用本 stack 的 workspace fragments 内容创建虚拟根 pyproject.toml(虚拟根无 [project]、不该 uv init),不等 4.4(b) .vscode/<name>.json.fragment(JSON 合并,目标项目根 .vscode/<name>.json)
extensions.json 的 recommendations 数组做有序去重 union;settings.json 对象做顶层键 union(键只一侧→并入;两侧都为对象→递归深合并;标量冲突→询问)。.vscode/<name>.json.fragment 依次合并进同一个项目根目标,得各 stack 推荐 / 设置的并集(前后端语言作用域键天然不相交,纯 union)。之所以汇聚到项目根:VS Code 单根工作区只读仓库根的 .vscode/,子目录 stack 也须借此落根。fragment 迁移去重(重要):当模板把某资源从「__subpath__ 普通文件」改为「__root__/*.fragment」时,diff 会同时出现「D __subpath__/X」与「A __root__/X.fragment」。判断二者目标项目路径是否相同:
python-uv 的 __subpath__/.vscode/settings.json(path . → 根)与新 __root__/.vscode/settings.json.fragment(→ 根)目标都是根 .vscode/settings.json)→ 判为机制迁移而非真删除:抑制删除提案,仅执行 fragment 合并(content 不变时合并为幂等 no-op,原文件原样保留)。react-vite 的 __subpath__/.vscode/*(path frontend → frontend/.vscode/)与新根 .vscode/*.fragment(→ 根))→ 二者互不矛盾:照常提案删除旧 frontend/.vscode/* + fragment 合并进根 .vscode/*。普通文件 → 变体组 迁移去重(重要):当模板把某资源从「普通文件 X」改为「一组变体 X.variant.<key>」时(如本机制把 .gitlab-ci.yml 改为 .gitlab-ci.yml.variant.docker / .variant.shell),老项目 normal sync 的 diff 会同时出现「D X」与多个「A X.variant.<key>」。这些变体的落地目标都是同一个 <target> == X(去 .variant.<key> 后缀),故:
X 的删除提案(项目侧已落地的 X 就是那份要保留 / 更新的目标文件,不能删)。A X.variant.<key>:marker 有该 target 选择 → 用选中变体与项目侧 X 四象限;marker 无(这类老项目 marker 必然无 variants)→ 标记「需补选」,第 5 节问用户选一个、落地 + 写回 marker。.gitlab-ci.yml」平滑迁到「按 runner 选定的变体」,.gitlab-ci.yml 文件本身不被误删。skipped 读写位置按顶部「三态收敛约定」(len >= 1 归 stacks[].skipped、len == 0 归顶层 skipped)。汇总所有来源的 skipped 后,对每条做「是否又变过」重检:
file(含来源 source 段,如 __root__/.github/labels.yml) 与 skipped_at_commitgit -C ~/.claude/global-repo log --oneline <skipped_at_commit>..<new> -- templates/<source>/<file>(<source> 是该文件实际来源 stack 或 _common)每文件一项,含:序号 + 文件(来源段)、模板侧动作(M/A/D)、模板变化摘要、项目侧状态(是否已自定义 / 是否存在)、建议动作。示例:
[1] .gitignore (root) M 新增 .ruff_cache/ | 项目侧已自定义(*.bak) → 智能 merge:保留 *.bak + 追加 .ruff_cache/
[2] .github/workflows/lint.yml (root) A | 项目侧不存在 → 创建
跳到第 5 节「用户批量决策」。
如果 2.3 输出空 + 2.5 没有"被重新提案的 skipped 项" + 没有需新增/删除的文件 → 报告「无需同步,模板与项目已对齐」并退出,不写 marker。
~/.claude/templates/ 下非下划线开头的子目录列表。
先按 bootstrap Step 3.1 同法探测每个 stack 的 default_path(读 templates/<stack>/stack.yml,缺省 .)。询问用户:列出可选 stack,让其勾选 0 个或多个(前端 / 后端可叠加)。path 不询问,由各 stack 的 default_path 决定(python-uv→.、react-vite→frontend)。
一个都不选 = 无 stack(只 _common):仅复用 _common 的 stack-无关资源(issue templates、labels.yml、.prettierrc 等)。适用于模板源仓库本身(claude-code-global)或确认所有 stack 都不合身的项目。此时 4.3 仅扫 _common/ 一个源,marker stacks 最终写为 []。
待新增的模板源由 4.2 选择决定:
_common/ + 每个选定 <stack>/ 的 __root__/* + __subpath__/* 全部当作"待新增"列入 TODO
~/.claude/templates/_common/(如存在,自动应用,__root__ 落项目根)~/.claude/templates/<stack>/:__root__ 落项目根、__subpath__ 落该 stack 的 <default_path>/(如 react-vite→frontend/)~/.claude/templates/_common/ 一个源判断:
<target>.variant.<key>):与 bootstrap Step 3.3.7 对称——同一 <target> 的多个变体当作一条 TODO「选一个变体落地」,第 5 节问用户选 key(展示人话说明),只把选中那份落地为 <target>、其余不落地;选择在 6.1 写进 marker 该 stack 的 variants[<target>]。项目侧已有 <target> → 冲突询问 take / 保留 / merge。*.fragment(pyproject.toml.*.fragment 与 .vscode/*.json.fragment)同 2.4 特殊处理.github/labels.yml 时:额外把"调 helper label-sync-from-file 同步 labels 到远端"作为单独一条 TODO(helper 契约见 ~/.claude/scripts/platform_issue.md)。跳到第 5 节。
选中的 stack 既不含 python-uv 也不含 python-uv-workspace 则整段跳过。命中其一时(落点 path 均 .,下列命令在项目根执行),先询问用户确认是否执行(默认 yes,给「只要配置不要装依赖」选项),yes 则按以下子步骤逐条执行;no 则跳过整段并把决策记录到收尾反馈。
逻辑等同 bootstrap 的 Step 3.5,区别在 adopt 模式下 pyproject.toml 更可能已存在(老项目),4.4.1 跳过 uv init 是常态。python-uv 与 python-uv-workspace 互斥,正常只命中其一。
单包 python-uv:
[ -f pyproject.toml ] && echo "exists, skip uv init" || uv init --package
--package 落标准 src 布局(src/<pkg>/__init__.py 空文件 + [build-system] uv_build 的 pyproject.toml),见 rules/python.md §2。adopt 下 pyproject.toml 多半已存在、本步 no-op。
多包 python-uv-workspace:绝不 uv init --package(会在虚拟根写 [project] + src/ 破坏 workspace 形态)。虚拟根 pyproject.toml 由本 stack 的 workspace fragments 合并而成、成员包随模板 packages/* 复制就位;本步只确保上述 fragments 已合(2.4 的 TOML 段合并对「目标不存在」会用 fragment 内容创建根 pyproject.toml)。
跑完后回处理 2.4 标记「待 4.4 后合并」的所有 pyproject.toml.*.fragment(清华源段必须先合,否则 4.4.2 在国内会卡)。
uv add --dev pytest pytest-cov ruff
uv 会跳过已装的,幂等。失败 → 报告 stdout/stderr,提示用户手动重试 + 暂停 skill,不自动回滚已写文件。
python-uv-workspace:uv add --dev在虚拟根同样写入根[dependency-groups] dev并触发一次uv sync,把packages/*各成员 editable 装入、解析跨成员workspace=true依赖——本步即让整个工作区可跑。
command -v pre-commit >/dev/null || uv tool install pre-commit
pre-commit install
成功后打印 pre-commit installed at .git/hooks/pre-commit。不强制跑 pre-commit run --all-files(首次接入易出大量 finding,让用户自决)。
跳到第 5 节。
选中的 stack 不含 react-vite 则整段跳过。含 react-vite 时,前端模板(含 package.json + 固化 npmmirror 源的 .npmrc)已在 4.3 当作待新增列入 TODO、第 6 节执行后落到 frontend/。先询问用户确认是否执行(默认 yes,给「只要文件不装依赖」选项):
cd frontend && npm install
失败 → 报告 stdout/stderr,提示用户手动重试,不自动回滚。装完可选 npm run lint / npm run build 验证。
跳到第 5 节。
向用户呈现 2.6 / 4.3 的 TODO,让用户给出统一指令,例如:
「全部 accept;第 3 条 skip;第 5 条改成全替模板,不要 merge」
AI 解析指令、产出最终执行计划,再次回显(per-file 写出每条最终动作)让用户显式确认后才执行。
按确认后的计划逐条执行:
accept (新增):写文件
accept (修改/智能 merge):用 Edit / Write 写回合并后内容
accept (删除):删文件
accept (pyproject 段合并):把 pyproject.toml.<section>.fragment 合并进 pyproject.toml 的对应段(按 2.4 命名约定与合并语义)
accept (.vscode JSON 合并):把 .vscode/<name>.json.fragment 合并进项目根 .vscode/<name>.json(按 2.4 (b) 合并语义:recommendations 数组 union / settings.json 顶层键 union)
accept (label sync):调 helper 自动按平台 dispatch,exit 2/3/4 按契约降级、不阻塞其他 accept 项:
python3 $HOME/.claude/scripts/platform_issue.py label-sync-from-file .github/labels.yml
helper 完整行为(gh/glab dispatch、color 转换、exit code 降级、stdout TSV)见 ~/.claude/scripts/platform_issue.md。
accept (变体落地 / 补选):把选中 key 的 <target>.variant.<key> 内容落地为 <target>(或按四象限 merge 进已存在的 <target>),其余变体不落地;把「<target> → 选中 key」写进对应 stack 的 variants map(6.1 持久化)。补选场景(老项目 marker 无记录)同理,落地 + 写 marker 一并完成。
skip:在 marker 的 skipped 列表(位置按「三态收敛约定」)追加 / 更新条目,字段:file、skipped_at_commit: <NEW_COMMIT>、reason: <可选>
注意:skipped[] 的更新策略:
skipped_at_commit 为 NEW_COMMIT回写 .agent-template.yml:
template_commit 更新为 NEW_COMMITbootstrap_time 不动(这是首次 bootstrap 时间)source 不动variants 按 6 节「accept (变体落地 / 补选)」更新:保留 marker 已有的变体选择(本次未触及的不动);本次落地 / 补选 / 改选的变体写 / 更新对应 stack 的 variants[<target>]。无任何变体组的 stack 不写该字段。Adopt 模式额外:
bootstrap_time 设为当前 ISO 时间source 取 git -C ~/.claude/global-repo config --get remote.origin.url,无则填占位stacks 按 4.2 用户选择写,每条 path 取该 stack 的 default_path;落了变体组的 stack 增写 variants map(4.3 的变体落地选择):
[{stack: python-uv, path: ".", skipped: [], variants: {.gitlab-ci.yml: shell}}, {stack: react-vite, path: "frontend", skipped: []}]stacks: [],同时顶层加 skipped: []列出实际改动的项目侧文件清单(path-by-path),提示用户:
git diff 自行 review.pre-commit-config.yaml 还未生效,跑 pre-commit install(adopt 模式 4.4 已自动做过;normal sync 不做);可选跑 pre-commit run --all-files 验证/commit 或自行 git commit不自动 commit —— 由用户决策(与 /bootstrap、/backlog 一致)。
按照 git 规则自动分析变更并提交代码
提交前的自动 review 迭代环:委派子 agent 跑 CC 自带 /code-review(默认 sonnet × medium,并发/难复现等硬 diff 升 opus × high),发现高置信正确性问题就修、跑测试+happy-path 验证、复审,迭代到「运行验证通过 + 无高置信 correctness 问题」才放行。收敛靠运行验证+置信过滤,非 reviewer 挑不出为止。三条硬规则:永远显式传档位、永远委派子 agent、只用两个合法的模型×档位组合。由 /commit 在生成 commit 前自动调用,也可手动跑
为空项目搭建文档骨架(README.md / CLAUDE.md / DEVTREE.md),仅在项目首次开发前调用一次
依据 docs/DEVTREE.md 中作者维护的 Epic 结构,重新生成可视化图表和节点索引
完成当前开发项:撰写 SUMMARY.md,反思跨项目可沉淀流程并可向 claude-code-global 提 issue,关联并关闭 issue(GitHub / GitLab,如有),提交代码
诊断本地分支分叉并按清单引导完成 rebase,历史保持 FF 直线