Search

Items tagged with: CLI


The text mode lie: why modern TUIs are a nightmare for accessibility — The Inclusive Lens xogium.me/the-text-mode-lie-wh… #Accessibility #CLI #TUI


The text mode lie: why modern TUIs are a nightmare for accessibility


The mythical, it's text, so it's accessible


There is a persistent misconception among sighted developers: if an application runs in a terminal, it is inherently accessible. The logic assumes that because there are no graphics, no complex DOM, and no WebGL canvases, the content is just raw ASCII text that a screen reader can easily parse.

The reality is different. Most modern Text User Interfaces (TUIs) are often more hostile to accessibility than poorly coded graphical interfaces. The very tools designed to improve the Developer Experience (DX) in the terminal—frameworks like Ink (JS/React), Bubble Tea (Go), or tcell—are actively destroying the experience for blind users.

The Architectural Flaw: Stream vs. Grid


To understand the failure, we must distinguish between two distinct concepts often conflated under “terminal apps”: the CLI (Command Line Interface) and the TUI.

  1. The CLI (The Stream): This operates on a standard input/output model (stdin/stdout). You type a command, the system appends the result below, and the cursor moves down. This is linear and chronological. For a screen reader, specifically kernel-level readers like Speakup, this is ideal.
  2. The TUI (The Grid): This treats the terminal window not as a stream of text, but as a 2D grid of pixels, where every character cell is a pixel. It abandons the temporal flow for a spatial layout.


Case Study: The gemini-cli Madness


Let's look at a concrete example: gemini-cli, a tool written in Node.js using the Ink framework. On the surface, it looks like a simple chat interface. But underneath, Ink is trying to reconcile a React component tree into a terminal grid.

When you use this tool with Speakup (Linux) or NVDA (Windows), the application doesn't just fail; it actively spams you.

Because the framework treats the screen as a reactive canvas, every update triggers a redraw. When the AI is “thinking,” the tool updates a timer or a spinner. To do this, it moves the hardware cursor to the timer location, writes the new time, and moves it back.

For a sighted user, this happens instantly. For a screen reader user, this is what you hear:“Responding... Time elapsed 1s... Responding... Time elapsed 2s... [Fragment of chat history]... Responding...”

It drives the screen reader mad. The cursor is teleporting all over the screen to update status indicators, spinners, and history. Speakup tries to read whatever is under the cursor at that exact millisecond. You end up hearing random bits of conversation mixed with timer updates, making it impossible to focus on what you are actually typing.

Worse, lets pretend that you've somehow managed well with speakup so far, but that you want to do some work with nvda. Maybe paste an error you're getting on windows. So you open your terminal, ssh into your linux box, attach to your screen session and paste your text.

The result is an immediate crash of the screen reader (NVDA) or massive system instability. Why? Every time you type a character or paste text, the application triggers a state change. The framework decides it needs to re-render the interface. Because the conversation history is part of that state, the application attempts to redraw or re-calculate the layout for thousands of lines of text instantly. The more messages you have in a conversation, the more this will happen. And no, you can't just avoid this by using insert+5, the key combo supposed to avoid announcing dynamic change of content.

The Lag Loop


Furthermore, frameworks like Ink running on single-threaded environments (like Node.js) suffer from massive performance degradation when the history grows. If you paste a large block of text, the system has to calculate the diff for thousands of lines.

This causes input lag. You press a key, and you wait. You can wait up to 10 seconds for a single character to echo back. The system is too busy calculating how to redraw the screen to actually process your input.

Why The “Old Guard” Works (nano, vim, menuconfig)


Sighted developers often ask: “If TUIs are bad, why do you use nano, vim, or menuconfig?”

The answer is not that these tools handle the cursor perfectly by default. The answer is that they allow you to hide the cursor entirely.

1. Hiding the Cursor (nano, vim)


In tools like nano or vim, usability depends on turning off features that track cursor position. If you run nano with options that show the cursor position (like --constantshow), or if you use vim without specific configuration, the experience is broken.

When the cursor is visible and tracking is active, Speakup prioritizes the cursor's location update over the character echo. Instead of hearing the letter “a” when you type it, you hear “Column 2”. You type “b”, and you hear “Column 3”.

These older tools succeed because they allow you to disable this noise. You can configure them to suppress the visual cursor or status bar updates, forcing the screen reader to rely on the character input stream rather than the noisy coordinate updates. Modern frameworks rarely offer a “no-cursor” or “headless” mode; they assume the visual cursor is essential.

2. Single Column Focus (menuconfig)


Tools like the Linux kernel's menuconfig work because they enforce a strict, single-column focus. Even though there are borders and titles, the active area is a vertical list. The cursor stays pinned to that list. It doesn't jump to the bottom right to update a clock, then to the top left to update a title. The spatial complexity is kept low enough that the screen reader never gets “lost.”

3. The Lost Art of Scrolling Regions (Irssi)


Irssi is the gold standard for accessible chat, but not because of luck. Irssi was built over 20 years with a custom rendering engine that utilizes VT100 Scrolling Regions.

When a new message arrives in Irssi: 1. It tells the terminal driver: “Define a scrolling region from line 1 to 23.”2. It sends a command: “Scroll up.” The terminal moves the bits up. 3. It draws the new text at the bottom of that region.

Crucially, it handles this in a way that minimizes interference with the input line. It relies on the terminal's hardware capabilities rather than rewriting every character on the screen manually. Modern frameworks ignore these hardware features in favor of “diffing” the screen state and rewriting characters, which is computationally heavier and hostile to accessibility.

The “Stale Bot” excuse: A Case Study in Neglect


Google and the maintainers of gemini-cli pretend to care about accessibility. “Pretend” is the operative word here. If you look at the repository, critical accessibility regressions like Issue #3435 and Issue #11305 have been left to rot. There is no discussion, no roadmap, and no fix. Even worse is the fate of Issue #1553, which was supposed to track these accessibility failures. It didn't get solved; it got silenced. It was closed automatically by a bot with this generic dismissal: > Hello! As part of our effort to keep our backlog manageable and focus on the most active issues, we are tidying up older reports. It looks like this > issue hasn't been active for a while, so we are closing it for now.”

This is unacceptable. Closing an accessibility report because the maintainers haven't touched it in months is not “tidying up”; it is hiding evidence. It effectively says that if a bug is ignored long enough, it ceases to exist. It boosts the project's “Closed Issues” metric while leaving the actual software unusable for blind users.

Conclusion


If you are building for the terminal and care about accessibility, stop using declarative UI frameworks that treat the terminal like a canvas.

The “modern” TUI stack has optimized for the developer's ability to write React-like code at the expense of the machine's ability to render text efficiently.

If you cannot guarantee that your application allows the user to hide the cursor, or if you rely on aggressive redrawing to show spinners and timers, you are building an inaccessible tool.

For the blind user, a dumb, linear CLI stream is infinitely superior to a “smart” TUI that lags, spams, and scatters the cursor across the screen.



🚨 NEW VIDEO: The Windows Exodus Has Begun.

2025 was the breaking point. Forced hardware retirement and intrusive AI have sparked a mass migration to GNU/Linux. In this video, I explore:

📈 The data behind the 3.20% Steam high.

🇪🇺 How the EU is saving millions by ditching Microsoft.

🛡️ Why 2026 is the year of Digital Sovereignty.

Stop fighting your OS. Start owning it.

🔴 Full Video: youtube.com/watch?v=dLzdTgCXyR…

#TerminalTilt #WindowsExodus #Windows10 #Windows11 #Microsoft #WindowsEOL #Recall #Copilot #DigitalSovereignty #Privacy #DigitalPrivacy #NoAI #HumanMade #DeGoogle #EthicalTech #Autonomy #DataSovereignty #AntiSpyware #Telemetry #SurveillanceCapitalism #RightToPrivacy #Encryption #SoftwareFreedom #ExitWindows #Migration #LinuxGaming #GamingOnLinux #SteamDeck #Valve #Proton #Bazzite #SteamOS #HandheldGaming #PCGaming #ROGAlly #LegionGo #GamingCommunity #SteamHardwareSurvey #EWaste #Sustainability #RightToRepair #PlannedObsolescence #CircularEconomy #GreenTech #SaveThePC #Hardware #Environment #EUtech #PublicMoneyPublicCode #OpenStandards #SchleswigHolstein #GermanyTech #GovernmentIT #DigitalRights #Linux #GNUlinux #Debian #Trixie #FOSS #FLOSS #OpenSource #LibreOffice #Thunderbird #Nextcloud #SelfHosted #HomeLab #CLI #CommandLine #Terminal #Bash #FishShell #Dotfiles #SysAdmin #QueerTech #TransInTech #DisabledInTech #Accessibility #Queer #LGBTQIA #LGBT #HumanContent #ContentCreator #SmallYouTuber #SmallStreamer #YouTube #IndieCreator #SupportIndependent #LinuxUser #Tech #TechNews #OperatingSystems


Libervia CLI Tip 15:

When publishing a blog or other pubsub based feature, the item ID is often used in the URL when it is rendered for the web (e.g.; Libervia or Movim use something like `https://…/blog/<user>/<item_id>`).

It is then important to have a user-friendly item ID (e.g.; `title-of-my-publication-abc123`), which is usually done by the software from the title.

If you want to change it, you can use `li pubsub rename`.

libervia.org/__b/doc/backend/l…

#Libervia #CLI #li #tips #xmpp #pubsub



Libervia CLI Tip 13:

Somebody is annoying you or you're receiving unwanted messages? You can block a single entity with `li blocking block some_jid@example.org` or a whole domain with `li blocking block example.net`.

See who is already blocked with `li blocking list`, and remove an entity from the list with `li blocking unblock some_jid@example.org`.

The commands use XEP-0191, which must be supported by your server.

libervia.org/__b/doc/backend/l…

#Libervia #CLI #li #tips #xmpp #spam


Libervia CLI Tip 11:

Libervia automatically caches pubsub nodes you are subscribed to.

You can control it with the `li pubsub cache` commands.

The search capabilities are really powerful, with full-text search and many filters.

You can find items across profiles, within a time frame, or on any field of parsed data.

You can show whole items or specific data (e.g., title/author/tags of forum posts within a time frame).

libervia.org/__b/doc/backend/l…

#Libervia #CLI #li #tips #xmpp #pubsub


Libervia CLI tip 6:

Most commands have an `-O, --output` option to format the output. By default, the output is pretty formatted for humans, but you can output in JSON, XML, or other formats.

With `template` output you can use Jinja templates, either built-in ones (the ones used in the web frontend), or your own; useful to build static HTML pages/sites, or reformat the data the way you want.

Use `--help` to see available outputs

libervia.org/__b/doc/backend/l…

#Libervia #CLI #li #tips #XMPP #FOSS


Libervia CLI tip 5:

You can retrieve or modify your contacts list (aka “roster” in XMPP terms) with `li roster`.

One of the subcommands, `stats`, gives you, as its name implies, statistics on your roster.

You’ll notably get the number of contacts per domain, with a percentage representing the domain's “weight.” It’s a simple way to see how decentralized your contacts network is.

libervia.org/__b/doc/backend/l…

#Libervia #CLI #li #tips #XMPP #roster #decentralization


Libervia CLI tip 4:

If you see an XMPP powered blog like those made with Libervia or Movim, you can use directly the `https:` URL to retrieve the XMPP blog or one of its posts.

For instance, to get my blog at goffi.org with Libervia CLI, you can do:
`li blog get -u goffi.org`

This works with all pubsub related commands, so if you have the right, you can also edit or publish like that.

libervia.org/__b/doc/backend/l…

#Libervia #Movim #XMPP #CLI #blog #tips #li


I am having a consistent problem where I am unable to clone everything from this repository into my local machine. Every time I clone using the command line, none of the documentation shows up. only one folder seems to show up and that appears to be the GitHub folder. Does anyone know what the cause of this could possibly be and how to rectify the issue? github.com/buttondown/docs #OpenSource #Git #GitHub #CLI


OK so as people seem interested, here is a first Libervia-CLI tip.

`li` is the short alias for `libervia-cli`.

If you want to quickly upload a file to share it, you can use:

`li file upload -P your_file.ext`

`-P` shows a progress bar.

You can even encrypt it with the `-e` option in which case you'll have an `aesgcm:` with the decryption token as a fragment of the URL (the `#…` part).

You can then decrypt with `li file get`.

libervia.org/__b/doc/backend/l…

#libervia #cli #li #tips #xmpp


I am slowly oxidizing my unix CLI. A lot of people have made rust based versions of common unix utilities and some of them are REALLY good.

Like fd-find for doing essentially find . -name blah. And rg (ripgrep) which does grep -R but it's aware of git, files like pyc or .bak files, and it excludes them by default.

Now I have sd which is hopefully replacing the last thing I used perl for. I write perl -pi -e s/x/y/g a lot. Just doing a quick string replace inside a file. So sd can start doing that.

I'm also trying to get used to zellij instead of tmux and starship for modern prompt decorations like the kids do.

These kids, my friends, are welcome on my lawn.

#rust #cli #linux




Hm, does someone know a #sip client that works from the #cli on #arm64 with 1und1.de #voip?

I tried

  • linphonec, but didn't get it to register on my arm64 debian installation
  • I like baresip, but I couldn't configure it to register to register with 1und1.de
  • sipsimpleclient.org - worked somehow on my desktop, but didn't get it installed on arm64

It doesn't need to be fancy, I'm just looking for a simple tool to let a phone ring. No need to connect nor for audio transmission.



Running commands of your servers or bots from Libervia CLI.


In this video, I show how to use the Libervia CLI to run ad-hoc commands, a powerful feature of XMPP that allows you to execute custom commands on your server or client. I'll demonstrate how to list available commands, run a command to get the server uptime, and send an announcement to all users. This tutorial is a great way to learn more about the Libervia CLI and how to use it to automate tasks and interact with your XMPP ecosystem.





“Defaults files” are a convenient tool to store, group, and combine related command line options.
E.g., instead of typing

pandoc --pdf-engine=xelatex -V csquotes

one could create a file `pdf.yaml` with

pdf-engine: xelatex
variables: {csquotes: true}

and use it with

pandoc -d pdf.yaml

pandoc.org/MANUAL#defaults-fil…

#pandoc #cli #yaml



Another project to share: dbcli.com/

This is for everyone who prefers the #CLI over a GUI. The website lists #database clients for the CLI.

I personally use mycli mycli.net/ since some years. I used dbeaver.io/ before (for people that prefer GUI).

mycli has a nice autocompletion, configuration file and color support. You also can store favourite database queries. It also allows you to open the current query within vim :)