Docs navigation

Concepts

How the mesh thinks

Repowire is a routing hub for live agent sessions. The daemon holds peer state; everything else is a transport. Reading this once makes the tool reference and troubleshooting pages obvious.

Session-native roadmap

The v0.13 architecture train is moving toward a session-first mesh: sessions become the durable unit of work, while peers remain live runtime executors. This is roadmap, not a claim that the product is fully session-native today.

Ask/notify delivery now goes through a transport router. The broader direction is transport-neutral routing across WebSocket hooks, experimental ACP, relay, and future transports; a dashboard session timeline that combines persisted history with realtime events; and a shared command surface for send, resume, schedule, approvals, and future backend/model controls.

Peers

A peer is one running agent session. Claude Code, Codex, Gemini CLI, and OpenCode all register as peers through the same hooks pattern. Peers have a name, a project, a circle, a status (online / busy / offline), and a free-form description the agent sets via set_description.

Peer state lives in the local daemon at 127.0.0.1:8377. It is not synced anywhere by default. Liveness is repaired lazily on the next MCP call rather than by a polling loop.

Circles

A circle is a logical subnet. Peers can only message peers in the same circle unless you explicitly bypass. Circles map to tmux sessions by default, so opening agents in the same tmux session puts them in the same circle.

Use circles to keep work-domain peers from talking to home-project peers when you don’t want them to. They are scoping, not authorization.

Peer identity lifecycle

The daemon routes by immutable peer_id, not by display name alone. Display names are human-facing and can collide across circles, so ambiguous name lookups refuse to guess unless you pass an explicit circle or use a peer_id.

Reconnects may reclaim a peer id only when the claim still matches the registered backend and path. Stale task descriptions are bounded by a clear-on-read TTL, and routing events record resolved peer ids so misroutes can be diagnosed without ad hoc logs.

Message types

The daemon routes four message types. Pick by lifecycle, not by content.

ask
Non-blocking. Returns a correlation_id immediately. The recipient closes the thread with ack(corr_id) (bare) or ack(corr_id, message) (with reply). Chain follow-ups with ask(reply_to=corr_id, ...).
ack
Close an open ask thread. Bare close signals 'seen, no action needed'. A reply ack delivers the message back as a notification framed [ack #cid from @peer].
notify_peer
Fire-and-forget. No lifecycle, no response expected. Use for status updates and announcements.
broadcast
Fan-out to all peers in your circle. Use sparingly.
schedule
Future delivery through the daemon. One-shot and recurring cron schedules can notify or open asks later.

Mesh command UX

Repowire’s command layer has a stable contract for common mesh operations:status, peers, pending-asks, ask, notify, schedule, timeline, result, and doctor.

Every command should have a human rendering for steering the mesh and a JSON rendering for agents, plugins, tests, and scripts. The JSON envelope carries command, status, schema_version, data, plus optional target, warnings, and next_actions.

Agents use Repowire tools for mesh peers: ask for tracked work, notify_peer for fire-and-forget updates, and ack to close inbound asks. SendMessage is only for same-session harness teammates.

timeline and result are views over existing peer, ask, schedule, event, and session-history data until a separate tracked-work lifecycle exists. ACP/channel broker health is reserved for the channel health work rather than claimed by this command contract.

Future Claude Code marketplace plugin packaging may expose these commands as slash commands, skills, docs, and an MCP bootstrap, but it remains optional. The plugin manifest should map to the same command ids and check drift against the installed Repowire package, repowire mcp, hook snippets, Claude Code version, and the declared compatible Repowire range. It does not replace repowire setup or install a second daemon.

Tracked work lifecycle

Durable tracked work is a separate daemon-backed lifecycle from conversational ask/ack. The design reserves work_id records with states such as queued, delivered, running, awaiting_input, completed, failed, cancelled, blocked, expired, and unavailable.

Status, result, and cancel semantics belong to that work lifecycle. Acks may close related conversation threads, but they do not complete work. Session and circle visibility should resolve by exact ids where possible, and protocol cancel should be attempted before transport teardown when a live backend connection can still accept it.

Lazy repair

Repowire avoids polling. Liveness, persistence, and ghost eviction run at most once per 30s and only when an MCP tool is already being handled. Disk writes are debounced via dirty flags and flushed on the same trigger or on shutdown.

The practical consequence: a fully idle mesh consumes near-zero CPU. Peers do not heartbeat. State catches up the moment something happens.

The orchestrator pattern

An orchestrator is a peer whose job is coordinating other peers. Nothing in the daemon enforces this. It is a workflow: one long-running session you address from your phone or dashboard, which then asks other peers on your behalf.

Worth setting up when you have more than a few peers and find yourself routing decisions manually. Skip it for two-peer setups.

Control surfaces

The dashboard, Telegram bot, and Slack bot are peers too. They show up in list_peers alongside agents and can ask, notify, and broadcast.

  • dashboard — Next.js UI at localhost:8377/dashboard with a live mesh log and per-peer chat.
  • telegram — bot you talk to from your phone. Sticky routing: /select peer sends subsequent messages as asks to that peer; /notify and /fyi remain fire-and-forget.
  • slack — Socket Mode bot. Same sticky-routing pattern with Block Kit peer pickers; notify and fyi remain fire-and-forget.

Messages from @telegram, @slack, and @dashboard are humans. Telegram and Slack inbound messages open tracked ask threads by default, and agents treat them as direct user instructions.