rulesyncとgit hookを活用してチーム内でシームレスにAIエージェントの設定ファイルを同期する
リテールアプリ共創部のるおんです。
最近、Claude CodeやCursorといったAIエージェントを使った開発が当たり前になってきました。その中で、プロジェクトごとに ルール(rules) や スキル(skills) 、カスタムコマンド(commands) を整備して、AIに「このプロジェクトの作法」を教え込むことが増えてきています。
しかし、いざこれをチームで運用しようとすると、ある問題にぶつかります。それは 「AIエージェントの設定ファイルが、ツールごと・人ごとにバラバラで共有できない」 という問題です。
今回は、この問題を rulesync で解決し、さらに git hook を組み合わせることで、チーム内でシームレスにAIエージェントの設定ファイルを同期する仕組みを紹介します。
先に結論
- AIエージェントの設定は、ツールごとに置き場所もフォーマットも違う。同じルールをClaude Code用・Cursor用…と二重三重に書くのは限界がある
- rulesync を使えば、
.rulesync/に一度書くだけで各ツール向けの設定(.claude/・.cursor/)を自動生成できる - 生成物(
.claude/・.cursor/)は gitリポジトリにはコミットせず(gitignore)、各メンバーがローカルで生成する 運用にする。コミットするのは元ネタの.rulesync/だけ - ただしこの運用には「
generateを忘れると、自分のローカルの生成物だけ古いまま」という弱点がある - そこで git hook(
pre-commit/post-merge)でgenerateを自動化し、prepareスクリプトでチーム全員に自動で効かせることで、ローカル生成物が常に最新に保たれるようにする
.rulesync/(元ネタ・1ソース・これだけコミットする)
│ commit / pull のたびに自動で generate
▼
.claude/ ・ .cursor/(各ツール向け生成物・gitignore・ローカルで常に最新)
問題提起:AIエージェントの設定はツールごとに分断している
AIコーディングツールは、それぞれ独自の場所・フォーマットで設定を持っています。
| ツール | 設定の置き場所 |
|---|---|
| Claude Code | .claude/(CLAUDE.md、skills、commands、agents …) |
| Cursor | .cursor/(rules、commands …) |
| その他のツール | それぞれ独自の形式 |
ここで問題になるのが、同じ「プロジェクトのルール」を、ツールの数だけ別の場所に・別の形式で書かないといけない ことです。
例えば「コミットメッセージは日本語で書く」「このフォルダ構成に従う」「課題管理ツールはこう参照する」といったルールを、Claude Codeを使う人のために .claude/ に書き、Cursorを使う人のために .cursor/ に書く……これを手作業でやると、次のような事故が起きます。
- 設定の重複:同じ内容を何度も書くことになる
- 同期ズレ:片方を更新したのに、もう片方を直し忘れて古いまま残る
- 属人化:人によって使うツールが違い、各自のローカルだけに設定があると、メンバーごとにAIの挙動が変わる
特にチーム開発では、「Aさんは最新のルールでAIを動かしているのに、Bさんのローカルだけ古いルールのまま」という状態が地味に効いてきます。AIに渡すコンテキストがメンバーごとに違えば、当然アウトプットの質もバラつきます。
ルールやスキルこそチームの資産なのに、それを 共有・同期する仕組みがない 。これが今回解決したい課題です。
rulesyncとは
そこで登場するのが rulesync です。
rulesyncは、1つの元ネタ(Single Source of Truth)から、複数のAIツール向けの設定ファイルをまとめて生成する OSSツールです(MITライセンス)。公式では、その価値を以下のように整理しています。
| 価値 | 内容 |
|---|---|
| Single Source of Truth | ルールを一度書けば、各ツールの設定を自動生成できる |
| Tool Flexibility | 標準を書き直さずに、チームが好きなAIアシスタントを選べる |
| Auditable Outputs | 生成物はプレーンな設定ファイル = バージョン管理・レビュー可能 |
| Consistent Onboarding | 新メンバーが既存の規約・コンテキストをすぐ引き継げる |
つまり、先ほどの「ツールごとに二重三重に書く」問題を、.rulesync/ という1箇所に集約し、そこから各ツールへ自動展開する ことで解消してくれます。
ディレクトリ構成
rulesyncを導入すると、元ネタは .rulesync/ 配下にまとまります。
your-project/
├── .rulesync/ # ← ここだけ書けばよい(元ネタ)
│ ├── rules/ # AIへのルール(overview.md など)
│ ├── commands/ # カスタムコマンド
│ ├── subagents/ # サブエージェント
│ ├── skills/ # スキル
│ ├── mcp.json # MCP設定
│ └── hooks.json # フック設定
│
│ rulesync generate で展開 ↓
│
├── .claude/ # Claude Code向け(自動生成)
│ ├── agents/
│ ├── commands/
│ ├── rules/
│ └── skills/
└── .cursor/ # Cursor向け(自動生成)
├── agents/
├── commands/
├── rules/
└── skills/
.rulesync/ に書いたルールやスキルが、rulesync generate を実行することで .claude/ と .cursor/ の両方に、それぞれの形式で書き出されます。
設定ファイル
生成対象や機能は rulesync.jsonc で指定します。実際に私のプロジェクトで使っている設定がこちらです。
{
"targets": [
"cursor",
"claudecode",
],
"features": [
"rules",
"ignore",
"mcp",
"commands",
"subagents",
"skills",
"hooks"
],
"baseDirs": [
"."
],
"delete": true
}
targets:生成先のツール。ここではCursorとClaude Codeを指定していますfeatures:生成する機能。rules / ignore / mcp / commands / subagents / skills / hooks に対応しています
generateの実行は package.json のスクリプトにまとめておくと楽です。
{
"scripts": {
"rulesync:generate": "pnpm dlx rulesync@latest generate"
}
}
pnpm run rulesync:generate
これで、.rulesync/ の内容が .claude/ と .cursor/ に展開されます。ルールやスキルを書く場所が1つになり、どのツールを使うメンバーでも同じルールでAIを動かせる ようになりました。
生成物はコミットをするかどうか
ここで一つ方針を決める必要があります。rulesyncが生成した .claude/・.cursor/ を、gitリポジトリにコミットするかどうか です。
- コミットする:生成物もバージョン管理され、cloneした時点で誰でも最新の設定が揃う(rulesyncの「Auditable Outputs」の考え方)。一方で、元ネタを変えるたびに生成物の大量の差分がコミットに乗り、レビューやマージのノイズになりやすい
- コミットしない(gitignore):コミットするのは元ネタの
.rulesync/だけ。生成物は各メンバーがローカルで生成する。差分がノイズにならず、元ネタが唯一の source of truth であることが明確になる
私のプロジェクトでは 後者(生成物はコミットしない) を採用しています。.gitignore で生成物を除外します。
# rulesync の生成物(元ネタは .rulesync/ のみコミットする)
**/.claude/
**/.cursor/
CLAUDE.md
Claude Code向けに生成されるルート直下の
CLAUDE.mdも、.rulesync/rules/から生成される「生成物」です。そのため、これも合わせてgitignore対象にしています(元ネタは.rulesync/rules/overview.mdなど)。
この運用の弱点:generate忘れ
生成物をコミットしない運用はスッキリしていて良いのですが、1つ弱点があります。それは 「.rulesync/ を変えても、手動で generate を実行しないと、自分のローカルの生成物が古いまま」 になることです。
生成物はリポジトリに入らないため、各メンバーが自分の手元で generate して初めて、最新のルールがAIに効きます。ところが、実際の開発ではこんなことが起きます。
.rulesync/skills/を編集したのに、generateを忘れて作業を続ける → 自分のローカルのAIだけ古いルールで動く- 他のメンバーが更新した
.rulesync/をpullしたが、generateしていない → pullしただけでは生成物に反映されない
結局、「誰が・いつ generate するか」が属人化してしまい、rulesyncで解決したはずの「同期ズレ」が、ローカル生成物という別の形でぶり返してしまうのです。
この generate の実行忘れ を、人間の注意力に頼らず仕組みで潰したい。そこで git hook の出番です。
git hookでgenerateを自動化する
やりたいことはシンプルで、以下の2つのタイミングで自動的に rulesync generate を走らせます。
| タイミング | git hook | やること |
|---|---|---|
| コミット時 | pre-commit |
.rulesync/ に変更があれば generate し、ローカルの生成物を最新化する |
| pull時 | post-merge |
pullで .rulesync/ が更新されたら generate してローカルを最新化する |
フックをリポジトリで共有する
まず、フックスクリプトをチームで共有できるようにします。Gitにはデフォルトで .git/hooks/ という置き場所がありますが、ここはバージョン管理されないため、チームで共有できません。
そこで、core.hooksPath を使って、フックの置き場所を リポジトリ管理下の .githooks/ に変更します。
git config core.hooksPath .githooks
これで、.githooks/ に置いたフックがリポジトリにコミットされ、チーム全員で同じフックを共有できるようになります。
pre-commit:コミット時に自動generate
.githooks/pre-commit を以下のように書きます。
#!/bin/sh
set -e
# .rulesync/ 配下の変更がステージされている場合のみ、各エージェント向けに展開する。
# CI 環境(GITHUB_ACTIONS など)では実行しない。
if [ -n "$GITHUB_ACTIONS" ] || [ -n "$CI" ]; then
exit 0
fi
if git diff --cached --name-only --diff-filter=ACMR | grep -q "^\.rulesync/"; then
echo "[pre-commit] .rulesync/ の変更を検知しました。rulesync:generate を実行します..."
if ! command -v pnpm >/dev/null 2>&1; then
echo "[pre-commit] エラー: pnpm が見つかりません。'pnpm install' でセットアップしてください。" >&2
exit 1
fi
pnpm run --silent rulesync:generate
# 生成物(CLAUDE.md / .claude / .cursor)は .gitignore 対象でありコミットしない。
# ここではローカルの生成物を最新化するだけで、git add は行わない。
echo "[pre-commit] ローカルの生成物(CLAUDE.md / .cursor)を最新化しました。"
fi
ポイントは以下です。
- ステージされた変更に
.rulesync/が含まれるときだけ 実行する(毎回generateしない)。git diff --cached --name-onlyでステージ済みのファイルパスを見て判定しています - generate後に
git addはしない 。生成物はgitignore対象なので、コミットには含めず、手元のファイルを最新化するだけにとどめます(gitignore済みのパスをgit addしようとすると、set -eのもとでフックがエラーになってしまう点にも注意です) - CI環境(
$CI/$GITHUB_ACTIONS)では何もせず抜ける。CIでフックが走って余計なことをしないためのガードです
これで、.rulesync/ を編集してコミットすると、その瞬間に手元の生成物も最新化されます。「元ネタは変えたのに生成し忘れて、古いルールでAIが動いている」 という状態が起きなくなるわけです。
post-merge:pull時に自動generate
次に「pullした瞬間にも走らせたい」というケースです。git pull は内部でマージを行うので、マージ完了後に走る post-merge フックが適任です。
#!/bin/sh
set -e
# git pull / git merge 後に実行される。
# 取り込んだ変更に .rulesync/ が含まれていれば、各エージェント向けに再展開する。
# CI 環境(GITHUB_ACTIONS など)では実行しない。
if [ -n "$GITHUB_ACTIONS" ] || [ -n "$CI" ]; then
exit 0
fi
# マージ前後の差分に .rulesync/ の変更が含まれるか判定する。
if git rev-parse --verify --quiet ORIG_HEAD >/dev/null; then
if ! git diff --name-only ORIG_HEAD HEAD | grep -q "^\.rulesync/"; then
exit 0
fi
else
exit 0
fi
echo "[post-merge] pull により .rulesync/ が更新されました。rulesync:generate を実行します..."
if ! command -v pnpm >/dev/null 2>&1; then
echo "[post-merge] エラー: pnpm が見つかりません。'pnpm install' でセットアップしてください。" >&2
exit 1
fi
pnpm run --silent rulesync:generate
# 生成物(CLAUDE.md / .claude / .cursor)は .gitignore 対象でありコミットしない。
echo "[post-merge] ローカルの生成物(CLAUDE.md / .cursor)を最新化しました。"
post-merge ではステージ情報が使えないので、代わりに マージ前のHEAD(ORIG_HEAD)と現在のHEADの差分 を見て、.rulesync/ の変更が取り込まれたかを判定しています。git pull を実行するとGitが自動的に ORIG_HEAD をマージ前の位置に設定してくれるので、これを使って「今回のpullで何が変わったか」を知ることができます。
これで、他のメンバーが更新した .rulesync/ をpullしたときに、自分のローカルの生成物も自動で最新化されます。
なお、
git pull --rebaseの場合はpost-mergeは実行されません。通常のマージpullが対象になる点には注意してください。
prepareスクリプトでチーム全員に自動で効かせる
ここまでで2つのフックができましたが、1つ問題が残っています。git config core.hooksPath .githooks を 各メンバーが手で実行しないとフックが有効にならない のです。これではせっかくの仕組みも「設定し忘れた人には効かない」ことになってしまいます。
そこで活躍するのが、package.json の prepare スクリプト です。prepare は pnpm install(npm install)したときに自動で実行されるライフサイクルスクリプトなので、ここで core.hooksPath を設定してしまいます。
{
"scripts": {
"prepare": "git config core.hooksPath .githooks || true",
"rulesync:generate": "pnpm dlx rulesync@latest generate"
}
}
これで、メンバーはリポジトリをcloneして pnpm install するだけ で、core.hooksPath が自動的に .githooks に設定され、フックが有効になります。各自が手でフックを仕込む必要はありません。
rulesyncが掲げる「Consistent Onboarding(新メンバーがすぐ環境を引き継げる)」を、フックのセットアップまで含めて実現できるわけです。
全体像
ここまでの仕組みを整理すると、以下のようになります。
| 要素 | 役割 |
|---|---|
| rulesync | .rulesync/ を元ネタに、各ツール向け設定を生成(Single Source of Truth) |
| .gitignore | 生成物(.claude/・.cursor/・CLAUDE.md)を除外し、コミットするのは元ネタだけにする |
| pre-commit | コミット時にgenerateし、手元の生成物を最新に保つ |
| post-merge | pull時にgenerateし、各メンバーのローカル生成物を最新化する |
| prepareスクリプト | pnpm install だけでフックを有効化し、チーム全員に自動で効かせる |
リポジトリにコミットするのは元ネタの .rulesync/ だけ。.claude/・.cursor/ は生成物なので コミットもせず、直接編集もしない 。この運用が、gitignoreとフックによって自然と守られるようになります。
おわりに
今回は、rulesyncとgit hookを組み合わせて、チーム内でAIエージェントの設定ファイルをシームレスに同期する仕組みを紹介しました。
AIエージェントのルールやスキルは、もはやチームの大事な資産です。しかし、ツールごと・人ごとに設定が分断していると、その資産を活かしきれません。
- rulesync で「1つの元ネタから各ツールへ展開する」仕組みを作り、
- 生成物は gitignore してコミットするのは元ネタだけにし、
- git hook で「各メンバーのローカル生成物が常に元ネタと一致する」状態を自動で担保し、
- prepareスクリプト で「チーム全員が何も意識せず仕組みに乗れる」ようにする。
この3点セットで、誰がどのAIツールを使っても、同じルール・同じスキルでAIが動く 環境が手に入ります。ルールやスキルを育てることに集中でき、同期の手間や不整合の心配から解放されるのは、想像以上に快適でした。
AIエージェントをチームで本格的に運用し始めると、必ずこの「設定の共有・同期」という壁にぶつかると思います。そのときに、本記事の仕組みが参考になれば幸いです。
以上、どなたかの参考になれば幸いです。
参考








