Dictate or type a rough message, pick a tone, get a polished rewrite on your clipboard.
A tiny Spotlight-style overlay for Wayland that rewrites your text in a chosen
tone — professional, kind, concise… — using Claude Code
(claude -p), then copies the result. Built for a voice-dictation workflow on
Arch + Sway.
One hotkey: the box opens and dictation auto-starts; speak, pick a tone, paste the rewrite.
You dictate a quick, messy message with your voice — "yo can we push the call to 3pm, thx" —
and want a clean version to paste into Slack / email / wherever, in the right tone,
without leaving the keyboard. friendly is the glue: a centered text box you dictate
into, a tone picker, and the rewrite lands in your clipboard. The thinking is done by
Claude Code; friendly just handles the UI and the clipboard.
hotkey ──▶ ┌──────────────────────────┐
│ centered text area │ GTK layer-shell overlay (friendly-input.py),
│ (dictate / type) │ focus ready — your dictation tool types in it
└────────────┬─────────────┘
│ Enter
┌──────────────────────────┐
│ tone menu (wofi) │ Professional · Kind · Concise · … · ✏️ Custom
└────────────┬─────────────┘
│
claude -p ──▶ rewritten text ──▶ 📋 clipboard + 🔔 notification
- Input — a multiline text area rendered as a centered
wlr-layer-shelloverlay (so it's never tiled by your compositor).Entersubmits,Shift+Enteradds a newline,Esccancels. - Tone — a
wofiSpotlight bar lists presets plus a free-form Custom… option. - Rewrite — the message + tone are sent to
claude -p(Claude Code's non-interactive mode). It uses your existing Claude Code login — no API key to manage. The model is told to return only the rewritten text. - Output — the result is copied with
wl-copyand shown in a notification.
Note
The rewrite runs in the cloud: your text is sent to Anthropic over HTTPS for the duration of the request. Keep that in mind for sensitive content. No network → no rewrite (the model is remote).
# stable
paru -S friendly # or: yay -S friendly
# or bleeding-edge (builds from git HEAD)
paru -S friendly-gitYou also need Claude Code logged in (claude):
paru -S claude-code # or: npm i -g @anthropic-ai/claude-code
claude # run once to authenticateGrab the .deb from the latest release:
sudo apt install ./friendly_*_all.deb
# Claude Code is not in Debian/Ubuntu — install it separately:
npm install -g @anthropic-ai/claude-code && claudeBuild it yourself from a checkout: cp -r packaging/debian debian && dpkg-buildpackage -b -us -uc.
Drop packaging/exherbo/friendly.exheres-0 into a repository
you own, then cave resolve -x friendly. See
packaging/exherbo/README.md (verify the dependency
atoms — gtk-layer-shell/wofi may need a personal repo).
git clone https://github.com/KannarFr/friendly
cd friendly
mkdir -p ~/.local/bin ~/.local/share/friendly ~/.local/share/icons/hicolor/scalable/apps ~/.local/share/applications
ln -sf "$PWD/friendly" ~/.local/bin/friendly
cp friendly-input.py spotlight.css friendly.svg ~/.local/share/friendly/
cp friendly.svg ~/.local/share/icons/hicolor/scalable/apps/friendly.svg
ln -sf "$PWD/friendly.desktop" ~/.local/share/applications/friendly.desktopThe script finds its resources next to itself or in ~/.local/share/friendly,
/usr/share/friendly, etc., so both layouts work.
Not supported. The UI is Wayland-only — the centered overlay needs
wlr-layer-shell (via gtk-layer-shell), the menu uses wofi, and the clipboard
uses wl-copy. Only claude -p is cross-platform. A macOS port would mean
replacing the UI layer (e.g. a native SwiftUI panel or Hammerspoon/Raycast) and
using pbcopy; the rewrite logic and prompt would carry over unchanged. Not
planned — open an issue if you want to drive it.
Sway — use an absolute path (Sway's PATH may not include ~/.local/bin):
bindsym $mod+y exec /usr/bin/friendly
Hyprland (hyprland.conf):
bind = $mainMod, Y, exec, friendly
GNOME — Settings → Keyboard → Custom Shortcuts → command friendly.
friendly doesn't transcribe — it takes whatever you type into its text area. Pair it
with any tool that types into the focused window, e.g.
Handy or
nerd-dictation.
To auto-start dictation when the box opens (so one hotkey does both), pass
--on-open CMD — it runs CMD once the window is focused. With Handy on Sway:
bindsym $mod+y exec /usr/bin/friendly \
--on-open 'handy --toggle-transcription' --on-cancel 'handy --cancel'
Now $mod+y opens the box and starts recording; speak, stop your dictation (Handy
types the text into the box), then Enter. Pressing Esc cancels and stops the
dictation via --on-cancel (so Handy doesn't keep recording). Both can also be set
globally with the FRIENDLY_ON_OPEN / FRIENDLY_ON_CANCEL environment variables.
GUI:
friendlyCLI / scriptable:
friendly -s "Professional" "my text" # preset by name
friendly -i "a very formal tone" "my text" # free-form instruction
echo "my text" | friendly -s Concise -n # from a pipe, result on stdoutThe rewrite keeps the language of your message — dictate in any language and the output stays in it; only the tone changes. Presets are editable in
presets.conf.
| Flag | Meaning |
|---|---|
-s, --style NAME |
use a preset by name (skip the menu) |
-i, --instruction TEXT |
free-form tone instruction (skip the menu) |
-o, --on-open CMD |
run CMD when the box opens (e.g. start dictation); env: FRIENDLY_ON_OPEN |
-c, --on-cancel CMD |
run CMD on cancel/Esc (e.g. stop dictation); env: FRIENDLY_ON_CANCEL |
-n, --no-copy |
print the result to stdout instead of copying |
-h, --help |
help |
Esc at any step cancels cleanly (exit 0, nothing copied).
Tones live in ~/.config/friendly/presets.conf (created on first run). One per
line, Display name|instruction sent to the model. The first preset is the
default — it's highlighted in the menu, so just pressing Enter picks it:
Pro & kind|a tone that is both professional, kind and composed
Professional|a professional, clear and composed tone
Concise|a more concise and direct phrasing, keeping the essentials
Look — tweak spotlight.css (the wofi bars) and the inline CSS in
friendly-input.py (the text area): colors, radius, font size, width.
All in the official Arch repos except Claude Code:
| Package | Role |
|---|---|
claude-code (AUR / npm) |
the LLM backend — claude -p (required) |
python + python-gobject + gtk-layer-shell + gtk3 |
the centered text area |
wl-clipboard |
clipboard (wl-copy) |
wofi |
tone menu (falls back to rofi, then zenity) |
libnotify |
notifications (optional but recommended) |
See packaging/README.md. TL;DR: push a vX.Y.Z tag and CI
creates the GitHub Release and auto-publishes the friendly AUR package.
MIT © 2026 KannarFr
