1. 重要な注意(必読)
このセットアップは非公式な方法です
- Claude Desktop のローカル保存 JSON をバックアップしたうえで書き換える方法であり、Anthropic 公式が提供する仕組みではありません。
- Claude Desktop / Claude Code のアップデートで保存場所や JSON フォーマットが変わると動かなくなる可能性があります。
- 万一セッションタイトルや動作がおかしくなったら
~/.claude/hooks/backup/<日付>/のバックアップから戻してください。 - 公式の言語設定対応が来たら、このセットアップは不要になります(ロールバック手順あり)。
3. 日本語化の呪文
この呪文を全文コピーして Claude Desktop の新規セッション(または Claude Code)に貼り付けると、自動でセットアップしてくれます。Claude がファイル作成・設定変更を提案するので、内容を確認してから許可します。
呪文を唱える場所
Claude Desktop のチャット欄(Code 機能あり)、または ターミナル版 Claude Code どちらでも OK。新規セッションで貼り付けてください。
Claude Desktop の Recents サイドバーに表示されるセッションタイトルを、自動で日本語化するセットアップをして欲しいです。
## 環境前提
- macOS であること
- jq コマンドが入ってること (なければ案内してください)
- Claude Code がインストール済みであること
## やってほしいこと
### 1. 前提確認
- macOS か確認 (`uname` で Darwin)
- `jq` `python3` `claude` の存在確認
- 不足してたら `brew install jq` 等の案内をして停止
### 2. ファイル `~/.claude/hooks/rename-session-title.sh` を以下の内容で作成
(ディレクトリも無ければ `mkdir -p ~/.claude/hooks` で作成)
```bash
#!/usr/bin/env bash
set -uo pipefail
LOG="$HOME/.claude/hooks/rename-session-title.log"
mkdir -p "$(dirname "$LOG")"
log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "$LOG"; }
if [ "${CLAUDE_RENAME_HOOK_ACTIVE:-}" = "1" ]; then exit 0; fi
export CLAUDE_RENAME_HOOK_ACTIVE=1
log "=== hook fired (pid=$$) ==="
if [ "$(uname)" != "Darwin" ]; then
log "ERROR this script supports macOS only (got: $(uname))"
exit 0
fi
MISSING=()
for cmd in jq python3 claude; do
command -v "$cmd" >/dev/null 2>&1 || MISSING+=("$cmd")
done
if [ ${#MISSING[@]} -gt 0 ]; then
log "ERROR missing required commands: ${MISSING[*]}"
log " Install hint:"
log " - jq: brew install jq"
log " - python3: brew install python3 (or use system python)"
log " - claude: visit https://claude.com/claude-code"
log " Ensure they are in PATH (e.g. /opt/homebrew/bin or /usr/local/bin)"
exit 0
fi
CLAUDE_BIN=$(command -v claude)
INPUT=$(cat 2>/dev/null || true)
SID=$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null || echo "")
EVENT=$(printf '%s' "$INPUT" | jq -r '.hook_event_name // empty' 2>/dev/null || echo "")
log "event=$EVENT session_id=$SID"
SESSIONS_DIR="$HOME/Library/Application Support/Claude/claude-code-sessions"
[ -d "$SESSIONS_DIR" ] || { log "no sessions dir"; exit 0; }
LOCKDIR="$HOME/.claude/hooks/.rename.lock.d"
PID_FILE="$LOCKDIR/pid"
acquire_lock() {
local retries=3
while [ $retries -gt 0 ]; do
if mkdir "$LOCKDIR" 2>/dev/null; then echo "$$" > "$PID_FILE"; return 0; fi
local old_pid=""
[ -f "$PID_FILE" ] && old_pid=$(cat "$PID_FILE" 2>/dev/null)
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
log "lock held by alive pid=$old_pid, skipping"; return 1
fi
log "stale lock (pid=${old_pid:-none} not alive), taking over"
rm -rf "$LOCKDIR"; retries=$((retries - 1))
done
log "could not acquire lock after retries, skipping"
return 1
}
if [ -d "$LOCKDIR" ]; then
if [ -n "$(find "$LOCKDIR" -maxdepth 0 -mmin +10 2>/dev/null)" ]; then
rm -rf "$LOCKDIR"; log "removed stale lock by age (fallback)"
fi
fi
if ! acquire_lock; then exit 0; fi
trap 'rm -rf "$LOCKDIR"' EXIT
is_non_ascii() {
printf '%s' "$1" | python3 -c 'import sys; sys.exit(0 if any(b>=0x80 for b in sys.stdin.buffer.read()) else 1)'
}
COUNT=0; SCANNED=0
while IFS= read -r -d '' f; do
SCANNED=$((SCANNED+1))
TITLE=$(jq -r '.title // empty' "$f" 2>/dev/null)
[ -n "$TITLE" ] || continue
if is_non_ascii "$TITLE"; then continue; fi
log "translating: $TITLE ($f)"
PROMPT="次の英語のセッションタイトルを、自然で簡潔な日本語に翻訳してください。
ルール:
- タイトルだけを1行で返す
- 引用符・前置き・補足説明は不要
- 20文字以内を目安に
- 固有名詞・コマンド名・ファイル名は原文のまま残す
タイトル: $TITLE"
JP_TITLE=$("$CLAUDE_BIN" -p --model haiku "$PROMPT" </dev/null 2>>"$LOG" \
| head -1 | sed -E 's/^[[:space:]"'''「『]+//; s/[[:space:]"'''」』]+$//')
[ -n "$JP_TITLE" ] || { log " empty result, skip"; continue; }
[ ${#JP_TITLE} -le 200 ] || { log " too long, skip"; continue; }
if ! is_non_ascii "$JP_TITLE"; then log " ascii result, skip: $JP_TITLE"; continue; fi
TMP="${f}.tmp.$$"
if jq --arg t "$JP_TITLE" '.title = $t | .titleSource = "user"' "$f" > "$TMP" 2>>"$LOG"; then
if jq -e '.sessionId and .cliSessionId and (.title != null)' "$TMP" >/dev/null 2>&1; then
BACKUP_DIR="$HOME/.claude/hooks/backup/$(date '+%Y-%m-%d')"
if ! mkdir -p "$BACKUP_DIR" 2>>"$LOG"; then
rm -f "$TMP"; log " backup dir creation failed, aborting"; continue
fi
BACKUP_FILE="$BACKUP_DIR/$(basename "$f")"
if [ ! -f "$BACKUP_FILE" ]; then
if ! cp "$f" "$BACKUP_FILE" 2>>"$LOG"; then
rm -f "$TMP"; log " backup failed, aborting"; continue
fi
fi
if mv "$TMP" "$f" 2>>"$LOG"; then
log " -> $JP_TITLE file=$f backup=$BACKUP_FILE"
COUNT=$((COUNT+1))
else
rm -f "$TMP"; log " mv failed, original not overwritten"
fi
else
rm -f "$TMP"; log " health check failed, skipping"
fi
else
rm -f "$TMP"; log " jq failed"
fi
done < <(find "$SESSIONS_DIR" -name "local_*.json" -print0 2>/dev/null)
log "done. scanned=$SCANNED translated=$COUNT"
exit 0
```
### 3. 実行権限を付ける
`chmod +x ~/.claude/hooks/rename-session-title.sh`
### 4. `~/.claude/settings.json` を編集 (重要: 重複登録に注意)
以下の要件を必ず満たしてください:
- ファイルが無ければ `{}` で新規作成
- 既存の場合はバックアップ (`cp ~/.claude/settings.json ~/.claude/settings.json.bak.$(date +%s)`)
- `.hooks` / `.hooks.Stop` / `.hooks.SessionStart` キーが存在しなくても壊れないマージ処理
- 同じ command が既に登録されていれば一度削除してから追加 (2 回実行しても重複しない冪等処理)
- `command` には `~` ではなく `$HOME` を展開した絶対パスを使用
参考の jq コマンド (安全版):
```bash
HOOK_CMD="$HOME/.claude/hooks/rename-session-title.sh"
[ -f ~/.claude/settings.json ] && cp ~/.claude/settings.json ~/.claude/settings.json.bak.$(date +%s)
[ -f ~/.claude/settings.json ] || echo '{}' > ~/.claude/settings.json
jq --arg cmd "$HOOK_CMD" '
.hooks = (.hooks // {}) |
.hooks.Stop = (
(.hooks.Stop // [])
| map(.hooks = ((.hooks // []) | map(select(.command != $cmd))))
| map(select((.hooks // []) | length > 0))
) |
.hooks.SessionStart = (
(.hooks.SessionStart // [])
| map(.hooks = ((.hooks // []) | map(select(.command != $cmd))))
| map(select((.hooks // []) | length > 0))
) |
.hooks.Stop += [{
"hooks": [{
"type": "command",
"command": $cmd,
"async": true,
"timeout": 120
}]
}] |
.hooks.SessionStart += [{
"hooks": [{
"type": "command",
"command": $cmd,
"async": true,
"timeout": 120
}]
}]
' ~/.claude/settings.json > ~/.claude/settings.json.tmp \
&& mv ~/.claude/settings.json.tmp ~/.claude/settings.json
```
### 5. `~/.claude/CLAUDE.md` の末尾に以下を追記
(ファイルが無ければ新規作成。既に同じセクションがある場合は重複追記しない)
```
## セッションタイトル
新しいセッションのタイトル / 会話のタイトルは必ず日本語で生成してください。
```
### 6. 動作確認
- `~/.claude/hooks/rename-session-title.sh` が +x で存在
- `~/.claude/settings.json` が valid JSON (`jq . ~/.claude/settings.json`)
- 手動 1 回走らせて動作確認:
`echo '{"session_id":"setup-test","hook_event_name":"Stop"}' | bash ~/.claude/hooks/rename-session-title.sh`
ログ確認: `tail -20 ~/.claude/hooks/rename-session-title.log`
### 7. 完了報告
完了したら以下をユーザーに伝えてください:
- 「セットアップ完了しました。Cmd+Q で Claude Desktop を完全終了 → 再起動してください。」
- 「再起動後、Recents の英語タイトルが順次日本語化されます (新規セッションも自動で日本語タイトルになるよう設定済み)」
- バックアップ場所: `~/.claude/hooks/backup/<日付>/` に編集前ファイルが残ります
途中で詰まったら、どこで止まったか教えてください。 4. セットアップ後の動作
| 場面 | 挙動 |
|---|---|
| 再起動前から存在してた英語セッション | 再起動後にほぼ全部日本語化される |
| 既に日本語化されたセッション | クリックしても英語に戻らない |
| 新規セッション作成直後 | 数秒だけ英語表示 → hook 発火後に日本語に切り替わる |
5. ログ確認方法
方法 A:Terminal アプリで実行
Mac の Terminal(またはiTerm2)を開いて、下のコマンドをコピペして Enter。
方法 B:Claude Code に頼む
Claude Code の新規セッションで「ログを見せて」と伝えるだけで確認してくれます。コマンドが分からなくてもOK。
Terminal を使う場合は、下記コマンドでリアルタイムにログを確認できます。
tail -f ~/.claude/hooks/rename-session-title.log done. scanned=N translated=M が出れば正常に動作している証拠です。
6. トラブルシューティング
コマンドに慣れていない方へ
このセクションにはコマンド(黒い画面に入力するやつ)が出てきますが、Claude Code の新規セッションに状況をそのまま伝えるだけでも調査・対処してもらえます。
「サイドバーのタイトルが日本語になりません。ログを確認して原因を調べてください」
↑ こんな感じで頼めばOKです。コマンドが分からなくても大丈夫。
セッションタイトルが日本語にならない
1. まずログを確認(Terminal または Claude Code に依頼)
tail -50 ~/.claude/hooks/rename-session-title.log 2. よくあるエラーと対処
-
lock held by alive pid=..., skipping
別の hook 実行が走り続けている可能性。しばらく待つ。10 分以上続く場合のみ強制クリア:
rm -rf ~/.claude/hooks/.rename.lock.d -
ERROR missing required commands
不足しているコマンドをインストール:
brew install jq/which claudeで確認 -
done. scanned=0 translated=0
Claude Desktop のアップデートで保存場所が変わった可能性。スクリプト内
SESSIONS_DIRが指す~/Library/Application Support/Claude/claude-code-sessionsが存在するか確認。
セッションが消えた等の重大トラブル
Qiita で Windows ユーザーが過去スレッド消失した事例あり(macOS では未観測)
バックアップはファイル名のみで保存されるため、元のサブディレクトリ情報はバックアップ側からは分かりません。ただしログにフルパスが残っているので復元は可能です。
- ログ (
~/.claude/hooks/rename-session-title.log) を見て、file=<フルパス> backup=<バックアップフルパス>の行を探す - その対応関係に従って、バックアップを元のパスへ個別にコピー (
cp <backup> <file>) - 不安な場合は手動復元せず、必ず詳しい人に相談する
機械的な一括コピーは推奨しません。複数 workspace に同名ファイルがある可能性、上書き対象を誤る可能性があります。
7. ロールバック手順
~/.claude/hooks/ には他のスクリプトが入っている可能性があるため、ディレクトリごと削除はしないようにしてください。
# 1. settings.json をバックアップから復元 (タイムスタンプは適宜置換) cp ~/.claude/settings.json.bak.<タイムスタンプ> ~/.claude/settings.json # 2. このセットアップ関連ファイルだけ削除 rm -f ~/.claude/hooks/rename-session-title.sh rm -f ~/.claude/hooks/rename-session-title.log rm -rf ~/.claude/hooks/.rename.lock.d # 3. ~/.claude/CLAUDE.md に追記した以下のセクションをエディタで削除 # ## セッションタイトル # 新しいセッションのタイトル / 会話のタイトルは必ず日本語で生成してください。 # 4. Claude Desktop を Cmd+Q で完全終了して再起動
バックアップ (~/.claude/hooks/backup/) はしばらく残しておくのが安全です。完全に不要になったら手動削除:
rm -rf ~/.claude/hooks/backup/ 8. 仕組み・コスト
仕組み概要
| 要素 | 役割 |
|---|---|
| Stop hook | Claude が応答完了するたびに発火 → 全英語タイトル翻訳 |
| SessionStart hook | Desktop 起動 / セッションフォーカス時に発火 → 同上 |
| titleSource: "user" | Desktop に「ユーザー設定」と認識させる(これで上書きされにくくなる) |
| PID ベースロック | 同時実行を防ぎつつ、ハングしたら即奪取 |
| バックアップ | 編集前ファイルを ~/.claude/hooks/backup/<日付>/ に保存 |
| JSON 健全性チェック | 編集後ファイルが壊れていないか確認、壊れていたら書き込みキャンセル |
既知の制約
- ・新規セッション直後の数秒: hook 発火までに英語が一瞬見える可能性(実害なし)
- ・Anthropic 側の挙動変更: Claude Desktop のアップデートで
titleSource: "user"の扱いが変わると壊れる可能性 - ・ネットワーク不調時:
claude -p haikuの失敗 → その回は英語のまま(次の hook 発火で再挑戦)
コスト目安
Claude Haiku 4.5 の API 単価(2026年5月時点): 入力 $1 / 100万トークン、出力 $5 / 100万トークン
タイトル翻訳は短文(入力 ~150 トークン / 出力 ~20 トークン)なので、1 回あたりのコストは非常に小さい想定です。
ただし claude -p の課金・利用枠の扱いは認証・契約形態(Pro / Max / Team / API キー直接)によって変わる可能性があります。
9. 公式対応について
この問題は GitHub Issue でも複数報告されています。特に今回のセットアップに近いのは:
- #55951
— Desktop sidebar ignores UserPromptSubmit hook
sessionTitleoutput - #54440 — [FEATURE] Localize auto-generated session titles in "Recents" sidebar
- #58848 — Session titles generated in English despite language setting
開けるものに 👍 しておくと公式対応が早まる可能性があります。公式対応が来たらこの hook は不要になるので、ロールバック手順で剥がしてください。
なお ターミナルで claude コマンドからセッション開始する習慣にすると、hook 経由で公式の backend rename がトリガされてサーバー側のタイトルも日本語になります。Desktop 新規セッションより筋がよい方法です。
10. Windows 向け(実験的・未検証)
このセクションは macOS 環境のみで検証済みです
Windows 版は未テストで、Kevin も動作保証できません。Qiita で報告された事例として、Windows ユーザーが JSON を直接編集して過去スレッドが全消失したケースがあります。
Windows で試す場合は 必ず自己責任 で以下を実施してください:
- 編集前に
%APPDATA%\Claude\を丸ごと zip でバックアップ - 1 ファイルだけテスト → 動作確認 → 次、という段階運用
- 消えた場合は zip から復元
Windows 向け呪文を表示 閉じる
Windows ユーザーには このページの URL + 下記の呪文を渡してください。ユーザーが自身の Claude Code に貼ると、Claude がその Windows 環境を探索しながら適応版を作成します。
あなたは Windows 環境で動いている Claude Code です。 私 (Windows ユーザー) の Claude Desktop サイドバーのスレッド名を、 自動で日本語化するセットアップをして欲しいです。 ## 元情報: macOS 用のリファレンス実装 紹介者 (Mac ユーザー) は以下の構成でこれを実現しています。 あなたはこれを参考にしつつ、Windows 環境に適切に翻訳してください。 [ここに https://kevin-claude-guide.pages.dev/sidebar-jp の呪文本体を貼り付け] ## ⚠️ 重大な注意 (Windows 特有のリスク) - Qiita で報告された事例として、`%APPDATA%\Claude\claude-code-sessions\` の JSON を直接編集して過去スレッドが全消失したケースあり。 - このリスクを下げるため、以下を必ず実施してください: 1. 最初に `%APPDATA%\Claude\` を丸ごと zip でバックアップ 2. テスト用に 1 セッションだけ翻訳 → Claude Desktop を完全終了 → 再起動して反映確認 3. 上記で問題なければ全体に展開 ## やってほしいこと ### 1. 環境探索 - Claude Desktop の `claude-code-sessions` ディレクトリ実パス(第一候補: `%APPDATA%\Claude\claude-code-sessions\`) - 使えるシェル(Git Bash / WSL / PowerShell) - 依存コマンドのパス(jq / claude / python) ### 2. macOS 版スクリプトを Windows に適応 - パスを Windows 形式に置換 - `kill -0 <PID>` の代替を検討 - 改行コード注意(LF で保存) ### 3. 段階テスト(重要) いきなり全セッションには適用しないでください。 1 セッションだけ翻訳 → Desktop 完全終了 → 再起動 → UI 確認 の順で進めてください。 途中で詰まったり判断に迷ったら、必ず私に確認してください。
macOS との主な違い
| 観点 | macOS | Windows |
|---|---|---|
| セッション保存先 | ~/Library/Application Support/Claude/... | %APPDATA%\Claude\... |
| シェル | bash(標準) | Git Bash / WSL / PowerShell(要選択) |
| 完全終了 | Cmd+Q | タスクトレイ右クリック→ Quit + Task Manager 確認 |