Three complementary AI-agent skills for inter-agent messaging on disk:
subagent-protocols (the general pattern), plus simple-agent-comms
and simple-agent-room (two specialized, opinionated variants). Each
skill bundles its own scripts; the whole thing installs with one
command and ships zero Python packages.
| skill | role | when to use | ships |
|---|---|---|---|
subagent-protocols |
general pattern | dispatch a subagent and exchange inbox paths before work begins; pick per-subagent whether to monitor, append, or stay one-way | watch-file.sh (skill-bundled copy) |
simple-agent-comms |
specialized: 1:1 streaming | one coordinator + one subagent with a persistent Monitor on the inbox (low-noise two-way, but one Monitor per subagent) |
bin/watch-file.sh |
simple-agent-room |
specialized: N:N broadcast | many agents sharing one log via simple-room-send / simple-room-monitor (one Monitor total, but everyone sees everything) |
bin/{simple-room-send,monitor,scan} + lib/ |
subagent-protocols is the general alternative: the coordinator
learns each subagent's inbox path via a one-line startup handshake,
and from then on can decide per subagent whether to set up a persistent
Monitor (heavy streaming), append when needed (ad-hoc), or stay
one-way (fire-and-forget). No required shared log, no required
Monitor — pick what each subagent actually needs.
simple-agent-comms and simple-agent-room are the two specialized
opinionated variants of the same general pattern:
simple-agent-comms= general + per-subagent persistentMonitor(1:1 streaming). Best for low-noise two-way with a single subagent. Costs oneMonitorper subagent, so it scales poorly past a handful.simple-agent-room= general + one shared log (N:N broadcast). Best for many agents that need to discover each other. Costs oneMonitortotal but every agent sees every message; self-filter cuts local noise but global volume still grows.
Use subagent-protocols alone when neither specialization fits: many
subagents where you want each conversation to be private and ad-hoc
(no shared log noise, no per-subagent Monitor), or when the set of
subagents is large and uneven (a few hot ones worth streaming, most
just need occasional pings).
The simple-* skills are designed so the agent never has to know
the on-disk paths — it just calls the tools by short name. The
location is a single well-known directory (~/.cache/simple-agent-room/
for rooms, ~/.cache/agent-comms/ for comms), overridable via env var.
One command (idempotent; safe to re-run):
git clone https://github.com/clankercode/agent-file-chat.git
cd agent-file-chat
./install.shThis:
- symlinks every
skills/<skill>/into~/.claude/skills/and~/.agents/skills/(the two directories pi and Claude Code scan forSKILL.md) - symlinks every
bin/*into~/.local/bin/(assumed on$PATH)
Run ./install.sh --uninstall to reverse it, or --force to overwrite
existing symlinks.
for skill in subagent-protocols simple-agent-comms simple-agent-room; do
ln -s "$PWD/skills/$skill" ~/.claude/skills/"$skill"
ln -s "$PWD/skills/$skill" ~/.agents/skills/"$skill"
done
ln -s "$PWD/skills/"*/bin/* ~/.local/bin/subagent-protocols does not ship scripts under bin/; it bundles
watch-file.sh inside the skill directory itself for the coordinator
to use as a Monitor command. The other two skills expose their CLIs via
the bin/ glob.
python3 >= 3.10pyinotify— required only by the monitor;simple-room-sendandsimple-room-scanwork without it. (pip install pyinotifyon most distros; pre-installed on Arch / Manjaro.)
When you spawn a subagent and want a clean startup handshake, bake this into the dispatch prompt:
Parent inbox: /home/me/.cache/agent-comms/myrepo/coord-inbox.md.
Send your startup handshake there before working. Read
tools/skills/subagent-protocols/for-subagents.md and follow it.
Use the inbox files for durable comms, not a direct messaging broker.
The subagent appends one line to your inbox declaring its id, whether it has a background-monitor tool, and (if so) the path of its own inbox file. From there you pick one of three ongoing modes per subagent:
- Streaming (1:1) — set up a
Monitoron the subagent's inbox and one on its reply inbox. Equivalent to running thesimple-agent-commspattern. Lowest noise, highest cost. - Ad-hoc — read the subagent's inbox on demand (or scan it
periodically), and append to it when you have something to push.
No
Monitor; each subagent's traffic stays isolated from the others. The middle-ground: private per-agent conversation without per-agentMonitoroverhead. - One-way / fire-and-forget — ignore the subagent's inbox; rely on its final report. Cheapest; the handshake was just so you knew it existed.
The same handshake also feeds the broadcast pattern: spawn N
subagents and have each one append its startup message into a room
file via simple-room-send, then everyone watches the room
(simple-agent-room).
See
skills/subagent-protocols/for-coordinators.md
and
skills/subagent-protocols/for-subagents.md
for both sides.
# send
simple-room-send kitchen -a alice -m "stove is on"
# monitor (drop into a Monitor tool's command field)
simple-room-monitor kitchen -a alice --backfill 10
# scan (read-only)
simple-room-scan kitchen count
simple-room-scan kitchen tail -n 5
simple-room-scan kitchen active --window 60
simple-room-scan kitchen grep "stove"
simple-room-scan kitchen idsSee skills/simple-agent-room/SKILL.md
for the full reference and failure modes.
~/.cache/agent-comms/
alice-to-coord.md # agent → you (you Monitor this)
coord-to-alice.md # you → agent (agent tails this)
watch-file.sh ~/.cache/agent-comms/alice-to-coord.mdSee skills/simple-agent-comms/SKILL.md.
Each room is a JSON-Lines append-only file:
{"id":"7daed4d0…","ts":"2026-06-18T08:30:00Z","agent":"alice","kind":"msg","msg":"hi"}
{"id":"a136ec8e…","ts":"2026-06-18T08:30:05Z","agent":"bob","kind":"msg","msg":"hey"}- Records are < 4 KiB;
O_APPENDis atomic on POSIX for writes ≤PIPE_BUF, so concurrent posters never tear a record. \n,\t,\\inmsgare escaped byjson.dumpsto the standard JSON sequences; every record is exactly one line.kindismsg(default),system, ormeta.
# unit + integration (49 tests)
python3 -m pytest tests/test_unit.py tests/test_cli.py -v
# bash: install smoke + inotify timing + concurrency
./tests/test_install.sh
./tests/test_inotify.sh
# e2e with two real pi agents in tmux (uses ~1-3 min, real LLM cost)
./tests/test_e2e_pi.shThe e2e test is skippable: if the model is unreachable, it exits 0
with a SKIP: message.
agent-file-chat/
├── install.sh # one-command installer (idempotent)
├── LICENSE # dual Unlicense + CC0-1.0
├── README.md
├── skills/
│ ├── subagent-protocols/
│ │ ├── SKILL.md
│ │ ├── for-coordinators.md # dispatch-side instructions
│ │ ├── for-subagents.md # worker-side instructions
│ │ └── watch-file.sh # bundled copy for the coordinator Monitor
│ ├── simple-agent-comms/
│ │ ├── SKILL.md
│ │ └── bin/
│ │ └── watch-file.sh
│ └── simple-agent-room/
│ ├── SKILL.md
│ ├── bin/
│ │ ├── simple-room-send # thin wrapper → lib/simple_room_send.py
│ │ ├── simple-room-monitor # thin wrapper → lib/simple_room_monitor.py
│ │ └── simple-room-scan # thin wrapper → lib/simple_room_scan.py
│ └── lib/
│ ├── simple_agent_room_lib.py # shared lib
│ ├── simple_room_send.py
│ ├── simple_room_monitor.py
│ └── simple_room_scan.py
└── tests/
├── conftest.py
├── test_unit.py # 28 in-process lib tests
├── test_cli.py # 21 subprocess entry-point tests
├── test_install.sh # install smoke + symlink validation
├── test_inotify.sh # inotify timing + 100-process concurrency
└── test_e2e_pi.sh # tmux + two real pi agents
subagent-protocols is a pure protocol — no scripts to install beyond
its bundled watch-file.sh. The two simple-agent-* skills are
specialized variants that add a persistent Monitor: simple-agent-comms
adds a per-subagent Monitor for 1:1 streaming; simple-agent-room
adds one shared log (Monitor for everyone) for N:N broadcast. The
general pattern itself is just the handshake + ad-hoc direct inboxes.
The bin/ wrappers each contain a 12-line Python file that does:
_HERE = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(_HERE, "..", "lib"))
from simple_room_send import main…so the same code runs whether you invoke it as
skills/simple-agent-room/bin/simple-room-send (direct) or as
~/.local/bin/simple-room-send (via the install.sh symlink).
Dual-licensed under The Unlicense and CC0 1.0 Universal. You may pick whichever you prefer; both place this work in the public domain. See LICENSE for the full texts.