Skip to content

Repository files navigation

polyglot

CI Release Go herdr License: MIT

Write prompts in the language you think in and keep the conversation in English. A herdr plugin: press a key on any agent pane, an overlay opens above it, you write, and the English translation lands in the agent's input. It works with Claude Code, Codex, opencode and the rest, because the prompt goes through herdr rather than into a particular tool.

the popup over a Claude Code pane: a German prompt written, translated, and typed into the agent's input

Why this exists

You think faster in your own language. But an agent answers in the language it was asked in, so your prompts end up in the replies, the comments, the commits and the docs — and a rule in CLAUDE.md or AGENTS.md cannot hold: the agent continues the context it has, and every prompt you send makes more of that context your language. Translate the prompt and the drift has no source.

Side effect: your sentence and its English sit side by side, prompt after prompt. It rubs off.

Quick start

herdr plugin install wazum/herdr-polyglot

That is enough to use it: with no key the popup is a prompt box that hands what you write to the agent, with the keys, the vim bindings and the resumed draft it always had. Nothing is translated and nothing leaves the machine.

For the translation, put your key in the plugin's own config directory, readable only by you — a plain redirect would leave it readable by everyone on the machine:

ENV_FILE="$(herdr plugin config-dir wazum.polyglot)/.env"
touch "$ENV_FILE" && chmod 600 "$ENV_FILE"
echo "HERDR_POLYGLOT_API_KEY=your-deepl-key" >> "$ENV_FILE"

A DeepL API key has a free tier. Free keys end in :fx, and the plugin sends those to DeepL's free host by itself.

Then bind a key in ~/.config/herdr/config.toml:

[[keys.command]]
key = "prefix+t"
type = "plugin_action"
command = "wazum.polyglot.prompt"
description = "write a prompt in your own language"

For one gesture instead of two, let the terminal send the prefix for you. In Ghostty:

keybind = super+p=text:\x02t

\x02 is ctrl+b, the prefix, and t is the binding above. Reload with ⌘⇧, and take a chord the terminal has free — ⌘G is find-next in Ghostty.

t as in translate — herdr already uses prefix+p for the previous tab. There is a second action, wazum.polyglot.compose, which types the prompt into the agent's input instead of sending it, and ctrl+r switches between the two while you write, so one keybinding is enough.

In the popup

alt+enter translate and hand the prompt over (ctrl+d does the same)
enter a new line, because a prompt is often more than one
ctrl+r switch between sending it and only filling the input
ctrl+l turn live translation on or off for this prompt
ctrl+t translate what is there now, or try again after a translation failed
tab read the translation across the whole popup, and back
ctrl+u throw the draft away, as it clears a line in a shell
esc close — with vim bindings on, first to normal mode, then close
ctrl+c close, always

The header says which of the two will happen: sends to agent hands the prompt over and the agent starts working, fills the input types it there and leaves the last keystroke to you. When something does not work the footer says so, esc takes the message away, and it goes by itself after a few seconds.

Settings

Every setting can be a line in the .env file or an environment variable, which wins over the file. A value that is neither on (1, true, yes, on) nor off (0, false, no, off) is refused rather than guessed at.

Setting Default Meaning
HERDR_POLYGLOT_API_KEY none Credentials for the translation service
HERDR_POLYGLOT_PROVIDER picked from what is configured Which service: deepl, google, cmd, dry-run or off
HERDR_POLYGLOT_COMMAND none A program that translates, for local translation
HERDR_POLYGLOT_LANGUAGE EN-US Target language
HERDR_POLYGLOT_ENDPOINT the service's own Override the service endpoint
HERDR_POLYGLOT_SUBMIT 1 0 types the prompt without sending it
HERDR_POLYGLOT_VIM 0 1 turns on the vim bindings
HERDR_POLYGLOT_LIVE 0 1 translates while you write
HERDR_POLYGLOT_CONFIRM 0 1 shows the English and waits for a second alt+enter
HERDR_POLYGLOT_KEEP_DRAFT 1 0 starts from an empty box instead of resuming
HERDR_POLYGLOT_MAX_DRAFT 2000 Characters before the box says the draft is too long
HERDR_POLYGLOT_PULSE 1 0 stops the live circle from breathing
HERDR_POLYGLOT_LOGO 1 0 leaves the empty draft box unsigned

The service is chosen by what you configured: a key means DeepL, a command means that command, neither means off — the plain prompt box. Both at once is refused rather than guessed at, and then HERDR_POLYGLOT_PROVIDER decides. Asking for a service that cannot be built is a case of its own: the popup says what is missing and where it belongs, and delivers nothing, so an untranslated draft never reaches the agent by accident. To keep keys for several services side by side, scope them by name: HERDR_POLYGLOT_DEEPL_API_KEY, HERDR_POLYGLOT_GOOGLE_API_KEY.

Google takes the same language setting and needs the Cloud Translation API enabled for the key. It reports no monthly count, so the header shows none with it, and it has no unbilled context parameter — live translation still pays for each sentence once, but translates each on its own.

What else it does

An unfinished prompt is kept. Drafts are stored privately, one per pane, and come back the next time you open the popup there, however it closed. A sent or discarded draft is forgotten.

Read the English first. With HERDR_POLYGLOT_CONFIRM=1, alt+enter translates and shows the result, a second alt+enter delivers it, and esc goes back to writing. It costs one translation, not two.

Live translation. The English follows your draft after a short pause. Each sentence is paid for once, and a translation you have already read is delivered as it stands, so writing costs little more than sending — how that works. Live translation starts off for a draft that came back from an earlier session and for text you paste in, since neither is something you asked to have translated; ctrl+l turns it on.

Translation on your own machine. HERDR_POLYGLOT_COMMAND points the plugin at a program instead of a service, so a draft need not leave the machine at all — how to set that up.

Code is not translated. A translation service rewrites code as if it were prose: it renames identifiers, translates comments and string literals, and reformats indentation. So anything in backticks or a fenced ``` block is taken out of the draft before it is sent, and put back exactly as it was — which also means it never leaves your machine and costs nothing to translate.

Vim bindings. HERDR_POLYGLOT_VIM=1 makes the draft box modal, with the motions, edits and counts that make sense inside a text box — the full list.

What leaves your machine

The draft goes to the translation service, so treat it the way you treat anything you paste into a web translator: prompts for a coding agent carry file paths, code and occasionally a secret, and in live mode the draft goes out again after every pause in typing.

Code does not leave either: backticked spans and fenced blocks are held back and restored afterwards, so a pasted stack trace or a file path is not sent anywhere.

Nothing else leaves. The API key goes to the translation service only — never to the agent, the herdr socket, a command line or a child process. Translated text is stripped of control characters before it is typed into a pane, so neither a line break nor an escape sequence can reach the agent's terminal. A translator on the machine keeps a draft off the network entirely.

Development

make qa     # formatting, linting, race tests, vulnerability scan
make build
herdr plugin link .

The overlay names palette slots rather than fixed colours, so it takes on whatever herdr theme is active, including a light one. How the pieces fit together, including how to add another translation service.

Credits

Created with ♥ by Wolfgang Klinger.

Built on herdr, Bubble Tea and Lip Gloss.

License

MIT.

About

Write coding-agent prompts in your own language — DeepL or Google Cloud Translate translates them to English and delivers them into Claude Code, Codex or any herdr agent pane.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages