Claude Codeにファイル末尾の改行を強制させる
先に結論
Hooksを設定する
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "FILE_PATH=$(jq -r '.tool_input.file_path') && [ -n \"$(tail -c1 \"$FILE_PATH\")\" ] && echo >> \"$FILE_PATH\""
}
]
}
]
}
}
些細な問題
AIにコードを書かせていると、ファイル末尾の改行を省略することがよくあります。プロジェクト内のコーディングルールとして空行で統一したいのと、GitHub上で差分を眺めたときに ⛔️ の表示が出るので気になっていました。

解決策
はじめは CLAUDE.md に Ensure the file ends with a blank line. などと書いていましたが、これは上手くいきませんでした。そもそもこれは機械的な処理なので、ファイル末尾に改行を追加する冪等な処理をHooksに追加すれば良いことに気づきました。
Hooksとは
Claude Codeが特定のタイミング、例えばタスク完了後やファイル編集前、ユーザープロンプト送信前などに到達したときに、指定したシェルコマンドを実行する仕組みです。
ユースケースとしては、Claude Codeの振る舞いをロギングしたり、フォーマッタを実行したり、通知を設定するなどが挙げられています。
今回は以下の設定をしました。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "FILE_PATH=$(jq -r '.tool_input.file_path') && [ -n \"$(tail -c1 \"$FILE_PATH\")\" ] && echo >> \"$FILE_PATH\""
}
]
}
]
}
}
今回は個人の設定というよりもプロジェクト単位の設定なので、設定は .claude/settings.json に設置しました。(設定ファイルについてはこちら)
"PostToolUse" "matcher": "Write" と書くことで、Claude Codeがファイルを追加した後に "hooks" に書かれた処理を実行しています。
フックイベントに関連するデータは、標準入力のJSONを処理することで取得できます。
"command" に書いた内容 COMMAND が以下のように処理されると考えるとわかりやすいかもしれません。
echo '{ "session_id": "...", "transcript_path": "...", ... }' > tmp.json
COMMAND < tmp.json
今回はClaude Codeが追加したファイルのパスを知る必要があり、 jq -r '.tool_input.file_path' として取得しました。
Discussion