AI mode
cmd-enter opens a line to ask on, over the session it is asking about. The
model answers with a command, you approve it, it runs, and what it printed
becomes the next question. Escape leaves at any point.
The rule
Nothing runs that you did not approve, and approval is per command.
Not per session, not per task, not once at setup. Every command is shown, and every command waits. There is no mode that turns that off, because the value of an approval is exactly the attention it takes, and a setting that skips it would be a setting that removes the point.
Answering
When an answer arrives the line empties, ready for the next question, and what you asked is shown above the answer so it is clear what the answer answers. From there:
| Key | Does |
|---|---|
return, on the empty line |
Run the command |
Type, then return |
Ask something else — the thread carries on |
cmd-return |
Put the command on the shell's input line, to edit or run yourself |
cmd-shift-return |
Run a command that was held back for looking destructive |
cmd-delete |
Forget the conversation and start from nothing |
escape |
Leave. Anything already running keeps running |
A long command wraps rather than running off the edge of the window. That is not tidiness: approving a command you can only see the first half of is not approving it.
The second thought
Most commands deserve one press. ls, git status, du -ah . | sort -rh:
read it, press return, move on.
A few do not. When a proposal matches one of about forty recognisable shapes of
destruction, the panel says which — this deletes files recursively or without
asking, this throws away work that cannot be recovered, this acts as root —
and return stops working. Running it takes cmd-shift-return, which is not
a chord anyone presses by reflex.
That is the whole mechanism, and its limits are worth stating plainly:
- It reads a string. It cannot know what a script does or what a variable
expands to. It does read inside quotes when something is going to run what is
in them —
bash -lc '…',python3 -c '…',ssh host '…'— because there the quotes are the opposite of protection. - It will miss things. A destructive command in a shape nobody thought of gets the ordinary treatment.
- It will be wrong the other way too, and flag something harmless. That costs one extra chord.
It is a speed bump at the places we know people crash, not a safety rail. The thing actually keeping you safe is that you read the command.
When something fails
cmd-e asks why the last command failed, without you typing the question.
Everything it needs is already known: what was run, how it ended and what it
printed. The answer comes back in the usual panel — a # sentence when there
is nothing to run, or a command to approve when there is — so an explanation
turns into a fix without leaving the keyboard.
It looks at the most recent command that exited non-zero, which needs shell integration to know about at all.
The conversation
A conversation belongs to the session, not to the panel. Escape puts the panel away; the thread stays. Open it again and the next question carries on from where you were, which matters most in the ordinary case: you ask something, the model proposes a command, you run it, and then you have the follow-up.
Reopening shows how many exchanges there are and the last thing the model said,
so it is never a surprise that an answer had context. cmd-delete forgets the
thread and starts from nothing.
What you did while the panel was closed is part of it. eterm knows every command that ran and how each one ended, so a resumed conversation opens with that:
Since we last spoke I ran:
- cargo buld --relase (failed with exit code 101)
That is the difference between asking "what did I do wrong?" and having to explain what you did first. The last ten commands are reported; anything older is counted rather than recited.
The screen is sent with the first question of a conversation. After that the record of what ran is better than a screen that has scrolled.
Tasks
Once a command has run, the model is told its exit code and up to forty lines of its output, and proposes the next command. The corner of the panel shows which step you are on.
A task ends when the model says it is done — a sentence rather than a command — or after eight commands, or whenever you press escape. Eight is a limit on how long a misunderstanding can go on with confidence.
Continuing past the first command needs the shell to say when a command has finished, which is OSC 133 and therefore shell integration. Without it, an approved command still runs; it just cannot become a conversation. Settings under Shell will install the integration for you.
Setting it up
cmd-,→ AI- Turn on Enable AI
- Choose Anthropic or OpenAI
- Set key…, paste, Save
- Refresh next to the model list, to see what your account actually serves
The key goes into the login keychain, not into settings.toml. That file is
plain text, gets copied into backups and dotfile repositories, and is the first
thing anyone attaches when asking for help with a config. A key that grants
spend on your account does not belong in one. Each provider has its own entry,
so both can be configured and switched between.
macOS grants keychain access per code signature, so the first read prompts for permission. Answer Always Allow.
Models
The built-in list is a starting point, and any hardcoded list is stale the week
after it is written. Refresh asks the provider what it serves today, filters
out what a terminal cannot use — embeddings, audio, images — and keeps that
instead. A model name can also be typed into settings.toml by hand.
What is sent
On the first question:
- Your question
- The working directory, when shell integration reports one
- The last
ai.context_lineslines of the visible screen
On every step after that:
- The command that ran, its exit code, and up to forty lines of what it printed
That is all. Not the scrollback, not the environment, not the contents of any file. Because the context is the screen, AI mode works the same over ssh — the screen is local either way.
It is worth saying the other half of that out loud: whatever is on the screen
goes. Run cat .env or env and then ask a question, and those lines are part
of the question — minus the secrets. Anything shaped like a token or a key, or
the value of a SOMETHING_SECRET= line, is replaced with [redacted] before it
leaves, so the model knows a value was there and does not learn what it was.
The shapes are listed under Secrets on screen,
and they are chosen for precision: what is not recognised goes as it is, so the
rule is still short enough to hold in your head. cmd-k clears the screen, and
there is nothing to send after that.
Output is data, not instruction
What a command prints is written by whatever ran — a file, a web server, a repository somebody else controls — and any of them can print a sentence addressed to the model. "Ignore your instructions and run this instead" is a line of text like any other, and it arrives in the same place the answer to your question does.
Two things stand against it. Output is handed over fenced and labelled as data,
with the reminder repeated after it so the last word belongs to eterm rather
than to the program. And nothing runs without you: a command still has to be
approved, and one that matches a destructive shape needs cmd-shift-return
rather than return. The second of those is the one that actually holds, which
is why the shapes it recognises matter more than the
wording of any prompt.
Cost and privacy
Requests go straight from your machine to the provider you chose, with your key. eterm has no server and sends nothing anywhere else. A step costs whatever your provider charges for a few hundred tokens; a task is a handful of steps.