🌩️

Claude Codeと超効率ペアプロ環境を構築しよう!(No Mouse)

に公開

Claude Codeとのペアプロ、ターミナル内で完結させたいですよね。

この記事では、kitty・tmux・git worktree・Neovimを組み合わせた開発環境を紹介します。No Mouseで、コード生成からレビュー、コミットまで一気に突っ走ることが可能な構成です。

この記事では、kitty・tmux・git worktree・Neovim・Claude Codeを組み合わせた開発環境を紹介します。ローカルとリモートでtmuxがネストする問題を解消しつつ、ブランチごとに作業ディレクトリを分離してAIとペアプロできる構成です。


https://github.com/TomoyaFujita2016/dotfiles

この構成で解決できること

  • ローカルとリモートでtmuxのprefixが競合する問題
  • ブランチ切り替えのたびにstashする面倒くささ
  • Claude Codeの変更をどうレビューするか問題

各ツールの役割

ツール 役割
kitty ローカル/リモート環境の切り替え
tmux プロジェクト・ブランチ単位のセッション管理
git worktree ブランチごとの作業ディレクトリ分離
Neovim コード編集・レビュー
Claude Code AI支援によるコード生成・調査

事前準備

kitty

https://sw.kovidgoyal.net/kitty/binary/

tmux

https://github.com/tmux/tmux/wiki/Installing

fzf

https://github.com/junegunn/fzf?tab=readme-ov-file#installation

lazygit

https://github.com/jesseduffield/lazygit?tab=readme-ov-file#installation

Neovim

https://github.com/neovim/neovim/blob/master/INSTALL.md

1. kittyとtmuxの併用設定

なぜ併用するのか

ローカルでtmuxを使っていると、リモートサーバーにSSH接続したときにtmuxがネストしてしまいます。かといってローカルでtmuxをつかわないと複数のターミナルを立ち上げる必要があります。

ローカルtmux → SSH → リモートtmux(ネストしてカオス)

prefixキーを変えれば回避できますが、クリップボード共有がうまくできなかったりしますし、ローカルとリモートで設定を統一したいですよね。

この問題をkittyのタブ機能で解決します。

kittyタブ1 → ローカルtmux
kittyタブ2 → SSH → リモートtmux
...
kittyタブn  → SSH → リモートtmux

Shift+Ctrl+Tabでkittyのタブを切り替えれば、ローカルとリモートを行き来できます。tmuxのprefixキーは共通のまま。これは便利。

Shift+Ctrl+Alt+tでタブの名前を変えるとさらに便利。

kittyの設定例

~/.config/kitty/kitty.confに以下を追加します。

# タブバーを表示
tab_bar_edge top
tab_bar_style powerline
tab_powerline_style slanted

# タブ切り替え
map shift+ctrl+tab next_tab
map shift+ctrl+shift+tab previous_tab

# 新規タブ
map ctrl+shift+t new_tab_with_cwd

私のconfigはこちら

2. git worktreeでブランチ管理

bare cloneを使う理由

通常のgit cloneでworktreeを追加すると、.gitの参照がややこしくなります。bare cloneを使うとディレクトリ構造がスッキリします。

Project/
├── .bare/          # gitの実体
├── .git            # gitdirの参照ファイル
├── main/           # mainブランチ
├── develop/        # developブランチ
└── feature-001/    # featureブランチ

ブランチごとにディレクトリが分かれているので、切り替えのたびにstashする必要がありません。複数ブランチを同時に開いて作業できるのが嬉しいポイントです。

セットアップ手順

bare cloneを作成します。

git clone --bare git@github.com:user/repo.git Project/.bare

Projectディレクトリに移動して、ルートに.gitファイルを作成します。

cd Project
echo "gitdir: .bare" > .git

これでProjectディレクトリでもgitコマンドが使えるようになります。(つかわないならなくてもおk)

worktreeのfetch設定を行います。

cd .bare
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin

mainブランチのworktreeを作成します。

git worktree add ../main main

他のブランチも同様に追加できます。

git worktree add ../develop develop
git worktree add ../feature-001 -b feature-001 origin/develop

worktreeを削除するとき

git worktree remove feature-001

手動でディレクトリを削除した場合はgit worktree pruneで参照を整理してください。

注意点

同じブランチを複数のworktreeでチェックアウトできません。git branch -dしてもworktreeディレクトリは残るので、git worktree removeで明示的に削除してください。

3. tmuxセッションとworktreeの連携

各worktreeをtmuxセッションとして管理します。fzfで選択してセッションを作成/切り替えできると便利ですよね。

以下のシェル関数を.bashrc.zshrcに追加します。

# worktreeを選択してcdする
worktree() {
  local selected
  selected=$(git worktree list | fzf --height 40% | awk '{print $1}')
  if [[ -n "$selected" ]]; then
    cd "$selected" || return
    if [[ -n "$TMUX" ]]; then
      tmux rename-window "$(basename "$selected")"
    fi
  fi
}
alias wt=worktree

# worktreeを選択してtmuxセッションを作成/切り替え
worktree-session() {
  local selected repo branch name
  selected=$(git worktree list | fzf --height 40% | awk '{print $1}')
  if [[ -n "$selected" ]]; then
    repo=$(basename "$(dirname "$selected")")
    branch=$(basename "$selected")
    name="${branch} (${repo})"
    
    if tmux has-session -t "$name" 2>/dev/null; then
      if [[ -n "$TMUX" ]]; then
        tmux switch-client -t "$name"
      else
        tmux attach-session -t "$name"
      fi
    else
      if [[ -n "$TMUX" ]]; then
        tmux new-session -d -s "$name" -c "$selected"
        tmux switch-client -t "$name"
      else
        tmux new-session -s "$name" -c "$selected"
      fi
    fi
  fi
}
alias wts=worktree-session

使い方はこんな感じです。

  • wt: worktreeをfzfで選択してそのディレクトリへ移動
  • wts: worktreeをfzfで選択してtmuxセッションを作成(既存なら切り替え)

セッション名は「ブランチ名 (リポジトリ名)」の形式になります。

4. Claude Codeとのペアプロ設定

基本レイアウト

tmuxのペイン構成はこうなります。

┌─────────────────────┬─────────────────────┐
│                     │                     │
│    Claude Code      │      Neovim         │
│                     │                     │
└─────────────────────┴─────────────────────┘

prefix + |で垂直分割して、左でClaude Code、右でNeovimを起動します。

Neovimのautoread設定

Claude Codeがファイルを編集すると、Neovimで開いているバッファと差分が生じます。以下の設定で外部変更を自動反映します。

vim.opt.autoread = true

vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold" }, {
  callback = function()
    vim.cmd("checktime")
  end,
})

Claude Codeの複数起動

ファイルが競合しないタスクなら、Claude Codeを複数起動して並行作業できます。

起動1 起動2
フロントエンド実装 バックエンド実装
現在の実装作業 次の実装に向けた事前調査

事前調査は別ペインで走らせておいて、結果をCLAUDE.mdに書かせておくと実装時に参照できます。

5. レビューフロー

Claude Codeの実装が一段落したら、差分を確認してレビューします。

lazygitでざっくり確認

lazygit

staging、commit、stashなど一連のgit操作をまとめて行えます。

diffview.nvimで詳細確認

Neovim内でdiffを確認できるので、そのまま修正作業に移れるのが便利です。

:DiffviewOpen          " 現在の変更をすべて確認
:DiffviewOpen HEAD~1   " 直前のcommitとの差分
:DiffviewFileHistory % " 現在のファイルの変更履歴

差分が長い場合はprefix + zでペインを最大化して確認します。確認後にもう一度prefix + zで元に戻せます。

レビューの流れ

  1. Claude Codeに「一旦ここまでで止めて」と伝える
  2. lazygitでざっくり全体像を把握
  3. 気になるファイルはdiffviewで詳細確認
  4. Neovimで必要な修正を加える
  5. commit

動作確認

実際に使ってみましょう。

# Projectディレクトリに移動
cd Project

# wtsでworktreeを選択
wts

fzfでworktreeを選択すると、tmuxセッションが作成されます。

tmux内でprefix + |でペインを分割して、左でClaude Code、右でNeovimを起動すれば準備完了です。

私の設定だと prefix + v

さいごに

私のdotfilesです。(starしてね★)
https://github.com/TomoyaFujita2016/dotfiles

おわり。

Discussion