Claude Codeでリンクが2回開く問題 — Windows Terminal/WSL2の対処法
Windows TerminalでClaude CodeのリンクをCtrl+クリックすると2回開く不具合の原因と、Ctrl+Shift+クリックや環境変数による回避策をまとめます。
このTipsでできること
Windows TerminalでClaude CodeのTUIに表示されたリンクをCtrl+クリックすると、同じURLを開くブラウザタブが2つ立ち上がります。原因はWindows TerminalとClaude Codeの両方が同じクリックに反応して、それぞれ独自にリンクを開いてしまうことです。この記事では、いますぐ止められる3つの回避策と、それぞれのトレードオフをまとめます。WSL2上のWindows Terminalでも同じ現象が起きます。
症状 — Ctrl+クリックでブラウザが2回開く
GitHub Issue #82582に投稿された計測によると、Claude Codeが出力したMarkdownリンクをCtrl+クリックすると、約650ミリ秒の間隔でHTTPリクエストが2回発生します。プレーンなクリック(Ctrlなし)では何も開かず、PowerShellのStart-Process <url>や、Claude Codeを介さずにWindows Terminal単体でOSC 8ハイパーリンクをCtrl+クリックした場合はちょうど1回だけ開きます。つまりOSやブラウザ、Windows Terminal単体の挙動は正常で、Claude CodeとWindows Terminalが同時に同じリンクを処理したときだけ二重に開きます。
再現環境として報告されているのは、Claude Code 2.1.220〜2.1.241、Windows Terminal 1.24.11911.0、Windows 11です。シェルはPowerShell 7とcmd.exeの両方で再現しており、シェルの種類には依存しません。
原因 — Windows TerminalとClaude Codeの両方がクリックに反応する
Issue #82582のコメントでは、Windows Terminalのソースコード(ControlInteractivity.cpp)を根拠に、次のようなpress/releaseの非対称性が指摘されています。
Windows TerminalのPointerPressed(マウス押下)はCtrl+クリックでカーソル下にOSC 8ハイパーリンクがあるかを最優先でチェックし、あればその場でリンクを開きます。マウス押下の時点でリンクが開いた場合、Claude Code向けのマウスレポートは転送されません。ところがPointerReleased(マウス解放)側にはハイパーリンクのガードがなく、Ctrl修飾子付きのマウスアップイベントがそのままClaude Codeへ転送されます。Claude Code側はこのマウスアップイベントを受け取ると、自前のクリックハンドラーで同じリンクを開きます。結果として、1回の物理的なクリックに対してWindows Terminalが1回、Claude Codeが1回、合計2回リンクが開きます。
この仕組みが働くのは、Claude Codeがフルスクリーンレンダリングでマウストラッキングを有効にしている場合に限られます。フルスクリーンレンダリングは?1000h ?1002h ?1003h ?1006hのマウスレポートモードを有効にし、これがマウスアップイベントの転送を可能にしている前提条件です。GitHub上の複数の報告者が「/tui defaultでクラシックレンダラーに切り替えると同じウィンドウ・同じリンクで再現しなくなる」と一致して確認しています。
WSL2上のWindows Terminalでも同じ「二重に開く」症状が報告されています。ただし原因の説明はissueによって食い違います。Issue #81905では「Claude Codeはマウス押下(SGRマウスレポート)で開き、Windows Terminalはクリック完了(押下+解放が同じリンク領域で完結したとき)で開く」という2フェーズの説明が示されていますが、これは押下・解放の役割を先述の#82582と逆に推定したものです。Windows Terminalのソースコード(ControlInteractivity.cpp)を直接確認した#82582の分析のほうが根拠が強く、本記事では押下側で開くのはWindows Terminal、転送された解放イベントで開くのはClaude Code、という説明を採用しています。#81905はこの現象をWSL2環境で最初に報告したissueで、根本原因が同じ#76022の重複として扱われ、切り分けの記録として残っています。コメント欄では「WSL2に限らず、素のPowerShellプロファイルでも同じように再現する」ことも確認されており、WSL2固有の問題ではありません。
「重複クリックイベント」系の不具合とは別物
同じ「リンクが2回開く」症状でも、原因が別のクラスの不具合が過去にありました。JetBrains製ターミナル(#68568)やWarpターミナル(warpdotdev/warp#13512)で報告されていたのは、ターミナル側が1回の物理クリックを2つのクリックイベントとして配送してしまうケースで、対策はイベントを時間・座標でまとめて重複排除することでした。
Windows Terminalのケースはこれとは違います。Issue #82582の分析によると、ここではクリックイベント自体は1回しか届いていません。届いた1回のマウスアップイベントに対して、Windows Terminal自身のOSC 8ハイパーリンク処理と、Claude Codeのクリックハンドラーがそれぞれ独立に反応しているだけです。ツール結果のクリック展開がWindows Terminalで二重にならないこと、Ctrlなしのプレーンクリックでは0回しか開かないことも、この違いを裏づけています。イベント重複排除の対策では、この現象は直りません。
今すぐ試せる回避策
公式には未修正のため、回避策は次の3つです。いずれも副作用があるため、失うものを理解したうえで選んでください。
Ctrl+Shift+クリックに変える
Windows TerminalはShiftキーが押されている間はマウスレポートの転送を止めるため、押下時のWindows Terminal側だけが開き1回で済みます。設定不要でその場で使える、もっとも手軽な回避策です。
CLAUDE_CODE_DISABLE_MOUSE_CLICKSを設定する
フルスクリーンレンダリング内でのクリック・ドラッグ・ホバーを無効にし、マウスホイールのスクロールだけ残します。設定するとClaude Code自身がクリックに反応しなくなるため、Windows Terminal側の1回だけが残ります。Claude Code v2.1.195以降で利用できます。
$env:CLAUDE_CODE_DISABLE_MOUSE_CLICKS = "1"
claude毎回のセッションで有効にしたい場合は、settings.jsonのenvキーに書いておくと、シェルの種類やセッションのたびに設定し直す必要がありません。
{
"env": {
"CLAUDE_CODE_DISABLE_MOUSE_CLICKS": "1"
}
}/tui defaultでクラシックレンダラーに切り替える
フルスクリーンレンダリングそのものをやめ、ターミナルのネイティブスクロールバックを使う旧来の表示に戻します。マウスレポートを有効にしないため、リンクを開くのはWindows Terminal側だけになります。ただしフルスクリーン特有のちらつき防止や検索ダイアログなどの機能も失います。
/tui default回避策の使い分け早見表
| 回避策 | 二重オープンの解消 | 失うもの | 設定の手間 |
|---|---|---|---|
| Ctrl+Shift+クリック | 二重オープンの解消◎ その場で解消 | 失うものなし(クリックのたびに意識する必要はある) | 設定の手間不要 |
CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1 | 二重オープンの解消◎ 恒久的に解消 | 失うものツール結果のクリック展開・ドラッグ選択 | 設定の手間環境変数1つ |
/tui default | 二重オープンの解消◎ 恒久的に解消 | 失うものフルスクリーンのちらつき防止・検索ダイアログ等 | 設定の手間コマンド1つ |
CLAUDE_CODE_DISABLE_MOUSE=1 | 二重オープンの解消◎ 恒久的に解消 | 失うものマウスホイールでのスクロールも失う | 設定の手間環境変数1つ |
CLAUDE_CODE_DISABLE_MOUSEはCLAUDE_CODE_DISABLE_MOUSE_CLICKSより強力で、マウス操作全体を無効にします。両方設定した場合はCLAUDE_CODE_DISABLE_MOUSEが優先されます。クリックだけ止めてホイールスクロールは残したいならCLAUDE_CODE_DISABLE_MOUSE_CLICKSを、マウス操作自体を使わないならCLAUDE_CODE_DISABLE_MOUSEを選ぶのが妥当です。
効かない回避策(先に知っておく)
Issue #82582のコメントでは、一見効きそうで効かない設定も具体的に検証されています。Windows Terminal側の"experimental.detectURLs": falseは、正規表現によるURL自動検出だけを止める設定で、Claude Codeが明示的なOSC 8ハイパーリンクとして送っているリンクには効きません。Windows Terminal自体にOSC 8ハイパーリンクの処理を無効化する設定は用意されていないため、この経路での回避はできません。
同様にFORCE_HYPERLINK環境変数はハイパーリンクの有効・無効を切り替えるだけで、二重オープンの原因である「押下と解放それぞれでの発火」自体は止められません。
VS Codeなど他のターミナルでは修正済み
同種の二重オープンは、VS Code統合ターミナルなどxterm.jsベースのターミナルでも過去に発生していましたが、公式changelogの記録によるとv2.1.77で「VS Code、Cursor、その他xterm.js系ターミナルでのCmd+クリック時の二重オープン」が、v2.1.94で「xterm.js系ターミナル上のtmux内での二重オープン」がそれぞれ修正されています。Claude Codeは公式ドキュメント上、VS Codeの統合ターミナルや同種のxterm.jsベースのターミナルではリンクのクリック処理をターミナル側の実装に委ねると説明されています。Windows Terminalはこの委譲の対象として挙げられておらず、v2.1.283までの公式changelogにもWindows Terminal向けの修正は記録されていません。
まとめ
Windows TerminalでClaude Codeのリンクが2回開くのは、フルスクリーンレンダリング下でWindows Terminal自身のOSC 8ハイパーリンク処理と、Claude Codeのクリックハンドラーが同じCtrl+クリックにそれぞれ反応するためです。WSL2上のWindows Terminalでも、シェルがPowerShellでもcmd.exeでも同様に起こります。設定なしで今すぐ試すならCtrl+Shift+クリック、恒久的に直すならCLAUDE_CODE_DISABLE_MOUSE_CLICKS=1か/tui defaultのどちらかを選ぶと、副作用を最小限に抑えながら二重オープンを止められます。関連するWindowsのstdout取得不良や非ブロッキングstdoutの設定も、同じくWindows環境変数まわりのトラブルシューティングとして参考にしてください。