投稿

Claude Code のステータスラインをOSC 8でクリック可能なリンクにする

Claude Code のステータスラインをOSC 8でクリック可能なリンクにする

やりたかったこと

ステータスラインに出しているカレントフォルダ名を、ローカルで動かしている Web ツール(localhost のビューア)へのリンクにしたかった。フォルダ名をCmd+clickしたらブラウザで該当フォルダが開く、という導線。

ステータスラインに渡ってくるデータ

カスタムステータスラインのコマンドには、stdin 経由で JSON が渡ってくる。モデル名・カレントディレクトリ・セッションID・差分行数などに加えて、現在のブランチに紐づくPRの情報(pr.number / pr.url / pr.review_state)まで入っている。PRリンクを貼りたいだけなら、この pr.url をそのまま使えばいい。

OSC 8 でリンクにする

リンク化の本体はエスケープシーケンスを組み立てるだけ。Node.js のステータスラインスクリプトならこう書ける。

// text を OSC 8 ハイパーリンクで包む。url が空なら素のテキストを返す。
function hyperlink(text, url) {
  if (!url) return text;
  return `\x1b]8;;${url}\x07${text}\x1b]8;;\x07`;
}

// 例: カレントフォルダ名をローカル Web ツールへのリンクにする
const dir = hyperlink(path.basename(workDir), buildUrl(workDir));

\x07(BEL)はリンクURLと表示テキストの区切り。終端の \x1b]8;;\x07 で「リンク終わり」を宣言する。この宣言を忘れると、以降のテキスト全部がリンク扱いになるので注意。

ポイントは、 OSC 8 に対応していない端末では表示テキストだけが残る こと。つまり対応・非対応をスクリプト側で分岐しなくても、そのまま出して問題ない。

端末側の対応が本番

出力自体が正しくても、実際にクリックできるかは端末の対応次第。cat -v に流すとエスケープシーケンスが可視化できるので、まずスクリプトの出力が正しいことを確認し、そのうえで実機でCmd+clickを試すのが切り分けの順番になる。

$ echo "$json" | node statusline.js | cat -v
[Model] ^[]8;;http://localhost:15174/?...^Gフォルダ名^[]8;;^G

tmux の中にいる場合は、外側のターミナルがハイパーリンク対応でも tmux がシーケンスを落とすことがある。自分もまさにtmux越しで、出力は完全に正しいのにリンクにならず少しハマった。出力が合っているのにクリックできないときは、スクリプトではなく端末とtmuxのレイヤーを疑うのが早い。

トレンドのタグ