-
Notifications
You must be signed in to change notification settings - Fork 0
Install
Hosting a jam is macOS and Linux — the host is tmux. Windows hosts through WSL2: install
claude-jam inside the distribution and run it there, where tmux and claude both live. A native
Windows host was investigated and dropped (nothing reattaches to a running ConPTY, so the host's
own operator would be the one person stuck on the slow proxied path).
Joining is macOS, Linux, and — since v0.32 W1 — Windows, natively: node ≥ 22 and Windows Terminal, no WSL and no tmux. Read The Windows client, honestly before you rely on it: it is implemented and unit-tested on real Windows in CI, and no human has run it yet.
Required to HOST. A guest needs only the first row:
| what | why | check |
|---|---|---|
| node ≥ 22 | the daemon and both clients — the only thing a guest needs | node --version |
| tmux | the host's session is a tmux session | tmux -V |
| claude on PATH | the actual Claude Code CLI | claude --version |
Optional, each unlocking one thing:
| what | unlocks | without it |
|---|---|---|
ttyd |
--view, the read-only browser view |
the flag refuses at startup, with the reason |
cloudflared |
--tunnel |
the flag refuses at startup, with the reason |
tailscale |
--funnel (and the printed join line uses your tailnet IP) |
the flag refuses; LAN addresses are printed instead |
git |
/diff |
/diff says the cwd is not a git repository; /files still works |
pngpaste |
/paste is faster |
macOS falls back to osascript, which is built in |
A guest needs node, tmux is not required for them, and the claude CLI is not required
either — a guest only runs the client. On Windows a guest also needs Windows Terminal.
Not on the registry yet. As of 0.23.0 claude-jam has never been published to npm, so this
command 404s:
npm i -g @roypadina/claude-jam # NOT YET PUBLISHED — 404 until it isUntil it is, use a local tarball. It installs the identical package, from the same files list,
through the same bin shim — which is what makes it a fair rehearsal of the published path:
git clone https://github.com/roypadina/claude-jam && cd claude-jam
npm install && npm pack # → roypadina-claude-jam-0.23.0.tgz
npm i -g ./roypadina-claude-jam-0.23.0.tgzThe same package Homebrew ships, and it installs the same two commands. It needs node ≥ 22 and
nothing else — no tmux and no claude are required to join a jam.
Once published: upgrading is npm i -g @roypadina/claude-jam@latest, uninstalling
npm rm -g @roypadina/claude-jam. The command is still claude-jam either way — the scope
is only how npm names the package.
Implemented, unit-tested on real Windows in CI, and never run by a human. Nobody working on
claude-jam has a Windows machine. Every decision the Windows code makes is a pure function
asserted on a windows-latest runner on every push — the PowerShell argv for a clipboard read,
the %APPDATA% path, the ACL that replaces 0600, the sound table, the key sequences, the
terminal check — and the client's entry point is spawned and checked there for real. What no
runner can do is look or listen: no toast has been seen, no sound heard, no key pressed in
Windows Terminal, no jam joined from Windows.
# NOT on npm yet — build the tarball, then install it globally.
git clone https://github.com/roypadina/claude-jam; cd claude-jam
npm install; npm pack
npm i -g .\roypadina-claude-jam-0.23.0.tgz
claude-jam join <invite-link>-
Windows Terminal is required. It ships with Windows 11 and is a free Microsoft Store install
on Windows 10. The legacy
cmd.execonsole is refused by name, with the reason, rather than painting escape codes at you — it has no alternate screen buffer and no ANSI by default. Git Bash (mintty), ConEmu with ANSI on, and the VS Code terminal work too.JAM_ASSUME_ANSI=1skips the check if you are certain. -
Client only.
claude-jam host, the launcher menu,sessions,invite,find,endandcleanall refuse with the WSL2 route;claude-jamwith no arguments prints that instead of a menu. -
No F3. It attaches tmux on the machine running it, and that machine is the host's. F2 (the
live view),
/answer,/send,/paste,/export,/c,/pingall work. -
Shift+Enter needs one line of config, because Windows Terminal sends a plain Enter for it.
End a line with
\, or add to theactionsarray in WT'ssettings.json:{ "command": { "action": "sendInput", "input": "\\u001b[13;2u" }, "keys": "shift+enter" } -
No
0600. Private files get an NTFS ACL granting only your account (icacls /inheritance:r /grant:r <you>:F) — the equivalent, not the same thing.
If you try it, please report what happened, including what looked wrong. That is the only way any
of this becomes verified. The per-capability table lives in the repo at docs/COMPATIBILITY.md.
brew install roypadina/tap/claude-jamThat installs two commands: claude-jam (the real one) and jam (a deprecated alias
of it, kept so anything you already typed still works). Nothing in the tool prints jam.
Upgrading:
brew update && brew upgrade claude-jamgit clone https://github.com/roypadina/claude-jam
cd claude-jam
npm install
./claude-jam --helpThere is no build step. npm install pulls five runtime dependencies (ws, ink, react,
@inkjs/ui and ink-text-input) and nothing else. Run it as ./claude-jam … from the
checkout, or npm link to put both commands on your PATH.
claude-jam --helpExpected: a usage block whose first line is
usage: claude-jam (no arguments) the launcher menu: host, join,
and which lists claude-jam host, join, invite, invites, sessions, ls, end, kill,
clean and remote. It should never print a bare jam command — that is a lint in the
test suite.
claude-jam sessionsExpected on a machine with no jam running:
no jams — `claude-jam host` starts one, and this list only ever shows claude-jam's own sessions
That command is read-only and safe to run at any time; it enumerates only claude-jam's own
state directories ($TMPDIR/claude-jam-<port>), never tmux list-sessions.
The alias, if you want to confirm it:
jam --help # same output — it execs claude-jam| path | what | when it goes |
|---|---|---|
$TMPDIR/claude-jam-<port>/ |
the state dir, mode 0700: session.json, token.json, roster.json, the generated settings.json, system-prompt.txt, the outbox |
when the jam ends, or claude-jam clean
|
~/.config/claude-jam/history |
your own last 50 submissions per client (mode 0600) | never automatically — delete it yourself |
<cwd>/jam-uploads/ |
files guests uploaded (host side) | never automatically |
./jam-downloads/ |
files you took with /get (guest side) |
never automatically |
./jam-session-<id>.jsonl |
a transcript you took with /export
|
never automatically |
$XDG_CONFIG_HOME is honoured for the history file when it is set to an absolute path.
On Windows those paths are %TEMP%\claude-jam-<port>\ and
%APPDATA%\claude-jam\history. There are no mode bits there: the same files get an NTFS ACL
granting only the current user (icacls /inheritance:r /grant:r <you>:F, and (OI)(CI) on the
directory so what is created inside it inherits the single entry). That is the equivalent of
0700/0600, not the same mechanism, and it is worth knowing which one you are relying on.
Nothing global is touched: the Claude Code hooks live in a generated settings.json passed with
--settings, and the tmux key binding lives on claude-jam's own tmux server (socket
claude-jam-<port>), not yours.
- Hosting a Jam · Joining a Jam
- Installing this from inside an agent: Agent-Install