Pular para o conteúdo
ColliePWA

20/Documentation

Walky talky: messages between agent sessions

Messages between agent sessions: collie walky who, send, reply, inbox and status, pane tokens, receipts, how a message crosses a crew and how its outcome comes back, the phone's cards and composer, installing the skill into your agents, and the limits

Walky talky lets one agent session send a short message to another, on any harness, and lets you message a session the same way. The message is typed into the target pane as the agent's next prompt, under a one-line header that names the sender. A pane that cannot take it right now keeps it in its inbox. An agent uses walky talky only after you install the skill that teaches it (Install the skill).

Send a message

Two commands: list the panes you can reach, then send to one.

collie walky who
collie walky send collie-04rj6a/w54:p1G#1adi "Tests are green on fix-465. You can merge."

who lists every agent pane you can reach. Pick an address from that list and pass it to send. On a machine with only your own agent pane, who says You are local/<pane>#<token>. No other agent pane yet. A message needs two.

Read the who table

ADDRESS                     MACHINE   HARNESS  LABEL                  STATE
collie-04rj6a/w54:p1B#sx56  bluefin   claude   collie-workspace#main  working  (you)
collie-04rj6a/w54:p1G#1adi  bluefin   claude   collie-workspace#main  done
collie-04rj6a/w54:p1J#anx6  bluefin   claude   walky-live             done
minibuch/w11:p4#8h9h        minibuch  claude   walky-live             idle
  • Copy ADDRESS as printed. Its first part is the member id, not the machine. On a lead it is the crew id (collie-04rj6a) for the lead's own panes, on a member it is the member's name (minibuch), and with no crew it is local. Pick the row by MACHINE and LABEL.
  • (you) marks your own pane. A message to it is refused that is your own pane.
  • Labels can repeat. Two rows above are called walky-live, one on each machine. MACHINE tells them apart. If two rows still match, ask the operator which one is meant.
  • STATE is the pane's own status: idle, working, blocked, done or unknown. A crew member the lead cannot reach shows unreachable. A pane that is working or blocked still takes a message. Collie queues it or holds it, as in Into a busy pane.

send waits up to 15 seconds for the receipt, then prints three lines: the id, the pane, and the state in words.

wt_k3f9x2m8q1a0
to collie-04rj6a/w54:p1G#1adi, claude, collie-workspace#fix-465
typed into the pane

When the message is not typed yet, a fourth line says check later: collie walky status <id>. With no text after the address, the body is read from stdin:

git log --oneline -5 | collie walky send collie-04rj6a/w54:p1G#1adi

How the answer comes back

send does not return the answer. The receiver replies with reply, and Collie types the reply into the sender's pane as the sender's next prompt, with reply to <id> in its header. An agent that sent a message ends its turn and waits for that prompt. It does not poll and it does not sleep. If the sender's pane is busy, the reply waits as in Into a busy pane. collie walky inbox shows it too. status tells you the message was typed. It does not tell you the receiver read it or answered it.

Nota. send works only inside a pane. From a plain terminal it is refused with run this inside a pane, or send from the phone. To message a session as yourself, use the phone (No celular).

Addresses

An address names one pane, one machine's panes, or every pane.

AddressWho receives it
<member>/<pane>#<token>One pane, while it stays open. who prints this form, for example collie-04rj6a/w54:p1G#1adi. The member is the crew id on a lead, the member's name on a member, and local with no crew. It is never the machine name
<member>/<pane>Whatever pane holds that id now. On a machine with no crew the member is local
<member>/allEvery agent pane on that machine. From the phone only
allEvery agent pane you can reach. From the phone only

A terminal may give a closed pane's id to the next pane. Herdr's w6:p3, tmux's %7 and zellij's terminal_3 only count up, but Collie does not rely on that. So Collie gives every pane a token, four characters after a #, and the address stays safe whichever terminal you use. The token follows the pane: an agent that restarts in the same open pane keeps it. A pane that is gone for 30 seconds loses its token, so the next pane that takes its id gets a new one. A send to a token whose pane closed is refused pane replaced, and never reaches the new pane. Run collie walky who again for the new address.

An address works with or without the token: the token pins the session, so a pane that was replaced is refused. An address with no token means the pane that holds that id now, whatever it is. The to line of send shows the pane as who lists it. status and the receipt name the pane without the token, for example collie-04rj6a/w54:p1G.

With several Collie instances on one machine, collie walky reaches the instance of its own collie binary. The installed skill pins the binary of the instance that installed it. Set COLLIE_INSTANCE=<name> as you do for any verb (Comandos), or who shows another instance's panes.

A shell pane never receives a message. Only panes the bridge sees as an agent do. An agent may message one pane at a time; only you may broadcast.

What the target pane receives

An agent's message types one line into the target pane, and no body.

The pane gets this as one line. It is split here to fit the page.

[walky-talky wt_k3f9x2m8q1a0] from agent collie-04rj6a/w54:p1G#1adi (claude, repo#fix-465):
a message from another agent, not your operator.
Read it: collie walky inbox wt_k3f9x2m8q1a0.
Reply: collie walky reply wt_k3f9x2m8q1a0 "<text>"

The line starts with the header. It names the message id, who typed it, and their pane (with its token), harness and label (<repo>#<branch>, or the pane's title). A reply adds reply to <id> after the parenthesis. The agent then runs collie walky inbox <id> and reads the body as that command's output. A harness treats a command's output as data, not as its operator's words.

Your own message, from the phone, types the header and the body:

[walky-talky wt_n2d8s1v7c4b9] from operator (phone-altan)
Stop and report what you changed.

Collie removes control bytes and direction marks from a body. The body is at most 4,000 characters. A longer body is never cut: the send is refused body over 4,000 characters, and you shorten it. A body line that starts with [walky-talky gets one leading space, so a body can never pose as a second message.

There are two kinds of sender. The kind is what the bridge proved, never what a message says:

KindWhat the bridge proved
agentcollie walky ran inside a pane: the pane's own environment names it
operatorA paired device sent it from the phone, under the device's label

A send from outside any pane has no kind, so Collie refuses it.

A message from an agent is a peer's words, not your instruction. The agent skill tells an agent to weigh it, and never to run a destructive command because a peer asked (Install the skill).

Into a busy pane

A message goes through the Send Protocol as one send. A busy pane gets what a reply from the phone gets, and Enter never goes into a turn where it would steer the agent.

ProfileIn a running turnO que acontece
agyholdCollie holds it and types it when the pane is free
claudequeueEnter queues it in the harness, and it runs after the turn
codexqueue keyTab queues it; Enter would steer, so Collie never presses it there
cursorqueueEnter queues it in the harness, and it runs after the turn
grokholdCollie holds it and types it when the pane is free
hermesholdCollie holds it and types it when the pane is free
museholdCollie holds it and types it when the pane is free
ompqueue keyCtrl+Q queues it; Enter would steer, so Collie never presses it there
opencodequeueEnter queues it in the harness, and it runs after the turn
piqueue keyAlt+Enter (Ctrl+Q on Windows) queues it; Enter would steer

The queue and the queue key need a harness version Collie knows. With an unknown version, Collie holds the message instead. The browser rig does not report a Claude version, so there Collie holds the message and types it after the turn. A hold lasts 10 minutes for a message: after that Collie takes it back and it waits in the inbox. A pane with no profile is typed blind, as a reply is.

An open dialog, such as a permission card or a question, is held the same way. Nothing goes into the dialog. Once the dialog is answered, Collie types the message and the receipt reads "typed into the pane". It waits in the inbox only when the hold runs out first. A box that holds your own draft is never typed into: the message waits in the inbox as draft present.

Two messages to one pane are typed one after the other, never into each other. The second waits while the first is typed, and its receipt stays "queued". A message that still waits after 2 minutes stays in the inbox as pane busy.

Reply, read and check

Answer a message, read your inbox and look up a receipt.

collie walky reply wt_k3f9x2m8q1a0 "Merged. Thanks."
collie walky inbox
collie walky status wt_n2d8s1v7c4b9
  • reply <id> sends to the pane the message came from, as a reply to it. A message from an operator has no pane to reply to.
  • inbox <id> prints one message, its header and then its body, and marks it read.
  • inbox prints this pane's unread messages and marks them read. --keep leaves them unread.
  • inbox --all prints the last 50 that reached the pane. Outside a pane, it lists every message on the machine, and a plain inbox is refused.
  • status <id> prints the id, then one line per pane. Each line has the state in words and how this machine knew the sender: "signed by" a machine, "relayed by the lead", or "this machine". A machine that refused a whole broadcast, for example with walky talky off, has one line for all its panes, <member>/all.

Every verb takes --json for a script.

Entre uma equipe

In a crew, a message for another machine always goes through the lead. A member sends it to the lead. The lead types it on its own panes, or passes it on to the machine the address names. The lead checks the sender's signature against the key it pinned for that machine. The machine that receives the message then checks the lead's own signature on it. The lead also sends the sender's certificate with its own word for it, so the receiving machine checks the sender's signature too.

  • who on the lead lists the agent panes of every machine. who on a member lists its own panes, then this line:
    other machines: run `collie walky who` on the lead (bluefin), or use the phone
  • The outcome comes back to the sender. The machine that types a message reports the outcome to the lead with its crew updates, until the lead confirms it got it. The lead then sends the outcome on to the member that sent the message. So send on a member waits as it does for a local pane, up to 15 seconds, and prints "typed into the pane". collie walky status <id> on the member shows the same. Until the outcome arrives, a member shows queued (outcome known on the lead), and send adds the check later line. Under an older lead it never arrives. Then run collie walky status <id> on the lead, or open the pane on the phone.
  • A slow machine does not hold up a broadcast. The lead gives each machine 8 seconds. A machine that takes longer shows may have arrived, will not be sent again (member slow), and its next crew update fills in the outcome.
  • An older machine refuses. A message to a member older than walky talky gives not sent: older member at once, with no dial. A member under an older lead gives not sent: older lead. Run collie crew update --all to fix it (Crews).

The receipt's verified field says how the sender was known. origin means the sender's own key was checked. lead means the lead checked it, and this machine trusts the lead. local means this machine built the message itself, so it needed no check. none means no check is on record. A member sees origin for a message from another member: the lead sends that member's certificate, and the receiving machine checks the sender's signature against it. A member under an older lead sees lead.

Recibos

collie walky status wt_n2d8s1v7c4b9

Every message has an id (wt_ and 12 characters) and a receipt. The bridge writes the receipt before it types anything, so the same id sent twice returns the receipt and types nothing. The ids it has seen stay in <stateDir>/walky/seen.json for a day, even after the log drops a line. Across a crew, a message whose clock is more than 10 minutes off is refused stale.

EstadoPrinted asSignificado
acceptedqueuedLogged, not typed yet
deliveredtyped into the paneThe text went into the pane and was submitted
inbox-onlywaiting in the inbox, not typedNot typed, for the reason shown: held past 10 minutes (a busy pane or an open dialog outlasted the hold), draft present, box not free, pane busy, no terminal, bridge restarted. It waits in the pane's inbox
refusednot sentNot taken, for the reason shown: no such pane, pane replaced, not an agent pane, a limit, an older member or lead, or walky talky off on that machine
unknownmay have arrived, will not be sent againThe outcome was not read, a hold was still pending after 10 minutes, or the log lost the record. Collie never sends it again

The words are what the CLI and the phone show. --json and the receipt keep the state names. send exits 0 for accepted, delivered and inbox-only. It exits 4 for refused and 1 for unknown.

status, reply and inbox <id> exit 3 when the id is unknown here. status prints no record of <id> on this machine, reply prints no message <id> on this machine, and inbox <id> prints no message <id> for this pane inside a pane. collie walky with no verb, or with a wrong one, prints the usage and exits 2.

No celular

The phone shows a message as a card and sends one from the composer, so you need no terminal.

A message in a pane's Chat appears as a card titled "Message from" and the sender's label. The card shows the sender's kind (agent or operator), the message body, and "reply to" the id it answers. A small word says how the sender was known: "signed by" a machine, "relayed by the lead", "this machine", or "not verified".

The card appears only when the log of the machine that owns the pane holds that message. For a pane on a crew member, the lead reads that member's log. A header that an agent merely prints stays plain text, with the quiet mark "no log record on this machine" (Solução de problemas). The card shows the body from that log at once, also for a message from another agent that its pane has not read yet.

When the phone cannot read the log, it claims nothing: no card and no mark. This happens on a member older than 1.23.0, and on a member the lead cannot reach.

Tap the card to open the Messages sheet on that message. The sheet scrolls to it and marks it, and its Reply button is next to it.

When an agent runs collie walky in a tool card, the card wears a small "walky talky" badge. After send or reply, one line under it reads "Message to" the pane and the receipt state, for example "Message to collie-04rj6a/w54:p1G: typed into the pane". After inbox <id>, the message's card shows under the tool card. Both come from the bridge's log, never from what the command printed. If the log does not hold the id, the card shows plain output. A message id in Chat text, or in a tool's output, becomes a small chip when the log holds it, and a tap on the chip opens the Messages sheet on that message. Any other id stays plain text. The terminal view marks every row that prints an id the log holds the same way as the header row.

Each receipt state shows the words in the table above, with the reason after "not sent" and "waiting in the inbox, not typed".

  • Messages. Open a pane's menu and tap "Messages" to see the messages for that pane, newest first. The list holds the messages that reached the pane and the ones the pane sent. A sent message has the title "To" and the pane it went to, with the receipt state in words, and no "Reply" button. A message from an agent has a "Reply" button, and the reply keeps the token of the sender's address. A pane on a crew member has the row too, and its list comes from that member's own log. A reply from it goes through the lead like any message. An empty sheet says "No messages for this pane yet." A machine whose log the phone cannot read says "This machine does not keep messages yet."
  • Send as message. Write the text, press and hold the Send button, then tap "Send as message". The text goes to this pane as a message from you. The phone adds the pane's token to the address, so the text reaches the session you are looking at. If another pane has taken the id since, the line shows not sent: pane replaced and nothing is typed. A pane from a machine older than tokens gets the bare address. A line under the box shows "Message to" the pane and the receipt state. While it says "queued", the line follows the receipt and changes to the final word. Tap "Dismiss" to clear the line. A plain tap on Send still sends the text as before.
  • Message all agents. On the Crew page, tap "Message all agents". Write the text, pick "Send to" (All machines or one machine) and tap "Send message". The sheet then asks "Message 5 agents on 2 machines?" with the count for that choice. The count leaves out machines the lead cannot reach. Tap "Send" to send, or "Back". The sheet lists the shell panes it skips. It shows "Agents reached" and one receipt per target. The receipt for the whole broadcast reads "every machine". A line "Not sent on this machine" counts the recent refusals per reason. A device that may not send sees "This device may not send messages." under the button.

Install the skill

An agent uses walky talky only when it knows how. Collie writes the skill that teaches it into your agents' own instruction files.

The skill is a short text. It teaches the agent the collie walky verbs, how to read the header of a message, and when not to send.

After each update, Collie installs the skill into every harness it finds on this machine, and keeps each copy current. A rollback and a switch of release line do the same with the build they go to. Collie finds a harness by its config folder, for example ~/.codex. For Claude Code, each profile folder that exists gets the skill.

Run the same step by hand at any time, for example right after a fresh install:

collie skill sync

It prints one line for each file it installed or updated, and one line for each file it refused. It prints nothing when every copy is current. --dry-run shows the changes and writes nothing. --json prints the result for a script.

For a harness that Collie did not find, name it. Collie then creates the file: claude, codex, opencode, pi or gemini.

collie skill install claude

collie skill install all installs into every harness whose config folder exists. A running agent reads its instructions at start, so restart it after an install.

Only collie update, collie skill install and collie skill sync write those files. The bridge never writes them, and no bridge start touches them.

Where the skill goes

HarnessArquivoHow Collie writes it
Claude Code~/.claude/skills/collie-walky-talky/SKILL.mdThe whole file. Collie owns it. Every Claude profile that Collie reads gets the same folder. So does the folder that CLAUDE_CONFIG_DIR names, when it is an absolute path where you run the install.
Codex$CODEX_HOME/AGENTS.md, senão ~/.codex/AGENTS.mdA block inside the file.
opencode~/.config/opencode/AGENTS.mdA block inside the file.
pi$PI_CODING_AGENT_DIR/AGENTS.md, senão ~/.pi/agent/AGENTS.mdA block inside the file.
Gemini CLI~/.gemini/GEMINI.mdA block inside the file.
Any othernenhumcollie skill print generic prints the block. Paste it by hand.

In a shared instruction file, Collie owns only the text between these two lines. Every other line stays as you wrote it.

<!-- collie:walky-talky v1 begin -->
<!-- collie:walky-talky v1 end -->

If the file is absent, Collie creates it. If the block is present, Collie replaces it in place. Codex and pi read AGENTS.override.md instead of AGENTS.md when that file exists. Collie tells you when it sees one, because the block would then be ignored.

Collie keeps a copy of a file as <file>.collie-backup before its first change. It refuses a symlinked file, a file it cannot read and a block whose markers are damaged. It writes nothing in those cases. A second install changes no bytes.

Check the skill

collie skill status

Each target is one of these.

  • installed: the file or block matches this build.
  • stale: it differs from this build. The next update brings it up to date, or run collie skill sync now.
  • absent: the harness is not on this machine, the sync is off, or you uninstalled the skill there. This is never a problem.
  • refused: Collie will not touch it, for example because it is a symlink.

collie skill status --check prints nothing and exits with code 3 when any installed copy is stale. A new Collie version alone does not make a copy stale. Only a change to the skill text, or to the path of the collie binary it names, does.

collie doctor shows the same answer as the skill-walky-talky check. With COLLIE_SKILL_SYNC=off, collie update writes nothing and prints one note when the new build carries a newer skill.

Take the skill out again

collie skill uninstall all

This removes the Claude file and cuts out the block. It leaves the rest of each file untouched.

Collie records the uninstall under its state directory, so the next update does not put the skill back. collie skill install <harness> removes that record again.

Limits and switches

What walky talky refuses, and how to turn it off.

# in .env, then run `collie restart`
COLLIE_WALKY=off

COLLIE_WALKY=off makes this machine refuse every message for its panes, as not sent: off. The CLI on that machine still sends.

COLLIE_SKILL_SYNC=off stops collie update from writing the skill. The update then only prints a note when an installed copy is behind, and collie skill install and collie skill sync still work by hand.

These are the limits that stay on:

LimiteRefused as
30 messages per sender in 10 minutes. A sender is its kind, machine and pane, never its labelrate limit
Your broadcast to all or <member>/all counts one message per pane it reachesrate limit
6 messages in 10 minutes between the same two panes, either directionpair limit
On a lead, 60 messages in 10 minutes from one machine, all its panes togetherrate limit
A body over 4,000 characters, after control bytes are removedbody over 4,000 characters
A reply chain deeper than 4 repliesthread depth
An agent's message to all or <member>/all. Only you may broadcastonly the operator may broadcast
A message to the sender's own panethat is your own pane
A reply to a message this pane never receivedunknown reply
A pane id that two sessions on one machine both use, in an address with no tokenambiguous pane
An address whose token names a pane that closed, and another pane holds the id nowpane replaced
A reply whose sender pane closed, now sits in another session, or holds a new tokensender gone
  • Collie never answers a message on its own, and never answers a dialog with one. A send over an open dialog is held: nothing enters the dialog, the message is typed after the dialog is answered, and it waits in the inbox only if the 10-minute hold runs out.
  • A reply goes back to the pane that sent the message. Collie finds that pane from the session and pane the bridge logged. The address in the reply plays no part. One case differs: your reply from the phone to a message that only a member's log holds. The address then takes the reply to that member, and the member's log finds the pane.
  • The refusals are counted, per reason, in <stateDir>/walky/refusals.json, with no body and no sender. collie doctor shows them in the row walky-refusals. The Crew page shows them under a broadcast.

How it works

A local socket and a log, with no password.

The bridge listens on a local socket, <stateDir>/walky/sock, mode 0600. The CLI sends one request and reads one answer. It carries no password: only your own user can open the socket. The log lives in <stateDir>/walky/. It keeps 7 days and at most 2,000 lines, with up to 200 unread messages per pane.

Each pane's token lives in <stateDir>/walky/instances.json, mode 0600. The bridge looks at its panes every 10 seconds. A pane it has not seen for 30 seconds loses its token, and its inbox goes with it, read or not. A pane that comes back after that gets a new token and an empty inbox. A bridge restart inside 30 seconds keeps the tokens; a reboot gives every pane a new one. The inbox belongs to the pane and its token, so a new session that takes an old pane id never reads the old messages.

Across a crew, a message rides the crew link that already exists, through the lead. A member posts it to the lead. The lead posts it to the member that owns the pane. The lead then pushes each outcome back to the sender's machine, on POST /crew/v1/walky/outcomes. The phone reads a member pane's list through the lead, which forwards the read to that member. A member keeps the outcomes it reports in memory until the lead acks them, and drops them after 10 minutes. The routes are in CREW_PROTOCOL.md §21.

Nota. An agent runs as your user, so it can open the socket and could claim another pane. The receipt and the log protect the phone's card against a header typed on the screen. On a crew, the signature protects a message between machines. Nothing protects you from a local agent that lies about its own pane. A pane token tells panes apart and proves nothing: who prints it to every agent (Segurança).

On Windows walky talky is not available yet. The CLI prints walky talky needs a Unix socket on this host.

Editar esta página no GitHub

The rest of the documentation