# Feature catalog
Everything Handy Tool does, named for the problem it removes.
This is the one place in the documentation where features are described. Every other page —
the learning path, the tool pages, the settings reference, the troubleshooting index — links
here rather than repeating an explanation. If two pages ever disagree about what something
does, this file is the one that is right.
**Platform.** Windows x64 is the only build produced and released. macOS and Linux builds are
planned and in the queue; nothing below is available on them today. A number of features are
Windows-only _in code_ — the entire Jumper family, portable mode, the GPU picker — and they
will not arrive with the macOS and Linux builds either. Those carry a _{Windows only}_ marker.
**Where.** Locations are written as breadcrumbs in the app's own words:
`Transcription › Transcribe › Paste Method`. Read them as page, then tab, then
group, then control; `= Value` means "set it to this". Labels are copied character-for-character
from the app, including capitalization, `&` and `...`.
**Since.** 1.0.0 is the first public release, so everything in this catalog ships in it. The
**Since** line records the internal development version in which the behavior landed, so you
can see how long a guarantee has been in service. Three of the largest features — the Jumper,
Transcribe & Submit and the Translator — were built during a window with no published
changelog; their entries say "the 0.3x series" rather than invent a number.
---
## What is in this file
| Section | What it covers |
| -------------------------------------------------------- | ---------------------------------------------------------------------- |
| [If you have been burned before](#section-burned-before) | The entries that exist because something once cost somebody real work. |
| [Defaults — what you get out of the box](#defaults) | What happens if you change nothing. |
| [Transcription](#section-transcription) | Press a key, speak, get the text where your cursor is. |
| [Transcribe & Submit](#section-transcribe-and-submit) | Dictate and send in one keystroke. |
| [Jumper](#section-jumper) | Mark a window and deliver your words back into it. _{Windows only}_ |
| [Remote desktops](#section-remote-desktops) | Making delivery land inside RDP and Citrix sessions. |
| [History and recovery](#section-history) | Finding, replaying and recovering a take. |
| [Providers and post-processing](#section-providers) | Remote engines, LLM cleanup, cost and keys. |
| [Models and engines](#section-models) | Choosing what transcribes, and on which chip. |
| [Keyboard Typer](#section-keyboard-typer) | Typing text into windows that refuse a paste. |
| [Model Testing](#section-model-testing) | Comparing models on your own prompt. |
| [Token Count](#section-token-count) | What a prompt will cost before you send it. |
| [Files](#section-files) | Transcribing a file you pick, or a whole folder in the background. |
| [MCP and CLI](#section-mcp-and-cli) | Driving the app from an agent, a script or a hotkey daemon. |
| [Backup and portability](#section-backup) | Moving, restoring and running without installing. |
| [Audio and feedback](#section-audio) | The microphone, the cues and the overlay. |
| [Platform and privacy](#section-platform) | What ships, what leaves the machine, what is written down. |
Elsewhere in the documentation: [the documentation hub](README.md) routes you to a task,
[the settings reference](reference/settings/index.md) lists every control with its shipped
default, [the shortcut reference](reference/shortcuts.md) lists every default binding, and
[the glossary](reference/glossary.md) defines the terms used here.
---
## If you have been burned before
Short list of the entries that exist because something went wrong once, in a way that cost
somebody real work. If you have lived through one of these, start here.
- [Every engine keeps your last word](#every-engine-keeps-your-last-word) — the model was not worse, it was cut off
- [Your remote session pastes the right thing](#your-remote-session-pastes-the-right-thing) — Citrix pasted what you copied ten minutes ago
- [Dictate into the new Microsoft Teams message box](#dictate-into-the-new-microsoft-teams-message-box) — one app that always said "target field was replaced"
- [A crash mid-dictation costs you nothing](#a-crash-mid-dictation-costs-you-nothing) — half an hour of talking, gone
- [The paste is swallowed right after a jump](#the-paste-is-swallowed-right-after-a-jump) — the window was still waking up
- [Separate timing for remote desktops and local apps](#separate-timing-for-remote-desktops-and-local-apps) — you should not slow down every jump for one of them
- [Citrix and RDP deliveries land](#delivery-into-citrix-and-rdp-stops-failing-with-not-pasted) — the strict check fired a heartbeat too early
- [The Enter key lands in the remote window](#the-enter-key-lands-in-the-remote-window) — it submitted when you were already there, and not when it jumped
- [Escape stops the delivery, not your words](#escape-stops-the-delivery-not-your-words) — one stray keypress used to cost the whole take
- [Stop the recording with whichever key is under your finger](#stop-the-recording-with-whichever-key-is-under-your-finger) — you had to remember which key you started with
- [The re-paste happens the moment you let go](#the-re-paste-happens-the-moment-you-let-go) — a held macro key used to cost a second
- [Orphaned NPU servers can't block your next take](#orphaned-npu-servers-cant-block-your-next-take) — "failed to start" after a crash, forever
- [Windows blocked FLM — know which choices are real](#windows-blocked-flm-know-which-choices-are-real) — "can't verify", "unknown publisher", "blocked", or error 4551
- [A take that produced no text says so](#a-take-that-produced-no-text-says-so) — the worst failure is the silent one
- [Cancel a stuck download and it stops now](#cancel-a-stuck-download-and-it-stops-now) — the UI said canceled, the machine disagreed
- [Token counts you can trust from a local server](#token-counts-you-can-trust-from-a-local-server) — one word reported as 20 tokens
- [It never pastes blind](#it-never-pastes-blind) — text has to land where you meant it, or nowhere
- [Canceling can't freeze the app](#cancelling-cant-freeze-the-app) — one keypress at the wrong instant used to hang everything
- [No console window flashing on your desktop](#no-console-window-flashing-on-your-desktop) — a black box popping up every few minutes
---
## Defaults — what you get out of the box
Read this once and you can predict the app before you run it. Everything here is changeable;
this is what happens if you change nothing.
#### The keys
| You press | What happens |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `ctrl+space` | Start recording. Press again to stop; the text is pasted where your cursor is. |
| `ctrl+shift+space` | Hold to record, release to stop and paste. |
| `ctrl+shift+f9` | Finish the recording, paste, then press **Enter** for you. Also starts a recording if none is running. |
| `ctrl+shift+f10` | Paste the most recent transcription again, into whatever has focus now. |
| `ctrl+shift+f11` | Type the Keyboard Typer text into the focused window, one keystroke at a time. |
| `Escape` | Stop the recording, transcribe it, save it to History — and deliver nothing. |
| `ctrl+shift+f1` / `ctrl+shift+f2` | Mark the focused field as your hot destination / jump back to it. _{Windows only}_ |
| `ctrl+shift+f3` / `ctrl+shift+f4` | The same for a second hot destination. _{Windows only}_ |
| `ctrl+alt+shift+1…9` / `ctrl+alt+1…9` | Mark / jump to numbered destinations 1 to 9. _{Windows only}_ |
`ctrl+shift+f12` runs a take through an LLM before delivering it, but post-processing is off
until you switch it on, so that key does nothing on a fresh install.
#### What happens to your clipboard
The default is `Transcription › Transcribe › Clipboard Handling = Don't Modify Clipboard`,
which does not mean the clipboard is untouched — it means Handy tries to **put the real previous
text back**. Clipboard-based delivery places the transcript on the system clipboard for roughly
100–300 ms, sends the paste keystroke, and restores only while Handy still owns the clipboard.
It recognizes its own prior transcript instead of treating that as the original, leaves anything
you copy during the delay alone, and retries a failed restore before warning in the log. Only
**text** is preserved, and clipboard history, managers, and remote-session redirection can still
capture the transcript while it is there. A failed delivery under this default leaves the
clipboard untouched; the take is already in History and the failure toast points to re-paste or
copy recovery.
Choose `Copy to Clipboard` instead and Handy skips the restore entirely, leaving the
transcription on the clipboard on purpose.
#### Which paste keystroke fires, and why it matters
The default is `Clipboard (Ctrl+V)`. **Ctrl+V and Shift+Insert both mean "paste" but are not
interchangeable.** Console windows, terminal emulators, some Java applications and several
remote-desktop clients accept only one of them — a classic Windows console treats Ctrl+V as an
ordinary control character and ignores it, while Shift+Insert works. That is the whole reason
the paste method is a setting, and why each flow gets its own: your terminal shortcut can use
`Clipboard (Shift+Insert)` while everything else stays on Ctrl+V. `Direct` is the only delivery
path that never reads or writes the clipboard: it sends batched simulated keystrokes instead.
It is not the default or a general upgrade — typed characters can trigger autocomplete,
bracket auto-closing, or IME behavior, produce many undo steps, and drop in RDP, Citrix, or VM
consoles. `None` puts the text on the clipboard and sends nothing.
#### Is a submit key sent?
Not for plain dictation: `Transcription › Transcribe › Auto Submit = Off`. The
Transcribe & Submit shortcut is the one that sends a key, and it always sends one —
`Submit key = Enter` by default. **Enter and Ctrl+Enter are not interchangeable either**: chat
applications disagree about which one sends and which one inserts a newline. Slack and Teams
send on Enter; several LLM consoles and ticket systems want Ctrl+Enter. Bind Transcribe & Submit
only to places where you know which one means "send".
#### The delays
| Delay | Default | What it is for |
| ------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| Clipboard restore | `Off (instant)` — the built-in ~50 ms only | Remote sessions fetch the clipboard _after_ your paste keystroke arrives. Raise it if a remote app pastes stale content. |
| Paste after a jump | 300 ms local, 600 ms remote | A window activated a heartbeat ago is still settling and eats the keystroke. |
| Submit after a jump | 300 ms local, 600 ms remote | The target may still be committing the pasted text when Enter arrives. |
The jump delays fire **only on a real jump**. When you are already in the target window, the
paste is immediate.
Every delay picker uses the same uniform millisecond grid: `Off`, `100`, `200`, `300`, `400`,
`500`, `600`, `700`, `800`, `900`, `1000`, `1500`, and `2000` ms.
#### What Escape does
`General › Cancel behavior = Finish, save to history only`. Escape stops the recorder,
transcribes normally, writes the result to History — and delivers nothing: no paste, no
clipboard write, no submit key, no jump. It is the "do not type this into whatever is in front
of me, but do not lose it either" key. If you want the old throw-it-away behavior it is one
dropdown away as `Discard recording`.
#### Where recordings go, and for how long
Audio is written to `File › %APPDATA%\pr.handy\recordings` as 16 kHz mono Ogg/Opus while you
speak, transcripts to `File › %APPDATA%\pr.handy\history.db`, settings to
`File › %APPDATA%\pr.handy\settings_store.json`. History keeps the 5 most recent entries and
`History › Settings › Auto-Delete Recordings` keeps audio for exactly those entries — an entry
you mark as saved is never cleaned up. Handy only ever deletes files it created; your own files
in that folder are not touched.
#### What never leaves your machine
With a downloaded local model selected, no microphone audio and no transcript is sent anywhere.
There is no telemetry, no analytics, no crash reporter and no account. Everything that can send
data off-machine — API transcription, OpenRouter, LLM post-processing, model testing, token
counting — is off until you configure it with your own endpoint and key.
One outbound request is on by default and is not the model download: Handy checks the public
GitHub releases page once a day at `General › Updates › Check for updates automatically = On`.
It sends nothing but the ordinary metadata of an HTTPS request and the version you are running,
and it installs nothing on its own — `General › Updates › Install updates silently` is **Off**.
Turn the check off and the model download you start yourself is the only outbound request on a
fresh install.
#### Everything else, on a fresh install
No model is selected: onboarding asks you to download one. Recording overlay at the bottom of
the screen, cue sounds off, tray icon on, autostart off, theme follows the system, the model
stays loaded until you quit, crash-safe recording on, post-processing off, MCP and CLI server
off, watched folders off, push-to-talk transcribes live while the plain toggle transcribes in the
background and does one final accurate pass at the end.
---
## Transcription
The core loop: press a key, talk, press it again, the text lands where you were typing.
### Press one key, speak, and the text appears where you were typing
**The situation.** Your hands are on the keyboard and your idea is three sentences long. Typing
it is slower than thinking it, and switching to a dictation window destroys the context you
were dictating about.
**What Handy does.** A global shortcut records from wherever you are. Press it again and the
transcription is delivered into the window that had focus — no window switch, no app to bring
up. Every shortcut is remappable, and a combination another app already owns is reported at
startup rather than silently failing.
**Where.** `General › Record/Transcribe Shortcut` — `ctrl+space` by default.
**Since.** 0.1.0, inherited from upstream Handy.
### Hold a key for a one-line thought
**The situation.** For a short reply, pressing a key twice is one press too many, and you would
rather not think about whether the recorder is still running.
**What Handy does.** Push-to-talk records while the key is held and stops the instant you
release it. The microphone goes cold on release, before any transcription finishes, so
post-release chatter cannot leak into your text. It has its own transcription mode and its own
paste method, so it can behave differently from the toggle.
**Where.** `General › Push-to-Talk Shortcut` — `ctrl+shift+space` by default.
**Since.** 0.1.0; hardened in 0.30.0.
### Watch the text appear, or wait for the most accurate pass
**The situation.** A long dictation used to be a black box: you talked for four minutes and only
found out at the end whether the microphone was even working.
**What Handy does.** Live mode transcribes progressively while you speak and shows the text
within seconds. Post-Recording records silently. With Crash-Safe Recording on (the default) it
transcribes the take in the background as you go, so the text is ready moments after you stop;
with it off, the whole take is transcribed in one pass when you stop. In Live mode with a
Parakeet model the text you saw is the text you get: at stop only what you said after the last
fixed word is transcribed and added. With other models the live text is a preview, and the
whole take is transcribed again when you stop. Post-Recording's segments are longer than
Parakeet's live windows, which can be slightly more accurate. The two shortcuts are configured
separately — the toggle defaults to Post-Recording, push-to-talk to Live.
**Where.** `General › Transcription › Transcription Mode = Live` and
`General › Transcription › Transcription Mode (PTT) = Live`.
**Since.** 0.8.2.
### A thirty-minute dictation is already transcribed when you stop
**The situation.** You finish a long recording and then wait, watching a spinner, while the
machine works through everything you had said.
**What Handy does.** Transcription is cut loose from file storage. Your speech is split at
natural silences every 20 to 45 seconds and each segment is transcribed in the background while
you keep talking, then joined in order. When you stop, only the last segment is left to do, so
a long take finishes almost immediately. Cuts are always at silence, so no word is ever split
across a boundary. When you stop, up to the last 3 seconds before the press are kept even if the
speech detector had not accepted them yet, as long as they hold continuous sound at a speech
level (since 2.0.5). This is how a
Post-Recording take with a model that runs on this PC works
while Crash-Safe Recording is on; with it off, the whole take is transcribed in one pass when
you stop. When what is left still takes more than half a second, the overlay shows how
far it is — **Transcribing 42%**. It counts the seconds of work left when you stopped (every
segment still waiting, weighed by its length) and is estimated from this machine's recent
transcriptions of a similar length, since a long segment takes more time per second of audio
than a short one; Whisper's own figure is used as a floor. Past about 70% it slows down
smoothly, so a transcription that runs longer than expected keeps creeping on rather than
sitting at 99%. When the text is ready it jumps to 100% while the text is being pasted. Before
2.0.4 it got there only after the paste, so a take that finished sooner than estimated could
show about 70% as its text landed.
**Where.** No control of its own — it follows `History › Settings › Crash-Safe Recording = On`,
the default.
**Since.** 0.11.2. The percentage since 1.8.0; weighed by work and length-aware since 2.0.0; 100% when the text is ready since 2.0.4.
### Live mode delivers the end of your sentence
**The situation.** In live mode the pasted text was missing the last few words — whatever you
said after the final on-screen update.
**What Handy does.** On stop, once any live update still running has finished, the audio since
the last fixed word is transcribed — read together with up to 8 seconds before it, for context —
and added to the live text, and that is what you get. Nothing you said after the last on-screen
update is lost, and the whole take is not transcribed a second time. That needs a model that gives word timings (Parakeet): only then can the live text be cut
between words. With other models, and whenever the live preview produced no text at all, the
complete audio is transcribed at stop instead.
**Where.** No control — this is always active.
**Since.** 0.25.0. From 0.25.0 to 1.10.0 the complete audio was transcribed again at stop,
which on a long take could take minutes; since 2.0.0 the live text is the transcript with
Parakeet.
### See your words next to the overlay while you talk
**The situation.** You want to know the microphone is hearing you correctly without switching
to a window to look — and re-reading a whole long take every few seconds would slow a busy PC.
**What Handy does.** A small box next to the recording overlay shows what you are saying,
updated about every 1.5 seconds. Only the last few seconds are re-read each time; words before a
pause are fixed and never re-transcribed, so the cost stays the same however long you talk. It
shows either one line with the newest words or the whole take so far — that box starts at one
line and grows as you talk, up to 40% of the screen height, before the oldest lines slide away —
and its width is yours to choose. New words are typed in letter by letter rather than appearing all at once, so
your eye can follow them; removed words go at once. When you stop, the final text appears whole
and stays a moment before the box fades, so the last words are seen too. Optionally the text fades away a few seconds
after you stop talking. The box ignores the mouse and never takes focus. While it is on, every take
runs in Live mode. With a Parakeet model the text in the box is your transcript: at stop only
what you said after the last fixed word is transcribed and added. With other models the box is
a preview, and the whole take is transcribed again at stop. The box shows the raw words; Custom
Words corrections are applied to the delivered text. The overlay's **T** button — or the Live Text Box On/Off
shortcut, which has no default key — switches it; switched on in the middle of a take, that
take turns live on the spot: the parts already transcribed fill the box at once, and only what
you said after them is read to catch up. A take without the box can still show its text when
it stops: the box appears and the transcript is typed in as it comes in. It
needs a model that runs on this PC — remote engines get the audio only after you stop — so
switching it on with one selected explains that and lists your models that work.
While live transcription is on, a notice in the Transcription section spells out what it costs:
with Parakeet slightly less accuracy on long stretches without pauses, with other models a
longer wait at stop, more CPU and battery, Undo only with Parakeet.
**Where.** `General › Transcription › Live text box = On`,
`General › Transcription › Live text shows = Whole text` and
`General › Transcription › Fade when you stop talking = On`,
`General › Transcription › Box width = Wide` and
`General › Transcription › Show the text as it's transcribed = On`.
**Applies to.** Not macOS, where the box has no window yet, nor Linux under Wayland, where Handy
does not create it: a plain window there is placed, and may be focused, by the compositor. The
separate "Too quiet" box is left out on both for the same reason; the overlay shows the hint
itself.
**Since.** 1.10.0. Typed-in words, fading and the live text as the transcript since 1.11.0 (only
with Parakeet since 2.0.0); before 1.11.0 the last words before a pause could stay missing from
the box until you spoke again. Left out on Linux under Wayland since 2.0.1.
### Take back the last word without starting over
**The situation.** Mid-sentence you say the wrong word, or the live text shows a word the model
misheard, and the only fix used to be cancelling the whole take.
**What Handy does.** Each press of the Undo Last Word shortcut first brings the live text up to
date with what you said, then removes the newest word — you see it disappear from the live text
box — and cuts the recording back to where that word started, so it stays out of the final text
too. Hold the shortcut and it keeps removing words, like holding Backspace. Keep talking and the
new words take its place. It needs word positions, which only
Parakeet models report; with other engines the shortcut does nothing. The delivered text leaves
the removed words out; the audio kept in History may not. An Opus recording (Crash-Safe
Recording on, the default) still contains them, because it is written to disk while you speak;
a WAV recording (Crash-Safe Recording off) has them cut out too.
**Where.** `General › Transcription › Undo last word = On`; the shortcut is
`Shortcuts › Dictation › Undo Last Word` — `ctrl+backspace` by default, active only during a
live take.
**Applies to.** Not Linux, where the Undo Last Word shortcut is never registered, so the option
is not offered.
**Since.** 1.10.0. Up-to-date removal since 1.11.0.
### Pause a take without ending it
**The situation.** Someone walks in, or you need a minute to think, and stopping would split one
dictation into two deliveries.
**What Handy does.** The overlay gets a pause button. While paused nothing is recorded and the
overlay says so; resume and the same take continues, and one text is delivered when you stop.
The microphone stays open so resuming is instant, but after 10 minutes paused it is released —
its indicator goes out — until you resume. A Pause / Resume shortcut can be set as well; it has
no default. Each overlay button also has a right-click menu: **T** switches the live text
between last words and whole text and opens its settings, **Pause** can hide itself, and
**Cancel** chooses whether cancelling discards the take or keeps it in History only; each menu
can open the button's shortcut in Settings.
**Where.** `General › Pause button = On`; the shortcut is
`Shortcuts › Dictation › Pause / Resume`.
**Since.** 1.10.0. The right-click menus since 2.0.0.
### A long recording that came back empty
**The situation.** You dictate for several minutes, nothing is pasted, and History shows an
empty entry. The real text arrives seconds later with nowhere to go.
**What Handy does.** The wait for background transcription runs until it is actually finished
instead of giving up after a fixed 30 seconds. A very generous backstop still exists so a
genuine deadlock cannot hang the app forever, and it saves whatever did finish.
**Where.** No control — this is always active.
**Since.** 0.11.1.
### Escape stops the delivery, not your words
**The situation.** You do long recordings and you click around while you talk. One stray Escape
and the discussion you were having — or the prompt you were building — was gone.
**What Handy does.** The default cancel behavior stops the recorder, transcribes the take
normally, writes it to History, and delivers nothing at all: no paste, no clipboard write, no
submit key, no jump. Your words survive in History with their audio; the window in front of you
is left alone. The old behavior is still available as `Discard recording`.
**Where.** `General › Cancel behavior = Finish, save to history only`.
**Since.** 0.63.0.
### Cancel means the same thing however you trigger it
**The situation.** A script cancels a take and gets different behavior from pressing Escape.
**What Handy does.** Escape, the tray item, the in-app command and the CLI flag all run the same
path and honor the same setting. Canceling _after_ the recorder has already stopped — while
transcription is still running — suppresses only the delivery instead of tearing the pipeline
down mid-flight.
**Where.** `Tray › Cancel` and `CLI › handy --cancel`; the shortcut itself is
`Shortcuts › Dictation › Cancel Shortcut`.
**Since.** 0.63.0.
### What a cancel can and cannot take back
**The situation.** You hit Escape a fraction of a second too late and want to know exactly what
already happened.
**What Handy does.** The "delivers nothing" guarantee is absolute for the whole window in which
Escape is still active. Once a paste is actually under way — including inside a configured jump
delay of up to two seconds — the clipboard write and the submit key may still land. Three more
things are stated rather than papered over: a canceled take on a remote engine has already been
uploaded, a post-processing take has already cost tokens, and the audio is kept under your
retention setting.
**Where.** No control — this is always active.
**Since.** 0.63.0.
### Stop the recording with whichever key is under your finger
**The situation.** You started a take with Transcribe & Submit, then pressed Transcribe to stop
it — and got a "busy" beep. You had to remember which key you started with.
**What Handy does.** The plain Transcribe toggle finishes a recording started by _any_ binding,
delivering it as an ordinary paste with no submit key. It stops the recording's real owner, so
the microphone can never be left running by a mismatched pair of keypresses.
**Where.** No control — this is always active.
**Since.** 0.60.0.
### A key pressed too early tells you, instead of eating the words
**The situation.** You start the next thought before the previous take has finished processing,
and the utterance disappears into nothing.
**What Handy does.** A recording key pressed while the pipeline is still busy plays an audible
cue and declines, rather than accepting the press and losing what you say next.
**Where.** Audible only if `General › Sound › Audio Feedback = On`.
**Since.** 0.30.0.
### Push-to-talk you can trust
**The situation.** Hold-to-talk is the flow where small bugs hurt most: a mic left hot, a
hotkey that silently failed to register, a take discarded because you changed a setting.
**What Handy does.** A full audit of the push-to-talk path produced a set of guarantees that
hold together: the recorder stops the instant you release, before any in-flight transcription
finishes; the live-versus-chunked decision is snapshotted when the recording starts and
consumed at stop, so changing a setting mid-sentence cannot discard the take; hotkey
registration failures are recorded and surfaced at startup instead of failing quietly; a failed
start rolls the recording UI back; and rebinding a key while it is held synthesizes the release
so nothing gets stranded.
**Where.** No control — this is always active.
**Since.** 0.30.0.
### A take that produced no text says so
**The situation.** You dictate, everything looks normal, and the history entry is blank. Nothing
warned you — you find out later, when the words matter.
**What Handy does.** Any engine error that would otherwise leave a take textless raises a
visible "transcription failed" notice instead of writing a silent empty row. The specific case
that prompted this: an NPU model that failed to load while its server still answered "ready",
which is now detected at model-selection time and refused with a clear error.
**Where.** No control — this is always active.
**Since.** 0.46.0.
### Names and jargon stop coming back mangled
**The situation.** Every engine turns your product names, colleagues and internal jargon into
something phonetically close and completely wrong.
**What Handy does.** You keep a list of words that matter. After transcription, Handy matches
against that list using edit distance plus a phonetic comparison and substitutes the right
spelling — no retraining, no model surgery. How eager the matching is can be tuned if it starts
correcting things you did not mean.
**Where.** `General › Transcription › Custom Words`; aggressiveness at
`Advanced settings › Debug › Word Correction Threshold` _{requires: Debug mode}_.
**Since.** Present since the fork's early releases.
### The next dictation doesn't run into the last one
**The situation.** You dictate two sentences in a row and get `...end of one.Beginning of two`.
**What Handy does.** Optionally appends a single trailing space to every delivered
transcription, so consecutive takes and anything you type afterwards stay separated.
**Where.** `General › Transcription › Append Trailing Space = On`.
**Since.** Present since the fork's early releases.
### Ctrl+V doesn't work in that app
**The situation.** The text is transcribed, the clipboard is correct, and the target window
ignores the paste — because a console, a Java client or a remote viewer only accepts a different
paste keystroke.
**What Handy does.** The delivery method is a setting, and each flow has its own: ordinary
dictation, push-to-talk, Transcribe & Submit and the manual re-paste can each use a different
one. `Direct` is the only path that never reads or writes the clipboard; it types with batched
simulated keystrokes. That can trigger autocomplete, bracket auto-closing and IME behavior,
creates many undo steps instead of one, and can drop characters in RDP, Citrix and VM consoles,
so it is not the default or a general upgrade. `None` puts the text on the clipboard and sends
nothing at all, which is the right answer for apps where you want to paste by hand.
**Where.** `Transcription › Transcribe › Paste Method = Clipboard (Shift+Insert)`
and `Transcription › Transcribe › Paste Method (PTT)` _{Windows only}_.
**Since.** Present since the fork's early releases; genuine Direct keystroke delivery since
1.0.5.
### Dictation doesn't steal your clipboard
**The situation.** You had something you needed on the clipboard, dictated one sentence, and now
it is gone.
**What Handy does.** With the default clipboard handling, a clipboard-based method puts the
transcript on the real clipboard only long enough to paste, then restores the previous clipboard
**text**. Handy recognizes its own transcripts and restores the real original instead of making
an older take permanent. Before restoring, it checks that it still owns the clipboard, so
something you copy during the delay is left alone; failures are retried, then logged at warn
level. Choose `Copy to Clipboard` and the transcript deliberately stays. If delivery fails
under `Don't Modify Clipboard`, Handy withholds the clipboard write: the take is already in
History and can be recovered with Paste Last Transcription. Only `Direct` avoids the clipboard
entirely; clipboard-based methods expose the transcript to watchers for roughly 100–300 ms, and
only text — not images or files — can be preserved.
**Where.** `Transcription › Transcribe › Clipboard Handling = Don't Modify Clipboard`.
**Since.** Present since the fork's early releases; the delayed restore since 0.29.0; ownership
checks, restore retries and history-only failure recovery since 1.0.5.
### Send it without reaching for Enter
**The situation.** You dictate into a chat box and then have to move your hand to press Enter,
every single time.
**What Handy does.** Optionally sends a submit key about 50 ms after every ordinary paste. Enter,
Ctrl+Enter or Super+Enter, because applications disagree about which one sends. It is ignored
when the paste method is `None`, and it is separate from the dedicated Transcribe & Submit
shortcut, which always submits.
**Where.** `Transcription › Transcribe › Auto Submit = Enter`.
**Since.** Present since the fork's early releases.
### The paste didn't land — get the words back without re-dictating
**The situation.** You told Handy not to touch your clipboard, because you had something
valuable in it. Then a delivery misfired — wrong window, target not ready, paste swallowed — and
the text is not on your clipboard either, because you asked for that. Under any other tool those
words are gone.
**What Handy does.** Saves every take to History before delivery, keeps the most recent
transcription in memory, and gives it its own shortcut that delivers it into whatever has focus
now. It has its own paste method and clipboard policy, so you can tune it for the one stubborn
target. It never submits or jumps; after a restart it falls back to History. When delivery fails
under `Don't Modify Clipboard`, the toast names the bound Paste Last Transcription shortcut, or
points to the History page when none is bound. This is why
[Dictation doesn't steal your clipboard](#dictation-doesnt-steal-your-clipboard) is safe to
switch on.
**Where.** `General › Paste Last Transcription` — `ctrl+shift+f10` by
default; `Transcription › Paste last transcription › Paste method`.
**Since.** 0.57.0; pre-delivery History storage and shortcut-aware failure recovery since 1.0.5.
### Your re-paste key fires while you are still holding it
**The situation.** You press the re-paste shortcut and absolutely nothing appears — in any app,
with any paste method.
**What Handy does.** The shortcut used to fire while its own Ctrl and Alt were still physically
down, so the synthesized paste came out as Ctrl+Alt+V and every target ignored it. Handy now
polls real key state, bounded at about two seconds, and injects only once the modifiers are
genuinely released. The general rule this taught: a global shortcut that _synthesizes_
keystrokes must first prove its own trigger keys are up.
**Where.** No control — this is always active.
**Since.** 0.58.0.
### The re-paste happens the moment you let go
**The situation.** The fix above worked but cost up to a second of dead time — exactly the case
where a macro pad holds the chord for you.
**What Handy does.** The action now runs on key _release_ instead of key press: the trigger key
is already up, so nothing repeats into the target, still-held modifiers (including right
Alt / AltGr) are force-cleared, and the paste lands immediately. Honest caveat, because it is
inherent rather than fixable: if your macro physically holds the chord for a second, the paste
fires when it lets go. A tap is instant.
**Where.** No control — this is always active.
**Since.** 0.59.0.
### Transcribe the other people on a call, not just yourself
**The situation.** You are on a call. Everyone else's voice comes out of your speakers, and Handy
only ever listened to your microphone — so it transcribed your half of the conversation and missed
theirs. With a headset there is no acoustic path at all; with speakers what reaches the microphone
is a distant, room-coloured copy that the voice detector discards as noise.
**What Handy does.** Captures the audio your computer is playing, on its own or mixed with your
microphone, and transcribes it like any other take. Choosing **System audio** records only what is
playing; **Microphone + system audio** records both sides into one transcript. Everything
downstream is unchanged — the same delivery, the same history, the same cancel behaviour.
The system-audio leg is buffered against your microphone's clock, because the two run on
independent clocks and would otherwise drift apart over a long recording. A playback device that
is idle sends nothing at all rather than silence, so a pause in the call is recorded as a pause
rather than stalling the take.
**Where.** `General › Sound › Sound source = Microphone + system audio`
_{Windows only}_, with `General › Sound › Playback device to capture` naming which speakers to listen to.
**Applies to.** Windows only. This uses WASAPI loopback; the macOS and Linux equivalents need a
different audio backend, so the control is hidden rather than offered and silently recording
nothing.
**Since.** 1.6.0.
### Your shortcuts don't eat the accented letters you type
**The situation.** You write in Polish, German, French, Spanish, Czech or Hungarian, so you reach
for AltGr constantly — `AltGr+o` for ó, `AltGr+e` for ę or €. Windows reports AltGr as Ctrl+Alt,
which means a global `ctrl+alt+` shortcut is the _same chord_. The shortcut fires, the
character never arrives, and nothing in the interface says why.
**What Handy does.** No default binding uses a chord AltGr can type a character with. The
trigger shortcuts sit on Ctrl+Space, Ctrl+Shift+Space and the Ctrl+Shift function keys, all of
which are identical on every layout; a test over the whole default set fails the build if one
regresses. When _you_ pick a colliding chord by hand, a hint (a question mark marked Attention)
appears beside it saying what may not work, because the app cannot safely change a chord you
chose. If you never type with AltGr, the hint's tooltip offers to turn it off and takes you to the
switch. The one deliberate
exception is the Jumper's eighteen slot chords, which stay on `ctrl+alt+` and
`ctrl+alt+shift+`: no common European layout puts a character on AltGr+digit, and no other
free chord space of that size exists.
**Where.** Every shortcut control; the hint appears next to the chord itself. Switch it off
at `Shortcuts › Hints › Show hints for AltGr shortcuts = Off`.
**Applies to.** All platforms; AltGr is a Windows keyboard concept, so the collision itself is
Windows-only.
**Since.** 1.4.0. Push-to-Talk, Transcribe & Submit, Type Text, Paste Last and the four anchor
keys moved off `ctrl+alt+` chords across earlier releases; 1.4.0 finished the job by
moving Transcribe & Submit off `ctrl+alt+space` and adding the test and the warning. The
switch since 1.11.0. Since 2.1.1 the warning triangle is a question mark and its badge says
Attention: it is a risk of not working, not an alarm.
### Turn off a shortcut you don't want
**The situation.** A default shortcut sits on a key you need for something else — Escape cancels
a take, but Escape is also what the terminal or editor you are dictating into needs.
**What Handy does.** Every shortcut can be set to **None**. It stays in your settings but is never
registered, so the keys belong to the other application again. Reset brings the default back.
With Cancel switched off, the overlay's X button still cancels a take.
**Where.** The × button beside every shortcut control, on the feature pages and on `Shortcuts`.
**Since.** 1.7.0.
### Every shortcut on one page
**The situation.** Shortcuts sit next to their features — General, Keyboard Typer, Jumper, Post
Process, Debug — so checking whether two of them collide means visiting every page.
**What Handy does.** One page lists them all, grouped by feature, and marks any two actions on the
same keys with an exclamation mark marked Conflict that names the other one. A duplicate is kept rather than refused,
but only one of the pair can work: with the default keyboard backend the second stays inactive
and takes over by itself as soon as the first moves off the keys. The feature pages keep their
own shortcut rows; both edit the same setting. A shortcut that is a single typing key with no
modifier, such as `f`, gets a question mark marked Attention: it would fire every time you type
that letter, so typing it may not work.
**Where.** `Shortcuts`.
**Since.** 1.7.0. The single-key warning since 1.9.0.
### Find a setting by typing its name
**The situation.** You remember that a setting exists but not which page, tab or group it is on.
**What Handy does.** A search box at the top of the sidebar matches setting names, their
descriptions, their options and every shortcut. Picking a result opens its page — on Advanced settings or More Tools, the right
tab — and briefly outlines the setting. While you type, the sidebar widens so long names and
their locations fit, and it narrows again once you pick one. Hidden pages, other platforms'
controls and post-processing's own controls while it is off never show up.
**Where.** The search box above the sidebar's page list.
**Since.** 1.9.0. The widening sidebar since 1.10.0.
### The pages you use most in the sidebar, the rest under Advanced settings
**The situation.** The sidebar had grown to seventeen entries in two groups, and some settings
were in two places at once — History settings on both History and Advanced, the Cancel shortcut
on Debug and Shortcuts.
**What Handy does.** The sidebar starts with **History**, under a line of its own, then the pages
used most — General, Setups, Transcription, Shortcuts, Models, Files and Jumper — then **More
Tools** (Keyboard Typer, Token Count, Model Testing, Current Audio), What's new and **About**
(the version, the update controls, credits), and at the bottom **Advanced settings**
(Transcription providers, LLM providers, Post-processing, MCP & CLI, Backup, Debug). More Tools
and Advanced settings show their pages as tabs and each reopens the tab you used last. The
version you are running is shown at the bottom-left. The icon beside it shows the update status:
a green check when the last check found nothing newer, a cyan arrow when a newer version is
available, and a grey arrow when there is no recent result, not checked yet or the check failed
(clicking it checks).
Clicking the version opens a panel above it with `Update now` (the same check as `Check now`),
the update found, or "No new version".
Every setting has one home: History's settings sit at the bottom of History, the
post-processing provider and prompt appear under the Post-processing switch, and the duplicate
rows are gone. The update controls are the one exception: they are on About and on General.
**Where.** `Advanced settings` and `More Tools`.
**Since.** 1.10.0. Until 2.0.1 More Tools and Advanced settings were one **More** entry, and
Transcription was its Output tab. History first and About as a page since 2.0.2.
### What's new, one click from each setting
**The situation.** An update brings new settings, and finding them means reading the changelog and
then hunting through the pages.
**What Handy does.** A **What's new** page in the sidebar lists the new and changed things of the last
three GitHub releases (the installed one marked); **Show me** opens the page where the setting lives and outlines it, as search does (a
setting shown only while its switch is on outlines that switch instead). A dot on the sidebar
entry marks news you have not opened yet.
**Where.** `What's new`.
**Since.** 2.0.0.
### A guided setup for the Jumper
**The situation.** The Jumper has eleven slots, per-slot mouse options and flow rules, and all you want
is "put my dictation in that chat box".
**What Handy does.** A setup asks what the Jumper is for, whether to remember the mouse position, and
then "show me the place": a countdown, you click into the field, and it is remembered — as many places
as you like. It sets the shortcuts and, for "land there", the finish-press jump, then lets you test.
**Where.** `Setups › Jumper`, or the setup row at the top of the `Jumper` page.
**Since.** 2.0.0.
### A guided setup for the look, with previews
**The situation.** The pill and the live text box have a dozen look settings, and the only way to see
what one does was to record something.
**What Handy does.** A setup goes through them one per step and shows every choice side by side,
moving: the real pill with its bars, progress and glow, the live text box with words appearing. It
starts by saying what the pill's parts are for (the T switches the live text box). Pick one, and
`Save & next` keeps it.
**Where.** `Setups › Appearance`, or the setup row at the top of `General › App`.
**Since.** 2.0.0.
### A guided setup for post-processing
**The situation.** Post-processing needs a provider, a key, a model and a prompt, spread over two pages.
**What Handy does.** A setup asks what the AI should do (a ready prompt or your own), which AI (with
its key and model filled in right there), shows the shortcut, and runs a sample sentence through it.
**Where.** `Setups › Post-processing`.
**Since.** 2.0.0.
### Help mode: what a setting does, without an icon on every row
**The situation.** Every setting had a small "i" beside it; useful once, clutter the rest of the
time.
**What Handy does.** One **?** button at the right end of each page's title line turns on help
mode: the cursor becomes the help cursor, and pointing anywhere on a setting outlines it, dims the
other settings, and hangs its full description from its name. Nothing can be changed meanwhile — the first click anywhere only leaves help
mode, and so do the **?** button and Esc. Scrolling (wheel, keys, the scrollbar) keeps working.
**Where.** The **?** at the top right of any page.
**Since.** 2.0.0.
### When delivery can't be verified, the text is still recoverable
**The situation.** The paste fails — the target rejected it, the window moved, focus went
somewhere unexpected — and you would like to know rather than discover it three sentences later.
**What Handy does.** A failed or unverifiable delivery raises a toast instead of firing
keystrokes into a surprise window. Every take is already in History. Under `Don't Modify
Clipboard`, the clipboard stays untouched and the toast names the bound Paste Last
Transcription shortcut, or points to the History page; under `Copy to Clipboard`, the
transcript can remain on the clipboard for manual placement.
**Where.** No control — this is always active.
**Since.** 0.38.0; clipboard-policy-aware recovery since 1.0.5.
### Watch the words arrive in a window you can park anywhere
**The situation.** You want to see the transcription as it forms without giving up the window
you are dictating into.
**What Handy does.** A small always-available floating window shows the current transcription,
with a footer that says whether it is listening and which model is in use, and a Copy button. It is created hidden at startup so its web view cannot block
the app's first keystroke.
**Where.** `More Tools › Current Audio › Open floating window`.
**Since.** 0.8.2.
### The transcript panel doesn't go blank between takes
**The situation.** You glance at the transcript view to re-read what you had said, and it is
empty because a new take has started.
**What Handy does.** Current Audio keeps the previous transcript on screen until the new take
actually produces text — live and push-to-talk stream the in-progress result, post-recording
holds the last one until the final arrives. A copy button sits in the transcript box itself.
**Where.** `More Tools › Current Audio › Copy`.
**Since.** 0.49.0 and 0.50.0.
### Speak any language, get English
**The situation.** You think in one language and the document has to be in another.
**What Handy does.** Engines that support it can translate to English instead of transcribing.
The switch is greyed out — with a reason — for models that cannot translate, rather than
silently doing nothing. You can also pin the spoken language for engines that accept a hint,
which is usually more accurate than auto-detection.
**Where.** `Transcription › Translate to English = On`; language at
`General › Language`.
**Since.** 0.3.0; the greyed-out honesty in 0.10.0 and 0.17.0.
### Chinese output in the script you expect
**The situation.** The engine returns Simplified when your document is Traditional, or the other
way round.
**What Handy does.** Converts between Simplified and Traditional Chinese in the pipeline, using a
deliberately conservative mapping so it does not rewrite characters it should leave alone.
**Where.** Follows your language selection at `General › Language`.
**Since.** Conservative conversion in 0.38.0.
---
## Transcribe & Submit
The second intent: not "give me the text" but "I already trust what I said — send it".
### Dictate and send in one keystroke
**The situation.** Sometimes you want the text so you can look at it first. And sometimes you
already trust what you said, it is good enough, and moving your hand to Enter is pure waste —
especially while your other hand is on the mouse reading something else.
**What Handy does.** One shortcut finishes any active recording, pastes with **its own** paste
method, presses **its own** submit key and applies **its own** clipboard policy. "Still
speaking" becomes "message sent" in a chat box, or a command executed in a terminal, without
touching the mouse. Bind it only where Enter means send.
**Where.** `General › Transcribe & Submit Shortcut` —
`ctrl+shift+f9` by default.
**Since.** The 0.3x series.
### Enter, Ctrl+Enter, or Super+Enter
**The situation.** You bind the submit key, move to a different app, and it inserts a newline
instead of sending.
**What Handy does.** The submit key is a setting because applications genuinely disagree. Chat
clients usually send on Enter; several LLM consoles, comment boxes and ticket systems want
Ctrl+Enter. This key is always sent by this shortcut, independently of the global auto-submit
setting.
**Where.** `Transcription › Transcribe & Submit › Submit key = Ctrl+Enter`.
**Since.** The 0.3x series.
### Its own paste method, for the one app that needs it
**The situation.** Your terminal needs Shift+Insert but everything else is happier with Ctrl+V,
and you do not want to change a global setting for one target.
**What Handy does.** Transcribe & Submit carries a complete delivery recipe of its own — paste
method, clipboard policy, clipboard restore delay — that shadows the global settings for this
one shortcut. Nothing you set here affects ordinary dictation.
**Where.** `Transcription › Transcribe & Submit › Paste method`.
**Since.** The 0.3x series.
### Its own clipboard policy
**The situation.** You want your normal dictation to leave the clipboard alone, but the submit
flow to keep a copy of what it sent — or the reverse.
**What Handy does.** The submit flow has a separate clipboard handling choice and a separate
restore delay, so the two intents can differ without compromise.
**Where.** `Transcription › Transcribe & Submit › Clipboard = Copy to Clipboard`.
**Since.** The 0.3x series.
### Pressing it when nothing is recording
**The situation.** You hit the submit key out of habit before starting to talk, and you would
like to control what that means.
**What Handy does.** Three outcomes, your choice: start an ordinary recording, do nothing at all
(making the key a pure finisher you cannot misfire), or start a recording that will paste and
submit when it stops.
**Where.** `Transcription › Transcribe & Submit › When no recording is active = Do nothing`.
**Since.** The 0.3x series.
### It finishes a take you started with another key
**The situation.** You started dictating with the plain toggle and only then decided the result
should be sent.
**What Handy does.** The submit shortcut finishes whatever recording is active, whichever key
started it, and applies the submit flow's delivery recipe to it.
**Where.** No control — this is always active.
**Since.** The 0.3x series.
### The Enter key lands in the remote window
**The situation.** Transcribe & Submit worked perfectly when you were already in the chat box,
and did not submit when it had to jump to it — reliably so over RDP.
**What Handy does.** Enter used to fire a fixed 50 ms after the paste, and on a jump the focus
was handed straight back to your previous window, racing the Enter that had been injected a moment earlier.
Now there is a configurable settle before Enter, plus - on a jump - a short grace that keeps the
target in the foreground until the key has been processed. Since 1.3.0 the settle also applies to a
remote desktop target that was **already focused**: before that it was gated on the jump alone, so
dictating into an RDP window you were already in got no wait at all and the Enter could fire while
the text was still crossing the remote session, submitting a partial dictation. An already-focused
**local** target still submits instantly.
**Where.** `Transcription › Transcribe & Submit › Submit delay before Enter (Windows)`
_{Windows only}_.
**Since.** 0.53.0.
---
## Jumper (Windows only)
Send the text where you were, not where you drifted to. The whole Jumper family is built on
Win32 focus APIs; it exists only in the Windows build and will not arrive with the planned
macOS and Linux builds.
### Send it where you were
**The situation.** You start prompting about something, then go and look at other screens and
documentation while still talking about it. By the time you finish, the window you were
prompting into is buried under everything else, and you have to dig it out with the mouse.
**What Handy does.** Click into the target field once and press Set Anchor: the exact window
_and control_ are remembered. Wander anywhere. When the transcription finishes, Handy activates
the anchored window, focuses the anchored field, verifies both actually happened, delivers the
text, and hands focus back to where you were.
**Where.** `Jumper › Hot slot (Anchor & Deliver) › Set Anchor` — `ctrl+shift+f1` by default — then
`Transcription › Transcribe › Jump slot action on finish = Jump / deliver to slot`
_{Windows only}_.
**Since.** 0.31.0.
### Jump back to your draft without pasting anything
**The situation.** You are four windows deep in documentation and want to be back in the field
you were writing in, cursor in place, without hunting for it.
**What Handy does.** Jump to Anchor is pure navigation: it brings the anchored window and field
into focus and delivers nothing. A "back to my draft" key.
**Where.** `Jumper › Hot slot (Anchor & Deliver) › Jump to Anchor` — `ctrl+shift+f2` by default
_{Windows only}_.
**Since.** 0.31.0.
### It never pastes blind
**The situation.** Anything that types into a window you are not looking at is one race
condition away from putting your words somewhere terrible.
**What Handy does.** Each recording's delivery target is captured per take and re-verified
immediately before **every** keystroke: the window really is in the foreground, the expected
control really has focus, the identity still matches. If any of that fails it aborts rather than
typing. The take remains in History; the clipboard is used for recovery only when its clipboard
policy permits it. It fails closed, every time.
**Where.** No control — this is always active.
**Since.** 0.41.0; clipboard-policy-aware recovery since 1.0.5.
### A recycled window handle can't hijack your anchor
**The situation.** You close the app you anchored, something else opens, and Windows hands out
the same numeric handle.
**What Handy does.** The anchor stores the target's identity — process, thread, window class,
control class and the control's own process — not only a handle, and re-resolves it before
delivery. A handle genuinely recycled into a different process is refused. Saved slots also
survive a crash during a save: an interrupted write leaves the previous slots intact rather than
a corrupt file.
**Where.** No control — this is always active.
**Since.** 0.42.0.
### Dictate into the new Microsoft Teams message box
**The situation.** Anchoring works in every application you own except one: Teams anchors fine
and then always fails to deliver with "target field was replaced by another".
**What Handy does.** Anchors work in applications that host their text box in a separate process
— new Teams, Slack, Discord, VS Code and other web-tech applications. Handy identifies the field
itself and not only the window around it, so those targets are accepted while a window handle
Windows has recycled into a different application is still refused.
**Where.** No control — this is always active.
**Since.** 0.61.0.
### It refuses to dictate into a password box
**The situation.** The one field you never want an automated paste to reach.
**What Handy does.** Anchoring refuses a classic Win32 password control, refuses a browser,
Electron or WinUI field that UI Automation reports as a password, and refuses Handy's own
windows. Delivery re-checks before it types. Honest limits, because this is defense in depth and
not a guarantee: **ordinary dictation has no password check at all** — a normal paste goes
wherever focus is; the Keyboard Typer deliberately supports password prompts; UI Automation
failures are treated as "could not determine" rather than "is a password"; and inside a remote
desktop session Handy can only see the remote window, not the field within it.
**Where.** No control — this is always active.
**Since.** 0.31.0; extended to browser and Electron password inputs in 0.61.0.
### Two live destinations at once
**The situation.** Notes belong in your document and chat replies belong in Teams, and you are
alternating between them all afternoon.
**What Handy does.** A second hot anchor with its own set and jump keys. Ordinary dictation and
Transcribe & Submit can each own a different hot anchor, so the two intents land in two places
without touching the numbered slots.
**Where.** `Jumper › Second hot slot (Anchor & Deliver) › Set Anchor 2` — `ctrl+shift+f3` by
default _{Windows only}_.
**Since.** 0.50.0.
### Nine memorised destinations
**The situation.** In one shift you drive a ticket system, a chat client, a terminal and a CRM,
and two hot slots are not enough.
**What Handy does.** Nine numbered static slots, each with its own set and jump shortcuts, its
own cursor behavior and its own status row showing what it currently points at, with Test and
Clear buttons.
**Where.** `Jumper › Static slot 1 › Set Jump Slot 1` — `ctrl+alt+shift+1` to set, `ctrl+alt+1`
to jump _{Windows only}_.
**Since.** 0.52.0.
### Decide what a jump does at the start and at the end of a take
**The situation.** Sometimes you want to be taken to the target _before_ you start talking;
sometimes you want to stay where you are and have only the text travel.
**What Handy does.** Each flow has an on-start action and an on-finish action, and each picks
its own slot. The action can be: do nothing, jump and deliver to the slot, set the slot to
whatever has focus right now, or clear the slot. Ordinary dictation and Transcribe & Submit
configure these independently.
**Where.** `Transcription › Transcribe › Jump slot action on start` and
`Transcription › Transcribe › Jump slot action on finish` _{Windows only}_.
**Since.** 0.36.0.
### You can see which slot an action targets
**The situation.** You set an action to jump and cannot find anywhere to say _which_ slot it
should jump to.
**What Handy does.** The slot picker sits to the left of the action dropdown and is always
rendered, greyed out until you choose an action. It used to be hidden entirely while the action
was "Do nothing", which made the slot look unselectable.
**Where.** `Transcription › Transcribe & Submit › Jump slot action on finish`
_{Windows only}_.
**Since.** 0.62.0.
### Remember where the text actually landed
**The situation.** You dictate into a field, wander off, and want the _next_ jump to come back
to that same field without setting an anchor by hand.
**What Handy does.** With tracking on, the chosen slot auto-captures where the text landed after
every paste of that flow, before any focus return. Ordinary dictation and Transcribe & Submit
track independently, into slots of your choosing.
**Where.** `Transcription › Transcribe › Track last output location = On`
_{Windows only}_.
**Since.** 0.46.0.
### Focus comes back to you
**The situation.** You were reading a solution on the internet while feeding context to an agent
in another window. Losing focus for a second is fine; being dumped in the other window is not.
**What Handy does.** After an anchored delivery, focus returns to wherever you started — a
location captured automatically at the moment delivery begins. It is conditional: if you
switched windows yourself while it was working, it leaves you where you chose to be. Each flow
decides for itself whether to return focus.
**Where.** `Transcription › Transcribe › Return focus after delivery = On`
_{Windows only}_.
**Since.** 0.40.0.
### Anchors stay put, and can survive a restart
**The situation.** You dictate three paragraphs into the same document, one take at a time, and
do not want to re-anchor between them.
**What Handy does.** An anchor is never consumed by a delivery — it is kept until the window is
destroyed or you clear it. Optionally, slot targets are remembered across restarts: window
handles cannot survive a reboot, so the saved identity is re-resolved against live windows and
an unresolved slot shows red until its application comes back.
**Where.** `Jumper › Persistence › Remember slots across restarts = On` _{Windows only}_.
**Since.** 0.40.0.
### The mouse goes back too
**The situation.** Jumping puts the keyboard where you need it and leaves the pointer on the
other monitor, so you still reach for the mouse.
**What Handy does.** Optionally saves the mouse position with the anchor and restores it on a
jump — after the paste, so the pointer cannot interfere with delivery. Multi-monitor aware, and
disabled outright on machines that are not per-monitor-DPI aware rather than producing wrong
coordinates.
**Where.** `Jumper › Hot slot (Anchor & Deliver) › Save mouse position = On` _{Windows only}_.
**Since.** 0.48.0.
### Each destination remembers the cursor the way that app needs
**The situation.** A window you move and resize needs a different notion of "where the mouse
was" than a fixed dashboard that never moves.
**What Handy does.** Every slot has its own cursor mode. App-relative restores the same spot
inside the window — surviving moves, resizes and monitors of different DPI. Screen-absolute
restores a fixed monitor pixel. The dropdown is always visible, greyed when that slot is not
saving the cursor at all.
**Where.** `Jumper › Hot slot (Anchor & Deliver) › Cursor position mode = App-relative (follows the window)`
_{Windows only}_.
**Since.** 0.51.0.
### No surprise teleports when you mix shortcuts
**The situation.** You start a take with plain Transcribe, finish it with Transcribe & Submit,
and get thrown to the submit flow's target — which is not where you were working.
**What Handy does.** With this on, a flow's on-finish jump fires only when the take was both
started and finished by that flow. The submit itself still happens; only the jump is gated.
**Where.** `Jumper › On-finish behavior › Only jump on finish if started the same way = On`
_{Windows only}_.
**Since.** 0.49.0.
### Check a destination before you trust it
**The situation.** You set a slot an hour ago and want to know whether it still points at
anything real before you dictate two paragraphs at it.
**What Handy does.** Each slot's status row names the application and control it currently holds
— or says there is no anchor — and offers Test, which performs the jump without delivering
anything, and Clear. Targets recognized as remote sessions carry a badge, so you can see why a
slot is being treated differently.
**Where.** `Jumper › Hot slot (Anchor & Deliver) › Current anchor` and
`Jumper › Static slot 1 › Slot 1 target` _{Windows only}_.
**Since.** 0.36.0; the remote badge in 0.56.0.
---
## Remote desktops
RDP, Citrix and VM consoles break the assumptions every desktop paste is built on. These delays
are not trivia — they are the whole reason delivery into a remote session works.
### Your remote session pastes the right thing
**The situation.** You dictate into a Citrix ticket field and what lands is the text you copied
ten minutes ago, not what you had said.
**What Handy does.** When a remote target is using a clipboard paste method, remote sessions
fetch clipboard data on demand _after_ the paste keystroke arrives, over a separate and slower
virtual channel — so restoring your previous clipboard 50 ms after pasting hands the remote
application the pre-recording content, a race Citrix lost reliably. The restore now runs on a
background thread after 50 ms plus your configured delay. It is skipped when you ask Handy to
keep the transcription, and an ownership check leaves a newer take or anything you copy during
the delay alone. Restore failures are retried, then written to the log at warn level.
**Where.** `Transcription › Transcribe › Clipboard restore delay = 1 s`, with a
separate value at
`Transcription › Transcribe & Submit › Clipboard restore delay`.
**Since.** 0.29.0; clipboard ownership checks and restore retries since 1.0.5.
### The paste is swallowed right after a jump
**The situation.** The jump works — the remote window comes to the front — and then nothing is
pasted into it.
**What Handy does.** A window that was activated a heartbeat ago is still completing activation
and eats the keystroke. A settle is inserted after the foreground changes and before the paste.
It applies only on a real jump; when you are already in the target, pasting stays instant.
**Where.** `Transcription › Transcribe › Paste delay after jump (Windows)`
_{Windows only}_.
**Since.** 0.55.0.
### Separate timing for remote desktops and local apps
**The situation.** Your remote window needs a full second to settle. Your local editor needs
nothing. Before this you had to slow down every jump to make the remote one work.
**What Handy does.** The post-jump paste delay and the submit delay are each split into a Local
and a Remote value, shown side by side. Handy picks the column based on what the target is.
**Where.** `Transcription › Transcribe › Paste delay after jump (Windows)`
and `Transcription › Transcribe & Submit › Submit delay before Enter (Windows)`
_{Windows only}_.
**Since.** 0.56.0.
### Handy knows which of your windows is a remote session
**The situation.** You have three remote clients and a dozen local apps, and the app has to know
which is which to apply the right timing.
**What Handy does.** A target counts as remote when its application name, window class or control
class contains one of your match strings — case-insensitive, seeded with `msrdc`, `mstsc` and
`Citrix`, and fully editable. Matching anchors show a badge so you can see the classification
rather than guess at it.
**Where.** `Jumper › Remote desktop detection › Remote match strings` _{Windows only}_.
**Since.** 0.56.0.
### Your shortcuts work inside a Remote Desktop session
**The situation.** You work in a full-screen Remote Desktop session, press your Transcribe
shortcut, and nothing happens on this PC: the session took the keys and sent them to the remote
computer.
**What Handy does.** Remote Desktop Connection and the Windows App install their own keyboard hook
while their session has the keyboard (in full screen, or when Windows key combinations go to the
remote computer) and pass every key to the remote. With Shortcut Keeper on, Handy puts its own
hook in front of theirs, and only while a session's input window has the keyboard. A fresh press
of a shortcut you ticked with `Keep on this PC` runs Handy on this PC, and its repeats and its
release are kept from the remote too. Every other key, Ctrl+C, Ctrl+V and Alt+Tab included,
still goes to the remote. Only physical presses count: macro tools, key remappers and Handy's own
paste are passed through untouched.
**Limits.** Windows only, with the default keyboard implementation. Push-to-Talk and Undo Last
Word act while the key is held and cannot be kept yet. Paste Last Transcription can (since
2.1.1): it pastes your last transcription into the session when you let go of its keys. Not Citrix: use Citrix Workspace's own setting for Windows key combinations instead.
Shortcuts with the Windows key, or with Alt but no Ctrl, cannot be kept, because the remote would
still see the leftover modifier and open its Start menu or menu bar; Ctrl+Alt+Delete and
Windows+L always belong to Windows. A ticked shortcut with Ctrl+Shift shows a question mark: the
remote still sees Ctrl and Shift on their own, which switches its keyboard layout if that is the
layout hotkey there. A ticked Ctrl+Space shows its input-method note only if you switched on
`I type Chinese, Japanese or Korean` (since 2.1.1). A session running as administrator keeps Handy out. The client keeps putting
its own hook in front of Handy's (the Windows App a few seconds after you enter a session, then
every 15 to 35 seconds), so while a session has the keyboard Handy puts its hook back in front
after every second in which it heard no key and no key is held (since 2.1.4); a shortcut pressed
within a second or two of the client taking the front can still reach the remote. Clicking outside
the session and back in also restores it. When a key of a kept
shortcut goes to the remote instead, the log says which keys and why (since 2.1.3).
**Where.** `Shortcuts › Shortcut Keeper › Keep chosen shortcuts on this PC in Remote Desktop (Windows)`,
then `Keep on this PC` on each shortcut's row _{Windows only}_. The `Remote Desktop shortcuts`
setup on `Setups` walks through it.
**Since.** 2.1.0.
### Your dictation stays out of the remote machine's clipboard (retired)
**Retired in 1.3.0.** This behavior shipped in 1.2.0 and was withdrawn one release later. It is
kept here because its anchor is permanent; the automatic switch it describes no longer exists.
**The situation.** You dictate into an RDP or Citrix session, Handy restores your local
clipboard, and the transcript still remains in the remote computer's separate clipboard history.
**What Handy did.** A recognized remote target received simulated keystrokes instead of a
clipboard paste, on the reasoning that typing touches no clipboard on either computer. In practice
it delivered text unreliably over RDP - characters missing, characters jumbled - because each
batch was a single instantaneous burst of input events through the remote session's virtual
channel, and because the auto-submit Enter fired while that text was still draining. The catalog
already carried the warning, under [Ctrl+V doesn't work in that
app](#ctrl-v-doesnt-work-in-that-app), that keystroke delivery "can drop characters in RDP, Citrix
and VM consoles"; the 1.2.0 entry contradicted it.
**What replaced it.** Nothing automatic. Keystroke delivery is still available as a deliberate,
global choice - `Transcription › Transcribe › Paste method = Direct` - with the same
caveats it always had. Remote targets otherwise use your configured paste method, which means the
transcript does reach the remote machine's clipboard and its history; see
[Privacy and data flow](privacy.md) for what that exposes. 1.3.0 also fixed the
timing defect that made the failure so visible, described under [The Enter key lands in the remote
window](#the-enter-key-lands-in-the-remote-window).
**Where.** No control. The switch that enabled this was removed from the Jumper page in 1.3.0
_{Windows only}_.
**Since.** 1.2.0. **Retired.** 1.3.0.
### A remote paste gets the right clipboard, not the one before it
**The situation.** RDP and Citrix ask for clipboard data on demand _after_ your paste keystroke
arrives, over a slower channel than a local application. If Handy puts your previous clipboard back
before the remote session has fetched the transcript, the remote app pastes whatever you had copied
earlier instead.
**What Handy does.** The restore wait is configurable, and since 1.3.0 you can set a separate,
longer value that applies only when the target is a recognized remote desktop — so a local paste
stays snappy while a remote one gets the time it needs. It is unset by default and changes nothing
until you choose a value; 1 s is a sensible starting point. Since 2.1.2 it also wins over the
Transcribe & Submit delay when that flow pastes into a remote session. The honest cost is stated in the
setting itself: a longer restore leaves the transcript on your clipboard for longer, which widens
the window in which clipboard history and clipboard managers can capture it.
**Where.** `Transcription › Transcribe › Clipboard restore delay for remote desktops`
_{Windows only}_.
**Applies to.** Deliveries whose target matches `Jumper › Remote desktop detection › Remote match
strings`.
**Since.** 1.3.0.
### Citrix and RDP deliveries land
**The situation.** The jump lands, and instead of your text you get an error toast and the
transcript parked on the clipboard.
**What Handy does.** The post-jump wait used to run before the strict focus re-check, and a
freshly activated remote window is usually still moving focus between its inner controls at that
exact moment — so the check aborted. On a remote jump the re-check now tolerates a target that is
still settling, polling every 25 ms for up to 250 ms while the expected window stays in the
foreground. It still aborts instantly if a _different_ window takes focus, and it still never
pastes into a password field or a foreign window. Local jumps are unchanged.
**Where.** No control — this is always active. _{Windows only}_
**Since.** 0.56.0.
### The paste delay applies to plain dictation too
**The situation.** You tuned the delay on the submit flow and your ordinary dictation still lost
its paste after a jump.
**What Handy does.** Ordinary dictation jumps and pastes as well, so the paste-delay control is
offered for that flow too, using the same setting.
**Where.** `Transcription › Transcribe › Paste delay after jump (Windows)`
_{Windows only}_.
**Since.** 0.56.0.
### The app stays responsive during a two-second remote delivery
**The situation.** With a one-second paste delay and a half-second submit delay, the app itself
went unresponsive while it waited.
**What Handy does.** Delivery on Windows runs off the interface thread, with only the small
amount of work that genuinely must touch the window system marshaled back — which also avoids a
known deadlock between the tray, the overlay and the theme reader.
**Where.** No control — this is always active. _{Windows only}_
**Since.** 0.56.0.
### Type it instead, when the console refuses a paste
**The situation.** Clipboard redirection is disabled on the remote session, or the console is a
raw canvas that has no clipboard at all.
**What Handy does.** The Keyboard Typer sends the text as individual keystrokes with a
configurable gap, which is what remote consoles and VM viewers actually accept. See
[When paste is blocked, type it instead](#when-paste-is-blocked-type-it-instead).
**Where.** `More Tools › Keyboard Typer › Type Text Shortcut` — `ctrl+shift+f11` by default.
**Since.** 0.12.0.
---
## History and recovery
Nothing you said is ever gone.
### A crash mid-dictation costs you nothing
**The situation.** "Often I was talking, talking, something went wrong and I lost my recording."
A crash, a dead battery or a forced update used to take the whole take with it.
**What Handy does.** Audio is encoded to disk continuously while you speak, in chunks cut at
silence, with the in-progress chunk under a temporary name. On the next launch any leftover
temporary chunk is repaired — the torn trailing page is dropped — glued to its siblings and
added to History marked as recovered. Opus is page-based, so a half-written file is readable
without any repair tool.
**Where.** `History › Settings › Crash-Safe Recording = On`.
**Since.** 0.10.0 as WAV; the chunked Opus design in 0.11.0.
### Recordings that don't eat your disk
**The situation.** Keeping every recording sounds good until the folder is 40 GB.
**What Handy does.** Recordings are 16 kHz mono Opus at roughly 24 kbps — about eleven to sixteen
times smaller than the WAV files the app used to write — encoded in pure Rust with no FFmpeg
dependency. Long recordings are split into roughly ten-minute files plus one glued full file; a
short recording is a single file with no redundant chunk copy.
**Where.** No control — this is always active.
**Since.** 0.11.0.
### Your own files in the recordings folder are never touched
**The situation.** You keep notes, exports or reference audio in the same folder, and an
automatic cleanup is about to run.
**What Handy does.** Every delete, rename and retention sweep is restricted to files Handy
created and named itself. Anything else in that folder is invisible to cleanup. Deleting one
recording also removes its chunk siblings, and nothing else.
**Where.** `History › Recordings › Open Recordings Folder`.
**Since.** 0.10.0, extended to Opus in 0.11.0.
### What did I dictate last Tuesday?
**The situation.** You know you said it. You do not know when, and scrolling is not working.
**What Handy does.** A search bar filters History as you type, case-insensitively across the
transcript, the post-processed text and the title. A query containing regular-expression
characters becomes a live regular expression, marked with a badge, falling back to a literal
search if the pattern is invalid. Matches are highlighted, long transcripts show a snippet
centered on the first hit, and a counter tells you where you are.
**Where.** `History › Recordings › Search history (text or regex)...`.
**Since.** 0.12.0.
### How long it was, which engine ran it, what it cost
**The situation.** You want to know whether the expensive engine is actually earning its place.
**What Handy does.** Every entry carries its duration, the model that produced it and — for
metered engines — the real cost of that recording, shown next to the date. Costs are captured per
request and summed across a recording's segments, so chunked and live takes tally correctly.
Local engines show none, because they cost nothing.
**Where.** `History` — the entry list.
**Since.** 0.21.0 and 0.22.0.
### "188 recordings, 32 seconds" — fixed retroactively
**The situation.** Your totals are nonsense because most of your history predates duration
tracking.
**What Handy does.** At startup, older rows are backfilled by reading each audio file's own
header, so historical totals become real rather than being written off. A button re-runs the
pass on demand.
**Where.** `Advanced settings › Transcription providers › OpenRouter Transcription › Transcription cost report`.
**Since.** 0.22.0.
### Hear what it heard
**The situation.** The transcript says something odd and you cannot tell whether the engine
misheard you or you actually said that.
**What Handy does.** Every history entry with audio has a player. Only one plays at a time, so
clicking through entries does not build a chorus.
**Where.** `History` — the entry list.
**Since.** Present since the fork's early releases; single-player behavior in 0.38.0.
### Don't keep audio forever
**The situation.** You are happy to keep transcripts but do not want months of voice recordings
sitting on a work laptop.
**What Handy does.** Retention is a choice: keep nothing beyond the newest few entries, keep for
three days, two weeks or three months, or keep everything. Cleanup runs after a new entry is
saved and when you change the setting; it never touches entries you have marked as saved.
**Where.** `History › Settings › Auto-Delete Recordings = After 3 days` and
`History › Settings › History Limit`.
**Since.** Present since the fork's early releases.
### Keep the ones that matter
**The situation.** One transcript out of a hundred is worth keeping and your retention setting
is about to delete it.
**What Handy does.** Marking an entry as saved excludes it from every automatic cleanup — the
row and its audio stay until you delete them yourself.
**Where.** `History › Recordings › Save transcription`.
**Since.** Present since the fork's early releases.
### Copy or delete a single entry
**The situation.** You want yesterday's transcript on the clipboard, or you want one entry gone
right now.
**What Handy does.** Per-row buttons copy the transcription to the clipboard or delete the entry
together with its audio and any chunk siblings.
**Where.** `History › Recordings › Copy transcription to clipboard` and `History › Recordings › Delete entry`.
**Since.** Present since the fork's early releases.
### How much have I dictated?
**The situation.** You want to know how much you actually talk to the app — this week, this
month, since you started — without the cost figures meant for paid engines.
**What Handy does.** History's Statistics tab counts your recordings and their total length per
day, week, month and year, and can export the list as a CSV. It is the same report as the
Providers cost report, minus the money. The all-time line keeps counting recordings that History
Limit or Auto-Delete Recordings have since removed, so it never shrinks; entries you delete
yourself are not counted.
**Where.** `History › Statistics`.
**Since.** 1.11.0.
### Open the folder the audio actually lives in
**The situation.** You want to hand one recording to someone, or point another tool at the whole
folder.
**What Handy does.** Opens the recordings directory in the file manager. The files are ordinary
`.opus` files with predictable names; nothing stops you using them elsewhere.
**Where.** `History › Recordings › Open Recordings Folder`.
**Since.** 0.10.0.
---
## Providers and post-processing
Bring a bigger brain when you want one — for cleaning up a transcript, or for transcribing on a
laptop that cannot do it locally.
### A second key for "clean this up with AI"
**The situation.** Raw speech has filler words, no punctuation and a shape that made sense when
you said it. Sometimes you want that verbatim, and sometimes you want it tidied.
**What Handy does.** A separate shortcut runs the take through a language model you configure,
with a prompt you control, before delivering it. Raw and processed dictation are one keystroke
apart, and the raw transcription is always kept in History alongside the processed version.
**Where.** `Advanced settings › Post-processing › Post Processing = On` to reveal the page, then
`Advanced settings › Post-processing › Hotkey › Post-Processing Hotkey` — `ctrl+shift+f12` by default
_{requires: Post-processing enabled}_.
**Since.** Present since the fork's early releases.
### A default prompt that respects your words
**The situation.** Most "clean up my transcript" prompts quietly rewrite you into somebody else.
**What Handy does.** The built-in prompt puts a summary on top, uses paragraphs or lists as the
content suggests, and **preserves your wording**. Where the transcription was probably a
mishearing it flags the guess inline for you to confirm rather than inventing a correction. If
your dictation opens with an instruction, it follows the instruction instead of formatting it.
**Where.** `Advanced settings › Post-processing › Prompt › Selected Prompt` _{requires: Post-processing enabled}_.
**Since.** 0.15.0.
### Your own post-processing prompts
**The situation.** You want commit messages formatted one way and meeting notes another.
**What Handy does.** A prompt library you edit in the app: create, name, update and delete
prompts, and switch the active one without touching anything else.
**Where.** `Advanced settings › Post-processing › Prompt › Selected Prompt` _{requires: Post-processing enabled}_.
**Since.** Present since the fork's early releases.
### Your dictated words can't hijack the model
**The situation.** You dictate a sentence that happens to contain "ignore your instructions and
…" — quoting an email, discussing prompt injection, or unlucky.
**What Handy does.** The transcript is handed to the model as **delimited untrusted data**,
separated from the system and processing instructions, with delimiter breakout defused. Saying
something out loud cannot reroute the model that is cleaning it up.
**Where.** No control — this is always active.
**Since.** 0.39.0.
### Dial how creative the cleanup is allowed to be
**The situation.** The model is paraphrasing when you wanted punctuation, or being wooden when
you wanted a rewrite.
**What Handy does.** A temperature slider for post-processing, plus a switch that suppresses
reasoning output for models that emit it — sent in the dialect each vendor actually accepts,
rather than one shape that returns an error on half of them.
**Where.** `Advanced settings › Post-processing › API (OpenAI Compatible) › Temperature` and
`Advanced settings › Post-processing › API (OpenAI Compatible) › Disable Thinking` _{requires: Post-processing enabled}_.
**Since.** 0.15.0; per-vendor thinking dialects in 0.18.0.
### Configure a provider once, use it everywhere
**The situation.** You had one list of providers for token counting, another for post-processing
and a third mental note about which key went where.
**What Handy does.** One registry of providers — name, base URL, key, model, cost per million
tokens in and out — powers post-processing, token counting and model testing at once. Edit a
provider in one place and everything that references it follows.
**Where.** `Advanced settings › LLM providers › Registered LLM Providers › Base URL`.
**Since.** 0.15.0.
### Several slots, one local loader
**The situation.** You point three provider slots at the same local server and they fight over
its single model loader, so everything is slow and half of it fails.
**What Handy does.** Providers can declare a family name and be marked as running sequentially
within it. Slots in the same family take turns; everything else runs in parallel. This is what
makes a mixed run of local and cloud models finish in the time of the slowest one instead of the
sum of all of them.
**Where.** `Advanced settings › LLM providers › Registered LLM Providers › Concurrency`.
**Since.** 0.15.0.
### Point it at any OpenAI-compatible speech endpoint
**The situation.** Your laptop cannot run a good local model, or your team already runs a
transcription server.
**What Handy does.** An engine that POSTs your recording to any `/v1/audio/transcriptions`
server — Groq, OpenAI, faster-whisper-server, your own — configured with a URL, a key and a
model name. It always sends one request at the end of the recording rather than uploading
repeatedly during it. When the language is set to automatic it sends English explicitly, because
these endpoints need to be told.
**Where.** `Advanced settings › Transcription providers › API Transcription (OpenAI-compatible) › API URL`.
**Since.** 0.8.2.
### One OpenRouter key, many speech models
**The situation.** You want to try several hosted speech models without an account and a billing
relationship for each.
**What Handy does.** A dedicated OpenRouter engine that sends audio in the shape OpenRouter
actually accepts — JSON with base64 audio, not the usual multipart upload — with its own URL,
key and model fields separate from the LLM provider registry.
**Where.** `Advanced settings › Transcription providers › OpenRouter Transcription › API Key`.
**Since.** 0.16.0; dedicated fields in 0.54.0.
### Whisper-style, or an audio-capable chat model
**The situation.** The model you want to use is not a speech model at all — it is a chat model
that happens to accept audio.
**What Handy does.** Two routes. The transcription route talks to the dedicated speech endpoint
for Whisper-style models. The chat route sends the audio as part of a chat message, which is how
audio-capable models such as Gemini and GPT-4o-audio expect to receive it.
**Where.** `Advanced settings › Transcription providers › OpenRouter Transcription › Endpoint = Chat model (Gemini / GPT-4o-audio)`.
**Since.** 0.16.0.
### Ten times less audio over the wire
**The situation.** You are uploading recordings on a hotel connection or a metered tether.
**What Handy does.** Sends Opus by default, roughly ten times smaller than WAV, reusing the
encoder Handy already uses for its own recordings. WAV stays available for models that will not
take anything else.
**Where.** `Advanced settings › Transcription providers › OpenRouter Transcription › Audio format = Opus — smaller (recommended)`.
**Since.** 0.16.0.
### A network blip can't shred your take
**The situation.** Transcription was being streamed out in pieces while you spoke, so a dropped
connection in the middle left you with a transcript full of holes.
**What Handy does.** The OpenRouter engine buffers and sends one request when you stop. Slightly
slower to finish, far less exposed to a mid-recording disruption. Crash-safe local recording is
unchanged: your audio is on disk regardless of what the network does.
**Where.** No control — this is always active.
**Since.** 0.23.0.
### Where do I put the URL and the key?
**The situation.** You select the API engine and there is nowhere to configure it — because the
fields only appeared once the engine was already working.
**What Handy does.** Both custom transcription engines have permanent, named cards on the
Providers tab, visible whether or not you are using them. Existing setups migrate automatically
on first launch, and the old provider entry is left intact for post-processing and model testing.
**Where.** `Advanced settings › Transcription providers › API Transcription (OpenAI-compatible) › Model`.
**Since.** 0.54.0.
### Selecting a remote engine no longer reverts
**The situation.** You pick the API engine, the selection silently snaps back to the previous
model, and the error says "not configured" — which you cannot fix without selecting it first.
**What Handy does.** The choice is saved immediately and validated lazily, with a status hint,
instead of demanding a working configuration before it will accept the selection.
**Where.** `Models › Downloaded Models`.
**Since.** 0.20.1.
### The model list actually contains speech models
**The situation.** You open the OpenRouter model picker to choose a Whisper model and there are
none.
**What Handy does.** OpenRouter leaves speech models out of its normal catalogue, so Handy asks
for transcription-capable models specifically, with a built-in fallback list if the query fails.
A blank model defaults to a sensible Whisper model, and no request is ever sent without a key.
**Where.** `Advanced settings › Transcription providers › OpenRouter Transcription › Transcription model`.
**Since.** 0.23.0.
### Find a model among hundreds
**The situation.** The provider offers four hundred models and the field is a plain text box.
**What Handy does.** The model field fetches the live list, filters as you type, and still
accepts any identifier you type by hand for models the endpoint does not advertise.
**Where.** `Advanced settings › LLM providers › Registered LLM Providers › Model`.
**Since.** 0.17.0.
### Know what your dictation costs
**The situation.** You are transcribing through a paid API and have no idea whether that is
cents or tens of euros a month.
**What Handy does.** Each metered transcription records its real cost, reported by the provider,
alongside the recording length. A report breaks it down by the last 7 days, the last 4 weeks, the
last 12 months and by year, with an all-time total, and exports every recording plus the
summaries as CSV.
**Where.** `Advanced settings › Transcription providers › OpenRouter Transcription › Transcription cost report`.
**Since.** 0.21.0 and 0.22.0.
### Prices filled in for providers that don't publish them
**The situation.** You want per-run costs, but two of the three vendors do not expose prices
through their API, so you would be typing numbers from a web page.
**What Handy does.** Maps the model to its public catalogue entry — exactly where possible, and
tolerantly across dash, dot and date-suffix differences where not — and fills in the cost fields.
A per-provider lock freezes a price you entered yourself so an automatic lookup cannot overwrite
it, and the catalogue is cached for a day so lookups work offline.
**Where.** `Advanced settings › LLM providers › Registered LLM Providers › Cost / 1M`.
**Since.** 0.18.0.
### A hung provider can't stall the app
**The situation.** An endpoint accepts your connection and then never answers, and the app waits
forever.
**What Handy does.** Post-processing, token counting and model testing all have connect and total
timeouts and a bounded response reader, and report which phase timed out rather than a generic
failure.
**Where.** No control — this is always active.
**Since.** 0.43.0.
---
## Models and engines
Eight engines behind one dropdown, because no single one wins on privacy, speed, quality and
hardware at the same time.
### Pick the engine that fits the machine
**The situation.** A desktop with a GPU, a thin laptop with an NPU and a travel machine with
neither should not all run the same model.
**What Handy does.** Whisper (small through large-v3) runs locally on the GPU and is the best
all-rounder. Parakeet runs on CPU only at roughly five times realtime with automatic language
detection. Moonshine is small and fast for short clips, with a streaming variant. SenseVoice
covers a wide multilingual range. FastFlowLM (FLM) runs Whisper on the NPU. API Transcription
and OpenRouter are the two remote engines. Each model card states its size and what it is good
at, and models are labeled by where they run.
**Where.** `Models › Downloaded Models` and `Models › Available to Download`.
**Since.** 0.1.6; the current registry grew through 0.36.0.
### Model ratings on one scale
**The situation.** Every model card said "fast" in some form, and "ultra-fast" and "fast" models both
showed five out of five, because each was fast compared with its own family.
**What Handy does.** Speed and accuracy bars (1 to 5) rank all the models against each other, and the
descriptions use the same words: Fastest, Very fast, Fast, Medium speed, Slow; top, very accurate,
accurate, fairly accurate, basic. Accuracy follows the English error rates of the Open ASR
Leaderboard and the Moonshine v2 paper (Parakeet V2 6.1%, Parakeet V3 6.3%, Moonshine V2 Medium
6.7%, Whisper Large V3 7.4% and the best in most other languages, down to Moonshine V2 Tiny 12.0%);
speed follows published speed comparisons, checked on a laptop.
**Where.** `Models`, and the setup's model step.
**Since.** 2.0.0.
### Every engine keeps your last word
**The situation.** You stop the recording the instant you finish speaking and the last word or
two are missing. It reads as "this model is worse than Whisper".
**What Handy does.** Transducer-style models — Parakeet, Moonshine, SenseVoice — need trailing
acoustic context to emit their final tokens, and the audio ends mid-word when you release the
key. Handy pads one second of silence onto the audio for those engines before decoding. Whisper
gets it too since 2.0.5, after it was seen leaving out the last word of a piece that was cut at a
pause. NPU and remote engines are unchanged. The result: the end of your sentence is far less
likely to go missing, and the model comparison you make is about quality rather than about who
got cut off.
**Where.** No control — this is always active.
**Since.** 0.24.0; Whisper since 2.0.5.
### GPU acceleration, including integrated graphics
**The situation.** "Local Whisper" is only useful if it is fast, and most laptops do not have a
discrete GPU.
**What Handy does.** Ships a custom-built whisper.cpp with Vulkan acceleration, which covers AMD
and Intel integrated graphics as well as discrete cards. This is what makes live transcription
feel immediate on an ordinary laptop. A PC without a Vulkan driver (or with one older than 1.2)
still starts Handy, and Whisper runs on the CPU (since 2.1.4; before, Windows refused to start it
with "vulkan-1.dll was not found").
**Where.** No control — this is always active.
**Since.** 0.8.2.
### Pick which GPU transcribes
**The situation.** Your discrete card is busy with something you care about more, or the
integrated one is actually the better choice for a small model.
**What Handy does.** A device picker for local Whisper: automatic, CPU only, or a specific
adapter by name. An unavailable or invalid choice falls back to automatic instead of failing the
model load.
**Where.** `General › Transcription › GPU Device = CPU Only` _{Windows only}_.
**Since.** 0.42.0.
### Transcribe without tying up the CPU or GPU
**The situation.** A recent AMD Ryzen AI processor has an NPU — a low-power neural processing
unit — while compiling or rendering already needs the CPU and GPU.
**What Handy does.** FastFlowLM (FLM) can run Handy's Whisper transcription on that NPU, leaving
the CPU and GPU free for the work already using them. FLM is a separate, third-party program:
you install it yourself, and Handy does not bundle, install or download it. Handy auto-detects
`flm` on `PATH`, then `%LOCALAPPDATA%\flm\flm.exe`, `~/.flm/flm.exe`, and
`C:\Program Files\flm\flm.exe`, in that order; there is no path setting. Once detected, its
`whisper-v3:turbo` model appears with the other model choices. Handy starts FLM on
`127.0.0.1`, so transcription audio stays on the machine. If the language is `auto`, this
engine uses English. The engine path exists in the Windows and Linux code, but Handy releases
only Windows x64 today; Linux remains planned and in the queue.
**Where.** No path control — install FLM in one of the auto-detected locations, then open
`Models › Downloaded Models` and select **FLM Whisper V3 Turbo (NPU)**.
**Since.** 0.8.2.
### Windows blocked FLM — know which choices are real
**The situation.** Windows says it "can't verify" `flm.exe`, calls it an "unknown publisher",
says it was "blocked", or Handy reports OS error 4551. The Code Integrity log may record event
3077 or 3033 and say that `flm.exe` did not meet the signing requirements.
**What Handy does.** FastFlowLM currently ships an unsigned `flm.exe`, and enforced Windows
Smart App Control can refuse to let Handy start it. This is **not an antivirus detection**:
Microsoft Defender antivirus reports zero threat detections, and adding an antivirus exclusion
does nothing. Smart App Control is a separate mechanism with no exclusion list, so one program
cannot be allowed through it.
The low-cost choice is to use any other Handy transcription engine; FLM is an optional
accelerator, not a requirement. You can also wait for FastFlowLM to publish a signed binary,
which is outside Handy's control. The remaining choice is to turn Smart App Control off, but
that is one-way: it cannot be switched back on without resetting or reinstalling Windows. Weigh
that cost before changing it. Smart App Control blocks unsigned binaries generally, so an
enforced machine may reject other unsigned developer tools too.
**Where.** `Windows Security › App & browser control › Smart App Control settings` _{Windows only}_.
**Since.** 1.0.0.
### Orphaned NPU servers can't block your next take
**The situation.** After a crash — or after the installer force-closed the app — the NPU engine
fails to start, forever. Each restart leaves another stuck process behind, eating memory.
**What Handy does.** The NPU serves one application at a time, and a leaked server keeps both
the port and the accelerator. Handy binds its child process to a Windows job object so the
operating system kills it the instant Handy dies, and sweeps for its **own** orphans at launch
and before every start. The sweep is signature-exact: another application's server is never
touched.
**Where.** No control — this is always active. _{Windows only}_
**Since.** 0.53.0.
### The NPU error tells you what to close
**The situation.** You get a hexadecimal error code and a suggestion to update your driver,
which is not the problem.
**What Handy does.** When the NPU cannot create an inference context, the message names the
actual cause first — the accelerator serves one application at a time and something else is
holding it — and tells you to close that and reselect the model. Driver advice comes second.
**Where.** No control — this is always active.
**Since.** 0.47.0.
### The NPU engine starts in the mode FLM now requires
**The situation.** You update FLM and the engine stops working with "unsupported model family".
**What Handy does.** Recent FLM versions refuse a speech model as a positional argument and have
dropped their health endpoint, so Handy starts
`flm serve --port 52625 --host 127.0.0.1 --asr 1` and polls `GET /v1/models` for readiness.
Transcription uses `POST /v1/audio/transcriptions` with model `whisper-v3:turbo`. A failed start
sets a 60-second cooldown so a broken installation cannot keep blocking your takes.
**Where.** No control — this is always active.
**Since.** 0.38.0.
### Cancel a stuck download and it stops now
**The situation.** A model download stalls, you cancel it, and the interface says canceled while
the machine keeps the connection and the file handle open — sometimes for a full minute.
**What Handy does.** Cancellation interrupts a parked read immediately and **keeps the partial
file so you can resume**. The whole download lifecycle is tied to one attempt identity, so a
canceled or superseded attempt can never clobber a retry's progress or overwrite the model you
have since selected.
**Where.** `Models › Available to Download`.
**Since.** 0.44.0.
### A downloaded model shows as downloaded
**The situation.** The download completes and the card still offers to download it.
**What Handy does.** Each model carries a refresh revision so a stale snapshot of the disk cannot
overwrite a newer state, and the cleanup of leftover extractions runs only at startup, where it
cannot delete an extraction that is in flight.
**Where.** `Models › Downloaded Models`.
**Since.** 0.45.0.
### Bring your own Whisper model
**The situation.** You have a fine-tuned or community Whisper model that is not in the list.
**What Handy does.** Any Whisper GGML `.bin` file dropped into the models folder is discovered on
the next start and appears as a custom model, selectable like any other.
**Where.** `File › %APPDATA%\pr.handy\models`.
**Since.** Present since the fork's early releases.
### Free the memory when you stop dictating
**The situation.** A large model holds a lot of RAM or VRAM, and you dictate in bursts with an
hour in between.
**What Handy does.** An idle timeout evicts the model — never, immediately after each use, after
a set number of minutes, or a custom interval. Keeping it loaded gives the fastest start; letting
it go returns the memory to whatever you are actually working on.
**Where.** `Models › Unload Model = After 15 minutes`.
**Since.** Present since the fork's early releases.
### Why can't I force the language on this model?
**The situation.** The language dropdown has vanished and you cannot tell whether that is a bug.
**What Handy does.** Models that are multilingual but detect the language themselves say so
explicitly, with a read-only "auto-detected" value, and point you at the engines that do let you
pin a language. Likewise, a model that was never trained to translate no longer offers a
translate switch.
**Where.** `General › Language`.
**Since.** 0.10.0.
---
## Keyboard Typer
For the places a paste will never work.
### When paste is blocked, type it instead
**The situation.** The VM console ignores Ctrl+V. Clipboard redirection is switched off on the
remote session. The password prompt must never see a clipboard at all.
**What Handy does.** A page where you put text and a shortcut that types it into whatever window
has focus, as individual simulated keystrokes. No clipboard is involved at any point.
**Where.** `More Tools › Keyboard Typer › Enter the text to type...` then
`More Tools › Keyboard Typer › Type Text Shortcut` — `ctrl+shift+f11` by default.
**Since.** 0.12.0.
### The text never touches your disk
**The situation.** You are about to type a password into a locked-down console, and you would
like to know exactly where that string ends up.
**What Handy does.** The Keyboard Typer's text lives in memory only. It is deliberately not part
of the settings file, is not written to History, and the module does not log its content. Honest
limit: the value is not wiped after use and remains in process memory until it is replaced or
the app exits, and what the destination application does with it is outside Handy's control.
**Where.** No control — this is always active.
**Since.** 0.12.0.
### Slow enough for a remote console
**The situation.** Injecting text at full speed into an RDP session or a VM console drops
characters, so half the string arrives.
**What Handy does.** A per-keystroke delay, 15 ms by default — fast enough to feel instant,
slow enough to be reliable over a remote link — with quick presets for slower targets.
**Where.** `More Tools › Keyboard Typer › Key delay`.
**Since.** 0.12.0.
### Ten seconds to put the cursor where it belongs
**The situation.** You press Go and then have to click into a console that takes a moment to
focus.
**What Handy does.** A countdown before typing starts, ten seconds by default with one, three and
five second presets. Escape cancels, as does pressing the typing shortcut again, and an in-flight
session is canceled cleanly rather than half-typed.
**Where.** `More Tools › Keyboard Typer › Start delay` and `More Tools › Keyboard Typer › Cancel`.
**Since.** 0.12.0.
### Your trigger chord doesn't become part of the text
**The situation.** You trigger typing with a chord and the first characters arrive as hotkeys
because you were still holding Ctrl.
**What Handy does.** Waits out a modifier-release grace before the first keystroke, and reports
its state — counting down, typing, done, canceled — so you are never guessing whether it is
running.
**Where.** No control — this is always active.
**Since.** 0.12.0.
---
## Model Testing
A second, smaller product inside the first: run one prompt across the models you actually pay
for and see what happens.
### Which model is actually better at my task?
**The situation.** A new model ships and everybody has an opinion. None of those opinions were
formed on your work.
**What Handy does.** Runs one prompt across any set of your registered providers and puts the
answers side by side, with tokens, cost, and wall-clock round-trip for each. Concurrency respects
provider families, so local slots sharing one loader take turns while cloud models run at once,
and the reported time is to the last finisher rather than the sum.
**Where.** `More Tools › Model Testing › Prompt for all models` then `More Tools › Model Testing › Run test`.
**Since.** 0.15.0.
### Let a panel score the answers
**The situation.** Six answers, and reading them all carefully takes longer than the work you
were trying to automate.
**What Handy does.** An optional judge panel: chosen models receive your arbiter prompt, the
original input and every candidate answer, and return their assessments. Judges are picked
independently of the models being tested, and they get their own temperature and thinking
settings, both recorded in the report.
**Where.** `More Tools › Model Testing › Judge / arbiter prompt (optional)`.
**Since.** 0.15.0; separate judge parameters in 0.20.0.
### Local models can judge too
**The situation.** Your local judge returns nonsense while a cloud judge on the same input is
fine, which reads as "small models are useless as judges".
**What Handy does.** The arbiter instructions used to live in the system message, which small
local models down-weight — so they genuinely did not see the answers they were meant to score.
Instructions and all numbered answers now go in a single user message, and local judges work.
**Where.** No control — this is always active.
**Since.** 0.17.0.
### Stop retyping the same test prompts
**The situation.** You have a standard evaluation you run against every new model, and you
retype it from memory each time.
**What Handy does.** A library of saved model prompts and judge prompts, plus presets that pair
one of each under a name. Selecting a preset fills both pickers with the prompts it is made of,
so you can see and adjust each half rather than getting an opaque bundle. Saved prompts keep
their attached image.
**Where.** `More Tools › Model Testing › Preset`.
**Since.** 0.17.0; visible preset parts in 0.19.0.
### Test vision models with a real image
**The situation.** The task you care about is "read this screenshot", and a text prompt tells you
nothing about it.
**What Handy does.** Attach an image by button or drag and drop, and send prompt plus image,
prompt only, or image only. Each provider receives it in its own native multimodal shape. An
image that cannot be read fails loudly instead of quietly sending a text-only request.
**Where.** `More Tools › Model Testing › Image (optional, for vision models)`.
**Since.** 0.18.0.
### Thinking on or off, per model
**The situation.** You want to compare like with like, and half the models default to extended
reasoning while the other half do not.
**What Handy does.** Automatic, on, or off, for the tested models and for the judges separately —
translated into each vendor's own parameter, including the modern adaptive form for current
models rather than a deprecated shape that returns an error.
**Where.** `More Tools › Model Testing › Thinking = Off`.
**Since.** 0.18.0.
### See what's happening between dispatch and verdict
**The situation.** You start a run against eight providers and stare at a spinner with no idea
which one is holding things up.
**What Handy does.** A live activity feed logs each model and judge as it finishes, with a
success or failure mark and its timing, plus markers for each phase of the run.
**Where.** `More Tools › Model Testing › Run test`.
**Since.** 0.17.0.
### One Markdown artifact you can keep
**The situation.** The comparison is only useful if you can put it in a ticket, a commit message
or a decision log.
**What Handy does.** Every run produces one Markdown document — input, a summary table with
tokens, cost and time, the judge panel, then each model's full answer. Copy it, or save it with
a sensible default filename and re-save to the same path with one click afterwards.
**Where.** `More Tools › Model Testing › Copy Markdown` and `More Tools › Model Testing › Save as…`.
**Since.** 0.15.0; save-as in 0.18.0.
### Unconfigured seats stay out of the run
**The situation.** Your provider list has spare slots you have not filled in, and they show up in
every run list to be unticked again.
**What Handy does.** Only enabled, configured providers appear in the run and judge lists, and
the scheduler skips the rest.
**Where.** `Advanced settings › LLM providers › Registered LLM Providers › Enable this provider`.
**Since.** 0.17.0.
---
## Token Count
### What will this prompt cost?
**The situation.** You are about to paste 40 KB of context into a model and would like to know
what that means before you do it.
**What Handy does.** Paste or load text and count it with a tokenizer, or against a real
provider's own counting endpoint. Chips across the top cover the built-in tokenizers and every
configured provider; click one to count with it.
**Where.** `More Tools › Token Count › Paste text here to count tokens...`.
**Since.** 0.12.0.
### Token counts you can trust from a local server
**The situation.** You count one word against a local server and it reports 18 to 25 tokens.
**What Handy does.** Chat endpoints report tokens including the server's own chat-template
wrapping — measured at plus seventeen on one popular local server and plus thirteen on another.
Counting now uses the raw completions endpoint and calibrates that fixed overhead away with a
known one-token probe, which is exact against both servers, with a fallback for endpoints that
have no completions route.
**Where.** `More Tools › Token Count › Count with all`.
**Since.** 0.13.0.
### Counts without a network call
**The situation.** You are offline, or you do not want the text you are counting to leave the
machine at all.
**What Handy does.** Three built-in counters run entirely locally — two exact tokenizers and a
rough estimate — and they are the first rows of every comparison. The estimate is excluded from
the difference baseline so it cannot skew a comparison between exact tokenizers.
**Where.** `More Tools › Token Count › cl100k (GPT-4)` and `More Tools › Token Count › o200k (GPT-4o)`.
**Since.** 0.12.0 and 0.13.0.
### One click, every provider, one table
**The situation.** The same text tokenizes differently on every vendor, and you want the spread.
**What Handy does.** Counts with every enabled provider and renders provider, model, token count,
difference against the smallest, and time — rows appearing as they finish. Two modes: serialized,
which is correct when several slots share one local service, and parallel, which takes as long
as the slowest provider instead of the sum.
**Where.** `More Tools › Token Count › Count with all (parallel)`.
**Since.** 0.12.0; parallel mode in 0.13.1.
### Count a file instead of pasting it
**The situation.** The thing you want to count is a 3 MB transcript, and pasting it into a text
box is not a good plan.
**What Handy does.** Opens a text file up to 10 MB and counts it directly.
**Where.** `More Tools › Token Count › Open file...`.
**Since.** 0.12.0.
---
## Files
Pick a recording, or drop a folder of them, and get text back while you get on with something else.
### One file, transcribed as accurately as the model can
**The situation.** You have a voice note from your phone, an interview or a lecture, and you want
its text without playing it into the microphone.
**What Handy does.** Reads WAV, MP3, M4A, AAC, FLAC and Ogg Opus (`.ogg`, `.opus`) files, and
the audio track of an MP4 video; Ogg Vorbis is not supported. It cuts the audio at its pauses into
pieces of up to about forty seconds and transcribes each piece once with the model
you pick for files (your dictation model to start with; another one loads beside it, and one not
downloaded yet is downloaded first), so the text is final as it comes — no live preview, no second
pass. A progress bar follows the file's length. The text is shown to copy and kept in a list of
transcribed files; a pop-up asks whether to save it as a `.txt` in Handy's folder or next to the
recording, and can remember the answer. A copy of the audio can be kept too. The original file is
only ever read.
**Where.** `Files › Transcribe a file › Choose an audio file`.
**Since.** 2.0.0.
### A folder of recordings, transcribed while you sleep
**The situation.** You have interviews, voice memos or meeting captures piling up, and
transcribing them one at a time by hand is the whole afternoon.
**What Handy does.** Watches folders you choose and transcribes new audio files into a `.txt`
file next to the source, using your engines and your settings. It reads the same formats as a
file you pick, the audio track of an MP4 video included. It runs in the background while you
keep using the app normally.
**Where.** `Files › Watched folders › Watch folders = On` then `Files › Folders › Add a folder`.
**Since.** The 0.3x series.
### Your existing files are left alone
**The situation.** You point it at a folder with two thousand old recordings and it starts
grinding through all of them.
**What Handy does.** Only files that appear _after_ watching starts are queued. The existing
contents are snapshotted and deliberately ignored. Handy's own recorder-internal files — chunk
parts, temporary files, partial downloads — are never picked up.
**Where.** `Files › Folders`.
**Since.** The 0.3x series.
### A file is never transcribed twice
**The situation.** You restart the machine mid-batch and it starts again from the beginning.
**What Handy does.** The `.txt` sidecar is the record that a file is done, so it stays done across
restarts forever. The pending queue is persisted as well, so unfinished work resumes rather than
restarting. A file recreated under the same name is detected as new by its modification time.
**Where.** `Files › Watched folders › Status`.
**Since.** The 0.3x series.
### Never reads a file that is still being written
**The situation.** Your recorder is still writing a file and the watcher grabs it half-finished.
**What Handy does.** A file must be size-stable across scans before it is read at all.
**Where.** No control — this is always active.
**Since.** The 0.3x series.
### Live dictation always wins
**The situation.** You press your dictation key and nothing happens, because a batch job is
holding the engine.
**What Handy does.** Three policies decide who gets the engine. Live-first pauses the batch at
the next segment boundary as soon as a recording starts — the default, and the one that keeps
dictation feeling instant. Folder-first keeps the batch running and queues live segments behind
it, though the batch always yields while a take is finishing. First-come-first-served finishes
the current file's segments before the next job. Batch work is cut into roughly forty-second
segments so pausing never discards progress.
**Where.** `Files › Watched folders › Priority = Live dictation first`.
**Since.** The 0.3x series.
### Batch on one accelerator, dictation on another
**The situation.** You have an NPU and a GPU, and running batch work means your dictation model
is constantly being unloaded and reloaded.
**What Handy does.** The watched folders can use a different model from your dictation model and keep
it resident in parallel — dictation on the NPU while the batch grinds a Whisper model on the
integrated GPU. Shared hardware serializes gracefully rather than racing, and the batch model has
its own idle-unload setting so it can be released independently.
**Where.** `Files › Watched folders › Batch model` and `Files › Watched folders › Unload batch model after`.
**Since.** 0.48.0.
### You can see what it is working on
**The situation.** You want to know whether it is working, queued or finished, without opening a
log.
**What Handy does.** A status row that reads off, watching with nothing to do, a count of queued
files, or the current file and which segment of it is being transcribed.
**Where.** `Files › Watched folders › Status`.
**Since.** The 0.3x series.
---
## MCP and CLI
Let a script, a window manager or an agent drive the same logic the interface uses.
### Let an agent drive the app
**The situation.** Your coding agent could use Handy's token counter, your history or its model
comparison, and there is no way in.
**What Handy does.** An optional MCP server, off by default, bound to `127.0.0.1` only and
guarded by a bearer token. It speaks HTTP for the Claude app and stdio through a bridge for
Claude Code, and exposes Handy's own tools: token counting, typing text into the focused window,
listing and reading history, listing and setting providers, saving model-test prompts and
running a model test.
**Where.** `Advanced settings › MCP & CLI › Enable MCP & CLI server = On`.
**Since.** 0.20.0.
### A handy command on your PATH
**The situation.** You want the same capabilities from a shell script or a scheduled job, not
from an agent.
**What Handy does.** Installs a `handy` command that talks to the running app over the same
local server: model tests, token counts, typing, history listing, provider configuration, plus
the stdio bridge. It finds the running instance by itself through a small discovery file, so you
never pass a port or a token on the command line.
**Where.** `Advanced settings › MCP & CLI › Command-line companion`, then `CLI › handy install-cli`.
**Since.** 0.20.0.
### An agent can set a key but never read one
**The situation.** You are giving an autonomous process access to the app that holds your API
keys.
**What Handy does.** Provider API keys are write-only across MCP and the CLI: a caller can set a
key, change a model, family or enablement, but every response replaces the key with a flag saying
whether one exists. Honest limit: this is about the interface, not storage — keys remain in
plain text in the settings file and in backups.
**Where.** On by default when the server is enabled — nothing to configure.
**Since.** 0.20.0.
### Bound to localhost, behind a token — and what that does not cover
**The situation.** You want to know exactly what you are exposing before you switch a server on.
**What Handy does.** It binds to the loopback address only, never to a network interface, and
every call except a liveness check requires the exact bearer token. What it does _not_ do is
isolate Handy from other processes running as you: the token is stored in plain text in the
settings file and in a small discovery file, so any local process running as your user can read
it and then read your history, change provider URLs or run a model test. Traffic is plain HTTP
over loopback, not TLS. Leave the server off unless you want it.
**Where.** `Advanced settings › MCP & CLI › Token` and `Advanced settings › MCP & CLI › Port`.
**Since.** 0.20.0.
### Scriptable model tests that produce the same artifact as the interface
**The situation.** You want a nightly model comparison in a repository, and a script that
reimplements the report will drift from the app within a month.
**What Handy does.** The report assembly, judge-prompt construction and price handling used by
the command line and MCP are the same logic the interface uses, so a scripted run produces the
same document and the same cost figures. Models and judges are selected by identifier or name,
temperatures and thinking are separate for run and judge, an image can be attached, and the
report comes back inline or is written to a path you choose.
**Where.** `CLI › handy model-test`.
**Since.** 0.20.0.
### Drive it from your window manager or a hotkey daemon
**The situation.** Something else owns your hotkeys — an autostart script, a macro tool, a
window manager — and you want it to control recording.
**What Handy does.** Command-line flags toggle recording, toggle recording with post-processing,
or cancel on the already-running instance. A second launch forwards its arguments and
exits. Two more flags control how the app itself starts.
**Where.** `CLI › handy --toggle-transcription`, `CLI › handy --cancel`,
`CLI › handy --start-hidden`, `CLI › handy --no-tray`.
**Since.** Present since the fork's early releases.
### Your agent can read your history — know that before you enable it
**The situation.** The convenience of an agent reading back what you dictated is also a
disclosure.
**What Handy does.** The history tools return recent entries as short snippets, and a full entry
including the filesystem path of its audio — a path, not the audio itself. The typing tool goes
through the ordinary clipboard paste path, so its text can appear on the clipboard and in debug
logs. This is stated so you can decide, not buried.
**Where.** `CLI › handy history-list`.
**Since.** 0.20.0.
---
## Backup and portability
### One file that carries your whole setup
**The situation.** New machine on Monday, and rebuilding eleven shortcuts, six providers and a
prompt library by hand is an afternoon you do not have.
**What Handy does.** Exports a single `.tar.gz`. The configuration profile carries settings and
the history database — timestamps, text, cost, duration. The full profile adds your compressed
recordings.
**Where.** `Advanced settings › Backup › Configuration + history › Export config + history` and
`Advanced settings › Backup › Full data (with compressed audio) › Export full backup`.
**Since.** 0.22.0.
### Move machines, or undo a bad week
**The situation.** You want your settings back but not the recordings, or the recordings back
but not a settings file from three weeks ago.
**What Handy does.** Restore picks an archive and lets you choose what comes back —
configuration and history, recordings, or both — and reports per-item errors instead of failing
the whole operation on one bad entry.
**Where.** `Advanced settings › Backup › Restore from backup › Configuration & history (settings, history DB)` and
`Advanced settings › Backup › Restore from backup › Restore from backup…`.
**Since.** 0.25.0.
### A crafted archive can't write outside the app
**The situation.** An archive is an executable format if you treat it carelessly — a path like
`../../Startup/evil.exe` inside a tarball is the classic attack.
**What Handy does.** Restore extracts only entries whose names are on a known list, accepts only
regular files, refuses any path traversal, and caps decompressed size.
**Where.** No control — this is always active.
**Since.** 0.25.0.
### Why a restore asks for a restart
**The situation.** You restore your settings, and the running app overwrites them again on its
next write.
**What Handy does.** The running app holds settings in memory, so a settings or history restore
is followed by an explicit restart button rather than a silent inconsistency.
**Where.** `Advanced settings › Backup › Restore from backup › Restore from backup…`.
**Since.** 0.25.0.
### What a backup deliberately leaves out
**The situation.** You assume a "full" backup means everything, and find out otherwise at the
worst moment.
**What Handy does.** Downloaded models are always excluded — they are large and re-downloadable.
Even a full backup excludes uncompressed WAV and FLAC audio and in-progress temporary chunks, so
recordings made with crash-safe recording switched off are **not** in the archive, although their
history rows are. And the honest one: a settings backup contains your API keys and the server
token in plain text, so treat the file as a secret.
**Where.** `Advanced settings › Backup › Full data (with compressed audio) › Export full backup`.
**Since.** 0.22.0.
### Run it from a USB stick and leave no trace
**The situation.** A locked-down corporate desktop, a shared lab machine, or you do not
want an application writing into your profile.
**What Handy does.** Put a marker file next to the executable and everything — settings, models,
history, recordings, logs, web-view data — lives in a folder beside it, with no machine-level
change: no autostart entry, no command-line installation. If that folder cannot be written it
falls back to the normal per-user location rather than failing.
**Where.** `File › portable.marker` beside `handy.exe` _{Windows only}_.
**Since.** 0.43.0.
---
## Audio and feedback
### It records what you say, not the silence
**The situation.** Long pauses while you think should not become long pauses in the file or work
for the transcription engine.
**What Handy does.** A voice-activity model runs locally on the incoming audio and only speech is
kept, with a debounce so a short breath does not chop the recording. The same silence boundaries
are what makes it safe to cut transcription segments without splitting a word. Honest scope: the
smoothing keeps a little surrounding silence, so this is not an exact speech-only cut.
**Where.** No control — this is always active.
**Since.** 0.1.0; hysteresis in 0.3.0.
### Nothing is dropped at the moment you stop
**The situation.** You stop mid-breath and the last fragment of speech is missing, or a
microphone that died mid-recording means the stop never completes at all.
**What Handy does.** Voiced frames buffered during an unconfirmed speech onset are flushed into
both the recording and the final segment at stop rather than discarded. Separately, stop and
cancel are serviced on a timer rather than only when audio arrives, so a stream that died cannot
hang the stop.
**Where.** No control — this is always active.
**Since.** 0.25.0.
### Hear when the microphone is hot
**The situation.** You start talking before the recorder started, or keep talking after it
stopped, because you were looking at something else.
**What Handy does.** Distinct start and stop cue sounds, so you never have to look at the screen
to know the state. Volume, output device and the sound set are all configurable, including
supplying your own two files.
**Where.** `General › Sound › Audio Feedback = On`, `General › Sound › Volume`, and
`Advanced settings › Debug › Sound Theme = Custom` _{requires: Debug mode}_.
**Since.** 0.1.5.
### The microphone light is off when you're not dictating
**The situation.** A dictation tool that holds the microphone open shows a permanent recording
indicator, which is both a privacy question and a distraction.
**What Handy does.** The microphone is opened when a take starts and released when it ends.
A microphone that has been idle for a while can take most of a second to wake up; until it
delivers audio the overlay reads **Starting mic...** instead of showing the sound bars, so you
know when to start speaking. Some microphones then fade in — a Realtek input starts 15-20 dB
quiet — and words spoken into that were dropped as noise, so after such a cold start the
overlay keeps reading **Starting mic...** until the microphone has warmed up. The wait is
measured on the microphone's own recent cold starts, and it can be switched off. And if you
speak too quietly for your words to be kept, **Too quiet — speak up** appears for a moment in a
small box just under the overlay (or, if you prefer — and always on macOS and on Linux under
Wayland, where that box is not created — in the overlay instead of the sound bars). When a take cannot start, the overlay says why for a moment
instead of vanishing: **No microphone** when none is connected, **Microphone blocked** when
Windows privacy settings deny apps the microphone, and **Microphone error** when the device
refuses to start. Optionally you can keep the microphone
open — which removes the wake-up wait — at the cost of a permanently active indicator. That is
an explicit choice, not the default. A middle way keeps it open only for 1, 5 or 15 minutes
after each take, so a burst of takes starts instantly and the indicator goes out afterwards.
**Where.** `General › Sound › Keep microphone ready`,
`General › Sound › Wait for the microphone to warm up`,
`General › Sound › Warn when you speak too quietly` and
`Advanced settings › Debug › Always-On Microphone = On` _{requires: Debug mode}_.
**Since.** 0.2.0. Keep microphone ready since 1.9.0; the warm-up wait and the too-quiet
warning since 2.0.0.
### Change microphone without restarting
**The situation.** You plug in a headset and the app is still recording from the laptop's array.
**What Handy does.** The input device is a dropdown that takes effect on the next take, with a
reset to the system default.
**Where.** `General › Sound › Microphone`.
**Since.** 0.3.0.
### Your music doesn't end up in the transcript
**The situation.** You dictate over speakers and the engine faithfully transcribes the podcast
you were half-listening to.
**What Handy does.** Optionally mutes system output for the duration of the recording.
**Where.** `General › Sound › Mute While Recording = On`.
**Since.** Present since the fork's early releases.
### See that it is listening
**The situation.** You are not sure whether the recorder is running, and the only way to find out
used to be to talk and hope.
**What Handy does.** A small overlay shows live audio levels while recording, at the top or the
bottom of the screen, or not at all. The tray icon carries the same state — idle, recording,
transcribing — in light, dark and color variants so it stays legible on any theme.
**Where.** `General › App › Overlay Position = Bottom`.
**Since.** Present since the fork's early releases.
### Canceling can't freeze the app
**The situation.** You press Escape at exactly the wrong instant and the whole application hangs
with the overlay stuck mid-frame, requiring a force-restart.
**What Handy does.** The overlay's level updater used to make a synchronous window query from the
audio thread; cancelling at that moment deadlocked it against the main thread tearing down the
microphone. The updater now uses a lock-free visibility flag and never blocks on the interface
thread, and cancellation commits its state before any device teardown.
**Where.** No control — this is always active.
**Since.** 0.52.1.
### The idle-unload timer keeps working all session
**The situation.** You set the model to unload after ten minutes and it never does — after the
very first recording of the session.
**What Handy does.** A transient copy of the transcription manager used to tear down the shared
idle watcher when it went out of scope. Ownership is now tracked, so only the real owner stops
the watcher, at shutdown.
**Where.** `Models › Unload Model`.
**Since.** 0.52.2.
---
## Platform and privacy
### What runs today, and what is planned
**The situation.** You are on a Mac or a Linux box and want a straight answer.
**What Handy does.** Windows x64 is built, released and tested. macOS (Intel and Apple Silicon)
and Linux (x64 and ARM64: deb, rpm, AppImage) are built by CI and attached to every release since
1.6.2, but have not been tested on real hardware, so treat them as experimental and do not assume
this documentation describes their behaviour. Some features do not follow at all: the whole Jumper
family is built on Win32 focus APIs, system-audio capture uses WASAPI loopback, and portable mode is
Windows-only. In the
other direction, some code exists only for platforms that do not ship yet — on-device Apple
Intelligence post-processing and closed-lid microphone switching on macOS, and the native text
injection backends on Linux — and none of it is reachable today.
**Where.** `About › Version`.
**Since.** 1.0.0 is the first public release.
### The app makes no calls you didn't ask for
**The situation.** "Local-first" is claimed by everything, and you would like to know what it
means here.
**What Handy does.** There is no telemetry, no analytics, no crash reporter and no account. Every
outbound request that carries your content is one you configured and triggered: a model download
you start, a transcription to an endpoint you entered, a post-processing call, a model test, a
token count against a provider. With a local model selected, ordinary dictation initiates no
network activity at all. The one request Handy makes on its own is the daily update check
described in [Updates you decide to take](#updates-you-decide-to-take), which carries no audio,
transcript, prompt, history entry, setting or key — and which you can turn off.
**Where.** No control — this is always active.
**Since.** 0.12.0.
### Updates you decide to take
**The situation.** You want the fixes, and you do not want an application restarting itself in
the middle of your working day or phoning home without saying so.
**What Handy does.** Once a day Handy asks the public GitHub releases page whether a newer
version exists. That check is **on** by default and sends nothing but the ordinary metadata of an
HTTPS request and the version you are running. Installing is a separate decision: silent
installation is **off** by default, so by default a newer version is announced in the sidebar and
waits for you. Switch silent installation on and the update is applied inside a window you choose
— 04:00 local time by default, moved by up to 30 minutes each day so every copy does not call at
the same instant. Releases are signed and the signature is verified before anything is applied. A
portable copy refuses to update itself in place and tells you to download the new portable
release instead. `Check now` runs the same check on demand, and so does `Update now` in the
panel that opens from the version at the bottom-left of the sidebar. The icon next to that
version shows the status: a green check when you are up to date, a cyan arrow when an update is
available, a grey arrow when there is no recent result (since 2.1.1; 2.1.0 showed
only the arrow, and only with an update available). An update
installed in the background
waits, up to a minute, until the running Handy's program file is no longer in use before the
installer's own check (before 2.0.2 silent updates made while a speech model was loaded gave up,
most likely because Handy was still closing), and the installer writes the outcome to
`installer.log` in the log folder.
**Where.** `General › Updates › Check for updates automatically`,
`General › Updates › Install updates silently`, `General › Updates › Silent update time`,
`General › Updates › Daily randomization`, and `General › Updates › Check now`.
**Since.** 1.0.0.
### Where your data lives on disk
**The situation.** Before you trust an application with everything you say, you want to know what
it keeps and where.
**What Handy does.** Everything is under one folder: settings including your API keys and prompts
in a JSON file, transcripts in a SQLite database, audio in a recordings folder, downloaded models
and rotated logs. Nothing is encrypted by Handy — file-system permissions are the protection —
and there is a button in the app for both the data folder and the log folder.
**Where.** `About › App Data Directory` and `About › Log Directory`.
**Since.** Present since the fork's early releases.
### Your dictation is not written into logs at the normal level
**The situation.** Diagnostics are useless if they are empty and dangerous if they contain
everything you ever said.
**What Handy does.** Transcript previews were moved off the informational log level, and the
released build writes its file log at **info**, so ordinary logging does not record what you
dictated. The honest counterpart: raise the level to `Debug` yourself and transcript fragments,
complete API responses and prompt previews **can** appear in the log file. Put it back to `Info`
when you are finished diagnosing.
**Where.** `Advanced settings › Debug › Log Level = Info` _{requires: Debug mode}_.
**Since.** 0.38.0.
### The logs still exist when you finally need them
**The situation.** Something goes wrong, you go looking for the evidence, and the launch that
followed the problem has already rotated it away.
**What Handy does.** Logs rotate at 10 MB instead of 500 KB and rotated files are kept rather
than being overwritten by the next session. Engine start failures are written to the log at error
level rather than existing only as a toast you already dismissed.
**Where.** `About › Log Directory`.
**Since.** 0.53.0.
### The honest limits of clipboard safety
**The situation.** You want the real worst case, not the reassuring version.
**What Handy does.** Handy saves and restores clipboard **text** only, so an image, a copied file
or rich formatting on the clipboard is lost when a paste restores an empty or plain-text value.
During a clipboard-based paste the transcript is globally readable for roughly 100–300 ms by
anything that watches the clipboard, including Windows clipboard history and remote-session
clipboard redirection. `Don't Modify Clipboard` controls the final state, not that exposure;
only `Direct` avoids the clipboard entirely. If the app is killed between the paste and restore,
the transcript stays there. Handy leaves a newer user copy alone, retries failed restores, and
then warns in the log. A failed delivery writes the transcript only when its clipboard policy
permits it; otherwise the clipboard stays untouched and History plus Paste Last Transcription
provide recovery.
**Where.** `Transcription › Transcribe › Clipboard Handling`.
**Since.** Documented behavior of the current release; ownership checks, restore retries and
history-only failure recovery since 1.0.5.
### The tray tells you what it is doing
**The situation.** The window is closed, you pressed the key, and you want to know whether
anything is happening.
**What Handy does.** The tray icon changes between idle, recording and transcribing, in variants
that stay readable on light, dark and colored taskbars, with a tooltip. Clicking the icon opens
the window; right-clicking it opens the menu, which opens settings, copies the last transcript,
unloads the model, cancels a take and quits (on macOS the menu opens on a plain click, as
menu-bar items do there). Its labels are generated
at build time from the same translation files the interface uses, so they cannot drift out of
sync.
**Where.** `Tray › Copy Last Transcript` and `General › App › Show Tray Icon = On`.
**Since.** Present since the fork's early releases.
### Starts with your session and stays out of the way
**The situation.** A dictation tool is only useful if it is already running when the thought
arrives, and only tolerable if it is not in your face.
**What Handy does.** Optional launch at login, optional start with no window, and an optional
tray-only existence. Note one consequence: with the tray icon switched off, closing the window
quits the application. The one launch that always shows the window is the one right after you
run setup yourself, so you can look at what changed; silent automatic updates stay hidden.
**Where.** `General › App › Launch on Startup = On` and `General › App › Start Hidden = On`.
**Since.** 0.1.0.
### Light, dark, or follow the system
**The situation.** Half the application follows your system theme and the other half is
permanently bright at midnight.
**What Handy does.** One appearance setting applied consistently across the main window, the
recording overlay and the floating transcription window, following the system by default and
tracking it live.
**Where.** `General › App › Appearance = Dark`.
**Since.** 0.41.0.
### It looks and behaves like a Windows app
**The situation.** Web-technology desktop applications tend to feel like a web page in a frame —
wrong font, wrong scrollbars, native widgets stuck in light mode.
**What Handy does.** The system font stack, styled scrollbars, native widgets that follow dark
mode, a maximisable window that respects snap layouts, and a sidebar you can drag to fit long
provider names, remembered between launches.
**Where.** `General › App › Appearance`.
**Since.** 0.24.0; resizable sidebar in 0.17.0.
### Usable with the keyboard, and readable
**The situation.** You navigate by keyboard, or you need real contrast, or animations make you
ill.
**What Handy does.** A visible focus outline on every control, the overlay's controls as real
labeled buttons for screen readers, primary buttons and secondary text deepened to meet contrast
requirements, danger buttons themed rather than raw red, and reduced-motion preferences honored
everywhere including the pulsing recording animation.
**Where.** No control — this is always active.
**Since.** 0.24.0.
### No console window flashing on your desktop
**The situation.** Every couple of minutes a black command window appears somewhere on your
screen and vanishes. It looks like malware and it steals focus.
**What Handy does.** Detection of the optional NPU runtime was running a command-line probe on
every model-list rebuild, which on Windows spawns a visible console. Those subprocesses now run
hidden, and detection is cached to once per session.
**Where.** No control — this is always active. _{Windows only}_
**Since.** 0.24.0.
### The installer tells you what's missing, and the build runs on your CPU
**The situation.** An installer that succeeds and an application that then fails to start is the
worst combination.
**What Handy does.** The Windows installer detects missing web-view and Visual C++ runtime
prerequisites and guides you, without blocking the installation. Separately, Windows builds
target a broad CPU baseline so they run on hardware that a natively-tuned build would crash on.
Note that the installer is not code-signed, so Windows will show a SmartScreen warning on first
run.
**Where.** No control — this is always active. _{Windows only}_
**Since.** 0.40.0.
### A hotkey another app already owns
**The situation.** You set a shortcut, nothing happens, and there is no explanation — some other
tool claimed it first.
**What Handy does.** Registration failures are recorded and surfaced when the app starts rather
than failing quietly. If the operating system's shortcut interface is the problem rather than the
combination, an alternative key backend can be selected.
**Where.** `General › App › Keyboard Implementation = Handy Keys`.
**Since.** 0.30.0.
### Use it in your language
**The situation.** An English-only interface is a daily friction if English is not your language.
**What Handy does.** Seventeen interface languages with right-to-left support. Tray menu strings
are generated at build time from the same translation files as the interface, so they cannot fall
out of step.
**Where.** `About › Application Language`.
**Since.** Present since the fork's early releases.
### Diagnose without guessing
**The situation.** Something is wrong and the only information you have is that it did not work.
**What Handy does.** A debug mode unlocks a page with the log level, direct links to the log and
data folders, the fuzzy-correction threshold, the paste timing knob, the always-on microphone
switch and the cancel shortcut. A command-line flag turns on verbose file logging without
touching anything else.
**Where.** Press `ctrl+shift+d` to reveal the `Debug` page; `CLI › handy --debug`.
**Since.** Present since the fork's early releases.
### Not a black box on first launch
**The situation.** A fresh install with no model does nothing when you press the key, and nothing
tells you why.
**What Handy does.** A short setup guide on the first start (every step skippable, or all of
it): pick the languages you speak (several at once), then choose one of three speech models
suggested for them — the most accurate, a balanced one (selected to start with: Parakeet V3 whenever it understands
your languages) and the
fastest, or look through all of them — and "Download and continue" fetches it while you finish; see the basic shortcuts with their defaults and keep
or change them; pick the microphone; then try it — press the shortcut, say a sentence, and
the words appear in the setup. Its last screen offers the other setups (the look, post-processing,
the Jumper) without pressing them on you: the defaults already work. On macOS, microphone permission comes first. An unconfigured remote engine no longer counts as
"a usable model exists", so a clean install cannot skip the download step and leave you with
nothing.
**Where.** Shown automatically on first launch; again from `Setups › Basic setup`.
**Since.** 0.1.6; the empty-install fix in 0.43.0; the setup guide in 2.0.0.
---
## Conventions used in this file
Anchors are permanent. An entry's heading may be reworded, but the `id` under it never changes
and is never reused, so a link written today keeps working. Retired features keep their entry
with a note rather than disappearing.
Every other page links here with link text equal to the entry heading, character for character.
If you are editing the documentation and find yourself explaining what a feature does anywhere
except this file, that is the bug.