Skip to content

dxfrontier/Pair-Claude

Repository files navigation

Pair-Claude

License: MIT Go Version Release Platforms Built by dxfrontier

Turn any Claude Code session into a live pair-programming session.

Pair-Claude wraps the Claude Code CLI in a pseudo-terminal, adds a tiny web server, and lets your teammates watch and type into the same session — right from their browser.

$ pair-claude
[pair-claude] ready · share with: \share (server idle on :8765)

> \share
[pair-claude] share URL (read-write): http://simon-laptop.tail.ts.net:8765/s/a1b2c3...
[pair-claude] (copied to clipboard)
[pair-claude] viewer joined (1 connected)

Your colleague opens the link, sees a live terminal with a statusbar, and can type alongside you. That's it. No screen-share lag, no "can you scroll up?", no waiting for someone to share their screen.


Why?

You're knee-deep in an investigation. Claude is helping you trace a bug. A colleague on Slack says "can I look at what you're seeing?"

With a regular screen share, they watch passively. With Pair-Claude, they join your terminal — full read/write access, real-time, zero setup. Both of you talk to Claude, both of you see the output, both of you can steer.

How It Works

┌─────────────────────────────┐
│       Your Terminal         │
│   (pair-claude wraps claude)│
└──────────┬──────────────────┘
           │ PTY
    ┌──────┴──────┐
    │  Broadcast  │──── Web Server (:8765)
    │     Hub     │         │
    └─────────────┘    ┌────┴─────┐
                       │  Browser  │  colleague's xterm.js terminal
                       └──────────┘
  • Single binary. No Docker, no Node, no runtime dependencies (besides claude in your PATH).
  • Cross-platform. macOS, Linux, Windows 10/11. Native PTY on each (Unix PTY / ConPTY).
  • Tailnet-native. Designed for Tailscale networks. Auto-discovers your MagicDNS hostname. No TLS needed — Tailscale encrypts end-to-end.
  • Instant replay. Late joiners see the last 64 KB of terminal output — enough context to jump right in.
  • Zero config. Start it, share the link, done.

Quick Start

Install

# From source (requires Go 1.22+)
go install github.com/dxfrontier/pair-claude/cmd/pair-claude@latest

# Or clone and build
git clone https://github.com/dxfrontier/Pair-Claude.git
cd Pair-Claude
go build -o pair-claude ./cmd/pair-claude

Use

# Start a shared Claude session
pair-claude

# Auto-share on startup (copies URL to clipboard — just paste!)
pair-claude --auto-share

# Pass arguments to claude as usual
pair-claude --model sonnet
pair-claude --resume

Inside the session, use backslash commands:

Command Description
\share Generate a share URL — read-write (copies to clipboard)
\share --readonly Generate a read-only URL (alias: \share -r)
\revoke Revoke all tokens, disconnect all viewers
\status Show active share info and client count
\help List available commands

Auto-Share

With --auto-share, the share URL is generated before Claude starts and automatically copied to your clipboard. You just paste it to your colleague — no need to type any commands:

$ pair-claude --auto-share
[pair-claude] ready · share with: \share (server idle on :8765)
[pair-claude] share URL copied to clipboard — just paste!

If the clipboard isn't available (e.g. headless server), the URL is printed to stderr instead.

Share

  1. Type \share in your running session
  2. Send the URL to your colleague (it's also copied to your clipboard automatically)
  3. They open it in any browser — instant live terminal with statusbar

Multiple colleagues can connect simultaneously. Everyone sees the same output, everyone can type. You'll see [pair-claude] viewer joined (N connected) in your terminal when someone connects.

Read-Only Sharing

Want someone to observe without being able to type?

> \share --readonly
[pair-claude] share URL (read-only): http://simon-laptop.tail.ts.net:8765/s/f9e8d7...

Read-only viewers see the full live terminal but their keyboard input is silently dropped. Read-write and read-only links use separate tokens — revoking invalidates both.

Stop Sharing

  • Type \revoke to kill the share and disconnect all clients
  • Or just exit Claude normally — the server shuts down cleanly
  • Tokens auto-expire after 8 hours (configurable via PAIR_TOKEN_TTL)

Control API

Pair-Claude exposes a local HTTP API for automation — Claude Code hooks, scripts, Slack bots, you name it.

# Generate a share token and get the URL
curl -X POST http://localhost:8765/api/share
# → {"token":"a1b2c3...","url":"http://..."}

# Revoke the active token
curl -X POST http://localhost:8765/api/revoke
# → {"status":"revoked"}

# Check status
curl http://localhost:8765/api/status
# → {"active":true,"clients":2,"url":"http://..."}

Claude Code Hook Example

Auto-share every session by adding a hook to .claude/settings.json:

{
  "hooks": {
    "SessionStart": [
      {
        "command": "curl -s -X POST http://localhost:8765/api/share | jq -r .url"
      }
    ]
  }
}

Configuration

All configuration via environment variables. Sensible defaults — you probably don't need to change anything.

Variable Default Description
PAIR_PORT 8765 Web server port
PAIR_HOSTNAME (auto) Override hostname in share URL
PAIR_TOKEN_TTL 8h Token lifetime
PAIR_REPLAY_BYTES 65536 Replay buffer size (bytes)
PAIR_CLAUDE_BIN claude Path to Claude binary
PAIR_BIND 0.0.0.0 Bind address

Security Model

  • Trust boundary = your Tailnet. If someone can reach the port, they're on your network.
  • Token-protected URLs. 32 random bytes, hex-encoded, timing-safe comparison. Protects against accidental access, not determined attackers on the same network.
  • No TLS. Tailscale already encrypts everything end-to-end.
  • Tokens are ephemeral. In-memory only, gone when the process exits.
  • Read-write by default. \share gives full access — pair programming means both people drive. Use \share --readonly for observers.

Cross-Platform Builds

make build              # current platform
make build-all          # all platforms

# Individual targets
make build-linux-amd64
make build-linux-arm64
make build-mac-amd64
make build-mac-arm64
make build-windows

Outputs go to dist/.

Architecture

cmd/pair-claude/       Entry point, lifecycle, goroutine wiring
pty/                   Platform PTY abstraction (Unix + Windows ConPTY)
broadcast/             Hub (pub/sub) + ring buffer for replay + viewer events
server/                HTTP server, WebSocket, Control API, embedded frontend
control/               Input parser for \-commands
config/                ENV var handling
tailscale/             Hostname auto-discovery
internal/rawmode/      Platform raw-mode for stdin
internal/clipboard/    Platform clipboard copy

The frontend is a single HTML file with vendored xterm.js — no npm, no build step, no CDN. Everything is embedded in the binary via go:embed.

License

MIT


About

Built by dxfrontier — we help teams ship faster with Claude Code and AI-assisted development.

Built with Claude, for people who pair with Claude.

About

Live pair-programming for Claude Code sessions — share your terminal with teammates over your Tailnet.

Topics

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors