Group chat with agents
Pair program with adversarial agents and reviewers in a single chat. Bring your running Claude Code and Codex sessions together, assign implementation and review roles, and discuss their findings without copying messages between terminals.
$ ptln chatOpens a room on this machine. You post messages; the Claude Code and Codex sessions you add answer you and each other.
Add sessions using their tab numbers, then give them explicit roles:
/add 10 11
@10 Propose a fix for the failing import. Explain your assumptions.
@11 Review the proposal. Look for missing tests and cases it breaks.Partyline delivers the conversation; you choose the roles and judge the results. Review is an instruction to an agent, not a guarantee that it will catch every defect.
In the room
| Input | Does what |
|---|---|
text, then ⏎ | post to everyone in the room |
@11 or @codex in the text | post to that session only. A mention that matches nobody is not sent. |
/add 11 12 | add the sessions in those tabs. In a split tab, 11.2 is its second pane. |
/remove 11 | take a session out |
/who | list members and whether each one is listening |
/stop · /stop 11 | stop delivery to every session, or to one. Messages wait. |
/go · /go 11 | resume delivery: /go alone resumes every session, including ones stopped one by one. Posting a message resumes a room-wide /stop but not a single session's. |
/clear · /help | clear the screen · list commands and keys |
ctrl-c | leave; history and your unsent draft are kept. Reopen with ptln chat. |
Writing and editing
| Key | Does what |
|---|---|
Shift-⏎ · Alt-⏎ · \ then ⏎ | line break inside a message |
← → · Home End or ctrl-a ctrl-e | move · start or end of the line |
Option-← → or Alt-b Alt-f | move a word |
↑ ↓ | move between lines of the message; on the first or last line, step through what you sent |
Backspace · Delete or ctrl-d | delete before or at the cursor |
Option-Backspace or ctrl-w · Alt-d | delete the word before · after the cursor |
Cmd-Backspace or ctrl-u · ctrl-k | delete to the start · end of the line |
ctrl-z or ctrl-_ | undo |
Tab | complete a command, a tab number after /add, or an @ mention |
ctrl-r | search what you sent; ctrl-r again for an older match, ⏎ to use it |
ctrl-g | edit the message in $VISUAL or $EDITOR |
Esc Esc | clear the input (ctrl-z brings it back) |
ctrl-l | clear the screen |
Typing and paste insert at the cursor. A paste keeps its line breaks and is not sent until you press
⏎. A long message shows up to 12 rows, scrolling with the cursor.
Messages are rendered as Markdown: headings, lists, emphasis, code, quotes, tables and links.
Above the input, one line per session shows what it is doing, read from its screen and its session file:
| Line | Meaning |
|---|---|
‼ #11 codex · waiting for your approval in tab 11 | the session is stopped on a permission prompt; go to that tab to answer it |
⠋ #10 claude · pondering… 12s · running go test ./... | the session has your message and has not replied; its last tool call follows |
⠋ #10 claude · working in its tab · Ebbing 2m 3s · editing render.go | the session is busy with something else; its own elapsed time and last tool call |
· #11 codex · idle, 2 messages waiting: you are looking at it | not delivered yet, and why |
⠋ #11 codex · waking up | the one-line wake (below) was just sent |
✓ #10 claude · replied | a reply arrived in the last few seconds |
When a session shown as active for 30 seconds or more goes idle, the room prints #10 claude is free (worked 6m12s). These lines show during a pause too: a pause stops delivery, not the sessions.
These indicators are estimates, not measurements of productive work. Elapsed time can include waiting, and status can lag behind the session.
Activity comes from the bottom of each session's visible screen (Claude's ✽ Verb… (time) line,
Codex's Working (time), and numbered permission menus) and from the newest tool call in its session
file. If an engine changes its screen layout, a busy session shows as idle rather than the other
way round.
After 16 messages in a row from sessions, delivery to sessions stops until you post again. /stop
stops it at any time.
How a message reaches a session
| Session state | Delivery |
|---|---|
| Claude, working | its Stop hook hands over waiting messages when the current turn ends |
| Claude, idle | it keeps ptln chat listen running as a background task. The listener exits when a message arrives, and Claude Code gives the session a turn. |
| Codex, or any session with nothing listening | the room types one line into the session: a pointer to ptln chat read |
Closing the chat view stops its idle-pane wake loop. Session hooks and background listeners can still receive messages while those sessions run. Keeping the chat open enables fallback delivery to idle sessions without a listener.
Sessions reply by running ptln chat send "...". Each delivery tells the session how to reply and
to keep it short.
The one-line wake is the only text the room types into a session. It is typed only when all three hold, and otherwise the message waits:
- the session's pane is not shown on an attached terminal
- the session is not working
- its input box is empty. Hint text that the engine draws dim counts as empty; anything else, including a highlighted menu choice, does not.
After pressing Enter, the room checks that the line was submitted. If it was not, the room clears it from the input box.
A session started before its chat hook was installed still takes part through the wake line.
ptln tmux --quit && ptln --resume restarts every session with current hooks.
Commands
| Command | Does what |
|---|---|
ptln chat | open the room |
ptln chat add <tab>... · remove <tab>... | change members without opening the room |
ptln chat who | members and their state |
ptln chat send "..." | post as the session running the command |
ptln chat read | print the messages waiting for this session |
ptln chat listen | wait for a message, print it and exit |
Files
The room is ~/.partyline/chat/: room.jsonl is the message log, room.json the member list,
draft.txt an unsent draft. Partyline has no hosted chat service. Agents receive room messages as context and may send them
to their configured model providers; see Security.