Sync template
Configuration governance for Claude Code. Bootstrap, audit, sync, and evolve .claude/ across projects.
npx -y skills add luiseiman/dotforge --skill sync-templateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Update an existing project's Claude Code configuration against the current dotforge template, without losing local customizations.
SKILL.md
4.9 KB, as published. Nobody here has run it
Sync Template
Update the current project's Claude Code configuration against the latest version of dotforge.
Principle: merge, not overwrite
NEVER overwrite existing files without confirmation. Compare and propose changes.
NEVER touch settings.local.json — it is the user's personal configuration.
NEVER modify sections marked with <!-- forge:custom --> in CLAUDE.md.
Step 0: Verify global
Before syncing the project, verify that ~/.claude/CLAUDE.md exists and contains behavior rules (communication, planning, autonomy). If global rules are active, the project's _common.md only needs technical rules (git, naming, testing, security). Do not duplicate what is already in global.
Step 1: Detect current state
- Read the current
.claude/settings.json - Read the current
CLAUDE.md - Read existing
.claude/rules/ - Read existing
.claude/hooks/ - Detect stacks using
$DOTFORGE_DIR/stacks/detect.md - Read
~/.claude/CLAUDE.mdto know which rules are already covered globally
Step 2: Compare against template
For each component, compare with the dotforge version:
settings.json — Smart merge
- allow: union of sets. Add missing permissions from base template + stacks. NEVER remove local permissions the project already has.
- deny: union of sets. Add missing security denies. NEVER remove local denies.
- hooks: add missing hooks from template. Preserve custom project hooks.
- Other fields: preserve everything that is not allow/deny/hooks (e.g., MCP configs).
Rules
- Is
_common.mdmissing? → propose adding it - Are rules for the detected stack missing? → propose adding them
- Are existing rules outdated? → show diff, propose update
- Custom project rules (not in template) → DO NOT TOUCH
.claude/rules/domain/→ NEVER TOUCH. Domain rules are project-owned knowledge, not template-managed. Skip entirely during sync.
Hooks
- Is
block-destructive.shmissing? → propose adding + chmod +x - Is the stack's lint hook missing? → propose adding + chmod +x
- Custom project hooks → DO NOT TOUCH
- Verify that existing hooks are executable (chmod +x)
CLAUDE.md
- Compare standard template sections with the project's sections
- Sections with
<!-- forge:custom -->→ SKIP entirely - Missing template sections → propose adding
- Custom project sections → DO NOT TOUCH
Step 3: Generate dry-run
Show the user what would change BEFORE applying anything:
═══ SYNC DRY-RUN: {{project}} ═══
dotforge: {{version}} (current project: {{previous_version or "unknown"}})
NEW FILES (will be created):
+ .claude/rules/_common.md
+ .claude/hooks/block-destructive.sh
UPDATED FILES (merge):
~ .claude/settings.json
+ allow: "Bash(docker *)", "Bash(docker compose *)"
+ deny: "**/.env.local"
(local permissions preserved: "Bash(custom-script *)")
~ .claude/rules/backend.md
diff: +3 lines (new common errors)
NO CHANGES:
= .claude/rules/frontend.md (already up to date)
= .claude/hooks/lint-ts.sh (already up to date)
IGNORED (custom):
⊘ .claude/rules/strategies.md (not in template)
⊘ CLAUDE.md section "<!-- forge:custom -->"
Apply changes? (yes/no/select)
Step 4: Apply with confirmation
Only apply the changes the user approves.
yes→ apply allno→ cancelselect→ show each change and ask yes/no individually
For settings.json: build the final merged JSON. Before writing, validate that the JSON is valid:
echo '<json_content>' | python3 -c 'import json,sys; json.load(sys.stdin)'
If validation fails, show the exact error and DO NOT write the file. Fix the JSON before continuing.
For hooks: copy + chmod +x.
Step 4b: Update manifest
After applying changes, update (or create) .claude/.forge-manifest.json:
- If manifest exists, read it
- For each file created or modified during sync, recalculate hash:
shasum -a 256 <file> | cut -d' ' -f1 - Update
dotforge_version,synced_at, andstacks(from detected stacks) - Write the updated manifest
Format:
{
"dotforge_version": "<version from $DOTFORGE_DIR/VERSION>",
"synced_at": "<current date YYYY-MM-DD>",
"stacks": ["<detected-stack-1>", "<detected-stack-2>"],
"files": {
".claude/settings.json": {"hash": "sha256:<hash>", "source": "template+stacks"},
".claude/rules/_common.md": {"hash": "sha256:<hash>", "source": "template"}
}
}
Include ALL files in .claude/ that are managed by dotforge (not only those that changed in this sync).
Step 5: Update registry
Update in $DOTFORGE_DIR/registry/projects.yml:
last_sync:→ current datedotforge_version:→ current dotforge version
Step 6: Verify
Run the /audit-project logic to confirm the score improved or held steady.
Show score before and after.