mcpField
S
sync-template

sync-template

github.com/rheinmir开发10266 次安装2 周前更新
代码仓库

关于 sync-template

sync-template 用于在项目与 Rheinmir/setup 之间同步模板变更。它会自动处理下游更新并保留本地修改,也为上游发布、迁移和调试提供手动流程。

主要功能

  1. 01本地与远程文件三方哈希比较
  2. 02自动拉取新增及本地未改文件
  3. 03保留本地内容并报告冲突
  4. 04OKF 回填、指纹刷新与验证
  5. 05安装到三个 Claude Code 位置
  6. 06支持预演和 JSON 报告

适用场景

  1. 01将模板修复同步到项目
  2. 02向上游发布已批准的模板变更
  3. 03检查本地与远程编辑冲突
  4. 04迁移旧版 skills 目录结构

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheinmir/setup --skill sync-template

安装后在 Claude Code 中输入/sync-template确认已加载。

详细介绍

技能:sync-template

内容

目的和背景
  • 目的: 在项目与 https://github.com/Rheinmir/setup.git 之间同步结构/模板改进。
  • 触发条件(何时使用):
    • 上游: 本地改进了模板 → 保存到 Master。
    • 下游: Master 有较新的修复 → 引入项目。
  • 非目标: 不同步 .env、凭据和业务文档;不自行使用 --strategy pull 来缩短时间;不 git clone 模板;不自动触发(disable-model-invocation: true);Antigravity 无法运行此技能(沙盒会阻止工具)。
心智模型

下游默认流程:version.json + manifest remote → 对 3 个时间点的哈希进行分类(disk ↔ R0 remote_synced ↔ 当前 remote)→ NEW/UPDATE 自动 PULL · KEPT 保留 · CONFLICT 保留本地 + 保存 remote 版本 → OKF 回填 → fingerprint → 在 3 个位置安装技能 → 验证 3 个位置 → 记录日志。上游 / 迁移 / 调试则执行 MANUAL STEPS 0–8,并在 Step 5 停下询问用户。

输入和输出约定
字段必填?含义
输入同步方向是downstream(默认,FAST PATH)或 upstream(MANUAL)
输入.template-manifest.json + harness/version.json是inclusion list、remote URL、branch、remote_synced
输入--branch、--strategy pull、--dry-run、--json否更改 branch、获取 CONFLICT 对应的 remote、预览、输出机器可读内容
输入用户决定CONFLICT 或 Step 5 时需要获取 remote 还是保留本地;拉取/推送哪些文件
输出已同步的模板文件 + OKF 回填是将旧 wiki 文件中的粗体转换为 YAML
输出刷新的 harness/version.json是OKF 后的 fingerprint + template_version + remote_synced
输出安装在 .claude/commands/、~/.claude/skills/、~/.claude/commands/ 的技能downstream验证 3 个位置
输出报告 + 退出代码是0 表示干净,1 表示下载/OKF/验证出错,3 表示存在需要决定的 CONFLICT
输出wiki/log.md 中的日志行 + 报告草稿输出是脚本在使用 --full 时自动记录日志
规则和能力
  • RULE-01(MUST):绝不同步 .env、凭据和业务文档。
  • RULE-02(MUST):始终审核 remote 分支——非默认分支可能是最新的。
  • RULE-03(MUST):始终为 [CONFLICT] 显示差异 → 等待指示。
  • RULE-04(MUST):绝不使用 cp -R——逐个文件处理。
  • RULE-05(MUST):每次同步都执行 Step 3——检测旧版 skills/,并提出迁移。
  • RULE-06(MUST):每次下游同步都执行 Step 7——安装所有 3 个 Claude Code 位置。
  • RULE-07(MUST):[NEW]:上游提交前添加到 manifest。
  • RULE-08(MUST):[MISSING]:下游复制后添加到 manifest。
  • RULE-09(MUST):Frontmatter:技能需要 name: + description:;斜杠命令只需要 description:。
  • RULE-10(MUST):跳过 README.md、index.md、log.md 以及没有 Purpose/Steps 的文件。
  • 能力:读取远程模板(HTTP/GitHub API);在项目和用户级技能/命令目录中写入文件;上游同步时推送到远程模板(仅在获准后)。
失败边界
  • CONFLICT(双方都做了更改)→ 保留本地,将 remote 版本保存到 /tmp/sync-template-conflicts/,退出代码为 3 → 与用户澄清。
  • 下载/OKF/验证出错 → 退出代码为 1 → 失败,完成前修复 ✗。
  • 无法确定哪个 remote 分支最新 → 澄清,询问用户使用哪个分支。
  • health-check 为 OK → 无需同步,停止(成功,无操作)。
  • 旧版 skills/ 布局 → 提议迁移,删除前须先确认。

操作

主工作流
步骤类型输入操作输出/退出失败/后续
W01判断要求选择路径:常规下游 → FAST PATH --full;上游、迁移旧结构、调试 → MANUAL(B01)路径—
W02效果manifest、远程服务运行一次 python3 harness/scripts/sync-template.py --full(同步 + OKF + 指纹 + 安装到 3 个位置 + 验证 + 日志)报告exit 1 → 失败;exit 3 → W03
W03判断报告阅读报告;若 CONFLICT 且想采用远程版本 → 重新运行 --strategy pull;若是其他分支 → 使用 --branch决策不确定 → 询问用户
W04确定性报告不要额外调用 okf-check、health-check、验证循环,也不要自行修改日志向用户报告—
W05效果结果输出 Report 草稿草稿 + 索引 + 日志0 个产物 → 跳过

各步骤详情(W01–W05 和 MANUAL 分支的事实来源):

FAST PATH — 下游通过一条命令 --full(< 30s,默认)

下游同步是一个非交互式、自包含的脚本。使用 --full 调用一次 → 所有同步后步骤(Step 6a/6b/8 + 写入日志)都在同一进程中运行。Agent 读取一份报告后进行汇报——不要重复运行单独的命令。此仓库的基准数据:稳定状态下 full 用时 0.27s · full pull+install+verify 用时 0.76s (harness/metrics/sync-template-bench.json)。

python3 harness/scripts/sync-template.py --full        # ⭐ MẶC ĐỊNH: sync + OKF backfill + fingerprint + verify ×3 + ghi log, 1 process
python3 harness/scripts/sync-template.py --full --json  # như trên, output máy đọc (đọc okf_migrated / verify_bad)
python3 harness/scripts/sync-template.py --dry-run      # xem trước, không ghi (kèm --full để xem OKF sẽ migrate gì)
python3 harness/scripts/sync-template.py --strategy pull # ghi đè cả CONFLICT bằng remote (backup .local-bak)

--full 运行一次即可——不要接着调用 okf-check、health-check --update、验证循环,也不要自行 Edit log.md(脚本已经完成所有操作)。这是将技能控制在 30s 以内的方法:旧瓶颈是同步后步骤中的 Agent 往返次数,而不是 CPU。未使用 --full 标志 = 行为与旧版完全一致。

通过 3 个哈希进行分类——磁盘 ↔ R0(上次同步时的远程版本,保存在 version.json:remote_synced)↔ 当前远程版本:

  • NEW(本地缺失)+ UPDATE(远程有更新,且本地未改动)→ 自动 PULL。
  • KEPT(我方已自定义,远程没有更新)→ 保持不变,不询问。
  • CONFLICT(双方都有改动)→ 默认保留本地版本 + 将远程版本保存到 /tmp/sync-template-conflicts/ 以便比较;退出代码为 3。绝不会为缩短时间而自动使用 --strategy pull。

脚本中的自动流程(--full):获取远程 version.json+manifest → 分类 → 并行下载 → 进程内 OKF 回填(将 bold 迁移为 YAML,幂等)→ 刷新 version.json(OKF 之后计算指纹 + template_version + remote_synced)→ 将技能安装到 3 个位置(.claude/commands/、~/.claude/skills/、~/.claude/commands/)→ 自行验证 3 个位置 → 追加写入 wiki/log.md。退出状态:0 表示无问题 · 1 表示下载/OKF/验证出错 · 3 表示需要处理 CONFLICT。

需要手动介入的情况(先运行脚本,再阅读报告):

  • 报告中有 CONFLICT,且你想采用远程版本 → 重新运行 --strategy pull(一个决策,而不是三个)。
  • 远程分支与 version.json:branch 不同 → 使用 --branch <分支名>(查看 Step 2 以审查分支)。
  • 需要迁移旧的 skills/ 结构(Step 3),或需要进行上游操作(推送)→ 使用下方的 MANUAL STEPS。

⚠ 已修复的 Bug:health-check --update 会将基准设为磁盘上的版本 → 同步无法区分“远程有更新”和“我方已自定义” → 差点覆盖自定义文件。此脚本使用独立的 remote_synced 基准(上次同步时的远程哈希),因此可以正确区分。不要再使用 patterns(磁盘版本)作为分类基准。


MANUAL STEPS(回退流程——上游操作、迁移旧结构或调试)
Step 0:预检——health-check(同步前诊断)

运行 /health-check(python3 harness/scripts/health-check.py --root .)以了解应该朝哪个方向同步:

  • NEEDS-SYNC(落后/缺失)→ 下游(拉取)。
  • DRIFT(本地已修改)→ 上游(推送)或还原。
  • OK → 无需同步,停止。
Step 1:加载 Manifest

读取 .template-manifest.json——文件包含清单 + 远程 URL。

Step 2:获取数据并审查分支
  • CRITICAL:列出所有远程分支:gh api repos/<owner>/<repo>/branches。
  • 检查每个分支的提交日期——不要假设 master/main 是最新的。
  • 不确定 → 询问用户要使用哪个分支。
  • 通过 gh api + curl 获取——不要使用 git clone。
步骤 3:检测旧结构迁移

检查是否存在需要迁移到 llmwiki/ 的旧 skills/ 布局:

# Signs of old structure:
[ -d "skills/" ] && [ ! -d "llmwiki/skills/" ]   # old only
[ -d "skills/" ] && [ -d "llmwiki/skills/" ]       # both exist → migration in progress

旧 skills/ 与新的 llmwiki/skills/ 并存:

  1. 列出 skills/(扁平的 .md 文件和子目录:dev-loop/、wiki-loop/ 等)
  2. 映射旧文件 → 新文件:
    • skills/dev-loop/*.md → llmwiki/skills/dev-loop/*.md
    • skills/wiki-loop/*.md → llmwiki/skills/wiki-loop/*.md
    • skills/orchestrate/*.md→ llmwiki/skills/orchestrate/*.md
    • skills/utils/*.md → llmwiki/skills/utils/*.md
    • skills/*.md(扁平文件) → 已由子目录覆盖,跳过重复项
  3. 内容相同 → 旧文件已过时,可以安全删除。
  4. 显示迁移表 → 删除前先确认。
步骤 4:比较清单文件

对 includes 中的每个文件执行本地与远程 diff:

BASE="https://raw.githubusercontent.com/<owner>/<repo>/<branch>"
for file in <includes>; do
  http_code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/$file")
  # SAME / DIFF / MISSING / NEW / ABSENT
done

状态:

  • SAME — 相同,跳过
  • DIFF — 内容不同
  • MISSING — 仅远程存在 → 下游候选项
  • NEW — 仅本地存在 → 上游候选项
  • ABSENT — 两者均不存在
步骤 5:同步计划

显示表格。停止 → 询问用户:全部拉取 / 全部推送 / 指定文件 / 为每个 DIFF 选择方向。

步骤 6:执行
  • 下游:mkdir -p → curl -sfL <url> -o <local_path> → 更新 wiki/log.md
  • 上游:通过 gh/git 提交并推送
  • 逐个处理文件 — 不使用 cp -R

步骤 6a/6b/8 已合并到 --full。 如果运行 FAST PATH --full,则跳过 6a/6b/8 — 脚本已在处理过程中完成 OKF-backfill + 刷新 fingerprint + 验证 + 记录日志。以下步骤仅 在 MANUAL 模式下使用(调试 / 上游 / 迁移旧结构),而不是在 --full 之后执行。

步骤 6a:OKF 回填 (MANUAL — --full 已完成)

新的模板/技能可能会升级 wiki 格式(例如 OKF v0.1 标准)。拉取后,将所有仍使用粗体伪 frontmatter(如 **Type:**)的旧内容文件转换为 YAML frontmatter,以免触发 R9:

python3 harness/scripts/okf-check.py --check      # exit 3 = có file chưa đạt OKF
python3 harness/scripts/okf-check.py --migrate    # convert bold → YAML (chỉ THÊM frontmatter, giữ body/## Origin)
  • 幂等 — 已有 --- frontmatter 的文件会被跳过。保留项(index/log/README/decisions/_template…)自动豁免。
  • 迁移后:重新运行 --check,直至 DAT CHUAN OKF v0.1,然后像处理其他 wiki 变更一样更新 index/log。
步骤 6b:刷新版本指纹 (MANUAL — --full 已完成)

模式内容刚刚发生变化 → 更新 harness/version.json,避免健康检查误报 DRIFT:

python3 harness/scripts/health-check.py --update   # KHÔNG --bump ở project con
  • --bump major|minor|patch 仅在模板仓库 Rheinmir/setup 中发布新模式版本时运行。
  • 在模板仓库执行上游同步:推送后,运行 --update --bump <part>,然后提交 harness/version.json。
步骤 7:安装为原生技能 (每次下游同步都会运行)

收集已同步的技能文件(清单中的 llmwiki/skills/ 下)。跳过:README.md、index.md、log.md,以及不包含 ## Purpose/## Steps 的文件。

A. 项目级(.claude/commands/ — 此仓库):

mkdir -p .claude/commands/
# Add description: frontmatter if missing, then copy
printf -- "---\ndescription: %s\n---\n\n" "$desc" | cat - <src> > .claude/commands/<name>.md

B. 全局用户级(~/.claude/skills/<name>/SKILL.md — 所有项目):

mkdir -p ~/.claude/skills/<name>/
# Requires name: + description: frontmatter
printf -- "---\nname: %s\ndescription: %s\n---\n\n" "$name" "$desc" | cat - <src> > ~/.claude/skills/<name>/SKILL.md

C. 全局斜杠命令(~/.claude/commands/<name>.md):

printf -- "---\ndescription: %s\n---\n\n" "$desc" | cat - <src> > ~/.claude/commands/<name>.md

全部安装。报告:

| Skill          | Project .claude/commands/ | ~/.claude/skills/ | ~/.claude/commands/ |
|----------------|---------------------------|-------------------|---------------------|
| propose        | ✓                         | ✓                 | ✓                   |
| ingest         | ✓                         | ✓                 | ✓                   |
| ...            | ...                       | ...               | ...                 |
步骤 8:验证并完成
for name in <skill-list>; do
  [ -f ".claude/commands/$name.md" ]          && echo "✓ proj  $name" || echo "✗ proj  $name"
  [ -f "$HOME/.claude/skills/$name/SKILL.md" ] && echo "✓ global $name" || echo "✗ global $name"
done

完成前修复 ✗。无需重启。

分支
ID类型条件行为跳过 / 失败汇合点
B01conditional_required需要上游同步、迁移旧 skills/ 结构或调试运行 MANUAL STEPS 0–8,在步骤 5 停止并询问用户常规下游同步 → FAST PATHW05
B02recoveryexit 3 CONFLICT,且用户选择采用远程版本重新运行 --strategy pull(覆盖,并备份到 .local-bak)用户保留本地版本 → 不执行任何操作W04
B03conditional_required远程分支与 version.json:branch 不同在审查分支(步骤 2)后使用 --branch <名称>—W02
B04user_optional想要预览使用 --dry-run(搭配 --full 可预览将迁移哪些内容至 OKF)—W02
B05conditional_required检测到旧 skills/ 布局(步骤 3)显示迁移表,确认后再删除用户拒绝 → 保留W05
验证与停止

所有必需条件:脚本退出码(0/1/3)、验证 3 个安装位置、okf-check.py --check 输出 DAT CHUAN OKF v0.1(MANUAL)、Step 8 中的 [ -f … ] 循环不再出现 ✗。--full 只运行一次,退出码为 0 时停止;退出码为 3 时停止并等待用户决定;MANUAL 在 Step 5 停止并等待审核。

示例
  • **成功:**子项目中,Master 有新修复 → python3 harness/scripts/sync-template.py --full → 2 个 UPDATE 自动 PULL,1 个 KEPT 保持不变,OKF 迁移 3 个文件,验证 3 个位置 ✓,在 < 1 秒内退出码为 0 → 报告结果,不再运行任何命令。
  • 边界情况/失败:llmwiki/skills/dev-loop/ship.md 在本地和远程都有修改 → CONFLICT,保留本地版本,将远程版本放在 /tmp/sync-template-conflicts/,退出码为 3 → 显示差异,等待用户;不自动使用 --strategy pull。
参考 — Agent 兼容性
Agent运行?原因
Claude Code是完整的工具访问权限
OpenCode是完整的工具访问权限
Antigravity否沙盒会阻止文件/命令工具
交付 — 输出报告

所有主要技能任务完成后,将提案草稿写入 wiki。

步骤

1. 构建文件名:

  • 格式:DDMMYY-<ten>.md
  • DDMMYY = 今天的日期(例如,2026 年 6 月 2 日为 020626)
  • <ten> = 2–4 个 kebab-case 单词,概括完成的工作(例如,landing-page-coteccons、brand-kit-fintech、ingest-auth-spec)

2. 写入 llmwiki/wiki/sources/draft/DDMMYY-<ten>.md:

---
type: draft
title: "DDMMYY-<ten>"
status: proposed
tags: [<skill-name>, output-report]
timestamp: YYYY-MM-DD
---

# DDMMYY-<ten>
**Type:** draft
**Status:** proposed
**Tags:** <skill-name>, output-report
**Proposed:** YYYY-MM-DD

## What
<One sentence — what this skill invocation produced or decided>

## Output
<Key artefacts, files created/modified, or decisions made>

## Files
| File | Action |
|------|--------|
| `path/to/file` | created / modified |

## Notes
- Invoked via: `/<skill-name>` skill

## Origin
- **Draft:** `wiki/sources/draft/DDMMYY-<ten>.md`
- **Commit:** _(filled by verify-before-commit)_
- **Date promoted:** _(filled by verify-before-commit)_

3. 更新 wiki 索引和日志:

  • llmwiki/wiki/index.md — 追加一行:| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |
  • llmwiki/wiki/log.md — 追加:## YYYY-MM-DD — <skill-name> — <ten>

仅当该技能没有生成任何产物且没有任何决策时才跳过(例如,/caveman-stats 这类纯显示模式)。

评论

支持 Markdown