SpyBara
Go Premium

plugins/mods/gallery.md 2026-11-09 23:02 UTC to 2026-11-10 21:57 UTC

No changes for this document in this history range.

2026

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 を実行すると新しいサンプルが表示されます。

要素を選ぶ

サンプルは画面に表示したい内容ごとにまとめられています。

テキストを表示する

画面に文字を表示する要素は 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'"] }),
  ],
})

スタイル名が付いた 9 行のテキストを表示したペイン:plain、bold、italic、underline、strikethrough、グレーの dimColor、inverse、赤の color、青の backgroundColor。

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',
})

太字の見出し Release notes、続いて太字の単語 1 つと色付きのコード単語 1 つを含む文、2 項目のリスト、左側にバーが付いた斜体の引用を表示したペイン。

見出しは # 記号なしで太字で描画されます。インラインコードはバッククォートなしで色付きで描画されます。引用は左側にバーが付いた斜体で描画されます。

Link は、ラベルとそれに続く URL を描画します。

Link({ href: 'https://code.claude.com/docs', label: 'Claude Code docs' })

1 行を表示したペイン:ラベル Claude Code docs と、グレーの URL。

ターミナルは 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)",
})

シンタックスカラーで表示された、行番号付きの 2 行の JavaScript を表示したペイン。

色はユーザーのテーマに従います。

差分としての 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.',
})

4 行の差分を表示したペイン。削除された行は赤、追加された行は緑で網掛けされ、それぞれ行番号が付いています。追加された行では、that runs code という語がより濃く網掛けされています。

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'"] })],
    }),
  ],
})

4 列ずつ間隔を空けて 1 行に並んだ 3 つの語、空行、1 行のテキストを囲む角丸の枠線を表示したペイン。枠線はペインの幅いっぱいに伸びています。

枠線はペインの幅まで伸びます。

入力を受け付ける

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 }),
  ],
})

1 行に 1 つずつ 3 つのボタンを表示したペイン:角括弧付きの Save、角括弧なしで n が色付きの n: Next、グレーで角括弧付きの Skip。

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

同じ 3 つのボタンで、2 番目の n: Next が反転表示で描画されています。

Input

Input はデフォルトで 1 行を保持するテキストフィールドで、ユーザーが Enter を押すと onSubmit を実行します。

Input({
  key: 'title',
  label: 'Title',
  placeholder: 'Type a title and press Enter',
  value: '',
  submitLabel: 'save',
  onSubmit: noop,
})

フォーカスがないとき、フィールドはラベルとプレースホルダーを表示します。

1 行を表示したペイン:ラベル Title と、グレーのプレースホルダー Type a title and press Enter。

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

同じフィールドで、ラベルが太字になり、プレースホルダーの最初の文字にブロックカーソルがあり、リターン記号の後に save という語が続いています。

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

同じフィールドに入力された文字 Rel があり、その後にリターン記号と save という語が続いています。

メモやコミットメッセージなど、複数行を保持するフィールドには 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 行を表示したペイン:ラベル Format、現在の選択肢 Markdown、小さな下向き矢印。

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

開いたピッカーで、ラベルの下に 3 つの選択肢が並んでいます。2 番目の選択肢 HTML が反転表示で描画されています。

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

再び閉じたピッカーで、現在の選択肢として HTML が表示されています。

画像を描画する

Raster

Raster は色付きの文字セルのグリッドで、ヒートマップ、スパークライン、ゲーム盤などに使います。描画はターミナルが行います。このサンプルでは、スターターモジュールの cellsOf 関数を使用しています。この関数は、セルを Raster が受け取る文字列にパックします。詳しくは 色付きセルのグリッドを描画する で説明しています。

Raster({
  key: 'grid',
  columns: 3,
  rows: 2,
  cells: cellsOf([
    [['█', 0x2e7d32], ['█', 0xf9a825], ['█', 0xc62828]],
    [['█', 0x2e7d32], ['█', 0x2e7d32], ['█', 0xf9a825]],
  ]),
})

色付きブロックの小さなグリッドを表示したペイン。3 つずつ 2 行で、緑、琥珀、赤、続いて緑、緑、琥珀。

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 を呼び出して代わりに何かを表示させることもできます。

次のステップ