Vision
Every window on the desk is addressable, scriptable and honest about what it can do.
An app's own command surface is derived from its message type, so the list you read can never drift from the program you are driving.
One language for every yantrik GUI on your desk — and on every machine you can reach. Find it, address it, ask it, drive it.
A graphical app is the one program you cannot pipe. You can script a server, a compiler, a database — but the window on your screen has always been a dead end for automation.
yell exists to end that. Every yantrik GUI writes a small manifest naming the socket where its embedded driver listens. yell reads those manifests, so a running window becomes something you can list, address, question and drive — from a terminal, from a script, from another machine.
Vision
Every window on the desk is addressable, scriptable and honest about what it can do.
An app's own command surface is derived from its message type, so the list you read can never drift from the program you are driving.
Mission
Give the graphical world one small language, and refuse to grow past its edges.
yell drives GUIs and only GUIs. Servers, chains and daemons are out of scope by definition — that boundary is what keeps the language small enough to hold in your head.
This is the whole trick to learning yell. There is no long list of verbs to memorise — there are five things you can be doing, and each word does exactly one of them.
Each family owns a colour throughout this site. When you meet a word you have not seen, you only need to place it in a family to know roughly what it does and what it needs beside it.
Discovery. Ask what is broadcasting right now, or start something that is not — and start it again when you have rebuilt it.
list spawn reload
Not a word but a place on the line, always just after the word:
@ names the yantra the rest of the line is spoken to. Name
several and the statement fans out to all of them.
@forge @iron/forge @iron/ @*
Look, and change nothing. These are exactly the words that read the window without reaching into it — the tree, one element, a picture, the console.
version help take_snapshot get_element take_screenshot wait_for read_console
The words that act. Seven arrive in the window as real input, exactly
as a hand would send them; ux is the eighth, and speaks
to the app in its own vocabulary.
click hover drag fill type_text press_key scroll_into_view ux
The session itself: bind a result and reuse it, write it to a file, listen to a yantra talk, wait for one to be ready, leave.
let $name save report wait attach detach quit
Every line you write is a word, the yantra it is spoken to, and whatever the word needs. Read it left to right: what, then who, then with what.
click @iron/forge 0e9da92a…4a11df8d92 dblClick=true
forge, on the machine reached as iron. Drop the machine and you mean every forge here.take_snapshot; a setting is key=value.
Not @forge click …. A line that opens with an address is
asking that yantra its version, and nothing may follow it — because a
line should mean one thing, and the one it means should be readable from
its first word.
Work down this list in a real terminal, against forge — the
example yantra that ships with yell. By the end you will have discovered
a live window, read its tree, and changed something on screen without
touching the mouse.
Start with the only question that needs nothing else running.
yell> list ADDRESS STATE CPU RSS UP PID TITLE/WHY @forge running 0.0% 119.7M 11s 2452392 the forge
An address on its own line is the cheapest question there is.
yell> @forge forge 1.0.0 speaks 2026-07-28 and offers appCommands console posture tools
The tree, indented, with a fingerprint for every element. This is where every element you will name comes from.
yell> take_snapshot @forge scrollable "" a0432a832b1587645…6d015f84a4cf text "the fire is at 20C" 4e8afda58895428…9ce499fb16ea25edb focusable "Anvil" 0e9da92a61f617cc8f…5b9a112e2b54a11df8d92 focusable "Bellows" 7bab125ead3eff4bc4…3d937e9be7935069
Name the element by its fingerprint. No coordinates, so it keeps working when the window moves or is resized.
yell> click @forge 0e9da92a61f617cc8f…5b9a112e2b54a11df8d92 click on 0e9da92a61f617cc8f…5b9a112e2b54a11df8d92
help addressed to a yantra lists the commands it answers to, in its own words. ux runs one.
yell> help @forge set_heat: heat the fire and hold it there temper: nudge the fire up or down from where it stands quench: put the work in the slack tub and let the fire go cold yell> ux @forge set_heat degrees=900 the fire is at 900C
Every yantra keeps a console. Read it back, or attach and hear it as it speaks.
yell> read_console @forge the fire is lit and the bench is empty the bench was told SetHeat { degrees: 900 } the fire is at 900C
Every word answers something, and every answer can be bound and written down.
yell> let $shot = take_screenshot @forge yell> save $shot /tmp/forge.png 34413 bytes written to /tmp/forge.png
The same language lives in Markdown. Prose is documentation, fenced
yell blocks are the program — so the file you hand a
newcomer to read is the file the machine executes.
Nothing drifts, because there is no second copy of the truth. Blocks run top to bottom in one session, and the first refusal ends the run and names the line it was written on.
yell runbook.md executes every yell block in order.
yell check runbook.md prints what each line means
and runs nothing — the parse without the doing. A block fenced as
text instead of yell is inert, so you can show
yell inside a yell runbook without it firing.
yell calls a machine a mettle, and ssh is the only channel it will ever use to reach one — a mettle name is simply a host alias in your ssh config, so keys, users and ports stay where they already live and never appear in yell at all.
That is why an address can carry a machine: @iron/forge is
one window on one host, while @forge is every forge here.
| Address | Means |
|---|---|
| @forge | Every live forge on this machine. Two of them, and the line runs against both. |
| @local/forge | The same thing, said out loud. |
| @iron/forge | Only the one on that mettle, reached over ssh. |
| @iron/ | Everything running on that mettle, whatever it is. |
| @* | Everything here. Useful, and worth a second thought. |