apply-template について
apply-template は、ai-env のエージェント開発環境テンプレートをリポジトリに適用するスキルです。プロジェクト固有の設定を保ちながらファイルをマージし、既存の AI コンテキストは確認を得てから移行します。
主な機能
- 01作業ツリーを確認して適用計画を提示
- 02テンプレートファイルのコピーとスマートマージ
- 03ファイル種別に応じた設定競合の処理
- 04AI コンテキスト移行前の確認
- 05作成、マージ、スキップしたファイルの一覧
活用シーン
- 01リポジトリへの ai-env 開発テンプレート適用
- 02プロジェクト設定を保ったテンプレート更新
- 03既存の AI 指示やメモリの新構成への移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ camacho/ ai-skills --skill apply-templateインストール後、Claude Code で/apply-templateを入力して読み込まれたか確認します。
詳細
ai-env テンプレートを適用する
エージェント型開発環境のテンプレートを現在のリポジトリに適用します。
引数: ai-env クローンの任意のパス。引数がない場合は、GitHub からクローンします(標準の方法)。
フェーズ 0 — 事前確認
作業ツリーがクリーンか確認
git status --porcelain を実行します。未コミットの変更がある場合は、ユーザーに警告し、続行するか、先にスタッシュするかを確認します。作業ツリーに変更があると、テンプレートによる変更内容を確認しにくくなります。
フェーズ 1 — ソースの解決と検出
テンプレートのソースを特定
- 引数が指定されている場合は、そのパスを使用し、クリーンな Git チェックアウトであることを確認します
- 引数が指定されていない場合は、GitHub からクローンします:
git clone --depth 1 https://github.com/camacho/ai-env.git /tmp/ai-env-templateを実行し、そのパスを使用します - デフォルトのローカルパス
~/projects/camacho/ai-envが存在し、引数が指定されていない場合は、GitHub からのクローンを優先します(最新バージョンを確実に取得するため) - すべて失敗した場合は、ユーザーに伝えて停止します
マニフェストを読む
テンプレートのソースディレクトリにある apply-template.manifest.json を読みます。ここでは、すべてのファイルを copy_if_absent、smart_merge、skip のいずれかに分類します。
適用先をスキャン
現在のリポジトリ(cwd)で、既存の copy_if_absent ファイルと smart_merge ファイルを確認します。
適用先にすでに存在する copy_if_absent ファイルは、スキップせず、スマートマージします。これにより、適用先のカスタマイズを保持しながら、テンプレートの新しい追加内容を取り込めます。
適用計画を提示
ユーザーに概要を提示します:
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?
続行する前に、確認を待ちます。
フェーズ 2 — コピー
copy_if_absent の各エントリーについて、次のとおり処理します:
- ディレクトリ(末尾が
/のエントリー):適用先ディレクトリにmkdir -pを実行してから、すべてのファイルを再帰的にコピーします。すでに存在するファイルは個別にスキップします。 - ファイル:適用先にファイルが存在しない場合は、そのままコピーします。存在する場合は、フェーズ 3 と同じスマートマージのロジックを適用します(ファイルがテンプレートから分岐しているため、適用先の意図を保ちながらテンプレートの追加内容を取り込みます)。
空の場合でも、次のディレクトリが存在するようにします:
ai-workspace/plans/ai-workspace/decisions/
フェーズ 3 — スマートマージ
smart_merge の各ファイルについて、テンプレート版と適用先の版(存在する場合)の両方を読みます。適用先のファイルが存在しない場合は、テンプレート版をそのままコピーします。両方が存在する場合は、以下のルールに従ってマージします。
AGENTS.md — 意味に基づくマージ
- 意図を理解する: 両方のバージョンを最後まで読みます。各セクションの目的を特定します。
- 適用先から保持:
## Stack、## Commands、## Architecture、## Gotchas— これらのセクションをそのまま保持します - テンプレートから追加(不足している場合):
## Agent Roles & Dispatch、## Protected Files、## Conventions、## Workflow Reference、## Context Loading Rules - 重複を解決: 同じ見出しのセクションが両方にある場合、構造や規約に関するセクションではテンプレート版を優先し、プロジェクト固有のセクションでは適用先の版を優先します
- 更新: タイトル行のプロジェクト名を、適用先リポジトリのディレクトリ名に置き換えます
- 保持: テンプレートにない、適用先のカスタムセクションはすべて保持します
- 整合性を確認: マージ後の内容を読み、各セクションが互いに矛盾していないことを確認します
tsconfig.json — 詳細マージ
- テンプレートをベースにする: テンプレートを土台として使用します
compilerOptionsを詳細にマージ: 適用先のcompilerOptionsをテンプレートの上に適用します。競合する場合は適用先を優先します。- 適用先から保持:
include、exclude、references、その他のトップレベルキー - 不足していれば追加: テンプレートの次の厳格なオプション:
strict、noUncheckedIndexedAccess、verbatimModuleSyntax、exactOptionalPropertyTypes、noImplicitOverride、noFallthroughCasesInSwitch - 競合を提示: テンプレートと適用先で同じオプションの値が矛盾する場合(例:
strict: trueとstrict: false)、解決のために競合をユーザーに提示します - 整合性をテスト: マージ後、
compilerOptionsに矛盾するフラグの組み合わせ(例:module: "commonjs"とverbatimModuleSyntax: true)がないことを確認します
.claude/settings.json
- ターゲットから保持: 既存の
permissions.allowおよびpermissions.denyの全エントリー、defaultMode - ユニオンマージ:
permissions.deny配列 — テンプレートのエントリーを、まだ存在しないものに限り追加します(重複は削除) - フックのユニオンマージ: 各フックイベント(PreToolUse、PostToolUse など)について、ターゲットのフックをすべて保持します。ターゲットに同じ
matcherを持つフックが存在しない場合に限り、テンプレートのフックを追加します - 保持: ターゲットにあるその他すべてのキー(disabledMcpjsonServers、enabledPlugins など)
package.json
- ターゲットから保持:
name、version、description、main、type、dependencies、repository、license、author—scriptsとdevDependencies以外のすべて - scripts をマージ: ターゲットに存在しないテンプレートのスクリプトを追加します。競合する場合はターゲットを優先します
- devDependencies をマージ: ターゲットの
devDependenciesにないテンプレートのパッケージを追加します(commitlint packages、lefthook、@biomejs/biome、typescript)。既存の依存関係は削除もダウングレードもしません - 存在しない場合に追加:
engines、packageManager
biome.json
- ターゲットから保持: 既存のすべてのルール、
filesの設定、formatterの設定 - 存在しない場合に追加: ターゲットにないテンプレートのリンタールール
- 削除禁止: ターゲットにすでにあるルールは削除しません
.gitignore
- ユニオンマージ: 両方のファイルにある一意の行をすべて結合し、重複を削除します
- 保持: 両方のファイルのセクションコメント(
#で始まる行)と空行のまとまり - 順序: 先にターゲットの行を並べ、その後、末尾に
# ai-env templateコメントを付けてテンプレートの新しい行を追加します
skills-lock.json — ユニオンマージ
.skillsオブジェクトをユニオンマージ: テンプレートとターゲットのすべてのスキルエントリーを結合します。各エントリーにはsource(sourceTypeに応じた Git URL またはローカルパス)、sourceType("git"または"local")、computedHash(SHA-256 整合性ハッシュ)が含まれます- 競合時はテンプレートを優先: 同じスキル名が両方に存在する場合は、テンプレートのエントリーを使用します(
source、sourceType、computedHashはすべてテンプレートの値を使用) - 削除禁止: テンプレートにないターゲットのスキルは必ず保持します。プロジェクトにはカスタムスキルが存在する場合があります
- トップレベルの
version: いずれかの側のうち大きい整数を保持します(これはロックファイルのスキーマバージョンであり、スキルのバージョンではありません。個々のスキルにはバージョンフィールドがありません) - マージ後: マージしたロックファイルを書き込んだ後、次のコマンドを実行して、追加されたスキルを両方のエージェントで利用可能にするよう指示します。「
npx skills install -a claude-code -a codexを実行して、両方のエージェントに新しく追加されたスキルを反映してください」
マージロジックの例:
Template: Target:
{ "version": 1, "skills": { { "version": 1, "skills": {
"validate": { "validate": {
"source": "[email protected]", "source": "[email protected]",
"sourceType": "git", "sourceType": "git",
"computedHash": "abc..." "computedHash": "abc..."
}, },
"reflect": { "custom-lint": {
"source": "[email protected]", "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
}}
ディレクトリ: .claude/agents/、.claude/rules/、.claude/skills/
- 各ディレクトリを再帰的に処理します
- 新しいファイル: テンプレートからコピーします
- 既存のファイル: 意味に基づいてマージします — 両方のバージョンの意図を理解し、ターゲットのカスタマイズを保持し、不足しているテンプレートのセクションを追加します
フェーズ 4 — 適用後
-
ai-workspace/.template-versionを次の内容で作成します。version: <manifest version> applied: <ISO 8601 timestamp> source: <template source path> -
依存関係の確認: package.json に devDependencies が追加されている場合、パッケージマネージャーを判別し(pnpm-lock.yaml → pnpm、yarn.lock → yarn、package-lock.json → npm)、次のように確認します。「devDependencies が新たに追加されました。
<pm> installを実行しますか?」 -
ワークフローに関する警告:
.github/workflows/のファイルがコピーされた場合、次のシークレットが設定されているか確認します。if 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 -
フックに関する警告:
.claude/settings.jsonが~/.claude/hooks/にあるフックスクリプトを参照している場合、各スクリプトがディスク上に存在するか確認します。存在しないものがあれば警告します。 -
ドットファイルの同期: ユーザーレベルの設定をインストールするか、ユーザーに確認します。
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/同意した場合は、テンプレートのソースディレクトリから(cwd ではなく)
"$TEMPLATE_SOURCE/dotfiles/sync.sh" pushを実行します。 -
TodoWrite を使ってセットアップ後の TODO を自動追加します:
- 「AGENTS.md を更新 — プロジェクトの Stack、Commands、Architecture、Gotchas を記入する」
- 「.claude/agents/ の説明を更新し、プロジェクトへの言及を追加する」
- 「
$TEMPLATE_SOURCE/dotfiles/sync.sh pushを実行してユーザーレベルの設定を適用する(上記で実施していない場合)」 - 「.claude/settings.json のフックを確認し、環境に合わせてパスを調整する」
-
概要: 作成、マージ、スキップしたファイルをすべて一覧表示します。
フェーズ 5 — コンテキストの移行(対話形式で確認、自動では行わない)
このフェーズでは、対象リポジトリ内の既存の AI コンテキスト、メモリ、設定をすべてスキャンし、ユーザーと対話しながら移行を進めます。コンテキストを自動で削除または上書きしないでください — すべての操作には、ユーザーによる明示的な確認が必要です。
検出スキャン
以下の場所をすべて確認します。いずれにも内容がない場合は、「既存の AI コンテキストが見つかりませんでした — 移行をスキップします。」というメッセージを表示し、このフェーズ全体をスキップします。
プロジェクトスコープ(リポジトリ内):
ai-workspace/MEMORY.md— プロジェクトメモリ(シードテンプレート以外の内容があるか確認)ai-workspace/plans/— 既存の計画(特に完了済みの.done.md計画)ai-workspace/decisions/— 既存の ADRai-workspace/scratchpad.md— 作業メモai-workspace/workflow.md— カスタムワークフロー(テンプレートと異なる場合があります).claude/skills/— 既存のスキル(今回のテンプレート適用で作成されたものではないもの).claude/agents/— 既存のエージェント定義.claude/rules/— 既存のルール.claude/settings.json— プロジェクトの権限、フック、拒否ルール.claude/settings.local.json— ローカルのみのオーバーライド(チェックイン対象外).codex/config.toml— プロファイルを含む Codex 設定CLAUDE.md— 既存の Claude 指示ファイルAGENTS.md— 既存の汎用指示ファイルGEMINI.md— Gemini 固有の指示(存在する場合).cursorrulesまたは.cursor/rules/— Cursor 固有のルール(存在する場合).claudeignore/.codexignore— 既存のコンテキスト除外設定.github/workflows/claude.ymlまたはclaude-code-review.yml— 既存の CI ワークフロー
ユーザースコープ(リポジトリ外 — 読み取り専用、ユーザーに通知):
~/.claude/projects/<path-encoded-cwd>/memory/— このプロジェクト用の Claude Code 自動メモリ- パスのエンコード方法:
/を-に置換します。例:-Users-patrickcamacho-projects-myapp - 各
.mdファイルには、name、description、type(user/feedback/project/reference)を含むフロントマターがあります
- パスのエンコード方法:
~/.claude/projects/<path-encoded-cwd>/MEMORY.md— このプロジェクト用の自動メモリインデックス~/.claude/CLAUDE.md— ユーザーのグローバル指示(プロジェクトのパターンを参照している場合があります)~/.claude/hooks/— プロジェクトのフックと重複する可能性があるグローバルフックスクリプト~/.claude/agents/— プロジェクトのエージェントによって影響を受ける可能性があるグローバルエージェント定義~/.claude/commands/— グローバルスラッシュコマンド(catchup、reflect など)~/.claude/plugins/— インストール済みプラグイン(設定のenabledPluginsを確認)
検出結果の提示
カテゴリ別にまとめた概要をユーザーに表示します。
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)
移行手順に進む前に、ユーザーによる確認を待ちます。
1. メモリ — ai-workspace/MEMORY.md
テンプレートとターゲットの両方に、実際の内容がある ai-workspace/MEMORY.md が存在する場合:
マージ方針(行単位ではなく、意味に基づいてマージ):
- 両方のファイルを最後まで読みます。テンプレートの MEMORY.md には、次のシード構成があります。
# Project Memory > Living document updated by /reflect after each task. 200-line limit. > Last updated: — ## Key Decisions ## Implementation Status ## Gotchas - ターゲットの MEMORY.md にある内容はすべて保持します。これは蓄積されたプロジェクトの知識です。
- ターゲットにテンプレートのシードにあるセクション(Key Decisions、Implementation Status、Gotchas)がない場合は、空のセクションとして末尾に追加します。
- ターゲットにテンプレートにない追加のセクションがある場合は、それらも保持します。
- ヘッダーコメントにテンプレートの
> Living document...行がない場合は追加します。 - マージ結果を提示し、ユーザーに確認を求めます。
ターゲットのみに内容がある場合: その内容を保持し、テンプレートにある不足セクションを追加します。
テンプレートのみに内容がある場合: シードテンプレートをコピーします(新規開始)。
2. メモリ — Claude Code の自動メモリ(~/.claude/projects/)
これらはユーザー単位で管理され、Claude Code の組み込みメモリシステムによって管理されます。リポジトリ外に保存されており、自動的には移行されません。代わりに、ユーザーに次のことを伝えます。
- 各メモリファイルについて、フロントマターにある
name、type、descriptionを一覧表示します。 - 次のように説明します。「これらは
~/.claude/projects/.../memory/に保存される、プロジェクトごとの Claude Code メモリです。セッションをまたいで保持され、このプロジェクトにおける Claude の動作に反映されます。」 - 次のように尋ねます。「古くなっていたり、誤っていたりするものはありますか?確認用にフラグを付けることはできますが、テンプレートの適用中に変更することはありません。」
projectまたはreferenceタイプのメモリに、他のエージェントも参照できるようai-workspace/MEMORY.mdに含めるべき情報がある場合は、その内容を手動で移動するようユーザーに提案します。
3. プランと決定事項
- 完了済みプラン(
*.done.md):必ず保持します。これらは変更不可の記録です。存在することをユーザーに伝えます。 - 進行中のプラン(
.done.mdのサフィックスがないもの):まだ進行中か、完了済みとしてマークすべきかを尋ねます。 - ADR:必ず保持します。コミット後は変更不可です。テンプレートによって変更されるパターンを参照しているものがないか確認し、該当する場合は警告します。
- テンプレート(
TEMPLATE.md):異なる場合はテンプレート版に置き換えます(これらは内容ではなく、ひな形です)。 - scratchpad.md:空でない場合は、保持、アーカイブ、リセットのいずれにするかユーザーに尋ねます。
- workflow.md:ターゲットにテンプレートと異なるカスタムワークフローがある場合は、両方を提示して、どちらを保持するか(またはマージするか)を尋ねます。
4. スキル
.claude/skills/ 内の各スキルディレクトリについて:
- テンプレートにない場合(カスタムスキル):そのまま保持します。保持したことをユーザーに伝えます。
- テンプレートのスキルと同じ名前の場合(例:両方に
validate/SKILL.mdがある場合):- 2つのバージョンの差分を取ります。
- 差分をユーザーに提示します。
- 選択肢:ターゲット版を保持する、テンプレート版に置き換える、またはマージする(マージ結果はユーザーが確認します)。
- テンプレートに新しいスキルがあり、ターゲットにない場合: これらはフェーズ 2 ですでにコピーされています。ユーザーに伝えるだけで構いません。
5. エージェント、ルール、コマンド
.claude/agents/ と .claude/rules/ 内の各ファイルについて:
- 両方に同じファイルがある場合: 差分を取ります。ターゲットにカスタマイズ(モデルの変更、追加の指示、プロジェクト固有のコンテキスト)がある場合は、差分を提示します。デフォルトでは、エージェントはカスタマイズされていることが多いためターゲット版を保持し、ルールは構造的なものであるためテンプレート版を保持します。
- テンプレートに新しいファイルがある場合: フェーズ 2 ですでにコピーされています。ユーザーに伝えます。
- ターゲットにのみある場合(カスタム): 保持します。ユーザーに伝えます。
グローバルエージェントとプロジェクトエージェントのシャドーイングを確認します。
~/.claude/agents/architect.mdと.claude/agents/architect.mdの両方が存在する場合は、プロジェクト版が優先されることを伝えます。
6. 設定と権限
.claude/settings.json の場合:
- これはフェーズ 3 ですでにスマートマージされています。追加・変更された内容を要約します。
- 特に、以下を明記します。
- フック: グローバル(
~/.claude/settings.json)とプロジェクトの両方に存在するフックを一覧表示します。フックの配置ルールに従い、グローバルフックは個人のワークフロー、プロジェクトフックはコードベースの規約です。同じフックが両方に存在する場合は、コストの高いフックが不必要に重複していることを警告します。 - 拒否ルール: テンプレートから追加された拒否パターン。
- 許可ルール: 新たに追加された許可パターン(ユーザーに確認を促します)。
- プラグイン:
enabledPluginsまたはdisabledMcpjsonServersが存在する場合は、それらを一覧表示します。
- フック: グローバル(
.claude/settings.local.json の場合:
- 絶対に変更しません。ファイルが存在することと、その内容をユーザーに伝えます。
.codex/config.toml の場合:
- 対象にカスタムプロファイルがある場合は保持します。競合しない新しいテンプレートプロファイルをマージします。
7. 指示ファイル(CLAUDE.md、AGENTS.md、GEMINI.md、.cursorrules)
- AGENTS.md: フェーズ 3 ですでにマージされています。追加・保持されたセクションを要約します。
- CLAUDE.md: 対象に
@AGENTS.mdのみを記述したものではないカスタム CLAUDE.md がある場合:- 内容を読みます。プロジェクト固有の指示と定型文を特定します。
- プロジェクト固有の内容を保持します。不足しているテンプレートの定型セクションを追加します。
- GEMINI.md: 存在する場合は、ユーザーに知らせます。テンプレートには含まれていないため、これはユーザーのカスタムファイルです。保持します。
- .cursorrules: 存在する場合は、AGENTS.md が推奨される汎用形式であることをユーザーに伝えます。.cursorrules の内容を AGENTS.md にマージするか、別々に保持するかを尋ねます。
8. CI ワークフロー
.github/workflows/claude.yml または claude-code-review.yml がテンプレート適用前から存在していた場合:
- テンプレート版との差分を確認します。
- 権限の違い(
contents: readとwrite、allowed_toolsの欠落など)を指摘します。 - 対象のワークフローの権限が弱い場合は、アップグレード方法を提示します。
9. コンテキスト除外(.claudeignore、.codexignore)
.claudeignore:.gitignoreとは別に扱います。対象に存在するか確認します。存在する場合は、(.gitignoreと同じ方法で)和集合としてマージします。存在しない場合は、テンプレート版をコピーします。.codexignore:存在する場合は保持します。テンプレートには含まれていません。
まとめのプロンプト
すべての確認事項を提示した後、次のように尋ねます。
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 above
重要な原則: このフェーズは情報提供と助言を目的とします。すべての判断は最終的にユーザーが行います。現在の内容を提示し、テンプレートで想定されている内容を説明して推奨事項を示します。ただし、確認を得る前に変更を加えてはいけません。
再適用
すでに ai-workspace/.template-version があるリポジトリで実行する場合:
copy_if_absentファイルは存在する場合にスマートマージされます(カスタマイズを保持しつつ、テンプレートの追加内容を取り込みます)。smart_mergeファイルは常に再マージされます(これによりテンプレートの更新が反映されます)。- ユーザーが
--forceを指定した場合、copy_if_absentファイルはマージせず、完全に上書きされます。