Skip to content

About

AI pairing partner that acts only through your editor and terminal

Resources

Contributing

Stars

11 stars

Watchers

0 watching

Forks

Repository files navigation

pairing-buddy

A pair programmer for Neovim that knows when to speak.

Pair is a Neovim plugin and a daemon that work next to you like a colleague in the second chair: it watches you code, says one short line under your cursor when it spots something, runs the tests you would skip, and takes the keyboard only when you hand it over. It is not code completion and not a chat sidebar, and it never writes your files: its edits land unsaved in your buffer as one undo step, and the disk changes only when you save. When you ask it for code (/gen), it proposes it where you asked, and you take it with one key, also unsaved; new files it drafts are buffers to review, and one reaches the disk only when you :w it. A sample you ask for to try out (/gen try) is written and run in a folder of Pair's own, outside your project, and /keep brings it in as one more buffer to review. A scaffold of many files (/gen scaffold) is built and run in a copy of your project in Pair's data folder, and you keep it a file at a time: a new file as a buffer to review, a change to one of yours as suggestions in it.

Docs: makefunstuff.github.io/pairing-buddy (source in docs/, built from site/).

Watch the tutorial on the site: 25 minutes with a voiceover and captions, one idea per scene, recorded live with a real model. Chapters: 0:00 what Pair is · 0:59 setup and pair doctor · 2:44 the roles · 4:16 the chat pane · 6:20 exploring code · 7:20 tests · 8:42 notes and the blank page · 11:11 the hand-over · 12:51 asking for code with /gen · 18:09 the board · 21:41 several worktrees · 22:14 voice · 23:20 with or without herdr · 23:55 the keys to remember. Its script and how to render it again are in docs/video.

Version 0.11 (changelog).

Why

Most AI coding tools sit beside your work: you stop, describe the problem, and read a long answer. A good human pair does something else. They notice when you start fixing the wrong file, run the tests you would skip, keep quiet while you think, and take the keyboard only when you hand it over. Pair aims for that:

  • It speaks rarely. A small, fast model, the Watcher, scores each moment first, and most moments are not worth a word. On a slow server Pair skips the moments you can see on screen, and still asks about the ones you cannot (watcher). An optional decision model (a classifier such as TypeSafe's Jev or Cloudflare's Clef) can sort the moments first and say, with a probability, whether one is worth interrupting you for. Remarks that can wait are held until your next break.
  • It shows, in place. Its words appear under the line you are on, it points at the line it means, and a suggested change is one key to take.
  • It runs what you'd skip. Save, and it runs the project's tests and tells you what your fix broke elsewhere.
  • You stay in charge. One role at a time: Navigator points and suggests, Scout also runs commands in its own pane, and the Driver edits only when you hand over, while you watch. Any key takes the wheel back. Ask it for code with /gen here or Alt-g, and it lands where you asked, to take with one key and undo as one request; /gen file drafts new files as buffers you review, which reach the disk only when you :w one; /gen try writes a sample in a folder outside the project and runs it in a sandbox, for you to read, change and run again, and /keep moves it in; /gen scaffold builds many files and their wiring in a copy of the project, runs and checks them there, and you keep what you want of it a file at a time. Every request runs against your brief (the goal and NOTES.md, in your words, which Pair never edits): it asks before going against it, and says what its code guessed. Pair knows its own edits from yours, so it never remarks on the code it wrote as if you had. Code you took stays marked ┊ until you edit it or :Pair own it, and :Pair today and pair stats say how much of it is not yours yet (/gen). In the chat pane, what a request made is a card with its keys: k keep, Enter open it in Neovim, d drop, u undo. A request too big to watch goes to your work board, Shepherdr, with /gen board: Pair writes the task's brief from yours (your words, the note's lines with file:line, the files, the tests, the open questions), lets you edit it, and adds it only as you pick: add only, add and delegate, plan first, research only, or copy the command. A request too big for /gen's limits is offered to the board. When a task is ready, :Pair review <id> (or Alt-r on its line) opens its branch as a review: what its reviewer said, ≠ brief on the branch, each file's diff, and k to keep a file or a hunk in yours, unsaved; tell, merge (a tell to its agent) and archive only on your pick. On a task's branch its brief on the board is part of yours, and /brief sync tells its agent, on your pick, what changed in your brief since.
  • Your other agents, in one line. When a board task or another agent needs you, is ready to merge or is done, Pair says so at your next pause, never while you type; o, d and t open what a task left behind (its report or pull request, its branch's diff, a terminal in its worktree), and the chat's header counts the repo's tasks. A file a working task also changes says so in its winbar, and when you edit lines its branch changes, Pair tells you at your next pause (your other agents).

Quick start

You need Node.js 22.19+, Neovim 0.11+, and a model: a local OpenAI-compatible server, an API key for any provider pi-ai supports, or a subscription login where the provider allows it. herdr (the older herdr, or herdr-core with the Herdr window) is the best home for Pair; Rex is another terminal backend. Without herdr or Rex, everything runs inside Neovim and tmux.

npm install -g github:makefunstuff/pairing-buddy   # puts `pair` on your PATH
pair setup                                         # writes the config, offers a login, installs the service

Add the plugin with lazy.nvim:

{
  'makefunstuff/pairing-buddy',
  dependencies = {'makefunstuff/semantic-grep.nvim'}, -- its picker for search by meaning (Alt-s)
  main = 'pair',
  lazy = false,
  opts = {auto_connect = true},
}

Set your model in ~/.config/pairing-buddy/config.json (models), run pair doctor to check every part, then pair in a herdr pane or Rex terminal next to Neovim (in the Herdr window it opens Pair's panel), or :Pair chat in Neovim, and work. In the chat pane, ? lists its keys and / its commands. Getting started walks through it, and the first ten minutes tutorial does it step by step, with what pair doctor shows. Optionally add the shell hook (eval "$(pair shell-hook bash)", or zsh, or fish) to your shell's rc file: Pair then gets every command you run, with its exit code, from the shell itself, and in zsh your typing too.

Let your AI agent set it up. Tell your coding agent "follow https://github.com/makefunstuff/pairing-buddy/blob/main/INSTALL.md": INSTALL.md takes it from a fresh machine to a passing pair doctor, step by step with checks, and asks you where only you can answer (which model, your keys and logins).

Documentation

  • Getting started and install and daily use
  • Tutorials: short how-tos, a few minutes each, from the first ten minutes to /gen, the board, worktrees and voice
  • How it works, roles and workflows
  • The chat pane: who speaks, what Pair is doing now, wide and narrow panes, a remark's own keys, the gen card, find, calm motion, role colours, its keys and commands
  • Your other agents: the board's tasks and herdr's agents in one line at your next pause, what a task left behind (report or pull request, its branch's diff, its worktree) one key away, and the files a working task also changes
  • /gen: ask Pair for code at your cursor, as new files to review, as a sample to run outside the project, or as a scaffold built in a copy of it, against your brief; take it with one key, :w, /keep or k per file, undo the request as one; Pair's own edits carry their origin, and taken code is marked ┊ until you own it; /gen board hands a request to the board as a task, its brief built from yours, and :Pair review opens a task's branch as a review to keep pieces of
  • Search by meaning: Alt-s is semantic-grep's live picker in Telescope, snacks.picker or fzf-lua that finds code by your words on every key and by what you mean as you pause, from a local index (EmbeddingGemma 2, or an embedding model of your own) Pair keeps up to date in the background, and optionally a small decision model that reranks a settled list's first pieces
  • Push-to-talk: ask aloud, heard by LFM3-Omni on your CPU (or whisper.cpp, or an OpenRouter model), with answers read aloud when you are away, or always in talk
  • Models and providers: local servers, API keys, subscription logins, one model for both roles, and the optional decision model
  • Reference: configuration, Neovim plugin, commands
  • Troubleshooting and known limitations
  • Data and privacy, tests
  • Contributing, also on the site, releasing and the changelog

The site is VitePress: cd site && npm ci && npm run dev previews it, and the Pages workflow builds and deploys it on every push to main that changes docs/ or site/. Its look is pixel art: the palette (PICO-8's 16 colours) and the fonts (Pixelify Sans for headings and labels, Inter for text) are in site/.vitepress/theme/tokens.css, and the sprites, the favicon and the PNG icons (with the web manifest) are drawn as pixel grids in site/sprites/build.mjs (npm run sprites redraws them).

A shared link shows the page's own title and description: a docs page's description from its frontmatter, or else its first paragraph, cut to 155 characters (site/.vitepress/meta.mjs). Give a page a description when it opens with a list, a heading or a code block. The preview image, site/public/og-v2.png (1200x630), is site/og/card.html: npm run og redraws it with a headless Chrome or Chromium, and the PNG is committed. X caches card images by URL, so a changed design goes out under a new file name (change it in site/og/build.mjs and meta.mjs); otherwise X keeps showing the old image. After npm run build, npm run check checks every built page has the full set of tags with absolute URLs (the Pages workflow runs it before it deploys), and node og/previews.mjs OUT renders mock X, Slack and Discord previews of the built pages into OUT/previews.png.

Contributing and license

Bug reports, ideas and pull requests are welcome: CONTRIBUTING.md says how to run Pair from a clone, run the tests, report a bug (with pair doctor output) and open a pull request.

pairing-buddy is under the MIT License. The fonts, a vendored animation library and a colorscheme used by the site and the video keep their own licences: see THIRD_PARTY_NOTICES.md.

About

AI pairing partner that acts only through your editor and terminal

Resources

Contributing

Stars

11 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages