SpyBara
Go Premium

plugins/mods/gallery.md 2026-11-05 23:03 UTC to 2026-11-06 23:01 UTC

No changes for this document in this history range.

2026

Galeri antarmuka untuk mod

Lihat elemen antarmuka yang dapat digambar oleh mod Claude Code, seperti teks, tombol, kolom, Markdown, kode, dan diff, beserta contoh kode dan tangkapan layar terminal.

Sebuah mod menggambar antarmukanya dari elemen: teks, kotak, tombol, kolom, dan beberapa elemen yang memformat konten untuk Anda. Contoh-contoh di sini menunjukkan kode yang menggambar sebuah elemen, dan sebagian besar disertai tangkapan layar hasilnya di panel terminal, sehingga Anda dapat memilih elemen berdasarkan tampilannya.

Untuk mempelajari cara kerja penggambaran, mulailah dengan Menggambar di antarmuka. Untuk props utama dan aplikasi mana yang menggambar setiap elemen, lihat referensi elemen. Deklarasi tipe mencantumkan setiap prop.

Mencoba contoh

Contoh-contoh di halaman ini adalah cuplikan, bukan mod utuh. Masing-masing adalah kode untuk satu elemen dan apa pun yang bersarang di dalamnya.

Untuk melihat contoh di terminal Anda sendiri, buat mod kecil dengan langkah-langkah berikut dan tempelkan contoh ke dalamnya. Mod ini menambahkan perintah /gallery yang membuka panel dan menggambar contoh di sana. Panel adalah bilah samping di sebelah transkrip pada terminal layar penuh yang lebar, atau wilayah berbingkai di atas prompt jika tidak.

1. Buat mod

Buat direktori bernama gallery dengan direktori .claude-plugin dan hooks di dalamnya. Membuat mod menjelaskan file-filenya.

Simpan manifes sebagai gallery/.claude-plugin/plugin.json:

{
  "name": "gallery",
  "version": "0.1.0",
  "description": "Opens a pane that draws one sample",
  "author": { "name": "Your Name" }
}

Tentukan titik masuk Anda di gallery/hooks/hooks.json:

{
  "modules": ["./register.js"]
}

Simpan kode sebagai gallery/hooks/register.js. Kode ini menambahkan perintah /gallery yang membuka panel, dan menggambar Plain text di panel tersebut:

// 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. Jalankan mod

Di shell Anda, jalankan Claude Code dari direktori yang berisi gallery:

claude --plugin-dir ./gallery

Di prompt Claude Code, jalankan /gallery. Sebuah panel terbuka dengan Plain text di dalamnya.

3. Ganti dengan contoh

Salin contoh dari halaman ini. Di register.js, tempelkan contoh tersebut menggantikan Text({ children: ['Plain text'] }), sehingga berada setelah return, lalu simpan file. Claude Code memuat ulang modul setiap kali Anda menyimpan, jadi jalankan /gallery lagi untuk melihat contoh yang baru.

Memilih elemen

Contoh-contoh dikelompokkan berdasarkan apa yang ingin Anda tampilkan di layar:

Menampilkan teks

Tiga elemen menampilkan kata-kata di layar: Text untuk gaya Anda sendiri, Markdown untuk konten yang sudah diformat, dan Link untuk URL.

Text

Text menggambar string dengan gaya yang Anda berikan. Contoh ini menampilkan teks biasa dan delapan gaya, satu di setiap baris:

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

Panel dengan sembilan baris teks, masing-masing dinamai sesuai gayanya: plain, bold, italic, underline, strikethrough, dimColor berwarna abu-abu, inverse, color merah, dan backgroundColor biru.

dimColor menggambar teks berwarna abu-abu. backgroundColor hanya mengisi selebar teks.

Markdown

Markdown memformat teks dengan cara yang sama seperti balasan Claude diformat. Berikan konten di text, bukan di children:

Markdown({
  text: '## Release notes\n\nThis build has **two** fixes and one `flag`:\n\n- Faster start\n- Fewer prompts\n\n> Quoted text',
})

Panel dengan judul tebal, Release notes, lalu sebuah kalimat dengan satu kata tebal dan satu kata kode berwarna, daftar dua item, dan kutipan yang digambar miring dengan bilah di sebelah kirinya.

Judul digambar tebal tanpa tanda #. Kode inline digambar berwarna tanpa backtick. Kutipan digambar miring dengan bilah di sebelah kirinya.

Link menggambar label diikuti URL-nya:

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

Panel dengan satu baris: label Claude Code docs, lalu URL berwarna abu-abu.

Terminal menggambar URL sebagai teks setelah label. Apakah klik akan membukanya bergantung pada terminal pengguna.

Menampilkan kode dan perubahan

Code menggambar teks sumber dengan warna sintaks milik Claude Code sendiri, atau sebuah diff. Di ekstensi VS Code, Code menampilkan source-nya sebagai teks biasa, tanpa warna, nomor baris, atau bayangan diff seperti pada tangkapan layar ini.

Code

Sebutkan language, atau berikan path agar Claude Code menyimpulkannya. Dengan startLine, baris-baris diberi nomor mulai dari angka tersebut:

Code({
  language: 'javascript',
  startLine: 1,
  source: "const name = 'mods'\nconsole.log('hello ' + name)",
})

Panel dengan dua baris JavaScript bernomor dalam warna sintaks.

Warnanya berasal dari tema pengguna.

Code sebagai diff

Dengan format: 'diff', source adalah satu atau beberapa hunk 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.',
})

Panel dengan diff empat baris. Baris yang dihapus diberi bayangan merah dan baris yang ditambahkan hijau, masing-masing dengan nomor barisnya. Pada baris yang ditambahkan, kata-kata that runs code memiliki bayangan yang lebih kuat.

Claude Code menggambar nomor baris sebagai pengganti baris @@. Jika baris yang dihapus dan baris yang ditambahkan mirip, kata-kata yang berubah mendapat bayangan yang lebih kuat.

Mengatur elemen

Box

Box menata isinya dalam baris atau kolom, dan dapat menggambar bingkai. Contoh ini menempatkan sebaris kata di atas kotak berbingkai:

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

Panel dengan tiga kata dalam satu baris, berjarak empat kolom, lalu satu baris kosong, lalu bingkai membulat di sekitar satu baris teks. Bingkai membentang selebar panel.

Bingkai membentang selebar panel.

Menerima input

Button, Input, dan Select adalah kontrol: pengguna berpindah di antaranya dengan Tab dan menggunakan kontrol yang sedang memiliki fokus. Fokus keyboard dan hotkey menjelaskan tombol mana yang mencapainya.

Buka panel dengan focus: true untuk mengajukan permintaan fokus keyboard bagi panel tersebut. Huruf yang diketik mencapai Input setelah kontrol itu memiliki fokus. Untuk memilih kolom mana yang memiliki fokus saat panel terbuka, lihat Mengatur hotkey dan fokus pertama.

Button

Sebuah tombol menjalankan onPress. Contoh ini menampilkan bentuk default, tombol plain dengan hotkey, dan tombol redup:

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

Panel dengan tiga tombol, satu per baris: Save dalam kurung siku, n: Next tanpa kurung siku dengan huruf n berwarna, dan Skip dalam kurung siku berwarna abu-abu.

Tombol yang memiliki fokus digambar dalam video terbalik. Di sini pengguna telah menekan Tab dua kali:

Tiga tombol yang sama, dengan tombol kedua, n: Next, digambar dalam video terbalik.

Input

Input adalah kolom teks yang secara default memuat satu baris dan menjalankan onSubmit saat pengguna menekan Enter:

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

Tanpa fokus, kolom menampilkan label dan placeholder-nya:

Panel dengan satu baris: label Title, lalu placeholder Type a title and press Enter berwarna abu-abu.

Dengan fokus, label menjadi tebal, kursor muncul, dan submitLabel ditampilkan setelah ⏎:

Kolom yang sama dengan label tebal, kursor blok pada huruf pertama placeholder, dan tanda return diikuti kata save.

Mengetik menggantikan placeholder:

Kolom yang sama berisi huruf yang diketik Rel, diikuti tanda return dan kata save.

Atur rows ke 2 atau lebih untuk kolom yang memuat beberapa baris, seperti catatan atau pesan commit:

Input({
  key: 'note',
  label: 'Note',
  placeholder: 'Write a note',
  rows: 4,
  onSubmit: noop,
})

Terminal dan aplikasi Desktop menggambar baris-baris tersebut. Di ekstensi VS Code, kolom ini memuat satu baris. rows memerlukan Claude Code v2.1.301 atau yang lebih baru. Pada versi sebelumnya, kolom ini memuat satu baris.

Kolom ini menempati jumlah baris yang Anda atur, bahkan saat kosong, hingga setinggi panel atau pita tempat kolom itu digambar. Selama kolom memiliki fokus, teks yang lebih panjang digulir di dalamnya.

  • Di terminal, Enter tetap mengirimkan. Di sana, pengguna memulai baris baru dengan mengetik garis miring terbalik lalu menekan Enter, atau dengan menekan Shift+Enter jika emulator terminal mendukungnya. Tombol-tombol ini sama dengan yang digunakan di prompt.
  • Di terminal, Up dan Down berpindah di antara baris-baris kolom. Dari baris pertama dan terakhirnya, tombol ini berpindah ke kontrol sebelum atau sesudahnya.
  • onSubmit dan onInput menerima seluruh teks dengan baris-barisnya digabungkan oleh \n.

Select

Select memungkinkan pengguna memilih salah satu dari beberapa opsi, dan menjalankan onSelect dengan value dari opsi tersebut:

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

Dalam keadaan tertutup, kontrol ini menampilkan label dan opsi saat ini:

Panel dengan satu baris: label Format, opsi saat ini Markdown, dan panah bawah kecil.

Dalam keadaan terbuka, kontrol ini mencantumkan opsinya dan menandai salah satunya:

Pemilih terbuka, dengan tiga opsinya tercantum di bawah label. Opsi kedua, HTML, digambar dalam video terbalik.

Setelah pengguna memilih opsi, daftar tertutup:

Pemilih tertutup kembali, kini menampilkan HTML sebagai opsi saat ini.

Menggambar gambar

Raster

Raster adalah kisi sel karakter berwarna, untuk peta panas, sparkline, atau papan permainan. Terminal yang menggambarnya. Contoh ini menggunakan fungsi cellsOf di modul awal, yang mengemas sel-sel ke dalam string yang diterima Raster. Menggambar kisi sel berwarna menjelaskannya:

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

Panel dengan kisi kecil blok berwarna, dua baris berisi tiga: hijau, kuning tua, dan merah, lalu hijau, hijau, dan kuning tua.

Raster membulatkan setiap warna ke palet yang lebih kecil, sehingga 0x2e7d32 digambar sebagai #337733.

Svg

Svg menggambar dokumen SVG di aplikasi Desktop dan ekstensi VS Code:

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

Di terminal, panel yang hanya mengembalikan Svg akan terbuka kosong. Untuk menggambar sesuatu yang lain di sana, periksa e.surface dan kembalikan tree yang berbeda.

Image dan Client

Dua elemen lagi tidak memiliki contoh di sini. Image menggambar PNG atau piksel mentah di terminal. Client adalah wilayah yang digambar oleh file kedua milik Anda, untuk animasi dan input penunjuk. Referensi elemen mencantumkan props-nya.

Image digambar sebagai gambar di terminal-terminal berikut:

  • kitty 0.28 atau yang lebih baru
  • Ghostty
  • iTerm2 3.5 atau yang lebih baru. Menggambar di iTerm2 memerlukan Claude Code v2.1.305 atau yang lebih baru.

Di terminal lain mana pun, pengguna akan melihat teks alt dari Image, dalam warna redup, sebagai pengganti gambar. Tulis teks alt yang dapat dipahami dengan sendirinya, karena teks tersebut juga ditampilkan dalam kasus-kasus berikut, di antara yang lain:

  • GNU screen: sesi yang berjalan di dalam screen, di terminal apa pun.
  • tmux: sesi yang berjalan di dalam tmux yang tidak memenuhi salah satu persyaratan untuk menggambar di dalam tmux.
  • Sesi latar belakang: setiap sesi latar belakang, dari terminal mana pun sesi tersebut dilampirkan.
  • iTerm2 di luar rendering layar penuh: di iTerm2, gambar hanya digambar di bawah rendering layar penuh, dan tidak saat CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT diatur ke 1. Untuk melihat gambar, jalankan /tui fullscreen di prompt Claude Code dan biarkan variabel tersebut tidak diatur.
  • Sumber berupa path file di iTerm2 atau tmux: di iTerm2 dan di dalam tmux, Image yang source-nya menyebutkan file menampilkan teks alt alih-alih gambar. Jika mod Anda memiliki pengguna iTerm2 atau tmux, berikan gambar sebagai base64 di source.png atau source.rgba alih-alih sebagai path di source.file.

Jika pengguna mod Anda melihat teks redup di terminal yang menggambar gambar protokol grafis kitty dengan placeholder Unicode, mereka dapat mengatur CLAUDE_CODE_FORCE_TERMINAL_IMAGES ke 1. Mereka sebaiknya tidak mengaturnya di dalam GNU screen, di dalam tmux yang lebih lama dari 3.3, di popup tmux, atau saat allow-passthrough tmux nonaktif. Di sana mereka tidak melihat gambar dan melihat sebuah kotak sebagai pengganti teks alt.

Menggambar Image di dalam tmux

Jika Image menampilkan teks alt-nya di dalam tmux, periksa persyaratan berikut bersama dengan kasus teks alt lainnya seperti sesi latar belakang:

  • Claude Code v2.1.310 atau yang lebih baru
  • tmux 3.3 atau yang lebih baru
  • Claude Code berjalan di panel tmux, bukan popup tmux
  • tmux berjalan di dalam kitty 0.28 atau yang lebih baru, Ghostty, atau iTerm2 3.5 atau yang lebih baru
  • Opsi tmux focus-events dan allow-passthrough bernilai on. Di dalam kitty atau Ghostty, allow-passthrough juga dapat bernilai all.
  • Di dalam iTerm2, tmux berjalan tanpa -CC, rendering layar penuh aktif, dan CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT tidak diatur.
  • Di dalam iTerm2, jendela tmux tidak lebih besar dari jendela iTerm2. Untuk memeriksanya, jalankan tmux display-message -p '#{window_bigger}' di jendela tmux tersebut. Jika perintah itu mencetak 1, sesuaikan ukuran jendela tmux, lalu mulai ulang Claude Code.
  • Pembuat mod memberikan gambar sebagai byte png atau rgba, bukan sebagai path file. Jika Anda menggunakan mod yang tidak Anda tulis sendiri dan persyaratan lainnya terpenuhi, minta pembuatnya untuk memeriksa persyaratan ini.

Untuk setiap opsi tmux yang belum diatur sesuai persyaratan, jalankan perintahnya di shell Anda:

tmux set -g allow-passthrough on
tmux set -g focus-events on

Kemudian lepaskan (detach) dari tmux, lampirkan (attach) kembali, dan mulai ulang Claude Code. Mulai ulang lagi setiap kali Anda melampirkan tmux dari terminal yang berbeda. Agar kedua opsi tetap berlaku setelah server tmux dimulai ulang, tambahkan kedua baris tersebut ke ~/.tmux.conf juga.

Melihat di mana mod dapat menggambar

Semua contoh menggambar di panel. Mod juga dapat menggambar di tempat lain, dan memanggil Claude Code untuk menampilkan sesuatu untuknya:

Langkah selanjutnya