- Anggapan bahwa aplikasi terminal pada dasarnya mudah diakses karena berbasis teks runtuh pada TUI modern, dan framework seperti Ink, Bubble Tea, serta tcell dapat menciptakan lingkungan yang lebih tidak ramah bagi pengguna pembaca layar
- CLI menumpuk output sebagai aliran linear
stdin/stdout secara kronologis, tetapi TUI memperlakukan terminal sebagai kisi 2D berbasis sel karakter sehingga pembaca layar sulit mengikuti alurnya
gemini-cli dapat menyebabkan Ink menggambar ulang pohon komponen React agar sesuai dengan kisi terminal sambil memindahkan kursor di antara spinner, timer, dan riwayat percakapan, yang bisa memicu pembacaan berulang, crash, dan keterlambatan input pada Speakup dan NVDA
- Alat lama seperti
nano, vim, menuconfig, dan Irssi mengurangi kebisingan pembaruan koordinat serta meminimalkan gangguan dengan baris input melalui penyembunyian kursor, fokus satu kolom, dan penggunaan scroll region VT100
- Untuk membuat alat terminal yang aksesibel, perlu menghindari framework UI deklaratif yang memperlakukan terminal seperti kanvas serta redraw agresif, dan memastikan perilaku yang mendekati aliran CLI yang sederhana dan linear
Kesalahpahaman bahwa “karena berbentuk teks maka aksesibel”
- Anggapan bahwa aplikasi yang berjalan di terminal secara inheren aksesibel tidak sesuai dengan lingkungan penggunaan nyata
- Harapan bahwa pembaca layar dapat dengan mudah menafsirkan teks ASCII mentah karena tidak ada grafis, DOM kompleks, atau kanvas WebGL runtuh pada TUI modern
- Framework UI terminal seperti Ink (JS/React), Bubble Tea (Go), dan tcell berupaya meningkatkan pengalaman pengembang (DX), tetapi bagi pengguna tunanetra justru dapat menciptakan lingkungan yang lebih tidak ramah
- Dalam banyak kasus, TUI modern lebih buruk dari sisi aksesibilitas dibanding antarmuka grafis yang diimplementasikan dengan buruk
Perbedaan struktural antara CLI dan TUI
-
CLI: aliran linear
- CLI bekerja berbasis
stdin/stdout; ketika perintah dimasukkan, hasil ditambahkan di bawahnya dan kursor bergerak turun
- Karena output bersifat linear dan menumpuk menurut urutan waktu, model ini cocok untuk pembaca layar tingkat kernel seperti Speakup
-
TUI: kisi 2D
- TUI memperlakukan jendela terminal bukan sebagai aliran teks, melainkan sebagai kisi 2D tempat tiap sel karakter ditulis seperti piksel
- Dengan meninggalkan alur waktu dan memprioritaskan tata letak spasial, strukturnya menjadi sulit diikuti oleh pembaca layar
Masalah yang tampak pada gemini-cli
gemini-cli adalah alat yang ditulis dengan Node.js dan framework Ink, dan dari luar tampak seperti antarmuka chat yang sederhana
- Namun di dalamnya, Ink berusaha menyesuaikan pohon komponen React ke kisi terminal
- Saat digunakan dengan Speakup (Linux) atau NVDA (Windows), aplikasi ini bukan sekadar gagal, tetapi terus membanjiri pembaca layar dengan hal-hal untuk dibacakan
-
Layar yang bertindak seperti kanvas reaktif
- Karena framework memperlakukan layar sebagai kanvas reaktif, setiap pembaruan memicu redraw
- Saat AI sedang “berpikir”, untuk memperbarui timer atau spinner, kursor hardware dipindahkan ke lokasi timer, waktu baru ditulis, lalu dikembalikan ke posisi semula
- Bagi pengguna visual ini adalah gerakan yang lewat seketika, tetapi bagi pengguna pembaca layar ini terdengar berulang seperti “Responding... Time elapsed 1s... Responding... Time elapsed 2s...”
- Saat kursor berpindah sesaat di antara indikator status, spinner, dan riwayat percakapan, Speakup mencoba membacakan apa yang berada di bawah kursor saat itu
- Akibatnya, pembaruan timer dan potongan percakapan terdengar bercampur sehingga sulit fokus pada apa yang benar-benar sedang diketik
-
Ketidakstabilan pada NVDA dan proses paste
- Di Windows, jika terminal dibuka dengan NVDA, lalu terhubung ke mesin Linux melalui SSH dan masuk ke sesi
screen, menempelkan teks dapat membuat NVDA langsung crash atau sistem menjadi sangat tidak stabil
- Setiap kali karakter diketik atau teks ditempel, status aplikasi berubah, dan framework menilai antarmuka perlu dirender ulang
- Jika riwayat percakapan termasuk dalam state, framework bisa langsung mencoba menggambar ulang atau menghitung ulang tata letak untuk ribuan baris teks
- Semakin banyak pesan percakapan, semakin sering masalah ini terjadi
- Bahkan kombinasi
Insert+5 untuk menghindari notifikasi konten dinamis tidak dapat menghindari masalah ini
-
Loop keterlambatan input
- Jika framework seperti Ink berjalan di lingkungan single-thread seperti Node.js, penurunan performa akan makin besar seiring membengkaknya riwayat
- Saat menempelkan blok teks besar, perbedaan untuk ribuan baris harus dihitung
- Sistem menjadi sibuk menghitung cara menggambar ulang layar sehingga pemrosesan input tertunda
- Menekan satu tombol saja bisa membuat pengguna menunggu hingga 10 detik sebelum karakter muncul kembali
Mengapa alat lama bisa bekerja
- Alat seperti
nano, vim, dan menuconfig digunakan bukan karena selalu sempurna dalam hal aksesibilitas
- Intinya, alat-alat ini dapat menyembunyikan kursor sepenuhnya atau mengurangi kebisingan yang timbul dari pelacakan posisi kursor
-
nano dan vim: menyembunyikan kursor
- Jika
nano dijalankan dengan opsi yang menampilkan posisi kursor seperti --constantshow, atau vim dipakai tanpa pengaturan tertentu, kegunaannya bisa rusak
- Saat kursor terlihat dan pelacakan aktif, Speakup memprioritaskan pembaruan posisi kursor dibanding echo karakter
- Ketika pengguna mengetik “a”, alih-alih mendengar “a” mereka mendengar “Column 2”, dan ketika mengetik “b” mereka mendengar “Column 3”
- Alat lama ini dapat dikonfigurasi untuk menekan pembaruan kursor visual atau status bar, sehingga pembaca layar bisa bergantung pada aliran input karakter alih-alih pembaruan koordinat
- Framework modern biasanya tidak menyediakan mode “no-cursor” atau “headless”, dan mengasumsikan kursor visual itu wajib
-
menuconfig: fokus satu kolom
menuconfig pada kernel Linux bekerja karena mempertahankan fokus satu kolom yang ketat
- Meski ada bingkai dan judul, area aktifnya adalah daftar vertikal, dan kursor terkunci pada daftar itu
- Kursor tidak bergerak ke kanan bawah untuk pembaruan jam lalu ke kiri atas untuk pembaruan judul
- Kompleksitas spasial tetap rendah sehingga pembaca layar tidak kehilangan orientasi
-
Irssi: memanfaatkan scroll region
- Irssi bukan sekadar kebetulan menjadi aksesibel, melainkan alat chat yang selama lebih dari 20 tahun memanfaatkan scroll region VT100 melalui mesin rendering kustom
- Saat pesan baru datang, ia memerintahkan driver terminal untuk “tetapkan baris 1 sampai 23 sebagai scroll region”
- Lalu ia mengirim perintah “scroll ke atas”, terminal memindahkan isinya ke atas, dan teks baru digambar di bagian bawah area tersebut
- Cara ini meminimalkan gangguan terhadap baris input
- Ia bergantung pada kemampuan hardware terminal alih-alih menulis ulang semua karakter di layar secara manual
- Framework modern mengabaikan kemampuan hardware seperti ini dan memilih menghitung perbedaan state layar lalu menulis ulang karakter, yang lebih mahal secara komputasi dan tidak ramah terhadap aksesibilitas
Masalah dalam penanganan issue gemini-cli
- Google dan para maintainer
gemini-cli tampak seolah peduli pada aksesibilitas, tetapi regresi aksesibilitas penting dibiarkan begitu saja di repositori
- Regresi aksesibilitas seperti Issue #3435 dan Issue #11305 tidak memiliki diskusi, roadmap, maupun perbaikan
- Issue #1553 adalah issue untuk melacak kegagalan aksesibilitas semacam ini, tetapi tidak terselesaikan dan akhirnya ditutup otomatis oleh bot
- Bot menutup issue dengan kalimat umum bahwa tidak ada aktivitas dalam waktu lama dan backlog perlu dikelola
- Menutup laporan aksesibilitas hanya karena maintainer tidak menyentuhnya selama berbulan-bulan bukanlah perapihan, melainkan menyembunyikan bukti
- Ini memberi sinyal bahwa jika bug diabaikan cukup lama maka bug itu seolah tidak ada, sementara perangkat lunaknya tetap tidak dapat digunakan oleh pengguna tunanetra
- Metrik “Closed Issues” proyek mungkin terlihat lebih baik, tetapi masalah aksesibilitasnya tetap tidak terselesaikan
Kesimpulan untuk membuat alat terminal yang aksesibel
- Jika aksesibilitas dianggap penting dalam aplikasi terminal, penggunaan framework UI deklaratif yang memperlakukan terminal seperti kanvas harus dihentikan
- Stack TUI yang “modern” dioptimalkan agar pengembang mudah menulis kode seperti React, dengan mengorbankan kemampuan mesin untuk merender teks secara efisien
- Jika aplikasi tidak dapat memastikan pengguna bisa menyembunyikan kursor, atau bergantung pada redraw agresif untuk menampilkan spinner dan timer, maka alat itu menjadi tidak aksesibel
- Bagi pengguna tunanetra, aliran CLI yang sederhana dan linear jauh lebih baik daripada TUI “cerdas” yang lambat, terus membanjiri hal-hal untuk dibacakan, dan menyebarkan kursor ke seluruh layar
1 komentar
Komentar Lobste.rs
Tulisan ini, seperti banyak posting blog lain, sangat berbau tulisan berbantuan AI
LLM menyukai judul seperti ini: “The Architectural Flaw”, “The Lag Loop”, “Why The ‘Old Guard’ Works”, “The Lost Art of Scrolling Regions”, “The ‘Stale Bot’ excuse: A Case Study in Neglect”
Ini sebenarnya bisa jadi posting blog yang bagus, tetapi kalau terasa seperti penulis hanya melempar kerangka ke ChatGPT lalu selesai, itu merugikan pembaca maupun penulis
Menyebut masalah yang sangat spesifik dan sekali lewat sebagai masalah yang “klasik” juga sama saja
Benar-benar menyedihkan. Singkatnya, ada TUI yang aksesibel seperti Irssi, tetapi framework TUI modern mengabaikan preseden seperti itu dan bergantung pada diff kisi serta perpindahan kursor
Alat pembaca layar membaca isi di posisi saat kursor bergerak, jadi hasilnya bisa berantakan atau memicu spam pembacaan yang sangat parah
Saya ragu penjelasan teknis di sini sepenuhnya akurat
Secara khusus, Ink sudah lama sama sekali tidak mendukung incremental rendering, dan kebanyakan aplikasi yang memakai Ink juga belum mengaktifkannya. Incremental rendering itu sendiri juga berbasis baris, jadi tidak benar-benar memindahkan kursor ke posisi timer yang sebenarnya
Gemini CLI memerlukan penggunaan alternate buffer untuk menyalakan incremental rendering, dan itu dinonaktifkan saat mode ramah pembaca layar bawaan aktif. Dokumentasi opsinya ada di sini
Selain itu, rich/textual di Python, meski berjalan di atas bahasa yang lebih lambat dan umumnya single-threaded, sering kali jauh lebih cepat daripada Ink. Menghitung diff ribuan baris tidak harus selalu selambat itu, apalagi sampai 10 detik
Saya tidak meragukan bahwa pengalaman penggunanya terasa lamban dan rusak, tetapi penyebab pasti yang diajukan tampaknya bisa jadi halusinasi LLM atau berbasis informasi yang tidak lengkap. Incremental rendering di Ink, bahkan saat aktif, tidak bekerja seperti yang dijelaskan
Dalam praktiknya, kemungkinan redraw seluruh layar yang membingungkan pembaca layar, dan redraw berbasis baris yang membuat potongan teks acak terputus yang tidak terkait dengan perubahan ikut dibacakan ulang, adalah masalah yang lebih nyata
Tidak adil jika hanya menyalahkan TUI
Masalah sebenarnya adalah dukungan aksesibilitas yang sangat buruk di hampir seluruh stack
Pertama, sebagian besar emulator terminal dengan rendering GPU sama sekali tidak memakai API aksesibilitas bawaan sistem. Jika teks dirender oleh GPU, alat aksesibilitas tidak bisa “membacanya” dan hanya melihatnya seperti gambar. Kitty, Alacritty, dan WezTerm termasuk di sini. Terminal saya, Ghostty, bisa dibaca melalui API aksesibilitas di macOS, begitu juga iTerm2 dan Terminal.app
Kedua, sama sekali tidak ada urutan terminal atau gerakan standar agar TUI bisa meneruskan informasi aksesibilitas ke emulator terminal. Kita butuh sesuatu seperti anotasi bergaya ARIA untuk sel terminal, rentang eksekusi, dan wilayah, tetapi belum ada upaya ke arah sana. Bahkan jika TUI mengelola kursor dengan baik, masalah tetap akan muncul di banyak kasus penggunaan
Sebagai contoh, di Ghostty ada pekerjaan untuk mengintegrasikan OSC133 dengan API aksesibilitas agar setiap prompt shell, input, dan perintah diekspos sebagai elemen yang bermakna secara struktural, bukan sekadar kotak teks biasa. Ini menunjukkan bahwa spesifikasi terminal, TUI, dan emulator terminal harus saling terhubung
Seluruh stack ini sudah busuk, dan hampir tidak ada orang yang benar-benar ingin memperbaikinya. Saya sendiri hanya berusaha sebaik mungkin dengan waktu yang terbatas, tetapi ini topik besar yang bahkan butuh politik ekosistem, jadi sulit ditangani
Sebagai bonus, kenyataan yang keren sekaligus mengerikan adalah AI justru membantu meningkatkan aksesibilitas di sini. Banyak alat AI memakai atau menyalahgunakan API aksesibilitas untuk membaca daftar jendela dan melakukan input. Karena itu, lebih banyak aplikasi mulai menangani integrasi aksesibilitas jauh lebih serius demi kasus penggunaan AI
Saya marah setiap hari karena Claude Code dan gemini-cli tidak berbasis readline
Mereka memang menambahkan beberapa penekanan tombol yang mirip, tetapi ekor panjang shortcut readline yang sudah akrab justru hilang
Anthropic bisa saja mengakui bahwa keputusan untuk “membuatnya seperti pengembangan web” adalah kesalahan dan mulai lagi dari readline
Anggapan bahwa pengalaman pengembangan yang akrab bagi pembuat alat lebih penting daripada pengalaman pengguna yang akrab bagi orang yang memakainya itu keliru
Nyaris tidak ada solusi pihak ketiga yang terkenal dan benar-benar terawat dengan baik. Jika butuh kotak input yang fleksibel, Anda pada dasarnya harus membuatnya sendiri dari nol
Ini kontras dengan widget Input yang sangat bagus di Textual atau pustaka lain di ekosistem JS, OpenTUI
Saya memang tidak suka LLM jadi UI yang buruk secara pribadi malah merupakan nilai plus, tetapi mungkin ada alasan mengapa mereka tidak memakai readline
Editor terminal seperti kakoune dan helix tampaknya akan sulit lolos standar aksesibilitas kecuali mereka memakai trik “sembunyikan kursor”
Walau begitu, kemungkinan besar tetap tidak akan seaksesibel VS Code
Selain VS Code, IDE-lite atau IDE lintas platform apa yang aksesibel? Saya tidak suka sikap VS Code yang makin terasa memusuhi. Mungkin IDE JetBrains
Kekurangannya, meski Emacs sendiri lintas platform, emacspeak mungkin punya ketergantungan lemah pada Linux karena TTS. Atau mungkin tidak. Saya belum pernah mencobanya di Windows
Jika aksesibilitas untuk tunanetra, maka perlu emacspeak atau alat aksesibilitas untuk tunanetra yang tersedia di platform tersebut
Aksesibilitas itu spektrum, bukan kotak centang
Links punya mode terminal Braille tersendiri, yang mengganti elemen GUI palsu dengan menu layar penuh yang lebih sederhana dan juga mengubah navigasi tombol panah menjadi per baris
Contoh menarik lain adalah edbrowse. Ini browser mode teks buatan Karl Dahlke yang tunanetra, dan berbeda dari browser web mode teks yang lebih populer, ia tidak memakai TUI melainkan antarmuka baris perintah bergaya ed
Jika memakai framework Ink, itu mungkin menjelaskan mengapa CLI memakai CPU 100% lalu macet selamanya sambil terus me-render ulang riwayat chat yang panjang. Sangat disayangkan