Standalone toolkit for running a dual-agent coding workflow with Claude Code and Codex:
- isolated workspaces
- independent planning
- plan cross-review
- plan revision
- plan consensus
- one-sided execution
- peer implementation review
It also includes a separate live mode for tmux-based side-by-side supervision when you want to watch both interactive sessions in real time.
This repo is designed to install cleanly as a Claude Code skill pack while still exposing a direct CLI launcher.
Current version: v0.16.0
Peer Forge now checks for new releases when a skill loads. Upgrade prompt state lives in ~/.peer-forge/, with support for auto-upgrade, snooze, disable-check, and just-upgraded notices.
peer-forge/
├── SKILL.md
├── peer-consensus/
│ └── SKILL.md
├── peer-forge-live/
│ └── SKILL.md
├── codex-collab/
│ ├── SKILL.md
│ └── scripts/
│ └── codex-headless-collab.sh
├── peer-forge-upgrade/
│ └── SKILL.md
├── tools/
│ ├── live_api.py
│ ├── live_protocol.py
│ ├── live_state.py
│ ├── live_tmux.py
│ ├── peer_consensus.py
│ └── peer_live.py
├── bin/
│ ├── peer-forge
│ ├── peer-consensus
│ ├── peer-forge-live
│ └── peer-forge-upgrade
├── scripts/
│ ├── live-api-smoke.sh
│ ├── live-apply-smoke.sh
│ ├── live-smoke.sh
│ └── live-web-smoke.sh
├── web/
│ └── live/
│ ├── index.html
│ ├── app.js
│ ├── render.js
│ ├── store.js
│ └── app.css
├── setup
├── uninstall
├── README.md
├── README.zh-CN.md
├── CHANGELOG.md
├── GITHUB_METADATA.md
├── LICENSE
└── VERSION
git clone git@github.com:andrewbai/peer-forge.git ~/.claude/skills/peer-forge
~/.claude/skills/peer-forge/setupAfter that, Claude Code can discover:
/peer-forge/peer-consensus/peer-forge-live/codex-collab/peer-forge-upgrade
If Claude Code was already open, restart it once so it reloads the skills.
From the target project root:
git clone git@github.com:andrewbai/peer-forge.git .claude/skills/peer-forge
./.claude/skills/peer-forge/setup --localThis keeps the whole repo inside the project, then registers the sibling skill links:
.claude/skills/peer-consensus -> peer-forge/peer-consensus.claude/skills/codex-collab -> peer-forge/codex-collab
Global install:
~/.claude/skills/peer-forge/bin/peer-forge \
--repo /path/to/project \
--task "Implement the change." \
--apply-finalProject-local vendoring:
./.claude/skills/peer-forge/bin/peer-forge \
--repo . \
--task "Implement the change." \
--apply-finalUseful runtime flags:
--agent-timeout-seconds 1800sets a per-stage Claude/Codex timeout. Use0to disable it.--supervisestreams Claude/Codex output to the terminal and writes prefixed verbose logs without changing the protocol.--supervise-checkpointsadds interactive stage-boundary checkpoints on top of--supervise. It supportscontinue,inspect,retry,note, andabort, and requires--taskor--task-file.--cleanup-workspacesremoves the temporary isolated workspaces after the run.--keep-workspaceskeeps those isolated workspaces even when cleanup is enabled.--keep-run-dirremains as a deprecated alias.
Upgrade the installed checkout:
~/.claude/skills/peer-forge/bin/peer-forge-upgradeCheck whether an upgrade is available without modifying the checkout:
~/.claude/skills/peer-forge/bin/peer-forge-upgrade --checkLive tmux mode:
~/.claude/skills/peer-forge/bin/peer-forge-live \
--repo . \
--task "Have Claude Code and Codex draft plans independently, cross-review, and converge while I supervise live."Recommended detached + browser-supervised startup (no tmux required):
~/.claude/skills/peer-forge/bin/peer-forge-live \
--repo . \
--task "Have Claude Code and Codex draft plans independently, cross-review, and converge while I supervise live." \
--transport pty \
--no-attach \
--open-uiTmux-based detached startup (requires tmux):
~/.claude/skills/peer-forge/bin/peer-forge-live \
--repo . \
--task "Have Claude Code and Codex draft plans independently, cross-review, and converge while I supervise live." \
--no-attach \
--open-uiIf you also want to call the local control API directly from curl or your own tooling:
~/.claude/skills/peer-forge/bin/peer-forge-live \
--repo . \
--task "Have Claude Code and Codex draft plans independently, cross-review, and converge while I supervise live." \
--no-attach \
--open-ui \
--print-control-tokenDetached startup JSON now includes:
control_urlevents_stream_urlweb_urlcontrol_tokenwhen--print-control-tokenis setprocess_mode(pty-detached,pty-inline, ortmux)owner_pidandowner_alivefor detached PTY runsstatus_commandandstop_commandfor lifecycle management
Check a detached PTY run:
~/.claude/skills/peer-forge/bin/peer-forge-live status \
--state-file /path/to/state.json \
--open-uiStop a detached PTY run:
~/.claude/skills/peer-forge/bin/peer-forge-live stop \
--state-file /path/to/state.jsonpeer-forge-live now starts Claude without --bare by default so Claude Max, OAuth, and keychain-backed auth continue to work in interactive live sessions.
Only opt into bare mode when you explicitly want it:
~/.claude/skills/peer-forge/bin/peer-forge-live \
--repo . \
--task "Run the live workflow with Claude bare mode enabled." \
--claude-bareResume or re-attach to an existing live run:
~/.claude/skills/peer-forge/bin/peer-forge-live resume \
--state-file /path/to/state.json \
--open-uiPreview how an approved live run would land back into the target repo:
~/.claude/skills/peer-forge/bin/peer-forge-live apply \
--state-file /path/to/state.jsonActually apply and commit onto a new branch:
~/.claude/skills/peer-forge/bin/peer-forge-live apply \
--state-file /path/to/state.json \
--apply \
--commitApply even when the target repo has unrelated dirty paths:
~/.claude/skills/peer-forge/bin/peer-forge-live apply \
--state-file /path/to/state.json \
--apply \
--allow-dirty-targetclaudeCLI installed and logged incodexCLI installed and logged intmuxavailable in PATH forpeer-forge-live- Python 3 available as
python3 - Git available as
git
Quick checks:
claude -v
codex -V
tmux -V
python3 --version
git --versionIf you do not want to spell out the full CLI, use the main skill:
/peer-forge 处理这个任务:.../peer-forge refactor this module so Claude Code and Codex draft independently, review each other, and converge
peer-forge is the easier front door:
- task-only usage is valid
- acceptance criteria are optional
- scope is optional
- Creates isolated Claude and Codex workspaces.
- Runs independent planning phases in parallel when possible.
- Makes each side review and revise the other side's plan.
- Uses consensus to choose the final plan base.
- Produces one final implementation plan.
- Lets the chosen side execute that plan.
- Lets the other side review the implementation result, with bounded fix-review rounds if needed.
peer-forge-live is the interactive counterpart to the batch workflow.
Current live scope:
- full plan -> execute -> review -> signoff workflow
- long-lived Claude and Codex sessions
- tmux panes for Claude, Codex, and the supervisor
- symmetric supervisor notes only
- protocol-level read-only enforcement for non-write phases
- package-based landing back into the target repo after approval
Current live phase flow:
- independent plans
- cross-review
- revision
- consensus
- final plan
- plan signoff
- selected-side execution
- peer implementation review
- bounded execution fix/signoff rounds
Startup note:
- The protocol continues automatically after startup, but CLI-native safety prompts are still manual by design.
- In practice, Claude may ask you to confirm entering
bypassPermissionsmode. - Codex may also ask you to trust the generated workspace on some machines or first-run states.
- We intentionally do not auto-press those prompts via tmux, because that is more brittle than letting the human supervisor confirm them once.
Recommended supervision path:
- Start with
--transport pty --no-attach --open-ui(no tmux needed). - Use
web_urlfor the browser dashboard, event feed, artifacts, and boundary controls. - Use
status --state-file ...to check the run andstop --state-file ...to end it. - Use
control_urlpluscontrol_tokenonly when you want direct API or SSE access outside the built-in UI. - Use tmux (
--transport tmux) only when you need CLI-native trust/bypass prompts and raw pane inspection.
Inside the supervisor pane, the main commands are:
statustail claudetail codexinspect claudeinspect codexshow final-planshow packageshow diffshow manifestnote bothwaitcontinueabort
status now also surfaces the selected executor/reviewer, plan/execution approval state, read-only violations, current package summary, and each pane's current mode.
The built-in Web UI drives the same supervisor actions:
StatusqueuesstatusContinueis only enabled at active boundariesAbortqueuesabort- the note form queues
note both <text>
If the supervisor pane dies or you detach and want to repair the session in place:
~/.claude/skills/peer-forge/bin/peer-forge-live resume \
--state-file <target-repo>/.claude/tmp/peer-forge-live/<run-id>/state.json \
--open-uiIf the live run finished and both plan and execution are approved, you can preview or apply the final execution package:
~/.claude/skills/peer-forge/bin/peer-forge-live apply \
--state-file <target-repo>/.claude/tmp/peer-forge-live/<run-id>/state.jsonApply semantics:
applywithout--applyis a dry-run preview only.- Real writes require
--apply. - The default landing branch is
peer-forge/<run-id>. --commitcreates a git commit after applying the package.- Live apply currently supports only git-backed live runs.
- If the target repo HEAD has drifted but the changed paths do not overlap the execution package, preview/apply is allowed automatically.
- If the target repo has unrelated dirty paths, you must pass
--allow-dirty-target. - If dirty paths or drifted paths overlap the execution package, apply stays blocked by default.
--allow-base-driftis the explicit override when drift overlaps the execution package.
Each live run writes artifacts under:
<target-repo>/.claude/tmp/peer-forge-live/<run-id>/
That includes:
state.jsonevents.jsonlsupervisor.logpanes/verbose.logpanes/claude.raw.logpanes/codex.raw.logpanes/supervisor.raw.logturns/<turn-id>/...report.jsonreport.mdapply/history.jsonlapply/<timestamp>-report.jsonapply/<timestamp>-report.md
Manual smoke coverage for live startup and supervisor recovery is included in:
scripts/live-api-smoke.shscripts/live-smoke.shscripts/live-apply-smoke.shscripts/live-web-smoke.shscripts/live-pty-detached-smoke.sh
Each run writes artifacts under the target repo:
<target-repo>/.claude/tmp/peer-consensus/<run-id>/
That directory includes:
- task and config
progress.logsupervisor.logwhen--superviseis enabledcheckpoints/history.jsonlwhen--supervise-checkpointsis enabled- per-checkpoint retry records such as
checkpoints/01-plan-initial-retry-01.json notes/history.jsonlwhen supervisor notes are added- isolated workspaces
- prompts
- model outputs
- per-stage diff packages
- per-stage retry artifacts under
<stage-dir>/retries/ - final plan
- implementation review results
report.jsonreport.md
Runtime behavior:
- Progress logs stream to
stderr, so the terminal shows which phase is currently running. - The same progress lines are also written to
progress.loginside the run directory. - With
--supervise, Claude/Codex stdout and stderr are streamed live to the terminal with prefixes and mirrored into a run-levelsupervisor.log. - With
--supervise, each stage also gets a prefixed<stage-dir>/verbose.logalongside the rawstdout.txtandstderr.txt. - With
--supervise-checkpoints, the run pauses after each major stage boundary. You cancontinue,inspect,retry,note, orabortwithout changing the agent protocol or workspace isolation. retryreruns the current checkpoint stage safely. Parallel plan checkpoints retry both agents together. Write stages restore their stage-entry snapshot before each retry.apply-finalremains inspect/continue/abort only.noterecords a symmetric supervisor note that is injected into both agents' later prompts. Multi-line note entry ends with a line containing only---. Notes added at a checkpoint do not affect retries of that same checkpoint.inspectprints the current stage artifact paths, active supervisor notes, retry attempt summaries,parsed.json,stdout.txt,stderr.txt,verbose.logwhen present, and diff package paths for write stages.- Final machine-readable output stays on
stdoutas JSON. report.jsonandreport.mdare written for completed, aborted, and failed runs.report.jsonincludesprogress_log,supervisor_log,checkpoint_history,checkpoint_events,retry_attempts,notes_history,supervisor_notes, and structuredstage_timingsentries for each Claude/Codex stage.
The simpler front door. Use this when the user wants the workflow without thinking in terms of detailed CLI flags. Task-only usage is valid.
The lower-level workflow when you want more explicit control over task, acceptance criteria, scope, and the exact two-phase protocol.
The live tmux-based full peer workflow when you want to watch both interactive sessions side by side and supervise planning, execution, and review in real time.
Smaller helper for Claude-driven headless Codex collaboration on a bounded file. This is faster, but it is not the same as the full peer workflow.
Self-upgrade helper for refreshing the installed peer-forge checkout through the packaged upgrade script and re-running setup.
- The repo itself is the main skill.
~/.claude/skills/peer-forge/SKILL.mdis directly discoverable by Claude Code. - Sub-skills are registered as sibling symlinks by
setup. - All skill docs route through the
bin/launchers rather than calling the Python entrypoint directly. - Exit codes:
0= approved final result,1= runtime failure,2= run completed but the final candidate was not approved.