agentleFS
kyungminleekyungminlee/agent-chat/SKILL.md

agent-chat

Skill0 starsChanged 3 months agoMITView on GitHub

Set up a shared chat room in a temp directory so multiple agents running at the same time (subagents, or separate Claude Code sessions in different terminals) can send each other messages, ask questions, and coordinate work while they run. Use this whenever the user wants agents to talk to each other, message or ping each other, hand off work between agents, run a debate or review between two agents, share findings live instead of only at the end, or coordinate parallel workers - and also when they describe the mechanism rather than naming it, e.g. "have the agents communicate through a folder", "a shared inbox/mailbox/scratch dir for agents", "let session A tell session B what it found", or "a message bus for my agents". Reach for it even if the user does not say "chat".

4 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions4 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 4

    1. profbernardoj/everclaw★ 112same name
    2. vicnaum/vics-agent-skills★ 53same name
    3. merijnvanes/agent-chat★ 1same name
    4. ZwaarContrast/skills★ 1same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 2 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    All of it goes through one script — don't hand-roll file writes into the room, because the cursor and ordering invariants are easy to break …

    line 17
  2. Distinctive:

    Expect your opening messages to cross, and don't re-answer: If two agents both open with a broadcast, each one composes before the other's …

    line 125
  3. Very specific:

    Don't chain say and leave in one shell command: If the say goes out mangled you've already left and can't post a correction.

    line 166

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Agent Chat

A chat room is a directory under $TMPDIR/agent-chat/<room>/. Every message is one immutable JSON file named with a nanosecond timestamp, so listing the directory in sorted order is the conversation. Nobody locks anything; writes land via os.rename(), which is atomic, so a reader never sees half a message.

Each agent has its own cursor file, which is what lets read return "what's new for me" without disturbing what anyone else has seen. 120 concurrent writers were verified to produce 120 correctly ordered messages with none lost.

All of it goes through one script — don't hand-roll file writes into the room, because the cursor and ordering invariants are easy to break by accident:

python3 ~/.claude/skills/agent-chat/scripts/chat.py <command> ...

Setting up a conversation

Two things every participant needs: a name and the room name. Export them once per agent so no later command has to repeat them:

export AGENT_CHAT_NAME=reviewer      # who you are; must be unique in the room
export CHAT="python3 $HOME/.claude/skills/agent-chat/scripts/chat.py"
$CHAT join design-review --role "reviews the API surface for breaking changes"

--role is worth filling in. It shows up in who, and it's how a peer decides whether you're the right agent to ask something.

By default a joiner's cursor starts at the end of the room, so arriving late doesn't bury you in backlog. Pass --history to replay everything instead.

Launching the participants

Subagents in one session — spawn them in a single message so they run concurrently, and give each one its name, the room, and the exact command:

You are builder in the agent-chat room refactor. Start with: export AGENT_CHAT_NAME=builder; export CHAT="python3 $HOME/.claude/skills/agent-chat/scripts/chat.py"; $CHAT join refactor --role "applies the edits" Then $CHAT wait refactor --timeout 240 for instructions from planner. When your work is finished, $CHAT say refactor --type done -m "<summary>".

Separate terminals / sessions — they share /tmp, so the same room name is all they need. Tell the user to run the join line in each session. If the sessions run as different users, set AGENT_CHAT_DIR to a path both can write.

Commands

CommandWhat it's for
join <room> --role "..."register, announce yourself, see who's already here
say <room> -m "text"post to everyone
say <room> --to bob -m "text"direct message — only bob and you can see it
say <room> --reply-to 7 -m "text"thread a reply onto message #7
say <room> --type done -m "..."tag a message: question, answer, status, done
read <room>messages new to you since last read; advances your cursor
read <room> --peeksame, but don't advance the cursor
read <room> --alleverything visible to you, from the top
wait <room> --timeout 300block until something new arrives, print it, return
wait <room> --from aliceblock until alice specifically says something
who <room>roster with roles and how long since each was last active
log <room> --tail 20full transcript, for a final summary
leave <room> -m "..."announce departure and deregister
rooms / clean [<room>]list rooms / delete one (or all)

read and wait skip your own messages, since echoing your own words back at you wastes context; pass --mine if you want them, or use log for the raw transcript. Add --json to read, wait, who, and log when you want to parse rather than read. Omit -m on say to take the message from stdin — better for multi-line payloads like code or log excerpts than fighting shell quoting.

wait exits 0 when it delivers messages and 2 on timeout, so a timeout is detectable in a shell conditional. Use --timeout-exit 0 if you'd rather treat "nobody answered" as normal.

Making the conversation actually work

The hard part of multi-agent chat isn't transport, it's that agents talk past each other or wait forever. A few habits prevent nearly all of it.

Compose messages on stdin whenever they contain code. Your shell expands $VAR, $(...) and backticks inside a double-quoted -m before chat.py ever runs, so a message quoting a Makefile recipe or a shell snippet arrives with those tokens silently blanked — and the send still reports success. Pipe or heredoc instead, which passes the bytes through untouched:

python3 <SKILL_DIR>/scripts/chat.py say "$CHAT" --to runner <<'EOF'
The rule is: $(CXX) $(CXXFLAGS) $< -o $@
EOF

say echoes back the text it actually stored — read that echo. It is there so you can catch mangling at send time, while you can still correct it. Nothing is treated as a format string, so % needs no escaping; write 60%, not 60%%.

Block with wait, never poll with read in a loop. A read loop burns a tool call and a slice of context every few seconds and adds latency besides. wait sleeps in one process and returns the instant a message lands.

Always bound the wait, and decide in advance what a timeout means. A peer can crash, finish early, or never have been started. Pick a timeout that fits the work you're waiting on, and on expiry do something definite — proceed with your best assumption, who to see if they're still around, or report the stall to the user. Silently waiting again is how a room deadlocks.

Announce that you're done. Send --type done with a one-line summary before you stop. Peers waiting on you have no other way to learn you're finished, and done is the difference between them continuing and them burning their full timeout.

Say what you need, not that you have a need. "Blocked" tells a peer nothing. --to builder -m "parse_config() drops the trailing newline — line 88 of config.py. Can you take it, or should I?" is answerable in one message. Long round-trips are the main cost here, so front-load the context.

Expect your opening messages to cross, and don't re-answer. If two agents both open with a broadcast, each one composes before the other's lands, so both arrive asking questions the other has already answered. This is the normal case, not bad luck. Two habits fix it: read once immediately before composing any long reply, and when you find your question already answered, say so in one line and move on rather than restating everything. Better still, have one side open and the other wait first — see the two-agent pattern below.

Send paths, not payloads. Room messages are for coordination. Write real artifacts to a normal file and send the path — a 500-line diff in a chat message costs every reader their context window.

Address your messages. Broadcast for anything the room should know; --to for anything only one agent needs. In a busy room, unaddressed chatter forces everyone to read everything.

One agent decides. With three or more participants, name a coordinator up front — it assigns work, resolves disagreements, and declares the end. Peer-to-peer negotiation between equals tends to converge slowly or not at all.

Patterns

Coordinator and workers. The coordinator joins, spawns workers, DMs each an assignment, then waits in a loop consuming done messages until all workers have reported or the deadline passes. Workers wait for their assignment, do the job, post done, and leave.

Two-agent debate or review. Decide up front which side opens; the other waits first. If both open at once their messages cross and you burn an exchange re-answering each other. After the opener lands, alternate wait --from <peer> and say --reply-to <n>. Agree in advance on how it ends — usually a fixed number of exchanges, or either side posting done — otherwise two agents will happily agree with each other forever.

Live findings channel. Parallel explorers each join and post --type status as they discover things. The reader doesn't need to wait for anyone to finish; read picks up whatever has landed. Cheap, and it lets one agent's discovery redirect another mid-run.

When something looks wrong

Don't chain say and leave in one shell command. If the say goes out mangled you've already left and can't post a correction. Send, look at the echo, then leave.

wait --from <peer> returns on their join too, since joins are ordinary messages. That's useful — a bare wait right after joining is how you learn a peer has actually started, which join itself won't tell you. But it means a --from wait can return something that isn't the reply you wanted; check the message before assuming your question was answered, and wait again if not.

log <room> --tail 30 shows the whole conversation including join/leave events and is almost always enough to see what happened: who never joined, who never answered, who left early. who <room> shows last-seen ages — an agent that hasn't been seen in minutes is finished or dead, not thinking.

The room lives in /tmp, so it does not survive a reboot and holds nothing you'd want to keep. Copy anything worth retaining out with log --json before running clean.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.