One gateway.
One message primitive.
Many agents.
Pinet is a local-first coordination layer for pi coding agents. One broker runs the mesh: it routes every Slack message, and you can talk to it directly at its own terminal. It keeps named worker agents shipping: writing code, reviewing each other's pull requests, and repairing themselves when something stalls.
$ pi install npm:@pinet/slack-bridgerequires pi · node ≥ 22 · a slack workspace where you can install apps
What Pinet is
You mention an agent in Slack. The right agent picks the message up. If that agent dies, another takes over. You never think about routing, lifecycle, or thread ownership — that is the whole point.
Underneath, Pinet runs a broker–worker model. One pi session acts as the broker: it owns ingress from Slack and from its own terminal, assigns work, and tracks what every worker holds. Worker sessions pick up tasks, write code, run tests, and open pull requests. The broker coordinates but does not write code; workers ship end to end.
Everything rides on a single primitive, message.send. Slack replies, agent-to-agent messages, and scheduled wake-ups are the same thing underneath; adapters translate at the edges. The broker reasons; the routing under it is deterministic policy code.
The life of a message
- Arrival.
A message arrives through one of two doors. From Slack over Socket Mode: a DM, an
@pinetmention, or a/pinetslash command. Or from the keyboard: the broker is a pi session in a terminal, and you can talk to it there. - Gatekeeping.
Access is default-deny. The sender must be in
allowedUsers(or the workspace-wide allowance must be explicit). Ingress guards can additionally require a mention in configured channels. - Routing.
The broker resolves thread ownership. A thread claimed by an agent keeps flowing to that agent; unclaimed work is assigned. No split brain; one control plane owns delivery.
- Inbox.
The message is queued in the owner's durable inbox. Busy agents drain it on their next turn; restarts do not lose it.
- Work & reply.
The agent acknowledges, does the work (code, tests, PRs), and replies in the same thread with
slack_send. If the agent stalls instead, the RALPH loop picks the thread up, so messages do not just disappear.
Operating principles
- one control plane
- A single broker owns routing, agent lifecycle, and message delivery.
- stable identity
- Agents keep a logical identity across reconnects. Heartbeats and leases handle liveness; dead agents get reaped, not ignored.
- smart broker, dumb routing
- The broker is an LLM agent that can reason and self-heal. The routing beneath it is deterministic policy code.
- RALPH loop
- An autonomous maintenance cycle: reap dead agents, release stale claims, drain unrouted messages, nudge idle workers.
- workers compute, broker keeps the lights on
- Workers do tasks. The broker is infrastructure. They do not share a process lifetime.
- extensions stay thin
- Tools like
slack_sendandpinet action=sendare shims over the broker. They do not own state.
Ten minutes to a working mesh
- Install the bridge.
pi install npm:@pinet/slack-bridge - Create the Slack app from the manifest.
At api.slack.com/apps, create an app "from a manifest" and paste
manifest.yaml. Socket Mode, scopes, events, and slash commands are configured for you. - Collect two tokens.
An app-level token (
xapp-…, withconnections:write) and a bot token (xoxb-…) from OAuth & Permissions. - Configure pi.
Add tokens, a runtime mode, and your Slack user ID to
~/.pi/agent/settings.json:{ "slack-bridge": { "botToken": "xoxb-…", "appToken": "xapp-…", "runtimeMode": "single", "allowedUsers": ["U_YOUR_USER_ID"] } } - Start pi.
Pinet appears in your Slack sidebar. DM it, mention it, or run
/pinet.
Full walkthrough, access control, and the complete configuration table live in the Slack Bridge document.
Built by the system it enables
Agents built Pinet, coordinating through Slack and GitHub: the same broker, the same inbox, the same thread ownership described on this page. During development the mesh merged over 50 pull requests in a single day, with little human help. Workers wrote the code. Other agents reviewed it. RALPH cleaned up after the ones that wandered off.
Humans set priorities, approve merges, and hold the API tokens. The system handles coordination and execution. The aim is to move you up a level, from doing every step to steering a mesh that coordinates itself.