apply-template
Original:🇺🇸 English
Translated
Apply the ai-env agentic development environment template to the current repo, with intent-preserving merge for existing files
8installs
Sourcecamacho/ai-skills
Added on
NPX Install
npx skill4agent add camacho/ai-skills apply-templateTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Apply ai-env Template
Apply the agentic development environment template to the current repository.
Argument: optional path to ai-env clone. No argument = clone from GitHub (primary path).
Phase 0 — Pre-flight
Clean working tree check
Run . If there are uncommitted changes, warn the user and ask whether to proceed or stash first. A dirty tree makes it hard to review what the template changed.
git status --porcelainPhase 1 — Source Resolution & Discovery
Locate template source
- If an argument was provided, use that path and verify it's a clean git checkout
- If NO argument was provided, clone from GitHub:
and use that
git clone --depth 1 https://github.com/camacho/ai-env.git /tmp/ai-env-template - If the default local path exists and no argument was given, prefer the GitHub clone (ensures latest version)
~/projects/camacho/ai-env - If all fail, tell the user and stop
Read manifest
Read from the template source directory. This classifies every file as , , or .
apply-template.manifest.jsoncopy_if_absentsmart_mergeskipScan target
Check which and files already exist in the current repo (cwd).
copy_if_absentsmart_mergeFor files that already exist in the target: these will be smart-merged (not skipped) to pick up any new template additions while preserving target customizations.
copy_if_absentPresent plan
Show the user a summary:
Template Application Plan:
Source: <path>
Target: <cwd>
Copy (new): N files — <list>
Smart merge (new): N files — <list of smart_merge files not in target>
Smart merge (both): N files — <list of smart_merge files in both>
Merge (existing copy_if_absent): N files — <list>
Skipped: N files (template-specific)
Proceed?Wait for confirmation before continuing.
Phase 2 — Copy
For each entry in :
copy_if_absent- Directories (entries ending with ):
/the target directory, then copy all files recursively. Skip individual files that already exist.mkdir -p - Files: if the file does NOT exist in the target, copy it verbatim. If it exists, apply the same smart merge logic as Phase 3 (the file has diverged from template — preserve target intent while adding template additions).
Also ensure these directories exist even if empty:
ai-workspace/plans/ai-workspace/decisions/
Phase 3 — Smart Merge
For each file in , read BOTH the template version and the target version (if it exists). If the target file doesn't exist, just copy the template version. If both exist, merge according to the rules below.
smart_mergeAGENTS.md — Semantic Merge
- Understand intent: read both versions completely. Identify the purpose of each section.
- Keep from target: ,
## Stack,## Commands,## Architecture— preserve these sections entirely## Gotchas - Add from template if missing: ,
## Agent Roles & Dispatch,## Protected Files,## Conventions,## Workflow Reference## Context Loading Rules - Resolve duplicates: if both have a section with the same heading, favor the template version for structural/convention sections, favor the target for project-specific sections
- Update: the title line — replace the project name with the target repo's directory name
- Preserve: any custom sections the target has that aren't in the template
- Cohesion check: after merge, read the result and verify sections don't contradict each other
tsconfig.json — Deep Merge
- Start from template base as the foundation
- Deep merge : overlay target's compilerOptions on top of template's. Target wins on collision.
compilerOptions - Preserve from target: ,
include,exclude, and any other top-level keysreferences - Inject if missing: these strict options from the template: ,
strict,noUncheckedIndexedAccess,verbatimModuleSyntax,exactOptionalPropertyTypes,noImplicitOverridenoFallthroughCasesInSwitch - Surface conflicts: if template and target have contradictory values for the same option (e.g., vs
strict: true), present the conflict to the user for resolutionstrict: false - Cohesion test: after merge, verify don't have contradictory flags (e.g.,
compilerOptionswithmodule: "commonjs")verbatimModuleSyntax: true
.claude/settings.json
- Preserve from target: all existing and
permissions.allowentries,permissions.denydefaultMode - Union merge: arrays — add template entries not already present (deduplicate)
permissions.deny - Union merge hooks: for each hook event (PreToolUse, PostToolUse, etc.), keep all target hooks. Add template hooks only if no hook with the same already exists in the target
matcher - Preserve: any other keys the target has (disabledMcpjsonServers, enabledPlugins, etc.)
package.json
- Preserve from target: ,
name,version,description,main,type,dependencies,repository,license— everything except scripts and devDependenciesauthor - Merge scripts: add any scripts from template that don't exist in target. Target wins on collision.
- Merge devDependencies: add packages from template that aren't in target's devDependencies (commitlint packages, lefthook, @biomejs/biome, typescript). Never remove or downgrade existing deps.
- Add if missing: ,
enginespackageManager
biome.json
- Preserve from target: all existing rules, config,
filesconfigformatter - Add if missing: linter rules from template that don't exist in target
- Never remove any rule the target already has
.gitignore
- Union merge: combine every unique line from both files, deduplicated
- Preserve: section comments (lines starting with ) and blank line groupings from both files
# - Order: target's lines first, then new lines from template appended at the end under a comment
# ai-env template
skills-lock.json — Union Merge
- Union merge object: combine all skill entries from both template and target. Each entry has
.skills(git URL or local path, depending onsource),sourceType(sourceTypeor"git"), and"local"(SHA-256 integrity hash).computedHash - Template wins on conflict: if the same skill name exists in both, use the template's entry (,
source,sourceTypeall come from the template)computedHash - Never remove: target skills not in the template are always preserved — projects may have custom skills
- Top-level : keep the higher integer from either side (this is the lockfile schema version, not a skill version — individual skills do not have version fields)
version - Post-merge: after writing the merged lockfile, instruct: "Run to materialize any newly added skills for both agents"
npx skills install -a claude-code -a codex
Example merge logic:
Template: Target:
{ "version": 1, "skills": { { "version": 1, "skills": {
"validate": { "validate": {
"source": "git@...ai-skills.git", "source": "git@...ai-skills.git",
"sourceType": "git", "sourceType": "git",
"computedHash": "abc..." "computedHash": "abc..."
}, },
"reflect": { "custom-lint": {
"source": "git@...ai-skills.git", "source": "local",
"sourceType": "git", "sourceType": "local",
"computedHash": "def..." "computedHash": "xyz..."
} }
}} }}
↓ merged result:
{ "version": 1, "skills": {
"validate": { ... }, ← kept (same in both)
"custom-lint": { ... }, ← preserved (target-only)
"reflect": { ... } ← added from template
}}Directories: .claude/agents/
, .claude/rules/
, .claude/skills/
.claude/agents/.claude/rules/.claude/skills/- Recurse into each directory
- New files: copy from template
- Existing files: apply semantic merge — understand the intent of both versions, preserve target customizations, add missing template sections
Phase 4 — Post-Apply
-
Createwith content:
ai-workspace/.template-versionversion: <manifest version> applied: <ISO 8601 timestamp> source: <template source path> -
Dependency check: if devDependencies were added to package.json, detect the package manager (pnpm-lock.yaml → pnpm, yarn.lock → yarn, package-lock.json → npm) and ask: "New devDependencies added. Run?"
<pm> install -
Workflow warning: if anyfiles were copied, check for the secret:
.github/workflows/bashif command -v gh &> /dev/null && gh secret list 2>/dev/null | grep -q "CLAUDE_CODE_OAUTH_TOKEN"; then # Secret exists — no warning needed else warn: "GitHub workflows added. You'll need to set CLAUDE_CODE_OAUTH_TOKEN as a repo secret (Settings → Secrets → Actions)." fi -
Hook warning: ifreferences hook scripts at
.claude/settings.json, check if each script exists on disk. Warn about any missing ones.~/.claude/hooks/ -
Dotfiles sync: Ask the user if they want to install user-level configs:
ai-env includes user-level configs for Claude and Codex (hooks, skills, profiles). Install them? Run: $AI_ENV_ROOT/dotfiles/sync.sh push (where $AI_ENV_ROOT is the template source directory) This copies dotfiles/claude/ → ~/.claude/ and dotfiles/codex/ → ~/.codex/If they agree, runfrom the template source directory (not cwd)."$TEMPLATE_SOURCE/dotfiles/sync.sh" push -
Auto-add post-setup todos via TodoWrite:
- "Update AGENTS.md — fill in Stack, Commands, Architecture, Gotchas for your project"
- "Update .claude/agents/ descriptions to reference your project"
- "Run to deploy user-level configs (if not done above)"
$TEMPLATE_SOURCE/dotfiles/sync.sh push - "Review .claude/settings.json hooks and adjust paths for your environment"
-
Summary: print a list of all files created, merged, and skipped.
Phase 5 — Context Migration (prompted, not automatic)
This phase scans for ALL existing AI context, memory, and configuration in the target repo and walks the user through migration interactively. Never delete or overwrite context automatically — every action requires explicit user confirmation.
Discovery scan
Check ALL of the following locations. If none have content, skip this phase entirely with a message: "No existing AI context found — skipping migration."
Project-scoped (in repo):
- — project memory (check if it has content beyond the seed template)
ai-workspace/MEMORY.md - — existing plans (especially
ai-workspace/plans/completed plans).done.md - — existing ADRs
ai-workspace/decisions/ - — working notes
ai-workspace/scratchpad.md - — custom workflow (may differ from template)
ai-workspace/workflow.md - — pre-existing skills (not from this template run)
.claude/skills/ - — pre-existing agent definitions
.claude/agents/ - — pre-existing rules
.claude/rules/ - — project permissions, hooks, deny rules
.claude/settings.json - — local-only overrides (not checked in)
.claude/settings.local.json - — Codex configuration with profiles
.codex/config.toml - — existing Claude instruction file
CLAUDE.md - — existing universal instruction file
AGENTS.md - — Gemini-specific instructions (if present)
GEMINI.md - or
.cursorrules— Cursor-specific rules (if present).cursor/rules/ - /
.claudeignore— existing context exclusions.codexignore - or
.github/workflows/claude.yml— existing CI workflowsclaude-code-review.yml
User-scoped (outside repo — read-only, inform user):
- — Claude Code auto-memories for this project
~/.claude/projects/<path-encoded-cwd>/memory/- Path encoding: replace with
/, e.g.,--Users-patrickcamacho-projects-myapp - Each file has frontmatter with
.md,name,description(user/feedback/project/reference)type
- Path encoding: replace
- — auto-memory index for this project
~/.claude/projects/<path-encoded-cwd>/MEMORY.md - — user's global instructions (may reference project patterns)
~/.claude/CLAUDE.md - — global hook scripts that project hooks may duplicate
~/.claude/hooks/ - — global agent definitions that project agents may shadow
~/.claude/agents/ - — global slash commands (catchup, reflect, etc.)
~/.claude/commands/ - — installed plugins (check
~/.claude/plugins/in settings)enabledPlugins
Present findings
Show the user a categorized summary:
Context Migration — Found <N> items across <M> locations:
Memory:
- ai-workspace/MEMORY.md (42 lines, last updated 2026-03-15)
- ~/.claude/projects/.../memory/ (6 files: 2 user, 2 feedback, 2 project)
Plans & Decisions:
- ai-workspace/plans/001-feature.done.md (completed, immutable)
- ai-workspace/decisions/001-architecture.md
Skills:
- .claude/skills/deploy/SKILL.md (custom, not in template)
- .claude/skills/validate/SKILL.md (CONFLICTS with template version)
Agents & Rules:
- .claude/agents/implementer.md (customized from template)
- .claude/rules/feature-branches.md (matches template)
Configuration:
- .claude/settings.json (12 allow rules, 3 hooks, 2 deny rules)
- .codex/config.toml (custom profiles: review, deploy)
Instruction Files:
- CLAUDE.md (project-specific, references @AGENTS.md)
- AGENTS.md (customized — 5 sections differ from template)
CI Workflows:
- .github/workflows/claude.yml (existing, may need permission updates)
User-scoped (informational):
- ~/.claude/projects/.../memory/feedback_testing.md
- ~/.claude/hooks/post-edit-format.sh (also referenced in project settings)Wait for user to review before proceeding to migration steps.
1. Memory — ai-workspace/MEMORY.md
If both template and target have with real content:
ai-workspace/MEMORY.mdMerge strategy (semantic, not line-by-line):
- Read both files completely. The template MEMORY.md has this seed structure:
markdown
# Project Memory > Living document updated by /reflect after each task. 200-line limit. > Last updated: — ## Key Decisions ## Implementation Status ## Gotchas - Preserve ALL content from the target's MEMORY.md — this is accumulated project knowledge
- If the target is missing sections from the template seed (Key Decisions, Implementation Status, Gotchas), add them as empty sections at the end
- If the target has extra sections not in the template, keep them
- Update the header comment to include the template's line if missing
> Living document... - Present the merged result and ask the user to confirm
If only target has content: keep it, add missing template sections.
If only template has content: copy the seed template (fresh start).
2. Memory — Claude Code auto-memories (~/.claude/projects/)
These are user-scoped and managed by Claude Code's built-in memory system. They live outside the repo and are NOT migrated automatically. Instead, inform the user:
- List each memory file with its ,
name, andtypefrom frontmatterdescription - Explain: "These are Claude Code's per-project memories stored at . They persist across sessions and inform Claude's behavior for this project."
~/.claude/projects/.../memory/ - Ask: "Are any of these stale or incorrect? I can flag them for your review but won't modify them during template application."
- If any or
projecttype memories contain information that should be inreferenceinstead (so other agents can see it), suggest the user move that content manuallyai-workspace/MEMORY.md
3. Plans and decisions
- Completed plans (): Always preserve — these are immutable records. Inform the user they exist.
*.done.md - Active plans (no suffix): Ask if still in progress or should be marked done.
.done.md - ADRs: Always preserve — immutable after commit. Check if any reference patterns that the template changes (warn if so).
- Templates (): Replace with template version if different (these are scaffolding, not content).
TEMPLATE.md - scratchpad.md: If non-empty, ask user whether to preserve, archive, or reset.
- workflow.md: If target has a custom workflow that differs from template, present both and ask which to keep (or merge).
4. Skills
For each skill directory in :
.claude/skills/- Not in template (custom skill): Keep as-is. Inform user it's preserved.
- Same name as template skill (e.g., both have ):
validate/SKILL.md- Diff the two versions
- Present the differences to the user
- Options: keep target version, replace with template, or merge (user reviews merged output)
- Template has new skills not in target: These were already copied in Phase 2. Just inform the user.
5. Agents, rules, and commands
For each file in and :
.claude/agents/.claude/rules/- Same file exists in both: Diff them. If target has customizations (model changes, extra instructions, project-specific context), present the diff. Default: keep target version for agents (they're often customized), keep template version for rules (they're more structural).
- New from template: Already copied in Phase 2. Inform user.
- Target-only (custom): Preserve. Inform user.
Check for shadowing between global and project agents:
- If and
~/.claude/agents/architect.mdboth exist, note that the project version takes precedence..claude/agents/architect.md
6. Settings and permissions
For :
.claude/settings.json- This was already smart-merged in Phase 3. Summarize what was added/changed.
- Specifically call out:
- Hooks: List which hooks exist in both global () and project. Per the hook placement rule: global hooks = personal workflow, project hooks = codebase contract. Warn if the same hook appears in both (unnecessary duplication of expensive hooks).
~/.claude/settings.json - Deny rules: Any new deny patterns from the template
- Allow rules: Any new allow patterns (user should review these)
- Plugins: If or
enabledPluginsare present, list themdisabledMcpjsonServers
- Hooks: List which hooks exist in both global (
For :
.claude/settings.local.json- Never touch. Inform user it exists and what it contains.
For :
.codex/config.toml- If target has custom profiles, preserve them. Merge any new template profiles that don't collide.
7. Instruction files (CLAUDE.md, AGENTS.md, GEMINI.md, .cursorrules)
- AGENTS.md: Already merged in Phase 3. Summarize what sections were added/preserved.
- CLAUDE.md: If target has a custom CLAUDE.md that doesn't just :
@AGENTS.md- Read it. Identify project-specific instructions vs boilerplate.
- Preserve project-specific content. Add template boilerplate sections if missing.
- GEMINI.md: If present, inform user. Template doesn't provide one — this is the user's custom file. Preserve.
- .cursorrules: If present, inform user that AGENTS.md is the preferred universal format. Ask if content should be merged into AGENTS.md or kept separately.
.cursorrules
8. CI workflows
If or existed before template application:
.github/workflows/claude.ymlclaude-code-review.yml- Diff with template versions
- Call out permission differences (vs
contents: read, missingwrite)allowed_tools - Present upgrade path if target workflows have weaker permissions
9. Context exclusions (.claudeignore, .codexignore)
- : Handle separately from
.claudeignore. Check if target has one. If so, union-merge (same strategy as.gitignore). If not, copy template version..gitignore - : If present, preserve. Template doesn't provide one.
.codexignore
Summary prompt
After presenting all findings, ask:
Ready to apply these migration decisions? (y/n)
You can also:
- "skip" to skip migration entirely (all files from Phases 2-4 are already applied)
- "details <item>" to see the full diff for any item aboveKey principle: This phase is informational and advisory. The user has final say on every decision. Present what exists, explain what the template expects, and recommend — but never act without confirmation.
Re-application
When running on a repo that already has :
ai-workspace/.template-version- files are smart-merged if present (picks up template additions while preserving customizations)
copy_if_absent - files are always re-merged (this is how template updates flow)
smart_merge - If the user passes , overwrite
--forcefiles completely instead of mergingcopy_if_absent