Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 0.8.1 (2026-11-06)

The agents' instructions now cover parallel work with subagents. A subagent inherits the author's
pair environment, so following "when you finish a task, request a review" it could open a review
thread in a checkout other subagents were still editing, or in its own worktree, where no auto
session serves the request. A new Delegating work section tells the author that it owns the review
loop: subagents return their changes and validation results without running pair commands, the
author integrates them and keeps the checkout stable while the reviewer runs, and separate PRs are
reviewed one at a time in the session's worktree. A subagent is told not to run pair commands even
with the author's role in its environment.

The auto author prompt says the same, and the README gains a Parallel work section. For PRs
reviewed in parallel, run one `pair start --worktree` session per PR. Instructions refresh in each
worktree on the next `send` or `wait`.

## 0.8.0 (2026-11-06)

Pair now covers more than code review: brainstorm a design, review the spec, then review the code
Expand Down
1 change: 1 addition & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ a chat channel. In manual mode, each runs as a live session in its own terminal.
| Brainstorms | `pair send request --brainstorm` opens a thread for ideas in the author's lane. The reviewer replies `continue` or `complete` instead of `approve` or `changes`. Its statuses are `brainstorming` and `completed`, and the kind comes from the status, so pair ≤ 0.7.4 rejects the request as corrupt and can't review it as code; both agents need 0.8.0. The request stores `budget:`, `PAIR_MAX_ROUNDS` when it opened, so the agents' shells can't disagree on it; on the last round `continue` is refused. It never escalates. |
| Disputes | Cap of 3 rounds (`PAIR_MAX_ROUNDS`). A review that still says `changes` at the cap marks the thread `escalated`, and both agents stop to ask the user. |
| Concurrency | At most one open thread per direction. |
| Delegation | A subagent inherits the author's pair environment, so the instructions make the parent own the pair loop: subagents return changes without running pair, the parent integrates them (or reviews separate PRs one at a time) in the session's worktree and keeps it stable during each round. Several threads per lane wouldn't stop files moving under a reviewer. One owner serving reviews for subagent worktrees is planned separately. |
| Storage | `~/.pair/<repo>-<hash>/` (or `$PAIR_HOME`). The hash comes from `git rev-parse --show-toplevel`, so each worktree gets its own channel. A reviewer reads the author's files, so both agents must run in the same worktree, and parallel pairs in different worktrees stay isolated. |
| Format | Markdown files with flat YAML frontmatter that the CLI writes. Findings go in the body. |

Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,21 @@ the reviewer to complete. A brainstorm never escalates, and `pair history` lists
Both agents MUST run pair 0.8.0 or later: an older pair rejects a brainstorm as a corrupt message
instead of reviewing it as code.

### 5.3. Parallel work

An author MAY split a task across subagents, but it alone runs the pair loop. Its instructions tell
it to have each subagent return its changes and validation results without running pair commands,
then integrate them into the session's worktree and request review of the combined change, keeping
the checkout stable while the reviewer runs. A subagent inherits the author's pair environment, so
without that rule it could open a thread of its own: in the shared checkout, against files others
are still editing, or in its own worktree, where no auto session serves the request.

When the subagents' work belongs in separate PRs, the author reviews them one at a time: it checks
out each branch in the session's worktree and finishes that PR's review loop before the next. For
PRs reviewed in parallel, run one `pair start --worktree NAME` session per PR
([Worktrees](#6-worktrees)). Approval in each worktree doesn't cover a later merge of their work;
review the integrated result as well.

<a id="5-worktrees"></a>
<a id="52-worktrees"></a>
<a id="6-worktrees-in-manual-mode"></a>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "claude-codex-pair",
"version": "0.8.0",
"version": "0.8.1",
"description": "Claude Code and Codex review each other's work over a file-system chat channel",
"keywords": [
"claude-code",
Expand Down
39 changes: 30 additions & 9 deletions prompts/pair.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ You are `{{AGENT}}`. Your partner `{{PARTNER}}` works on the same repo. In auto
reviewer for each round.
You talk only through the `pair` CLI. Always pass `--as {{AGENT}}`.

## Delegating work

If you delegate implementation to subagents, you still own the pair loop: requests, responses,
retries and verdicts. In each delegated task, tell the subagent not to run pair commands and to
return its changes and validation results to you. Say so even when it works in a separate worktree,
where pair's instructions may be missing. Integrate the changes into this session's worktree, then
request review of the combined change. Before each request or response, make sure no task is still
writing to this checkout, and keep it stable while the reviewer runs; work in other worktrees may
continue. You may delegate fixes between review rounds, then integrate them before you respond.

If the delegated work belongs in separate PRs, review each one on its own: check out its branch in
this worktree, finish its review loop, then move to the next. Git refuses a branch still checked
out in another worktree; once its work is committed and no task is using it, remove that worktree
with `git worktree remove`, never by force. Or ask the user to run one `pair start --worktree`
session per PR.

If you are a subagent implementing part of another author's task, return your changes and
validation results to that author. Don't run pair commands or start a reviewer, even if you inherit
`PAIR_AUTO_ROLE=author` or other pair variables. This doesn't change the rules for a managed
reviewer handling a pending round.

## Auto mode

At session start and after a clear or compaction, check `PAIR_AUTO_ROLE` in your shell before
Expand All @@ -14,14 +35,14 @@ choosing the pair workflow below.
In auto mode the launcher sets `PAIR_BIN` to its own CLI. Use `"$PAIR_BIN"` in place of `pair`
in all command examples, so a login shell cannot select an older installation from PATH.

If `PAIR_AUTO_ROLE=author`, pair owns the reviewer. After finishing a task, send your request as
usual. `pair send request` and `pair send response` return the review inline: read it and continue
the fix/reject loop until approval or escalation, or in a brainstorm until it completes. In
interactive Claude Code, run these commands and managed retry waits with Bash's
`run_in_background: true`, end your turn, and read their output when the completion notification
arrives. Reviews can exceed the foreground Bash timeout. This
background command is active review work, not an idle wait loop. Do not register, call `pair_listen`,
or run idle waits.
If `PAIR_AUTO_ROLE=author`, pair owns the reviewer. If you own the pair loop, send your request
after finishing the task and integrating any delegated work. `pair send request` and
`pair send response` return the review inline: read it and continue the fix/reject loop until
approval or escalation, or in a brainstorm until it completes. In interactive Claude Code, run
these commands and managed retry waits with Bash's `run_in_background: true`, end your turn, and
read their output when the completion notification arrives. Reviews can exceed the foreground Bash
timeout. This background command is active review work, not an idle wait loop. Do not register,
call `pair_listen`, or run idle waits.

If a managed review fails, the request stays on disk. Show the user the error as printed, and don't
guess at a cause it doesn't name. Retry once with `pair wait --as {{AGENT}}`. If the same failure
Expand Down Expand Up @@ -71,7 +92,7 @@ cancelled by you or the user), don't restart it. Tell the user what happened.

## Ask {{PARTNER}} for a review (you are the author)

When you finish a task:
When you own the pair loop and finish a task, including integrating any delegated work:

1. Send a request with what changed and why, what to focus on, and the files touched.
```
Expand Down
2 changes: 1 addition & 1 deletion src/auto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ export async function startAuto(options: AutoOptions): Promise<number> {
heartbeat = setInterval(() => sendGuardian({ type: "heartbeat" }), 1000);
for (const name of ["SIGINT", "SIGTERM", "SIGHUP"] as const) process.on(name, signal);
// No run-specific path: Claude records the system prompt and reuses it when the conversation is resumed in a later run.
const authorPrompt = `You are the interactive author in pair auto mode, with ${reviewer} as your automatically managed reviewer. The pair CLI is "$PAIR_BIN", which the launcher sets for each run; use it in place of pair in every example below. Follow the pair review rules. After completing a task, feed a Markdown summary, review focus and file list through stdin to pair send request --as ${options.author} -. Follow-up replies use pair send response --as ${options.author} - with the fix/reject explanations on stdin. In this mode both commands return the review inline: read it, verify each finding, fix or reject it, and send a response until approval or escalation. To brainstorm a design with ${reviewer} before a task, use pair send request --brainstorm: each contribution comes back inline the same way, and you answer with pair send response until ${reviewer} completes it. Do not register, call pair_listen, or start idle waits in auto mode. ${FAILED_REVIEW_RULE.replaceAll("{{AGENT}}", options.author)} For interactive Claude Code, run managed send and retry commands with run_in_background: true in the Bash tool, end your turn, and read their output on the completion notification. A reviewer can take longer than the foreground Bash timeout; backgrounding the active review command is different from idle polling. Do not start your own reviewer processes. Wait for the user's task.`;
const authorPrompt = `You are the interactive author in pair auto mode, with ${reviewer} as your automatically managed reviewer. The pair CLI is "$PAIR_BIN", which the launcher sets for each run; use it in place of pair in every example below. Follow the pair review rules. After completing a task, feed a Markdown summary, review focus and file list through stdin to pair send request --as ${options.author} -. Follow-up replies use pair send response --as ${options.author} - with the fix/reject explanations on stdin. In this mode both commands return the review inline: read it, verify each finding, fix or reject it, and send a response until approval or escalation. To brainstorm a design with ${reviewer} before a task, use pair send request --brainstorm: each contribution comes back inline the same way, and you answer with pair send response until ${reviewer} completes it. If you delegate implementation, tell subagents not to run pair commands and to return their changes and validation results; you own the review loop, integrate their work here (or, for separate PRs, review each branch here in turn), and keep this checkout stable during each review round. Do not register, call pair_listen, or start idle waits in auto mode. ${FAILED_REVIEW_RULE.replaceAll("{{AGENT}}", options.author)} For interactive Claude Code, run managed send and retry commands with run_in_background: true in the Bash tool, end your turn, and read their output on the completion notification. A reviewer can take longer than the foreground Bash timeout; backgrounding the active review command is different from idle polling. Do not start your own reviewer processes. Wait for the user's task.`;
// The user's options go first; codex gets -- before the prompt so a multi-value option like --image can't take it.
const authorArgs = options.author === "claude"
? [
Expand Down
Loading