pair-mode 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +40 -78
  2. package/package.json +2 -1
package/README.md CHANGED
@@ -1,8 +1,16 @@
1
1
  # pair mode
2
2
 
3
- A coding agent proposes an edit. Pair mode opens a side-by-side diff in a terminal
4
- editor. Every line you type becomes a question the model must answer, and the edit
5
- does not apply until you close the editor.
3
+ #### For when your agent needs a rubber ducky.
4
+
5
+ `pair-mode` is a tool that allows you to sit somewhere between being an approval monkey for your agent running in manual mode and just totally vibe coding in auto mode.
6
+
7
+ If you've ever found yourself wanting to pay attention to the code that your agent of choice is generating and (god forbid) suggest changes, I'm sure you've run into: "_oh no, I clicked 'reject' and now the proposed diff is gone - what did I want to suggest again?_"
8
+
9
+ `pair-mode` attempts to solve this.
10
+
11
+ When enabled, your agent will push diffs to your editing interface of choice (your choices are currently: in a separate terminal tab/pane, multiplexer sub-pane or web - sorry if your interface of choice is not actually here (yet)). From there you can go line by line over the diff and add comments, suggestions, chidings, deranged ramblings, etc. Your agent will receive your thoughts and proceed accordingly.
12
+
13
+ ![The pair review pane open in a zellij floating pane, with three notes anchored to line numbers](https://raw.githubusercontent.com/oFrusch/pair-mode/main/docs/images/pane-zellij.png)
6
14
 
7
15
  ## Install
8
16
 
@@ -11,55 +19,36 @@ npm install -g pair-mode
11
19
  pair-mode setup
12
20
  ```
13
21
 
14
- Install pair-mode globally before you run setup. Setup writes the install path into each
15
- CLI's config as an absolute path. `npx pair-mode setup` runs from a package cache that
16
- npm later prunes, which would leave every hook pointing at a deleted file. Setup detects
17
- that case and stops.
22
+ Install pair-mode globally before you run setup. Setup writes the install path into each CLI's config as an absolute path. `npx pair-mode setup` runs from a package cache that npm later prunes, which would leave every hook pointing at a deleted file. Setup detects that case and stops.
18
23
 
19
24
  The setup command detects the CLIs and multiplexers on your machine, registers the
20
- required hooks, and writes a config file. Restart Claude Code after setup, because
21
- Claude Code loads hooks only at startup.
22
-
23
- If you install from git instead of npm, run `pnpm build` first. The package does not
24
- ship a committed `dist/` directory; npm builds it fresh through the `prepublishOnly`
25
- script, but a git checkout does not run that script.
25
+ required hooks, and writes a config file.
26
26
 
27
27
  ## Supported CLIs
28
28
 
29
- | CLI | Hook | Status |
30
- | ----------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------- |
31
- | Claude Code | `PreToolUse`, matcher `Write\|Edit\|MultiEdit` | Shipped. |
32
- | Codex | `PreToolUse`, matcher `apply_patch\|Edit\|Write` | Shipped. |
33
- | pi | `tool_call` extension hook | Planned for 1.0.0. The adapter exists and passes its unit tests. Setup does not offer it yet. |
34
- | opencode | `tool.execute.before` plugin hook | Planned for 1.0.0. Nobody has run it against a live opencode. Setup does not offer it yet. |
35
-
36
- Codex has no `MultiEdit` matcher alias. Its `apply_patch` parser reads single-file Add,
37
- Update, and Delete patches only. A multi-file or rename patch passes through untouched.
29
+ | CLI | Hook | Status |
30
+ | ----------- | ------------------------------------------------ | ------------------------------------------- |
31
+ | Claude Code | `PreToolUse`, matcher `Write\|Edit\|MultiEdit` | Should work. |
32
+ | Codex | `PreToolUse`, matcher `apply_patch\|Edit\|Write` | Should work. |
33
+ | pi | `tool_call` extension hook | Will maybe work. Probably not. Coming soon. |
34
+ | opencode | `tool.execute.before` plugin hook | Will maybe work. Probably not. Coming soon. |
38
35
 
39
36
  ## The /pair command
40
37
 
41
- `pair-mode setup` installs a `/pair` command for every CLI whose hook it registers. The
42
- command toggles pair mode for the current directory. It also tells the agent how a held
43
- edit comes back.
38
+ `pair-mode setup` installs a `/pair` (`$pair` for Codex) command for every CLI whose hook it registers. The command toggles pair mode for the current directory. It also tells the agent how a held edit comes back.
44
39
 
45
40
  | CLI | Installed at | Invoked as |
46
41
  | ----------- | ------------------------------- | ----------------------- |
47
42
  | Claude Code | `~/.claude/commands/pair.md` | `/pair on`, `/pair off` |
48
43
  | Codex | `~/.codex/skills/pair/SKILL.md` | `$pair on`, `$pair off` |
49
44
 
50
- Codex deprecated `~/.codex/prompts/` in favour of skills, so pair mode installs a skill
51
- there. Codex invokes a skill with `$`, not `/`.
52
-
53
45
  The command runs a bare `pair-mode`, unlike a hook, which each CLI invokes by absolute
54
46
  path. So `pair-mode` must resolve on your PATH. A global install puts it there.
55
47
 
56
- `pair-mode doctor` warns when the command is missing, and warns when `pair-mode` does not
57
- resolve on PATH. Neither warning raises the exit code.
58
-
59
- Setup backs up an existing file before it rewrites the file.
60
-
61
48
  ## Editors
62
49
 
50
+ This is what will render your diff if you choose to use one of the CLI-based approaches. We ship the `pair` editor, which has good syntax highlight and mouse highlighting support. This makes the annotation process a bit easier. But we also support most popular terminal-based editors.
51
+
63
52
  | Editor | Diff colour | Syntax colour on changed rows |
64
53
  | -------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65
54
  | pair (default) | Yes | Yes. pair is the built-in review pane, so it paints syntax colour and change colour on the same row. It also reads mouse clicks and drags for selection, and it anchors a note to the exact span you select, not the whole line. |
@@ -97,28 +86,16 @@ keyboard only.
97
86
  | `Ctrl+q` `Ctrl+c` | — | Quit. With no notes, the edit applies. With notes pending, asks: `s` sends, `d` discards and quits, `Esc` cancels. |
98
87
  | `?` | — | Toggle the keymap overlay. |
99
88
 
100
- zellij consumes the mouse scroll wheel, so pair mode never depends on it. `Ctrl+d` and
101
- `Ctrl+u` page instead.
102
-
103
- Holding `shift` during a click or drag passes the mouse event straight through to the
104
- terminal, which then selects text for copy — the same as any other terminal program.
105
-
106
89
  ## Multiplexers
107
90
 
108
- Claude Code and Codex run their hooks with no controlling terminal. `/dev/tty` returns
109
- `ENXIO` there. Pane mode needs zellij or tmux to open an editor pane under those two
110
- CLIs.
111
-
112
- Session mode removes the requirement. See the next section.
91
+ If you want to do all your development in one terminal pane while using either Claude Code or Codex, you'll need to use a multiplexer (I use zellij but tmux works great as well). Both harnesses run their hooks with no controlling terminal. A multiplexer allows us to open up the agent's diff in a floating sub-pane.
113
92
 
114
93
  ## Session modes
115
94
 
116
- Pane mode is the default. The hook opens an editor in a floating pane and blocks. That
117
- needs a multiplexer under Claude Code and Codex.
118
-
119
95
  Session mode moves the review out of the agent's process. The hook posts to a Unix
120
- socket and waits. A client you start renders the review and answers. There are two
121
- clients, and both remove the multiplexer requirement.
96
+ socket and waits. A client you start (another terminal tab or the web view) renders the review and allows you to provide your annotations.
97
+
98
+ ### Session mode config
122
99
 
123
100
  Set `transport` to `"session"`, then pick a client.
124
101
 
@@ -126,39 +103,37 @@ Set `transport` to `"session"`, then pick a client.
126
103
  pair-mode config transport session
127
104
  ```
128
105
 
129
- `pair-mode config` with no argument prints every setting and its value. `pair-mode
130
- config <key>` prints one. `pair-mode config <key> <value>` changes one and validates it
131
- before it writes.
106
+ - `pair-mode config` with no argument prints every setting and its value.
107
+ - `pair-mode config <key>` prints one.
108
+ - `pair-mode config <key> <value>` changes one and validates it before it writes.
132
109
 
133
110
  **Watch mode** reviews in a terminal you own.
134
111
 
135
112
  ```
136
- pair-mode watch # in any terminal, at the repo root
113
+ pair-mode watch
137
114
  ```
138
115
 
139
- The watcher paints an idle screen between reviews and opens the pair TUI for each one.
116
+ ![Claude Code on the left, the pair review pane on the right in a second terminal pane](https://raw.githubusercontent.com/oFrusch/pair-mode/main/docs/images/watch-terminal.png)
117
+
118
+ Run this command in the directory or any subdirectory of where you are working with your agent. The diffs your agent suggests will be pushed to the running Unix socket and rendered wherever this command was run. You can then mark up the diffs as you please and send them back to your agent.
119
+
140
120
  `q` on the idle screen quits and releases the socket.
141
121
 
142
122
  **Web mode** reviews in a browser and needs no terminal at all.
143
123
 
144
124
  ```
145
- pair-mode on --web # prints a link
125
+ pair-mode on --web
146
126
  ```
147
127
 
148
- That spawns a detached watcher, binds an HTTP server on `127.0.0.1`, and prints a link
149
- carrying a random token. Drag across any text in the diff. A popup opens under the
150
- selection. Type the note and press Enter. `pair-mode off` stops the watcher.
151
-
152
- The watcher process binds the socket, so there is no separate daemon to manage. If the
153
- watcher dies, the socket goes away and every hook fails open at once.
128
+ ![The web review in a browser, with a note popup open under a selected span](https://raw.githubusercontent.com/oFrusch/pair-mode/main/docs/images/web.png)
154
129
 
155
- A hook that finds no watcher applies the edit rather than hanging. So does a hook whose
156
- watcher never answers within `session.timeout`.
130
+ That spawns a detached watcher, binds an HTTP server on `127.0.0.1`, and prints a link carrying a random token. Drag across any text in the diff. A popup opens under the selection. Type the note and press Enter. Same stuff as the other solutions, just within an HTML page.
157
131
 
158
132
  ## Configuration
159
133
 
160
- Pair mode reads `$XDG_CONFIG_HOME/pair-mode/config.json`, or `~/.config/pair-mode/config.json`
161
- when `XDG_CONFIG_HOME` is not set.
134
+ Run `pair-mode setup` when first installing and that should get you most of the way there in terms of pair mode working for your setup. Regardless, all configuration options and their accepted values are listed below.
135
+
136
+ Pair mode reads `$XDG_CONFIG_HOME/pair-mode/config.json`, or `~/.config/pair-mode/config.json` when `XDG_CONFIG_HOME` is not set.
162
137
 
163
138
  | Key | Type | Default | Meaning |
164
139
  | ----------------- | --------------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------- |
@@ -191,19 +166,6 @@ controls the diff itself — split into two columns, or one inline column. `note
191
166
  controls only where a note you write renders — in a docked panel, or anchored next to
192
167
  the span it annotates. Setting one does not affect the other.
193
168
 
194
- ## Limits
195
-
196
- - Pair mode opens one pane per tool call. It cannot batch a changeset, because a hook
197
- returns one verdict per call and an allow cannot be withdrawn.
198
- - The pane reviews. It does not edit the proposal.
199
- - Syntax colour in pair needs `shiki` installed. A missing package disables colour and
200
- the pane still works.
201
- - A client answers one review at a time. It cannot skip ahead in the queue.
202
- - Web mode does not defend against another user on the same machine. The token sits in
203
- the URL, and a local user can read the process list.
204
- - Watch mode needs the watcher running before the agent edits. A missing watcher fails
205
- open, so an unattended agent applies its edits.
206
-
207
169
  ## License
208
170
 
209
171
  MIT. See `LICENSE`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pair-mode",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Annotate a coding agent's proposed edits line by line, in your terminal.",
5
5
  "keywords": [
6
6
  "ai",
@@ -37,6 +37,7 @@
37
37
  "scripts": {
38
38
  "build": "node scripts/build.mjs",
39
39
  "capture": "node scripts/capture-fixtures.mjs",
40
+ "release": "node scripts/release.mjs",
40
41
  "test": "vitest run",
41
42
  "test:watch": "vitest",
42
43
  "typecheck": "tsc --noEmit",