DEV Community

Cover image for paste-sloth: Ctrl+Space+V pastes your clipboard back tidied, by a 1-bit Gemma
Wal
Wal

Posted on

paste-sloth: Ctrl+Space+V pastes your clipboard back tidied, by a 1-bit Gemma

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 3, Slow and Steady.

What I Built

paste-sloth is a background process. you copy the way you already do, and when the text is a mess you hold ctrl, press space, press V, and let go. the clipboard goes to a model, comes back restructured, and gets pasted into whichever window has focus. csv becomes a markdown table, json gets pretty-printed, logs become one entry per line.

name,score,city
ada,10,lagos
grace,12,accra
Enter fullscreen mode Exit fullscreen mode

the usual repair is a second app: paste into a chat, type "just the table", wait, select the reply, copy it, go back, paste. that whole loop is now one chord. the chord is awkward on purpose, so it never fires while you're typing, and the model is small enough that leaving it running feels lazy rather than expensive.

Demo

paste-sloth turning name,score,city into a markdown table

the gif is a real paste-sloth clean run against a stub server. the stub is rude on purpose: it answers with Here is the table: and a code fence, so you can watch the tool strip both, check the numbers, and print the table. paste-sloth clean restructures the clipboard once and prints the result - the easy way to see what the model does before the keyboard is involved.

the installer is one line. it finds python 3.11 or newer, makes a venv, and opens a menu:

# macOS or Linux
curl -fsSL https://raw.githubusercontent.com/walsoup/paste-sloth/main/install.sh | bash
Enter fullscreen mode Exit fullscreen mode
# Windows
irm https://raw.githubusercontent.com/walsoup/paste-sloth/main/install.ps1 | iex
Enter fullscreen mode Exit fullscreen mode

the installer menu, choosing gemma at 1-bit

enter on the first row asks for a base url, a key, and a model name. down, then enter, is the local option: it installs ollama if it's missing and downloads gemma 4 e2b at 1-bit (IQ1_S, about 2.4 gb - google doesn't publish a 1-bit file, so it's an importance-matrix quant of the instruction-tuned weights), then writes the config and an autostart entry.

How I Built It

the model does the one job a very small model can be asked to do. the code holds the pen for everything else.

the request is a chat completion at temperature 0. the system prompt is short: reply with only the restructured text, keep every value, pick the structure that fits. before the reply touches the clipboard it gets checked:

  • code fences and one-line preambles ("here is...") are stripped
  • if the reply contains a number the input never had, it's asked once more with a sterner prompt, then dropped. invented numbers are the worst failure for pasted text: a figure that looks right and isn't. dropped numbers are allowed, because stripping timestamps off a log is legitimate
  • empty reply, error, or timeout (15s by default): nothing is pasted. your original text is still on the clipboard

the number check is the part i would not ship without:

def introduces_numbers(source: str, output: str) -> bool:
    """True when the output contains a number the input never had.

    Dropped numbers are allowed: stripping timestamps from a log is legitimate.
    Ordered-list markers the model adds (``1.``, ``2)``) are not data.
    """
    invented = number_tokens(output, ignore_list_markers=True) - number_tokens(
        source, ignore_list_markers=False
    )
    return bool(invented)
Enter fullscreen mode Exit fullscreen mode

the chord was the fiddly part, because space is also a spacebar. ctrl is forwarded as it happens. space is held back, and if you press another key or release space before V, the held space gets replayed, so autocomplete and input-method switching still work. V while both are held is the paste, and both keys are swallowed so the app doesn't also get a raw paste. a second chord while a request is in flight is ignored. ctrl+space+esc releases the keyboard and quits.

on linux this is evdev with an exclusive grab plus a uinput virtual keyboard - wayland won't let an ordinary app watch every key or type into other windows, and a desktop shortcut can't express ctrl+space+V because space is not a modifier. the grab needs a one-time sudo setup, which paste-sloth setup prints. windows and macos use pynput.

Why Does Open Innovation Matter?

  • the clipboard is the most private stream on the machine: passwords, tokens, a paragraph you haven't sent. "reformat what i just copied" is the last feature i'd hand to a service i can't inspect. with ollama on localhost, nothing you copy leaves the machine.
  • open weights are what make this version possible. google released gemma, someone quantized it to 1 bit and published the file, ollama serves it on cpu with no account. every layer can be read, swapped, or run with the network off.
  • it costs nothing to run, so there's no meter on a chord you hit all day.
  • not locked in: base_url takes any openai-compatible endpoint, local or hosted. your clipboard, your pick.

what it can't do yet

  • windows and macos are written and unit-tested, but not run on real machines. macos will ask for accessibility and input monitoring, and ctrl+space may already switch input sources.
  • on my own wayland box the uinput paste still needs the sudo setup, so a live ctrl+v from the virtual keyboard is unconfirmed there. wl-copy and wl-paste do work from a detached process, which is the part i could check without it.
  • text only. images and files on the clipboard are ignored.
  • a 1-bit model can still be wrong in ways a number check can't see.

repo: https://github.com/walsoup/paste-sloth - python 3.11, MIT.

Top comments (0)