「modsが出たらしいけど、結局なにが変わるの?」
正直、私も最初はそう思っていました。Claude Codeには自作のstatusline(入力欄の下に出る情報行)とhooksがあり、毎日それで足りていたからです。
そこで、自分のstatuslineの4行をmodで描き直してみました。結果、元のstatuslineは残し、modは上に「足す」のが正解でした。
TL;DR: 入力欄の下でmodが使えるのは1行だけで、複数行の情報は入りません。そのかわり入力欄の上の帯なら、色付きゲージや推移グラフ、statuslineに無かったeffortやリポジトリ名まで足せました。
modsは「Claude Codeの中で動く小さな部品」
ざっくりいうと、modsはClaude Codeの見た目や動き方を変える追加パーツです。2026年10月1日に公式ブログで発表され、v2.1.287以上で使えます。私の環境はMac M5(メモリ16GB)、Claude Code 2.1.288でした。
これまでのhooksは、決まったタイミングで外部のスクリプトを呼ぶ仕組みでした。modsはJavaScriptやTypeScriptの関数で、Claude Code本体の中で呼ばれます。だから画面に描けるし、イベントの中身も書き換えられます。公式ブログも、hooksでは「書き換え・UIの描画・機能の置き換え」ができなかったことを作った理由に挙げています。
事例は、tensyoku_kuraさんの記事が日本語でよくまとまっています。待ち時間にDoomで対戦するmod、スピナーを漫画にするmod、計画の進捗バー、リマインダーを入力欄の上に出すmodなどです。ただ、その記事は「実機検証したものではありません」と断っています。この記事はその続きとして、手元で実際に動かした記録です。
まず自作した天気modは、数字がstatuslineと重複していた
最初は公式ガイドの「Token Weather」(コンテキストの埋まり具合を天気で出すmod)を真似て、Claudeに作らせました。Claude Codeに頼むと内蔵のplugin-authoringスキルが動き、15行ほどのmodができます。最初のファイルが書かれた瞬間に「Enable hot reloading for this session?」と聞かれ、有効にするとそのターンの終わりに読み込まれました。
出てきた表示がこちらです。

一番上の「⚠ token-weather:」が自作mod。その下の3行が元のstatusline
見て気づいたことが2つありました。先頭に「⚠」とmod名が付くので、警告に見えます。しかも、すぐ下のstatuslineに「26.0% used」と同じ数字がもう出ていました。数字を1行出すだけなら、従来のstatuslineで足りていたわけです。
公式サンプルのtoken-weatherも読み込んでみました。こちらは122行で、入力欄の上に専用の帯を描き、直近12ターンの推移を小さなグラフで出します。天気を絵文字ではなく「☀☁☂」のような記号で描いているのは、端末によって桁がずれないようにするためだと、コードのコメントに書いてありました。modらしさは、この「帯に描く」ほうにあるのだなと感じました。
statuslineの4行を、modの帯に描き直してみた
そこで本題です。自分のstatusline(モデル・コスト・フォルダ・ブランチ/コンテキスト/5時間と7日の利用枠)を、modの帯に色付きゲージで描き直すことにしました。modの$.session.usage()は、statuslineと同じコンテキスト・利用枠・コストの数字を返してくれます。
入力欄の下に置いたら、ずれた
statuslineと同じく入力欄の下に置きたかったので、まずはそこに描きました。

入力欄の下に描いた帯。2行目以降が右に押し出されている
左端の「▸▸ auto mode on」は、Claude Codeが必ず描く権限モードの表示です。modが入力欄の下で描けるのは、その横のヒント行(「? for shortcuts」などが出る1行)だけでした。そこに複数行を描くと、2行目以降が権限モード表示の幅だけ右にずれます。
Claudeに直させた1回目は、別の表示を消せば揃うという見立てでした。ところが消したのはフッター右側のラベルで、左端のこの表示ではありません。型定義の読み違いでした。

直したつもりの2回目。やはり右にずれる
権限モードの表示は、modからは動かせません。statuslineがいる「入力欄の下の複数行」は、modには開放されていない場所でした。1行に詰める版も作りましたが、元の情報が減ってしまいます。
上に置いたら、statuslineに無い情報まで足せた
そこで帯を入力欄の上に戻し、元のstatuslineも設定に戻して、両方を出すことにしました。

上の3行がmodの帯、下が元のstatusline(入力内容・IDとアカウント名はぼかしています)
帯のほうには、元のstatuslineに無かった情報を3つ足せました。
- effort(考える深さ): 画面の「medium」。モデルに送る直前のリクエストを覗いて取っています
- リポジトリ名: originのURLから「owner/repo」の形で取得(画像ではぼかしています)
- ターンごとのコスト増分: 「(+0.28)」の部分
effortだけは少し手間取りました。使用量のように問い合わせて取る方法がなく、モデルへのリクエストを流すturn.stepというイベントで覗くしかありません。しかもこのイベントは中身が少しずつ流れてくる形式で、普通の関数ではなくasync function*で書く必要がありました。中身は変えず、見るだけにしています。
できたmodは213行で、claude plugin validateを通すと、使うイベントと呼ぶAPIが一覧で出ます。
hooks: session.start, turn.step, turn.complete, ui.render{component=AbovePrompt}, ...
calls: $.process.run (via gitInfo), $.session.usage (via refresh), ...
書き込みや外部への通信が無いことを、入れる前に一覧で確かめられるのは安心でした。modsはサンドボックスなしで、ユーザーと同じ権限で動くからです(公式ドキュメント)。
守りのhooks 4本は、modに移さなかった
ついでに、毎日動いているhooks 4本も見直しました。rmを止めるもの、人間専用のメモ置き場への書き込みを止めるもの、記事を書いた直後に文章チェックをかけるもの、完了タスクを記録するものです。
4本とも「止める」か「記録する」だけで、画面に描きたいものはありませんでした。公式の比較表でも、手元のスクリプトで止める・通す・記録するならhooksを選ぶ、とされています。
もう1つ理由があります。私はlaunchdからclaude -pで無人の処理を回しています。Claudeがセッション中に書いたmodは、承認する人がいないそこでは読み込まれません(公式ドキュメント)。settings.jsonのhooksなら、どちらでも効きます。
modsは「置き換え」ではなく「足す」層
- 入力欄の下でmodが描けるのは1行だけ。複数行のstatuslineは置き換えられない
- 入力欄の上の帯なら、ゲージや推移グラフ、effortやリポジトリ名まで足せる
- 止める・記録するhooksは、移さなくていい
個人的には、modsは今あるものを作り直す道具ではなく、「画面にもう1つ何を出しておきたいか」から考える道具だと感じました。次は、文章チェックの点数を帯に出すmodを試すつもりです。
作ったmodは、claude --plugin-dirでほかのセッションでも読み込めるよう、手元の別フォルダに保管しています。

コメント