Skip to main content

prosefmt

Rewrite text in any app — press a hotkey, get polished prose back.

CI PyPI Python License: MIT

Highlight text in any application — browser, email, Slack, VS Code, anything — press your hotkey, and prosefmt silently rewrites it and pastes the result back. Grammar fixed, tone shifted, fully rephrased: all without leaving the app you are in.

It also works as a standard CLI tool that composes with pipes and scripts.

$ prosefmt fix "i can haz good grammer?"
I can have good grammar?

$ echo "this sentense has a typo" | prosefmt fix
This sentence has a typo.

$ prosefmt professional --clipboard    # reads clipboard → rewrites → writes back

→ Jump to hotkey setup ↓


Table of Contents


Why prosefmt?

Every existing tool in this space is a GUI desktop app — Electron, Tauri, or PyQt5. They are 100–200 MB, framework-dependent, and impossible to script.

prosefmt is a plain CLI tool: two Python dependencies, composes with pipes, works from hotkeys or scripts, and runs on every OS.

prosefmt GUI tools
Size ~2 Python deps 100–200 MB runtime
Composability Pipes, scripts, automation GUI click-through only
Providers Ollama, OpenAI, Anthropic, any OpenAI-compat Varies
Custom modes One line in a config file Fork the source
Hotkey integration Any window manager or OS shortcut Their own UI

Installation

# Recommended — installs as an isolated tool
uv tool install prosefmt

# Or with pip
pip install prosefmt

New to uv? Install it with: curl -LsSf https://astral.sh/uv/install.sh | sh


Setup Guide

Follow these steps once after installing. This takes about 5 minutes.

Step 1 — Install clipboard tools

prosefmt uses your system clipboard to read and paste text. The tools needed depend on your OS. macOS and Windows users can skip this step — everything is built in.

Linux (X11 — most desktops: GNOME, KDE, i3, XFCE, …)

# Debian / Ubuntu / Mint / Pop!_OS
sudo apt install xclip xdotool

# Fedora / RHEL / CentOS / Rocky
sudo dnf install xclip xdotool

# Arch / Manjaro / EndeavourOS
sudo pacman -S xclip xdotool

# openSUSE
sudo zypper install xclip xdotool

Linux (Wayland — GNOME on Wayland, KDE Wayland, Sway, Hyprland, …)

# Debian / Ubuntu / Mint
sudo apt install wl-clipboard wtype

# Fedora / RHEL / CentOS
sudo dnf install wl-clipboard wtype

# Arch / Manjaro
sudo pacman -S wl-clipboard wtype

# openSUSE
sudo zypper install wl-clipboard wtype

Not sure if you are on X11 or Wayland? Run echo $XDG_SESSION_TYPE — it prints x11 or wayland.

macOS — nothing to install. pbcopy, pbpaste, and osascript are built in.

Windows — nothing to install. clip.exe and PowerShell are built in.


Step 2 — Choose an AI provider

Pick one. You can always add more later.

No API key needed. Runs entirely on your machine.

# 1. Install Ollama  →  https://ollama.com/download
#    (macOS / Windows: download the installer; Linux: one-liner below)
curl -fsSL https://ollama.com/install.sh | sh

# 2. Pull a model  (qwen2.5:1.5b is fast and small — great for CPU-only)
ollama pull qwen2.5:1.5b

# 3. Start the server (keep this running in the background)
ollama serve

Other good models to try: llama3.2:3b, mistral:7b, phi3:mini

Option B — OpenAI

export OPENAI_API_KEY="sk-..."

Add to your shell profile (~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish) so it is always available:

echo 'export OPENAI_API_KEY="sk-..."' >> ~/.bashrc

Option C — Anthropic (Claude)

export ANTHROPIC_API_KEY="sk-ant-..."

Option D — Any OpenAI-compatible endpoint

Works with Groq, Together AI, LM Studio, vLLM, and any server that speaks the /v1/chat/completions format. Configure the URL and model in your config file (see Step 3).


Step 3 — Create your config

Run this once to create a ready-to-edit config file:

prosefmt config init

It also checks whether your clipboard tools from Step 1 are installed and tells you exactly what to run if anything is missing.

Open the file to set your default provider and model:

# Linux / macOS
nano ~/.config/prosefmt/config.toml    # or: code, vim, whatever you prefer

# Windows
notepad %APPDATA%\prosefmt\config.toml

The minimum config for Ollama — the defaults already cover this, so you may not need to change anything:

default_provider = "ollama"

[providers.ollama]
url   = "http://localhost:11434"
model = "qwen2.5:1.5b"

For OpenAI:

default_provider = "openai"

[providers.openai]
model = "gpt-4o-mini"    # API key comes from OPENAI_API_KEY env var

Step 4 — Verify everything works

prosefmt check

Expected output:

✓ Clipboard tools installed
✓ Provider 'ollama' is reachable  (model: qwen2.5:1.5b)

If anything is wrong, prosefmt check prints the exact command to fix it.


Step 5 — Try it out

# Pass text directly
prosefmt fix "me and him went to the store yesterday"

# Pipe from stdin
echo "this sentense has a typo" | prosefmt fix

# Read from clipboard and print the result
prosefmt fix --clipboard

# Read from clipboard, rewrite, and write the result back to clipboard
prosefmt professional --clipboard

# System-wide: read selected text from any app, rewrite, paste back in-place
prosefmt fix --system

System-Wide Hotkeys

The --system flag is what makes prosefmt useful beyond the terminal. Highlight any text, press your hotkey, and the rewritten version is pasted back automatically — without touching the mouse or switching windows.

Two bindings are recommended:

Hotkey Action
Mod+G Fix grammar immediately — no prompt
Mod+Shift+G Open a mode picker — choose fix / professional / casual / rephrase / …

Linux — i3wm / Sway

Install rofi if you do not have it already:

sudo dnf install rofi   # Fedora
sudo apt install rofi   # Debian / Ubuntu
sudo pacman -S rofi     # Arch

Create the mode picker script at ~/.config/prosefmt/prosefmt-menu.sh:

#!/bin/bash
set -euo pipefail
PROMPT=$'\uf044'" prosefmt"
choice=$(prosefmt list --names | rofi -dmenu -i -p "$PROMPT" -theme-str 'window {width: 28%;}')
[[ -z "$choice" ]] && exit 0
exec prosefmt "$choice" --system --notify
chmod +x ~/.config/prosefmt/prosefmt-menu.sh

Add to ~/.config/i3/config (or ~/.config/sway/config):

bindsym $mod+g       exec --no-startup-id prosefmt fix --system --notify
bindsym $mod+Shift+g exec --no-startup-id ~/.config/prosefmt/prosefmt-menu.sh

Reload i3 with Mod+Shift+C.


Linux — Hyprland

Install wofi (Wayland-native picker) or rofi (also supports Wayland on modern builds):

sudo dnf install wofi   # Fedora
sudo apt install wofi   # Debian / Ubuntu
sudo pacman -S wofi     # Arch

Create the mode picker script at ~/.config/prosefmt/prosefmt-menu.sh:

#!/bin/bash
set -euo pipefail
# Use wofi if available, otherwise fall back to rofi
if command -v wofi &>/dev/null; then
    choice=$(prosefmt list --names | wofi --dmenu --prompt "prosefmt")
else
    choice=$(prosefmt list --names | rofi -dmenu -i -p "prosefmt")
fi
[[ -z "$choice" ]] && exit 0
exec prosefmt "$choice" --system --notify
chmod +x ~/.config/prosefmt/prosefmt-menu.sh

Add to ~/.config/hypr/hyprland.conf:

bind = $mainMod,       G, exec, prosefmt fix --system --notify
bind = $mainMod SHIFT, G, exec, ~/.config/prosefmt/prosefmt-menu.sh

Linux — GNOME / KDE (any desktop)

rofi works on GNOME and KDE too — install it and use the same script from the i3wm section above. Then add the shortcuts in Settings → Keyboard → Custom Shortcuts:

Name Command Shortcut
prosefmt fix prosefmt fix --system --notify Super+G
prosefmt mode picker ~/.config/prosefmt/prosefmt-menu.sh Super+Shift+G

macOS — Hammerspoon

Hammerspoon provides both the hotkey binding and a built-in chooser for the mode picker. Add to ~/.hammerspoon/init.lua:

-- Grammar fix
hs.hotkey.bind({"cmd"}, "g", function()
  hs.task.new("/usr/local/bin/prosefmt", nil, {"fix", "--system", "--notify"}):start()
end)

-- Mode picker — opens Hammerspoon's native chooser
hs.hotkey.bind({"cmd", "shift"}, "g", function()
  hs.task.new("/usr/local/bin/prosefmt", function(_, stdout)
    local choices = {}
    for line in stdout:gmatch("[^\n]+") do
      table.insert(choices, { text = line })
    end
    local chooser = hs.chooser.new(function(choice)
      if choice then
        hs.task.new("/usr/local/bin/prosefmt", nil,
          {choice.text, "--system", "--notify"}):start()
      end
    end)
    chooser:choices(choices)
    chooser:show()
  end, {"list", "--names"}):start()
end)

Reload the Hammerspoon config from the menu bar icon.


macOS — Automator / Shortcuts app

For a fix-only binding without Hammerspoon, create a Quick Action in Automator that runs:

/usr/local/bin/prosefmt fix --system --notify

Assign it a keyboard shortcut in System Settings → Keyboard → Keyboard Shortcuts → Services.


Windows — AutoHotkey v2

Create prosefmt-menu.ps1 anywhere on your system (for example %USERPROFILE%\prosefmt-menu.ps1):

# prosefmt-menu.ps1
$modes = (& prosefmt list --names) -split "`n" | Where-Object { $_ }
$mode  = $modes | Out-GridView -Title "prosefmt — choose a mode" -PassThru
if ($mode) { & prosefmt $mode --system --notify }

Add to your AutoHotkey v2 script:

; prosefmt.ahk
#g::  Run "prosefmt fix --system --notify",, "Hide"
#+g:: Run 'powershell -WindowStyle Hidden -File "%USERPROFILE%\prosefmt-menu.ps1"',, "Hide"

Built-in Modes

Mode What it does
fix Fix grammar, spelling, and punctuation only
professional Rewrite in a polished workplace tone
casual Rewrite in a friendly, conversational tone
rephrase Improve clarity and flow without changing the meaning
concise Same meaning, fewer words
expand Add more detail and explanation
summarize Condense to the key points
email Format as a professional email with greeting and sign-off

Run prosefmt list to see all modes including any custom ones you have added.


Custom Modes

Add any number of custom modes to your config file:

# ~/.config/prosefmt/config.toml

[modes.translate-spanish]
prompt = "Translate to Spanish. Keep technical terms in English."
label  = "Translated to Spanish"

[modes.code-comments]
prompt             = "Add clear, concise comments to this code. Do not change the code itself."
label              = "Comments added"
preserve_structure = false

[modes.slack]
prompt = "Rewrite for Slack: brief, friendly, one or two sentences max. No formal sign-off."
label  = "Slack-ready"

[modes.eli5]
prompt = "Explain this like I'm five — simple words, short sentences, no jargon."
label  = "Simplified"

Use them exactly like built-in modes:

prosefmt translate-spanish "Good morning, how are you?"
prosefmt slack "Please review the pull request I opened for the authentication refactor."

Custom modes appear automatically in the mode picker — no changes to your hotkey scripts needed.


Configuration Reference

Config file location:

OS Path
Linux / macOS ~/.config/prosefmt/config.toml
Linux (custom) $XDG_CONFIG_HOME/prosefmt/config.toml
Windows %APPDATA%\prosefmt\config.toml

Run prosefmt config init to create it, prosefmt config show to see active values.

Full example

# ~/.config/prosefmt/config.toml

# Which provider to use by default
default_provider = "ollama"

# System prompt applied to every rewrite mode.
# Uncomment and edit to change the AI's base behaviour.
# system_prompt = "You are a text editor. Output ONLY the rewritten text — no preamble."

# ── Providers ────────────────────────────────────────────────────────────────

[providers.ollama]
url   = "http://localhost:11434"
model = "qwen2.5:1.5b"          # any model you have pulled

[providers.openai]
# API key: set OPENAI_API_KEY or PROSEFMT_OPENAI_API_KEY in your environment
model = "gpt-4o-mini"

[providers.anthropic]
# API key: set ANTHROPIC_API_KEY or PROSEFMT_ANTHROPIC_API_KEY in your environment
model = "claude-haiku-4-5-20251001"

# Any OpenAI-compatible endpoint: Groq, Together AI, LM Studio, vLLM, etc.
# [providers.openai-compat]
# url   = "https://api.groq.com/openai/v1"
# model = "llama-3.3-70b-versatile"
# API key: set PROSEFMT_COMPAT_API_KEY in your environment

API keys — environment variables

Never put API keys in the config file. Set them as environment variables instead:

Provider Environment variable
OpenAI PROSEFMT_OPENAI_API_KEY or OPENAI_API_KEY
Anthropic PROSEFMT_ANTHROPIC_API_KEY or ANTHROPIC_API_KEY
OpenAI-compat PROSEFMT_COMPAT_API_KEY

Add them to your shell profile (~/.bashrc, ~/.zshrc, ~/.config/fish/config.fish) so they load automatically in every session.


Commands

prosefmt <mode> [TEXT]         Rewrite TEXT (or stdin if omitted)
prosefmt <mode> --clipboard    Read from clipboard, print result (also writes back)
prosefmt <mode> --system       Read selected text, rewrite, paste back in-place
prosefmt <mode> --provider P   Override the AI provider for this run
prosefmt <mode> --model M      Override the model for this run
prosefmt <mode> --notify       Show a desktop notification when done

prosefmt list                  List all available modes (human-readable)
prosefmt list --names          Mode names only — used by hotkey picker scripts
prosefmt undo                  Restore the original text from the last rewrite
prosefmt check                 Check clipboard tools and provider connectivity
prosefmt config init           Create ~/.config/prosefmt/config.toml
prosefmt config show           Show the active configuration

prosefmt --version             Show version
prosefmt --help                Show help

Development

git clone https://github.com/digitronik/prosefmt.git
cd prosefmt
uv sync --extra dev

# Git hooks (ruff + file hygiene) — uses .pre-commit-config.yaml
uv run pre-commit install
uv run pre-commit run --all-files   # once, to verify hooks

# Run tests
uv run pytest -v

Contributions welcome — open an issue or pull request on GitHub.


License

MIT

Metadata

Release files for prosefmt 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for prosefmt 0.2.0
File Size Uploaded Provenance
prosefmt-0.2.0.tar.gz 57.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for prosefmt 0.2.0
File Interpreter ABI Platform
prosefmt-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 81.8 kB

Release files / prosefmt-0.2.0.tar.gz

Download URL prosefmt-0.2.0.tar.gz
Size 57.2 kB
Tags Source
SHA-256 checksum
How to use checksums
771e6cb5630f5688de767b5d91a4bc325a306ea7e0a975fa366dd31a0470b6a4
BLAKE2b-256 checksum
How to use checksums
1434033d42f803cc173714b04f8f0888a090db122e38bf2f901bd785e3eb694b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / prosefmt-0.2.0-py3-none-any.whl

Download URL prosefmt-0.2.0-py3-none-any.whl
Size 24.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b486417f0eacc11c24690787b4a879cffd7968b0d6569bad020a7ff353153da3
BLAKE2b-256 checksum
How to use checksums
6daaa2edd807ffe009e2ba49668c833c077b78344a95999e261ae99bece99a6c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for prosefmt 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for prosefmt-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page