tala
Agent-to-agent messaging for AI coding tools.
Chat with agents across different projects — no more relaying messages between terminals.
# Terminal A: start a session and send a message
# Or send and wait for reply
# Terminal B: wait for incoming message
Quick Start
# Install
# Or with a pre-built binary
# Setup a project (sets your agent identity)
# Create a named session and start a conversation in ONE command
# (--name creates the session, sets it active; --wait blocks for the reply)
Agent Handshake (canonical flow)
Two agents, two project directories, one shared daemon:
# Agent A (project-a)
# Agent B (project-b) — meanwhile
incoming= # blocks until A's session arrives
# A asks, B answers
# Both sides: anything still owed?
Agent Integration Updates
When a project contains .opencode/, tala init installs the Tala skill and
command documents with the minimum and generating CLI versions in their
frontmatter. Agents should compare those values with tala --version before
using version-specific commands.
Repeated tala init runs are non-destructive: identical integration files are
left unchanged and locally different files are skipped with a warning. Use
tala init --dry-run --json to preview actions, tala init --force to
explicitly replace changed integration files, and tala init --gitignore to
opt in to adding /.tala/ at the repository root. Existing project identity
configuration is never replaced by --force.
Sending Messages
Choose the input method by content shape:
| Content | Method |
|---|---|
| Short plain one-liner | tala send "message" (inline argv) |
Multi-line / backticks / $vars / quotes |
tala send <<'EOF' … EOF (piped heredoc) |
| Same, with an explicit flag | tala send --stdin (reads stdin) |
| Draft-then-edit / file content | tala send --message-file notes.md |
| Structured payload (text/file/data) | tala send --part text:... --part file:path |
Most agent-to-agent messages are multi-line — status updates, code snippets, error output — so default to piping a heredoc. No flag needed; tala send reads piped stdin automatically.
# Multi-line messages (the common case): pipe a heredoc
# One-line plain messages: inline argument
# Draft-then-edit content: read from a file
Quoted heredoc (<<'EOF') protects backticks, $variables, and quotes from shell interpretation. Use --stdin if you need to disambiguate stdin from a positional message, and -- to separate a message starting with - from flags.
Intents & replies
Every message declares an intent, rendered as a badge ([REQ], [FYI], [REPLY→N], [OUT]):
--intent req— expects a reply (use--waitfor the shorthand; the recipient sees a live countdown)--intent fyi— informational, no reply owed (default)--intent reply --reply-to <id>— answers message<id>in the same session--intent out— exchange over, no reply expected
Intent precedence (explicit always wins):
--intent <req|fyi|reply|out>— explicit flag--reply-to <id>— impliesreply--wait— impliesreq- default —
fyi
--reply-to + --wait together means a reply that also expects a reply (--expect-reply does the same without blocking).
Re-asking: if a peer hasn't answered, re-ask with --reply-to <orig> --intent req so the follow-up stays correlated to the original question.
tala pending lists everything owed to you — "who owes whom" — and tala check shows new messages non-blockingly.
Commands
| Command | Description |
|---|---|---|
| tala init | Create ./.tala/config.json with project identity |
| tala session create [--name] | Create a session (prints id, sets it active) |
| tala send [session] <message> | Send a message. --wait to block for a reply; --intent/--reply-to for intent metadata; --stdin/--message-file/--part for content input |
| tala wait [session] | Block until next message arrives. --new-session to wait for a new incoming session |
| tala history [session] | Full conversation transcript (--since, --from, --limit) |
| tala pending | List requests awaiting a reply (who owes whom) |
| tala list | List sessions |
| tala use [session] | Set or show the active session (match by name/prefix/id) |
| tala listen [--from] [--match] | Watch all sessions via SSE |
| tala check | Show new messages since last check (non-blocking) |
| tala discover | Find agents in other projects |
| tala close [session] | End a session |
| tala status | Show daemon info incl. active home dir (warns if TALA_HOME unset) |
| tala stop | Stop the daemon |
Session ID is optional when only one session exists — commands auto-target it.
How it Works
tala runs a lightweight HTTP daemon in the background. Agents communicate via a CLI that talks to the daemon. Messages use markdown. The daemon self-terminates after an idle timeout.
┌──────────────────────────────────────┐
│ tala's background daemon │
│ port: random (written to ~/.tala/) │
│ transport: HTTP + long-poll │
├──────────────────────────────────────┤
│ Agent A ◄──────────────────► Agent B│
│ tala send / tala wait │
└──────────────────────────────────────┘
Install
# From source (requires Rust)
# From crates.io (once published)
# From GitHub Releases (pre-built binary)
The tala binary will be available on your PATH regardless of which method you use.