Claude CodeでWezTermの記号が入力できないときの対処法
WezTermでShift+記号や大文字が反転して入力される不具合の原因と、公式の修正状況、今すぐ使える回避策をまとめます。
WezTermでenable_kitty_keyboard = trueを有効にしていると、Shift+/を押しても?ではなく/が入力されることがあります。人によってはShift付きの英字が小文字のまま入力される、Shift+1やShift+Enterごと反応しなくなるなど、崩れ方の範囲が違います。原因はClaude Code側のキーボードデコーダにあり、v2.1.247で入った回帰です。
WezTermで記号入力がおかしくなるとはどんな症状か
最初に報告されたのは、Shift+/だけが?にならない症状でした。WSL2上のUbuntuでWezTermを使う環境で、v2.1.246では問題なく、v2.1.247に上げた直後から発生しています。Shift付きの英字は正しく入力されるため、記号だけがおかしいことに気づきにくいのが厄介な点です。
その後の報告では範囲が広がりました。AZERTYレイアウトのWindowsネイティブ環境では、Shift+英字も小文字のまま入力され、大文字が一切出せません。QWERTZキーボードの環境では、Shift+1やShift+-、Shift+Enterまで幅広く反応しなくなるケースも確認されています。一方でTERM=xterm-256colorとして動く環境では逆に、Shift+1やShift+;は正しく動きながらShift+/だけがおかしいという、最も狭い症状も報告されています。同じ不具合でも環境によって影響範囲が異なる点が、この問題の切り分けを難しくしています。
原因はkitty keyboardプロトコルの取りこぼし
WezTermはenable_kitty_keyboardを有効にすると、Claude Codeが要求するkitty keyboardプロトコルのflagに応答します。v2.1.246まではflag 1相当を要求していましたが、v2.1.247からはflag 4(代替キーの報告)を含むflag 5を要求するようになりました。
flag 4が有効だと、WezTermはShift+/を単なる?の1バイトではなく、ESC [ 47:63;130uという13バイトのエスケープシーケンスで返します。47は素の/、63はShift込みの?、130はShiftとNumLockのモディファイア値です。Claude Codeのデコーダはこのうち63(Shift込みの文字)を読み取らず、47だけを取り出してからtoUpperCase()で大文字化を試みる作りになっています。英字なら'a'.toUpperCase()は'A'になるので救われますが、記号の'/'.toUpperCase()は'/'のままで、Shiftが反映されません。
13バイトのシーケンスは、v2.1.246以前が使っていた「1バイトの生の?をそのまま通す」経路も通らなくなります。そのため影響は記号だけにとどまらず、環境によってはShift+英字の大文字化まで失われます。
自分の環境が影響を受けているか確認する
症状の切り分けには、WezTermが実際に送っているバイト列を確認するのが確実です。ターミナルで次のコマンドを実行し、Shift+/を押してからEnter、Ctrl+Dの順に入力します。
printf '\033[>5u'; od -c; printf '\033[<u\n'バイト列を調べるときは、Claude Codeが実際に要求するflag(>5u)を使うことが重要です。>1uなど別のflagで試すと問題が再現せず、誤って「ターミナル側は正常」と判断してしまいます。
キー入力を生のバイト列で捕捉した報告では、flagの違いによる差が次のように確認されています。
[A] flagを送らない(レガシー)
SHIFT + / : 3f ?
SHIFT + 1 : 21 !
[B] flag >1u(v2.1.246が要求していた形)
SHIFT + / : 3f ?
SHIFT + 1 : 21 !
[C] flag >5u(v2.1.247以降が要求する形)
SHIFT + / : ESC[47:63;130u
SHIFT + 1 : ESC[49:33;130uESC [ 47:63;130uのような13バイトのシーケンスが返ってくれば、kitty keyboardプロトコルのflag 5が有効になっている証拠です。単に?の1バイトだけが返る場合は、この不具合の対象外です。
症状別の対処法早見表
崩れ方によって、有効な対処が変わります。
| 症状・環境 | 有効な対処 | 補足 |
|---|---|---|
| Shift+/など記号だけがおかしい | 有効な対処enable_kitty_keyboardを無効化 | 補足最も確実。設定のホットリロードだけで直り、再起動は不要 |
| Shift+Enterのためだけに有効にしている | 有効な対処Ctrl+Jで改行するか、Enterキーだけ個別にバインドし直す | 補足kittyプロトコル自体を切れる |
| Shift+英字の大文字化も失われる(AZERTY等) | 有効な対処記号用と大文字用の両方のLuaバインドを追加 | 補足記号と英字でWezTerm内部の正規化処理が異なり、片方だけでは直らない |
| v2.1.269以降でも症状が残る | 有効な対処サードパーティのバイナリパッチかWezTerm側の更新を待つ | 補足公式修正の対象外になっているレイヤーの問題の可能性がある |
最も確実な対処 — enable_kitty_keyboardを無効化する
最短の対処は、~/.wezterm.luaのenable_kitty_keyboard = trueをコメントアウトまたは削除することです。WezTermはデフォルトでこの設定をオフにしています。無効化すると、Claude Codeが要求するflag自体をWezTermが無視するようになり、記号もShift付き英字も従来どおりの1バイトの応答に戻ります。
反映は設定のホットリロードで完了し、WezTermの再起動もClaude Codeセッションの再起動も必要ありません。ただし、kitty keyboardプロトコルをShift+Enterの改行のためだけに有効にしていた場合、この設定を切ると改行手段も一緒に失われる点に注意が必要です。
プロトコルを維持したまま個別キーだけ直す
kitty keyboardプロトコルを他の用途で使い続けたい場合は、影響を受けるキーだけをLuaのSendStringアクションでバイパスする方法があります。WezTerm側でキーを横取りし、プロトコルを経由せず生のバイト列をptyへ直接書き込む仕組みです。
local SHIFTED_PUNCTUATION = {
'~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
'_', '+', '{', '}', '|', ':', '"', '<', '>', '?',
}
for _, ch in ipairs(SHIFTED_PUNCTUATION) do
table.insert(config.keys, { key = ch, mods = 'SHIFT', action = wezterm.action.SendString(ch) })
end注意点は、記号側はmods = 'SHIFT'のバインドだけが実際に発火することです。WezTermはnormalize_shiftという内部処理で、ASCII英字だけをShift解除後の大文字表記に正規化し、記号はSHIFT修飾子を保持したまま扱います。そのためmods = 'NONE'側の記号バインドは一度もマッチしません。
Shift+英字の大文字化まで失われている環境では、英字用に別のバインドが必要です。
{ key = 'A', mods = 'SHIFT', action = wezterm.action.SendString 'A' },英字は記号と逆で、Shift付きの小文字キーが大文字キー側に正規化されるため、バインドはSHIFT修飾子付きの大文字キーに対して書きます。この方法はAZERTYレイアウトでAltGr経由の入力までは救えません。AltGrは別のモディファイアとして届くため、どちらのバインドにも一致しないからです。
Shift+Enterだけが目的ならCtrl+Jで代用する
kitty keyboardプロトコルを有効にしている理由がShift+Enterでの改行だけなら、プロトコルなしで解決する方法が2つあります。
Ctrl+Jはどのターミナルでも設定なしに改行を挿入でき、kitty keyboardプロトコルを経由しません。急ぎのときはこちらが手早い方法です。
もう1つは、WezTerm側でShift+Enterに生の改行文字を送るキーバインドを登録する方法です。
{ key = 'Enter', mods = 'SHIFT', action = wezterm.action.SendString '\n' },Claude CodeはCR(0x0d)をreturn(送信)、LF(0x0a)をenter(改行)として区別して扱います。このバインドはLFを直接送るだけなので、kitty keyboardプロトコルを一切経由せずにShift+Enterでの改行が動きます。
なおWezTermは/terminal-setupの対応対象には含まれていません。公式ドキュメントの対応表でWezTermは設定不要で動くターミナルに分類されているためで、/terminal-setupが書き込むキーバインドの対象はVS Code・Cursor・Devin Desktop・Alacritty・Zedに限られます。terminal-setupコマンド自体の使い方はterminal-setupコマンドでShift+Enterが効かないときの対処にまとめています。
v2.1.269で公式修正、それでも報告が続くケース
この不具合はv2.1.269の公式changelogに修正項目として記載されています。「Shift+punctuationの入力がWezTermでShiftなしのキーとして扱われる、v2.1.247での回帰」を直したという記述です。GitHub issueでも、一度はこのバージョンで解決したという報告がありました。
ところが翌日には、同じissueにv2.1.272でも再現するという報告が入り、issueは再度オープンされています。QWERTZキーボードでenable_kitty_keyboard = trueにしていると発生する、というのがその報告の環境です。さらに別の報告では、v2.1.270でもAZERTYレイアウトのWindowsネイティブ環境でShift+英字の大文字化が失われる症状が続くとされました。これは最初の報告者が挙げた「記号だけがおかしく英字は無事」という症状とも、Shift+/だけが崩れるという別の報告とも異なる範囲です。
つまり同じ13バイトのエスケープシーケンスに対して、環境やキーボードレイアウトによって崩れ方が違う複数の症状が重なっており、v2.1.269の修正は少なくとも1つの経路には効いたものの、すべての経路を閉じてはいない状態です。GitHubで公開されているサードパーティ製のバイナリパッチツールで回避しているケースや、WezTerm側の更新版では発生しなくなっているとする報告もあります。
まとめ
WezTermで記号やShift付きの文字がおかしくなる症状は、Claude Code側のkitty keyboardプロトコル実装がv2.1.247で退行したことが起点です。v2.1.269で一部は修正されていますが、AZERTYではv2.1.270、QWERTZではv2.1.272でも、別範囲の症状が報告されています。すぐに直したい場合はenable_kitty_keyboardを無効化するのが最も確実で、プロトコルを維持したい場合は影響を受けるキーだけをLuaでバイパスする方法が使えます。
ターミナル全般のキー入力設定はClaude Codeショートカット一覧、iTerm2固有の入力不具合はClaude CodeをiTerm2で使うとGOKが入力される不具合の対処法、IMEまわりの入力トラブルはClaude CodeのIME入力が重い・変換候補が重複する問題と対処法も参考にしてください。