mod のインターフェースギャラリー
Claude Code の mod が描画できるインターフェース要素(テキスト、ボタン、フィールド、Markdown、コード、差分など)を、サンプルコードとターミナルのスクリーンショットで確認できます。
mod は要素を組み合わせてインターフェースを描画します。要素には、テキスト、ボックス、ボタン、フィールドのほか、コンテンツを整形してくれるものがいくつかあります。このページのサンプルは要素を描画するコードを示しており、ほとんどにはターミナルのペインに表示された結果のスクリーンショットが付いているため、見た目で要素を選べます。
描画の仕組みを学ぶには、まず インターフェースに描画する をお読みください。主なプロパティと、各要素を描画するアプリについては 要素リファレンス を参照してください。すべてのプロパティは 型宣言 に記載されています。
サンプルを試す
このページのサンプルはスニペットであり、mod 全体ではありません。それぞれが 1 つの要素と、その中に入れ子になったもののコードです。
サンプルを自分のターミナルで確認するには、以下の手順で小さな mod を作成し、そこにサンプルを貼り付けます。この mod は /gallery コマンドを追加し、このコマンドがペインを開いてそこにサンプルを描画します。ペイン は、幅の広いフルスクリーンのターミナルではトランスクリプトの横に表示されるサイドバーで、それ以外ではプロンプトの上に表示される枠付きの領域です。
1. mod を作成する
gallery という名前のディレクトリを作成し、その中に .claude-plugin ディレクトリと hooks ディレクトリを作成します。各ファイルについては mod を作成する で説明しています。
マニフェストを gallery/.claude-plugin/plugin.json として保存します。
{
"name": "gallery",
"version": "0.1.0",
"description": "Opens a pane that draws one sample",
"author": { "name": "Your Name" }
}
gallery/hooks/hooks.json でエントリポイントを指定します。
{
"modules": ["./register.js"]
}
コードを gallery/hooks/register.js として保存します。これはペインを開く /gallery コマンドを追加し、そのペインに Plain text を描画します。
// Stands in for your own callback in the samples that take one
const noop = () => {}
// The Select sample keeps its choice here
let picked = 'md'
// The Raster sample packs its cells with this function
const DEFAULT_COLOR = 0x01000000
function cellsOf(rows) {
const numbers = rows.flat().flatMap(([char, color]) => [char.codePointAt(0), color, DEFAULT_COLOR])
return new Uint8Array(Uint32Array.from(numbers).buffer).toBase64()
}
export function register(on) {
on('session.start', async ($, e, next) => {
await $.command.register({ name: 'gallery', description: 'Open the sample pane' })
return next(e)
})
on('command.run', { command: 'gallery' }, async ($) => {
await $.ui.open({ id: 'gallery', focus: true, closeOnEscape: true })
return {}
})
on('ui.render', { component: 'Pane' }, async ($, e, next) => {
if (e.requestId !== 'gallery') return next(e)
const { Box, Text, Button, Input, Select, Link, Markdown, Code, Raster, Svg } = $.ui.resolve(e)
// Replace the element after return with a sample
return Text({ children: ['Plain text'] })
})
}
2. mod を実行する
シェルで、gallery を含むディレクトリから Claude Code を起動します。
claude --plugin-dir ./gallery
Claude Code のプロンプトで /gallery を実行します。Plain text が表示されたペインが開きます。
3. サンプルを差し替える
このページからサンプルをコピーします。register.js で、return の後に続くように Text({ children: ['Plain text'] }) をサンプルで置き換え、ファイルを保存します。Claude Code は保存のたびにモジュールを再読み込みするため、もう一度 /gallery を実行すると新しいサンプルが表示されます。
要素を選ぶ
サンプルは画面に表示したい内容ごとにまとめられています。
- テキストを表示する:
Text、Markdown、Link - コードと変更を表示する:
Code - 要素を配置する:
Box - 入力を受け付ける:
Button、Input、Select - 画像を描画する:
Raster、Svg、Image、Client
テキストを表示する
画面に文字を表示する要素は 3 つあります。独自のスタイルを付ける Text、すでに整形済みのコンテンツ向けの Markdown、URL 向けの Link です。
Text
Text は、指定したスタイルで文字列を描画します。このサンプルでは、プレーンテキストと 8 つのスタイルを 1 行ずつ表示します。
Box({
flexDirection: 'column',
children: [
Text({ children: ['Plain text'] }),
Text({ bold: true, children: ['bold'] }),
Text({ italic: true, children: ['italic'] }),
Text({ underline: true, children: ['underline'] }),
Text({ strikethrough: true, children: ['strikethrough'] }),
Text({ dimColor: true, children: ['dimColor'] }),
Text({ inverse: true, children: ['inverse'] }),
Text({ color: 'red', children: ["color: 'red'"] }),
Text({ backgroundColor: 'blue', children: ["backgroundColor: 'blue'"] }),
],
})

dimColor はテキストをグレーで描画します。backgroundColor はテキストの幅の分だけ塗りつぶします。
Markdown
Markdown は、Claude の返答と同じようにテキストを整形します。内容は children ではなく text で渡します。
Markdown({
text: '## Release notes\n\nThis build has **two** fixes and one `flag`:\n\n- Faster start\n- Fewer prompts\n\n> Quoted text',
})

見出しは # 記号なしで太字で描画されます。インラインコードはバッククォートなしで色付きで描画されます。引用は左側にバーが付いた斜体で描画されます。
Link
Link は、ラベルとそれに続く URL を描画します。
Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })

ターミナルは URL をラベルの後にテキストとして描画します。クリックで開くかどうかはユーザーのターミナルによって異なります。
コードと変更を表示する
Code は、Claude Code 独自のシンタックスカラーでソーステキストを描画するか、差分を描画します。VS Code 拡張機能では、Code は source をプレーンテキストとして表示し、これらのスクリーンショットにあるような色、行番号、差分の網掛けはいずれも表示されません。
Code
language を指定するか、Claude Code に言語を推測させるために path を渡します。startLine を指定すると、その番号から行番号が付きます。
Code({
language: 'javascript',
startLine: 1,
source: "const name = 'mods'\nconsole.log('hello ' + name)",
})

色はユーザーのテーマに従います。
差分としての Code
format: 'diff' を指定すると、source は 1 つ以上の unified diff のハンクになります。
Code({
format: 'diff',
source: '@@ -1,3 +1,3 @@\n # Mods\n-A mod is a plugin.\n+A mod is a plugin that runs code.\n Read on.',
})

Claude Code は @@ の行の代わりに行番号を描画します。削除された行と追加された行が似ている場合、変更された語はより濃く網掛けされます。
要素を配置する
Box
Box は中の要素を行または列に配置し、枠線を描画することもできます。このサンプルでは、単語の行を枠線付きのボックスの上に置いています。
Box({
flexDirection: 'column',
gap: 1,
children: [
Box({
flexDirection: 'row',
columnGap: 4,
children: [Text({ children: ['a row'] }), Text({ children: ['of three'] }), Text({ children: ['items'] })],
}),
Box({
borderStyle: 'round',
paddingX: 1,
children: [Text({ children: ["borderStyle: 'round'"] })],
}),
],
})

枠線はペインの幅まで伸びます。
入力を受け付ける
Button、Input、Select はコントロールです。ユーザーは Tab でこれらの間を移動し、フォーカスのあるものを操作します。どのキーが届くかについては キーボードフォーカスとホットキー を参照してください。
ペインにキーボードフォーカスを要求するには、focus: true を指定してペインを開きます。入力した文字は、Input がフォーカスを持つと届くようになります。ペインが開いたときにどのフィールドにフォーカスを置くかを選ぶには、ホットキーと最初のフォーカスを設定する を参照してください。
Button
ボタンは onPress を実行します。このサンプルでは、デフォルトの形式、ホットキー付きの plain ボタン、淡色のボタンを示します。
Box({
flexDirection: 'column',
children: [
Button({ key: 'save', label: 'Save', onPress: noop }),
Button({ key: 'next', label: 'Next', hotkey: 'n', plain: true, onPress: noop }),
Button({ key: 'skip', label: 'Skip', dimColor: true, onPress: noop }),
],
})

フォーカスのあるボタンは反転表示で描画されます。ここではユーザーが Tab を 2 回押しています。

Input
Input はデフォルトで 1 行を保持するテキストフィールドで、ユーザーが Enter を押すと onSubmit を実行します。
Input({
key: 'title',
label: 'Title',
placeholder: 'Type a title and press Enter',
value: '',
submitLabel: 'save',
onSubmit: noop,
})
フォーカスがないとき、フィールドはラベルとプレースホルダーを表示します。

フォーカスがあると、ラベルが太字になり、カーソルが表示され、⏎ の後に submitLabel が表示されます。

入力するとプレースホルダーが置き換わります。

メモやコミットメッセージなど、複数行を保持するフィールドには rows を 2 以上に設定します。
Input({
key: 'note',
label: 'Note',
placeholder: 'Write a note',
rows: 4,
onSubmit: noop,
})
ターミナルと Desktop アプリでは複数行が描画されます。VS Code 拡張機能では、フィールドは 1 行になります。rows には Claude Code v2.1.301 以降が必要です。それより前のバージョンでは、フィールドは 1 行になります。
フィールドは空の場合でも設定した行数を占めますが、描画されるペインまたはバンドの高さが上限になります。フィールドにフォーカスがある間は、それより長いテキストはフィールド内でスクロールします。
- ターミナルでは、Enter は引き続き送信を行います。その場合、ユーザーはバックスラッシュを入力してから Enter を押すか、ターミナルエミュレーターが対応している場合は Shift+Enter を押すことで改行します。これらはプロンプトと同じキーです。
- ターミナルでは、上下キーでフィールドの行間を移動します。最初の行と最後の行からは、前後のコントロールに移動します。
onSubmitとonInputは、各行を\nで連結したテキスト全体を受け取ります。
Select
Select では、ユーザーが複数の選択肢から 1 つを選べます。選択された選択肢の value を引数に onSelect を実行します。
Select({
key: 'format',
label: 'Format',
value: picked,
options: [
{ value: 'md', label: 'Markdown' },
{ value: 'html', label: 'HTML' },
{ value: 'txt', label: 'Plain text' },
],
onSelect: (value) => {
picked = value
},
})
閉じているときは、ラベルと現在の選択肢を表示します。

開いているときは、選択肢を一覧表示し、そのうち 1 つをマークします。

ユーザーが選択肢を選ぶと、リストが閉じます。

画像を描画する
Raster
Raster は色付きの文字セルのグリッドで、ヒートマップ、スパークライン、ゲーム盤などに使います。描画はターミナルが行います。このサンプルでは、スターターモジュールの cellsOf 関数を使用しています。この関数は、セルを Raster が受け取る文字列にパックします。詳しくは 色付きセルのグリッドを描画する で説明しています。
Raster({
key: 'grid',
columns: 3,
rows: 2,
cells: cellsOf([
[['█', 0x2e7d32], ['█', 0xf9a825], ['█', 0xc62828]],
[['█', 0x2e7d32], ['█', 0x2e7d32], ['█', 0xf9a825]],
]),
})

Raster は各色をより小さなパレットに丸めるため、0x2e7d32 は #337733 として描画されます。
Svg
Svg は Desktop アプリと VS Code 拡張機能で SVG ドキュメントを描画します。
Svg({
alt: 'Three bars of rising height',
width: 120,
height: 60,
source:
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 60"><rect x="10" y="40" width="20" height="20" fill="#2e7d32"/><rect x="50" y="25" width="20" height="35" fill="#f9a825"/><rect x="90" y="5" width="20" height="55" fill="#c62828"/></svg>',
})
ターミナルでは、Svg だけを返すペインは空のまま開きます。そこに別のものを描画するには、e.surface を確認して別のツリーを返してください。
Image と Client
さらに 2 つの要素については、ここにサンプルがありません。Image はターミナルで PNG または生のピクセルを描画します。Client は、アニメーションやポインター入力のために、ユーザーが用意した別のファイルが描画する領域です。これらのプロパティは 要素リファレンス に記載されています。
Image は次のターミナルで画像として描画されます。
- kitty 0.28 以降
- Ghostty
- iTerm2 3.5 以降。iTerm2 での描画には Claude Code v2.1.305 以降が必要です。
その他のターミナルでは、ユーザーには画像の代わりに Image の alt テキストが淡色で表示されます。alt テキストは、それだけで意味が通じるように記述してください。このテキストは、特に次の場合にも表示されるためです。
- GNU screen: screen の中で実行されているセッション。どのターミナルでも該当します。
- tmux: tmux の中で実行されているセッションのうち、tmux 内での描画の要件を満たしていないもの。
- バックグラウンドセッション: すべてのバックグラウンドセッション。どのターミナルからアタッチしているかは問いません。
- フルスクリーンレンダリング以外の iTerm2: iTerm2 では、画像はフルスクリーンレンダリングの下でのみ描画され、
CLAUDE_CODE_ALT_SCREEN_FULL_REPAINTが1に設定されている間は描画されません。画像を表示するには、Claude Code のプロンプトで/tui fullscreenを実行し、この変数は未設定のままにしてください。 - iTerm2 または tmux でのファイルパスのソース: iTerm2 および tmux の中では、
sourceでfileを指定しているImageは、画像の代わりにaltテキストを表示します。mod に iTerm2 または tmux のユーザーがいる場合は、画像をsource.fileのパスとしてではなく、source.pngまたはsource.rgbaに base64 として渡してください。
Unicode プレースホルダーを使った kitty グラフィックスプロトコルの画像を描画できるターミナルで mod のユーザーに淡色のテキストが表示される場合は、CLAUDE_CODE_FORCE_TERMINAL_IMAGES を 1 に設定できます。ただし、GNU screen の中、3.3 より古い tmux の中、tmux のポップアップ内、または tmux の allow-passthrough がオフの状態では設定しないでください。これらの環境では画像は表示されず、alt テキストの代わりにボックスが表示されます。
tmux 内で Image を描画する
tmux 内で Image が alt テキストを表示する場合は、バックグラウンドセッションなどのその他の alt テキストが表示される場合とあわせて、次の要件を確認してください。
- Claude Code v2.1.310 以降
- tmux 3.3 以降
- Claude Code が tmux のポップアップではなく tmux のペインで実行されている
- tmux が kitty 0.28 以降、Ghostty、または iTerm2 3.5 以降の中で実行されている
- tmux のオプション
focus-eventsとallow-passthroughがonになっている。kitty または Ghostty の中では、allow-passthroughはallでもかまいません。 - iTerm2 の中では、tmux が
-CCなしで実行され、フルスクリーンレンダリングがオンで、CLAUDE_CODE_ALT_SCREEN_FULL_REPAINTが未設定になっている。 - iTerm2 の中では、tmux のウィンドウが iTerm2 のウィンドウより大きくない。確認するには、その tmux ウィンドウで
tmux display-message -p '#{window_bigger}'を実行します。1が出力された場合は、tmux のウィンドウを収まるように調整してから Claude Code を再起動してください。 - mod の作成者が画像を
fileのパスとしてではなく、pngまたはrgbaのバイトとして渡している。自分で作成していない mod を使用していて、ほかの要件を満たしている場合は、この要件を確認するよう作成者に依頼してください。
必要な設定になっていない tmux オプションごとに、対応するコマンドをシェルで実行します。
tmux set -g allow-passthrough on
tmux set -g focus-events on
その後、tmux からデタッチして再度アタッチし、Claude Code を再起動します。別のターミナルから tmux にアタッチするたびに、再度 Claude Code を再起動してください。tmux サーバーを再起動しても両方のオプションを維持するには、両方の行を ~/.tmux.conf にも追加してください。
mod が描画できる場所を確認する
サンプルはすべてペインに描画しています。mod は他の場所にも描画でき、Claude Code を呼び出して代わりに何かを表示させることもできます。
- ペインとバンド:描画する場所を選ぶ
- スピナーなど Claude Code 自身の行:Claude Code がすでに描画しているものを変更する
- トースト、ステータスライン、ログ行:ターンを開始せずに何かを表示する
- 質問ダイアログ:ユーザーが決定するまでツール呼び出しを保留する
次のステップ
- インターフェースに描画する:タブ付きのペインを段階的に作成する
- 描画をテストする:テストからボタンを押す
- 要素リファレンス:各要素の主なプロパティと、それを描画するアプリ