1 poin oleh GN⁺ 1 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • 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

 
GN⁺ 1 jam lalu
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”

    • Dari judulnya saja sudah terasa seperti artikel AI hasil produksi massal. Topiknya sendiri memang baru, jadi mungkin pelaporan sebagai spam agak berlebihan, tetapi 1) saya sudah tidak tahan lagi dengan gaya yang sama berulang di mana-mana dan 2) itu juga membuat saya meragukan akurasi isinya
      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
    • Salah satu hal yang paling saya benci dari tulisan LLM adalah cara mereka menulis seperti “The <sesuatu yang sama sekali bukan konsep mapan>” sehingga seolah-olah itu konsep resmi
      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

    • Terminal benar-benar sedang menjadi browser kecil
  • 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

    • Pemahaman saya, bagian besar dari masalah ini adalah Ink pada dasarnya puas menjadi backend rendering dan tidak menyediakan widget input
      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
    • Bukankah readline berlisensi GNU? Apa akhirnya ada seseorang yang membuat versi non-GPL?
      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

    • Ada emacspeak, dan itu memberi antarmuka yang sangat aksesibel untuk Emacs
      Kekurangannya, meski Emacs sendiri lintas platform, emacspeak mungkin punya ketergantungan lemah pada Linux karena TTS. Atau mungkin tidak. Saya belum pernah mencobanya di Windows
    • Yang harus ditentukan dulu adalah aksesibilitas untuk siapa. Jika untuk tunarungu, perlu teks dalam bahasa lokal dan bahasa isyarat lokal. Di Amerika Serikat biasanya ASL
      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