zudo-paper

Claude Codeのskill + subagentで複数リポジトリの同期を自動化した

Author: Takazudo | 作成: 2026/02/18

概要

複数のMacを使い分けていると、マシンを切り替えるたびに各リポジトリでgit pull/git pushするのが面倒になる。Claude Codeにはskill(手順書)とagent(サブエージェント)という仕組みがあり、これを組み合わせて/globalsyncと打つだけで9つのリポジトリを並列に同期してくれる仕組みを作った。そのまとめ。

問題: 複数マシンでのリポジトリ同期

自分は複数のMacを使い分けて作業している。仕事用・個人用あわせて9つのgitリポジトリを日常的に使っていて、マシンを切り替えるたびに各リポジトリでgit pullしてgit pushする必要がある。

9つのリポジトリに対して毎回これをやるのは面倒だし、忘れる。例えば、あるマシンで設定ファイルを更新して、別のマシンでpullし忘れて古い設定のまま作業を始める、みたいな状況を想像してみる。地味だが確実にストレスになる。

Claude Codeのskillとagent

Claude Codeにはskillとagentという仕組みがある。

skillは、Claude Codeに特定のタスクをやらせるための手順書みたいなもの。/globalsyncのようにスラッシュコマンドで呼び出すと、skillに書かれた手順に従ってClaude Codeが動く。知識やワークフローの定義。

agentは、特定のタスクを自律的にこなすサブプロセス。Task toolでspawnすると、独立したプロセスとして動いてくれる。skillがオーケストレーターだとすれば、agentはワーカー。

この2つを組み合わせると「skillが全体の段取りを指示し、agentが個々の作業を並列に実行する」という構成が作れる。

対象リポジトリ

同期対象の9つのリポジトリは以下の通り。

仕事用リソース(~/repos/w/配下):

  • cgCodeGrid執筆用のDocusaurusサイト。執筆ルールやリファレンスをまとめている
  • esaesa執筆用のDocusaurusサイト。記事の下書きやルールを管理
  • message — メール・Slackなどのメッセージ下書きヘルパー。Docusaurusで構築
  • zpaper — 個人ブログ(Next.js)+ 執筆ルールのDocusaurusドキュメントサイト

スタンドアロン:

  • ~/.claude — Claude Codeの設定、skill、agent、コマンドなどの格納場所

個人用リソース(~/repos/p/配下):

  • claude-resources — Claude Code設定の公開リポジトリ。コマンド・skill・agentなどを共有
  • dotconfigetc~/.config配下の管理対象(ghosttyなど)をシンボリンクで管理
  • dotconfignvimNeovim/VimRの設定ファイル群
  • dotfiles.zshrc.gitconfigなどのdotfilesを複数Macで共有

repo-syncer agent

まず作ったのが「repo-syncer」というagent。1つのリポジトリに対してgit同期を行うサブエージェント。

ファイルは~/.claude/agents/repo-syncer.mdに置いている。

---
name: repo-syncer
description: Git pull-push sync agent for a single repository. Handles fetch, pull with rebase, conflict resolution, and push.
model: sonnet
color: green
---

処理フローはこういう感じ。

  1. git fetch --allでリモートの最新状態を取得
  2. git statusで現在の状態を確認(ブランチ、未コミットの変更、ahead/behind)
  3. 未コミットの変更がある場合はgit stashで退避
  4. git pull --rebase origin <current-branch>でpull
  5. stashした変更があればgit stash popで復元
  6. git push origin <current-branch>でpush
  7. 結果をレポート

コンフリクト解決の方針

コンフリクトが発生した場合の方針は以下の通り。

  • 軽微なコンフリクト(異なる箇所の編集)は自動解決してスムーズに進める
  • 同じ行の編集など判断が必要なものはrebaseをabortしてユーザーに確認を求める
  • 変更を暗黙的に捨てることは絶対にしない

最後のポイントが一番重要で、git同期の自動化で怖いのは「知らないうちに変更が消えていた」という事態。repo-syncerは判断に迷ったら必ず止まるようにしている。

modelにSonnetを指定する

agentの定義でmodel: sonnetを指定している。git操作のような定型的な処理にはSonnetで十分で、Opusを使う必要がない。コストの最適化としても有効。

globalsync skill

次に作ったのが「globalsync」というskill。9つのリポジトリそれぞれに対してrepo-syncerをspawnするオーケストレーター。

ファイルは~/.claude/skills/globalsync/SKILL.mdに置いている。

---
name: globalsync
description: Sync all personal repos across machines via git pull & push. Use when: (1) User says 'globalsync', 'sync repos', 'pull push all', (2) User wants to sync their daily resources across machines, (3) User starts or ends a work session and needs repos up to date.
allowed-tools: Bash, Read, Task
---

skillの中身は、対象リポジトリのリストと、それぞれに対してrepo-syncerをspawnする手順が書いてある。Claude Codeはこのskillの指示に従って、Task toolを使い9つのrepo-syncerを1つのメッセージで並列にspawnする。

アーキテクチャ

全体の構成はこういう形になっている。

globalsync (skill) ─ オーケストレーター

    ├─ Task(repo-syncer) → ~/.claude
    ├─ Task(repo-syncer) → ~/repos/w/cg
    ├─ Task(repo-syncer) → ~/repos/w/esa
    ├─ Task(repo-syncer) → ~/repos/w/message
    ├─ Task(repo-syncer) → ~/repos/w/zpaper
    ├─ Task(repo-syncer) → ~/repos/p/claude-resources
    ├─ Task(repo-syncer) → ~/repos/p/dotconfigetc
    ├─ Task(repo-syncer) → ~/repos/p/dotconfignvim
    └─ Task(repo-syncer) → ~/repos/p/dotfiles
 
    全エージェント完了後 → サマリーテーブルを表示

skillがオーケストレーター、agentがワーカーという役割分担。9つのrepo-syncerは並列に動くので、逐次実行するよりかなり速い。

実行結果

実際に/globalsyncを実行した結果がこれ。

RepoStatusDetails
~/.claudeOKAlready up to date
w/cgOKPulled 1 commit, 7 uncommitted files preserved
w/esaOKAlready up to date, 1 uncommitted file preserved
w/messageOKPulled 1 commit, 1 uncommitted file preserved
w/zpaperOKAlready up to date
p/claude-resourcesOKAlready up to date
p/dotconfigetcOKAlready up to date
p/dotconfignvimOKAlready up to date
p/dotfilesOKPulled 3 commits

9リポジトリすべてがコンフリクトなく同期完了。未コミットの変更があるリポジトリ(cg、esa、message)ではstash→pull→stash popの手順で変更が保護されている。全体の結果がサマリーテーブルで出てくるので、何が起きたか一目でわかる。

skill + agent構成のパターン

今回の/globalsyncで使った「skillがオーケストレーター、agentがワーカー」という構成は、他の場面にも応用できるパターンだと思う。

ポイントをまとめると以下の通り。

  • skillに全体の段取りと対象リストを書く
  • agentに1つの作業単位の処理を書く
  • skillからTask toolでagentを並列にspawnする
  • agentのmodelは処理内容に応じて選ぶ(定型処理ならSonnetで十分)
  • 判断が必要な場面ではagentが止まってユーザーに確認を求める設計にする

繰り返し作業で、かつ並列化できるものがあれば、このパターンが使えそう。