Claude Codeを放置で動かす話 ── autoモードとtmux連携
最近Claude Codeをかなり使い込んでいます。で、あるとき気づいたんですよね。「毎回permissionの確認で止まるの、だるくないか?」と。
ファイルの編集、コマンドの実行、テストの実行。それぞれに対してClaude Codeが「これ実行していいですか?」って聞いてくるんですが、信頼できるタスクなら全部Yesで進めたい。特に大きめのリファクタリングを頼んでいるときとか、1タスクで何十回もEnterを押すことになる。
調べてみたら、permissionをスキップして自律的に動かす方法がいくつかあって、tmuxと組み合わせると「タスクを投げて放置」ができるようになりました。その設定と使用感のメモです。
Claude Codeの権限モード
まずClaude Codeの権限の仕組みを整理しておきます。
デフォルトでは、ファイル編集やBash実行のたびに確認プロンプトが出ます。安全だけど面倒。これを制御する方法が3段階あります。
1. --allowedTools:特定のツールだけ自動許可
claude -p "テストを実行して失敗を修正して" \
--allowedTools "Bash(npm run test)" "Read" "Edit"
これが一番バランスがいい。「読み書きとテスト実行はOK、でもそれ以外は聞いて」という設定ができます。パターン指定もできるので、コマンドの範囲を絞れます。
--allowedTools "Bash(npm run *)" "Bash(git diff *)" "Read" "Edit"
自分は基本これを使っています。必要なコマンドだけホワイトリストにして、それ以外はブロック。
2. settings.jsonで永続化
毎回フラグを書くのが面倒なら、.claude/settings.json に書いておけます。
{
"permissions": {
"allow": [
"Bash(npm run test)",
"Bash(npm run lint)",
"Bash(git diff *)",
"Bash(git commit *)",
"Read",
"Edit"
]
}
}
プロジェクト単位で設定できるので、「このリポジトリではこのコマンドまでOK」みたいな管理ができます。
3. --dangerously-skip-permissions:全部スキップ
claude --dangerously-skip-permissions -p "プロンプト"
名前の通り危険なやつ。全ツールの権限チェックを飛ばします。rm -rf だろうが何だろうが聞かずに実行されます。
tmuxと組み合わせる
ここからが本題。Claude Codeを -p フラグで非インタラクティブに動かすと、tmuxのセッションに放り込めます。
基本の使い方
# tmuxセッションを作って、Claude Codeを実行
tmux new-session -d -s claude-task \
'claude -p "src/api/配下のエラーハンドリングをリファクタリングして。テストも修正して。" \
--allowedTools "Bash(npm run test)" "Read" "Edit"'
これでターミナルを閉じてもClaude Codeが裏で動き続けます。進捗が気になったら覗きにいける。
# セッションにアタッチして様子を見る
tmux attach -t claude-task
複数タスクを並列で動かす
tmuxのウィンドウを分けて、複数のClaude Codeを同時に走らせることもできます。
# ウィンドウ1: テストの修正
tmux new-session -d -s task1 \
'claude -p "failしているテストを修正して" \
--allowedTools "Bash(npm run test)" "Read" "Edit"'
# ウィンドウ2: ドキュメントの更新
tmux new-session -d -s task2 \
'claude -p "READMEをコードの現状に合わせて更新して" \
--allowedTools "Read" "Edit"'
自分は一度、2つのセッションが同じファイルを編集して競合して、差分がぐちゃぐちゃになりました。
完了通知をつける
放置するなら完了を知りたいですよね。自分はこんな感じでSlack通知を飛ばしています。
tmux new-session -d -s claude-task \
'claude -p "タスクの内容" \
--allowedTools "Bash(npm run test)" "Read" "Edit" \
--output-format json > /tmp/claude-result.json 2>&1; \
curl -X POST -H "Content-Type: application/json" \
-d "{\"text\": \"Claude Code タスク完了\"}" \
$SLACK_WEBHOOK_URL'
--output-format json をつけると結果をJSONで受け取れるので、後から結果をパースして内容確認もできます。
macOSなら terminal-notifier で通知を出すのでもいいです。
# macOSのデスクトップ通知
brew install terminal-notifier
tmux new-session -d -s claude-task \
'claude -p "タスク" --allowedTools "Read" "Edit"; \
terminal-notifier -title "Claude Code" -message "タスク完了"'
使用感
よかったところ
- 大きめのリファクタリングが楽になった。 「このディレクトリのファイル全部にエラーハンドリングを追加して、テストも通して」みたいなタスクを投げて、コーヒー淹れて戻ってきたら終わってる。これは体験として良いです。
- 夜に投げて朝見る運用。 退勤前にtmuxでタスクを仕込んで、翌朝
git diffで確認する。差分が気に入らなければgit checkoutで戻せるし、良ければそのままcommit。この流れが定着してからは、日中の作業時間を他のことに使えるようになりました。 - PRのレビュー指摘対応。 レビューで「ここ直して」と言われた箇所を、Claude Codeにまとめて投げる。細かい修正の積み重ねって地味に時間かかるんですが、これを放置で回せるのは助かります。
気をつけているところ
- 必ず差分を見る。 放置で動かした後、
git diffを全部読んでからcommitしています。AIが自律的に動いた結果をノーチェックで入れるのは怖い。特にtmuxだと途中経過を見ていないので、なぜその変更をしたのかの文脈がわからない。 --allowedToolsは最小限にする。 「面倒だから全部許可」とやりたくなるんですが、我慢して必要なコマンドだけに絞っています。特にBashは危険で、Bashとだけ書くと任意のコマンドが通ります。Bash(npm run test)のようにコマンド単位で指定するのが大事。- ブランチを切ってから投げる。 mainブランチで直接やると事故ったときに面倒なので、必ず作業ブランチを切ってからタスクを投げています。
git checkout -b refactor/error-handling
tmux new-session -d -s claude-task \
'claude -p "..." --allowedTools "Read" "Edit" "Bash(npm run test)"'
- タスクのスコープを絞る。 「プロジェクト全体をリファクタリングして」みたいな大きすぎるタスクだと、Claude Codeが迷走することがあります。ディレクトリやファイルを指定して、1タスク1目的にするのがコツです。
自分のtmux設定
Claude Code用に .tmux.conf に追加した設定です。
# セッション名を見やすくする
set -g status-left-length 30
# スクロールバッファを増やす(Claude Codeの出力が長いので)
set -g history-limit 50000
# マウスでスクロールできるようにする
set -g mouse on
history-limit はデフォルトだと2000行で、Claude Codeの長い出力が途中で切れます。50000くらいにしておくと、後から全部の出力を遡れるので安心です。
よく使うエイリアス
毎回長いコマンドを打つのは面倒なので、.zshrc にエイリアスを入れています。
# Claude Codeをtmuxで実行
ct() {
local session_name="${2:-claude-$(date +%H%M)}"
tmux new-session -d -s "$session_name" \
"claude -p \"$1\" --allowedTools 'Bash(npm run test)' 'Bash(npm run lint)' 'Read' 'Edit'; echo 'Done. Press Enter to close.'; read"
echo "Started session: $session_name"
echo "Attach with: tmux attach -t $session_name"
}
# 使い方
# ct "failしているテストを修正して"
# ct "エラーハンドリングを追加して" my-task
最後の read は、終了後にセッションが即座に閉じるのを防ぐためです。これがないと結果を確認する前にセッションが消えます。最初ハマりました。
所感
Claude Codeのauto的な運用、便利ではあるんですが、「AIが自律的にコードを書き換える」ことへの不安は正直まだあります。
自分が見ていないところで何十ファイルも変更されて、それをレビューする作業がむしろ増える、みたいなことも起きます。結局、AIに任せた時間を差分レビューで使っていたら、トータルでは変わらないじゃないかと。
ただ、タスクのスコープを小さくして、--allowedTools で権限を絞って、ブランチを切ってから投げる。このルーティンが定着してからは、だいぶ安定してきました。コツは「信頼しすぎない」ことだと思います。便利だけど、最終チェックは人間がやる前提で。
次は Claude Code の Agent SDK を使ったプログラマティックな自動化を試してみたいですね。CLI経由のtmux運用よりも、コールバックでツール実行を制御できるほうがもう少し安全に回せそうな気がしています。
ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。
- 選考ではありません
- 履歴書不要
- 技術の話が中心
- 所要時間30分程度
- オンラインOK