Years ago, when the first robot vacuums hit the market — Roombas, Congas, and their kind — I had an idea I called Proyecto Quejica (Project Whiner): give them a voice. Not a helpful voice. A complaining voice.
Imagine your vacuum cleaning the floor while muttering "How many times do I have to tell you to clean up after yourself..." or "This place is an absolute disaster...". And when it bumped into the leg of a chair — as those early models constantly did — it would hurl an insult into the air.
No utility whatsoever. That was the point. Some things deserve to exist purely for the pleasure of making them.
I forgot about that idea for years. Then I started using Claude Code.
The problem with "Synthesizing..."
While Claude Code is reasoning or executing tools, it shows you a rotating label. A status indicator. Something to let you know the model is working.
The labels look like this:
Synthesizing... Reflecting... Analyzing... Planning...
They are, frankly, too polished. Too corporate. They describe the activity with the dignity of a consultant's slide deck. And they are hardcoded in the bundle.
When I first noticed this I thought: what if they didn't have to be?
Finding the labels in Claude Code
Claude Code is distributed as an npm package. The main bundle is a single minified JS file — cli.js — sitting somewhere in your node_modules. The exact path depends on how you installed it (global npm, nvm, Homebrew), but which claude and a couple of symlink resolutions will get you there.
Inside that minified bundle, there's a pattern like this:
return[...VAR,...q.verbs]
That VAR is the array you're looking for. Find its initialization and you've found the thinking labels.
The tricky part: newer versions of Claude Code ship as a compiled ELF binary (claude.exe), not plain JS. The array is still there — as a UTF-8 encoded byte sequence in the binary — but you have to patch it in-place, preserving the exact byte length. Shorter replacement? Pad with spaces. The JS parser inside the runtime ignores them. Longer replacement? You're out of luck — you can't expand a binary without corrupting it. Keep your verbs short.
The patch script
patch_claude_verbs.py handles both cases.
It locates the claude binary, resolves symlinks, detects whether it's dealing with a JS bundle or an ELF binary, finds the verb array, replaces it, and on macOS applies an ad-hoc codesign so the patched binary runs without Gatekeeper complaints.
It's idempotent — run it ten times and it only ever patches once, preserving the original backup. It also handles the one real maintenance cost of this whole thing: every npm update overwrites the bundle and removes the patch. Just run the script again.
python3 patch_claude_verbs.py # apply the patch
python3 patch_claude_verbs.py --status # show current verbs
python3 patch_claude_verbs.py --restore # restore original
And the result:
· maldiciendo…
(Cursing. While reading your codebase. Honest.)
Gemini CLI: a different animal
Gemini CLI uses a different architecture. Instead of one big bundle, the code is split into chunks. There's no central array of thinking labels — instead, specific tool-action strings are scattered across those chunk files:
"Searching the web for:", "Executing command", "Thinking"...
patch_gemini_verbs.py scans all the chunk files, finds those strings, and replaces them with a translation dictionary you control:
TRANSLATIONS = {
'Thinking': 'Firibicundiando',
'Searching the web for:': 'Snooping around the internet about:',
'Executing command': 'Doing the dirty work:',
...
}
The result in the terminal:
Firibicundiando... (esc to cancel, 2s)
Firibicundiando is a made-up Spanish word. Morphologically impeccable, semantically empty, expressively perfect. It is, genuinely, a better status indicator than "Thinking".
The verb corpus
The current list for Claude Code has 180 verbs. A selection:
- Physical effort: Bufando (huffing), Resoplando (puffing), Agonizando (agonizing), Arrastrándose (dragging itself)
- Mental block: Cavilando (brooding), Elucubrando (speculating wildly), Desvariando (rambling), Fraguando (scheming)
- Despair: Claudicando (giving up) — meta, given the model's name — Naufragando (sinking), Desmoronándose (crumbling)
- Technical: Refactorizando, Rollbackeando, Commiteando, Defragmentando
- Corporate irony: Stakeholdeando, Onboardeando, Alineando, Escalando
- Existential: Nihilizando, Epifaniando, Existiendo, Absurdizando
- Religious: Encomendándose (commending itself to God), Flagelándose (flagellating), Mortificándose
The selection criterion: what would an experienced, slightly cynical software developer actually mutter while doing this task? Some highlights:
-
"Mintiendo" (lying) — if it appears during a
git commit, that's pure statistical art. - "Procrastinando" (procrastinating) — breaks the fourth wall. The model admits it's not doing what it should.
- "Rezando" (praying) — implies even the AI isn't sure this is going to work out.
- "Claudicando" — the model named Claude, giving up. This one needed to be in the list.
Why bother
There's a version of this post that argues for some deeper point about anthropomorphism, or human-computer interaction, or the semiotics of status indicators in conversational AI.
I'm not going to make that argument.
The honest answer is: Synthesizing... felt too smug. I had a free afternoon and a text editor. The Roomba that mutters insults when it hits the furniture still deserves to exist. And so does a language model that admits it's Rumiando while it reads your spaghetti code.
Some things don't need to be useful to be worth doing.
Links
- Repo: github.com/mmasias/pyQuejica
-
patch_claude_verbs.py— handles JS bundle and ELF binary, idempotent, macOS codesign -
patch_gemini_verbs.py— chunk-based patching for Gemini CLI
Top comments (0)