npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agent-relay

v12.4.1

Published

Real-time agent-to-agent communication system

Readme

agent-relay

A thin operator console for a local agent workforce: stand up the broker, staff it with off-the-shelf agent CLIs, and watch/steer them from the terminal. Each command is a shallow wrapper over a backing package (@agent-relay/sdk, @agent-relay/harness-driver, @agent-relay/cloud).

Install

Requires Node.js 22 or newer.

npm install -g agent-relay

Common commands

agent-relay status                 # workspace + cloud login + local broker
agent-relay mcp                    # MCP stdio server

agent-relay message post --channel general --text "hello"
agent-relay workspace list

This machine's node

The node command group manages the broker on your machine and the agents it runs:

agent-relay node up                          # serves an auto-discovered agent-relay.{ts,js,…} node file,
                                             # or the implicit local node from teams.json
agent-relay node up --config ./my-node.ts    # serve a specific defineNode(...) file
agent-relay node status
agent-relay node down

agent-relay node workflow run workflows/my-workflow.ts
agent-relay node workflow logs <run-id> --follow
agent-relay node workflow sync <run-id>

agent-relay node agent new claude            # spawn + attach
agent-relay node agent new codex --runtime native
agent-relay node agent spawn opencode --runtime pty
agent-relay node agent spawn devin --name reviewer --task "Review the current diff"
agent-relay node agent list
agent-relay node agent list --status            # + inbound delivery mode and pending-queue contents per agent
agent-relay node agent attach <name> --mode view
agent-relay node agent release <name>

node agent spawn and node agent new accept --runtime auto|native|pty. auto is the default and keeps experimental dual-runtime adapters on PTY. Claude Code, Codex, and OpenCode support explicit native or PTY selection; Pi and Deep Agents are experimental native-only harnesses and require --runtime native.

For AI SDK native harnesses, attach renders structured activity, text, tools, approvals, files, usage, and lifecycle events. Add --json for NDJSON, --reasoning for reasoning events, or --diagnostics for sidecar diagnostics. Native harness drive is line-oriented and acknowledged; native harness passthrough is unsupported because no terminal stream exists. PTY attach behavior is unchanged.

Local operation during a Relaycast outage

agent-relay node up --local-only
agent-relay node status
agent-relay node agent spawn claude --runtime pty
agent-relay node agent attach <name> --mode view

--local-only deliberately starts a DEGRADED broker without waiting for Relaycast. Startup, /health, /api/status, and node status report that mode. The authenticated /api/session exposes operation_mode: "local_only" and degraded: true; its existing mode still describes persistence. The standalone broker accepts init --local-only --persist; SDK callers can set AGENT_RELAY_LOCAL_ONLY=1 and enable persistence. The API must bind to a loopback IP, and the mode supports a single workspace key.

Local spawn, terminal view/input, and the durable automatic delivery queue remain available. POST /api/send accepts only a worker currently running on this broker; channel, cross-workspace, and remote destinations are rejected. It reports delivery_status: "queued_local", local: true, and relaycast_published: false. Acceptance means the work was saved, not that an agent has read it. Pending work survives restart and waits for an absent local recipient to respawn without exhausting retries. A restarted recipient gets a fresh transport retry budget. Explicit release and exhausted transport failures while the recipient is present still use the dead-letter lifecycle. Manual-flush mode is unavailable and returns capability_disabled explicitly.

Fleet routing, worker presence, remote terminal attachment, node capability providers, and injected Relaycast messaging tools are disabled. Local agents receive a degraded-mode notice. Their model provider and any tools they configure themselves still have their own connectivity requirements.

When a workspace key is configured through the normal workspace selection, the broker retries an independent audit connection in the background. Audit endpoints require HTTPS, with HTTP allowed only for literal loopback IPs used in local development. Audit records never follow HTTP redirects. Queued local delivery records are persisted in state-<name>.local-outbox.json beside broker state, then reconciled as local.delivery.queued events under a separate broker audit identity when Relaycast responds. These events contain the original delivery/event IDs, sender, recipient, body, and queue timestamp. They record local acceptance, not model completion. They are audit replay, not re-sent messages: replay must never execute the work twice or address a local worker name on another machine. Reconciliation is at least once; consumers can deduplicate by event_id after an ambiguous response or crash.

node status reports the reconciliation backlog and the last connection result. Without a workspace key, local work still runs and records remain on disk with no upload destination; no workspace is created. A nonempty unscoped backlog cannot acquire a destination on restart. Keep its state directory and continue without a key, or select a different state directory for new work with a configured destination. The outbox is bounded to 10,000 records / 32 MiB and rejects new sends when full. A digest pins a configured backlog to its original workspace key and Relaycast base URL; restore that configuration to drain it before rotating keys or changing the destination. Corrupt outboxes cause an explicit startup failure rather than being discarded. Preserve the state directory until reconciliation completes.

Recovery never silently enables fleet capabilities. Stop the broker and start normally (without the flag or environment opt-in) to enable them; a normal restart drains retained audit backlog only when its configured destination and digest match; an unscoped backlog remains on disk. Restart local workers as needed to give them Relaycast messaging tools and registered identities.

Workspace binding and recovery

agent-relay up and agent-relay node up resolve the workspace through one precedence ladder. The first source that resolves wins:

| # | Source | Where it comes from | | --- | ------------------------------- | ----------------------------------------------------------------------------- | | 1 | Command-line flag | --workspace-key / --wk | | 2 | Environment | RELAY_WORKSPACE_KEY, then AGENT_RELAY_WORKSPACE_KEY, then RELAY_API_KEY | | 3 | Repository pin | <project>/.agentworkforce/relay/workspace-key.json | | 4 | Machine-global active workspace | the active entry in ~/.agentworkforce/relay/workspaces.json | | 5 | Created workspace | created only when nothing above resolves |

The repository pin always beats the machine-global active workspace, so agent-relay workspace switch <name> never silently re-homes a checkout that already pinned one. A new workspace is a last resort: a fresh directory joins the machine-global active workspace when one exists, and startup explicitly announces creation when none of the first four sources resolves.

Startup and node status report the winning source without printing key material. Status uses the same five labels: command-line flag, environment, repository pin, machine-global active workspace, or created — but the two commands print different strings: startup shows the resolved origin (an absolute path for a repository pin), node status shows a fixed, relative-path label.

Startup output:

Workspace source: repository pin (/repo/.agentworkforce/relay/workspace-key.json)
Workspace: joined rw_7ccfea89

node status output:

Workspace source: repository pin (.agentworkforce/relay/workspace-key.json)

A Cloud enrollment (RELAY_NODE_TOKEN, or a record in the Fleet enrollment store) selects the node's identity, not its workspace, so it never appears on the ladder. If a stored enrollment addresses a different workspace than the repository pin, node up refuses to start and names both source files and workspace IDs, never their keys.

One live broker per enrolled node

The Fleet enrollment store is machine-global and is not scoped to a broker state directory, so a second node up — another checkout, or the same one with a different --state-dir — used to adopt the same node id. Both brokers then registered as that node, the engine handed the node-control delivery socket to whichever registered last, and the first broker kept running and reporting healthy while messages silently stopped arriving.

A start now takes machine-global ownership of its enrolled node id in ~/.agentworkforce/relay/node-claims/<node-id>.<generation>.json (pid, state dir, API port, broker name, claim time) before it spawns a broker, because the broker registers with the engine from its own startup — anything claimed afterwards is claimed after the delivery socket could already have moved. Ownership is handed to the broker process once its identity is verified, and is released only after that process is observed to exit.

Ownership is the exclusive creation of the next generation file, so concurrent starts cannot both win and no start ever deletes a record another one might have replaced: whoever creates …000002.json first owns the node, and the others re-read and refuse. Releasing a claim retires its generation number instead of freeing it, so a number is never handed out twice and a start that was suspended across a full release-and-restart cycle cannot wake up and win a node id that now belongs to somebody else. A crashed start leaves a generation whose pids are dead, which is stale rather than blocking.

Each generation also has a …000002.hold file that the supervising CLI opens before it spawns a broker and the broker child inherits. Whether anything still holds it open is answered by the kernel, not by a file either process has to survive long enough to write — so a supervisor killed anywhere between the spawn and the broker's first write still leaves a node id that reads as held, instead of one that looks free right up until the orphan registers. node up refuses to adopt a node id that a live claim names, printing the holding broker's pid and state directory:

Refusing to start: node node_2230437463 is already served by a live broker on this machine.
  holding broker      pid 48211, state dir /repo/.agentworkforce/relay, API port 3891

A claim whose pids are gone — or whose pids have since been recycled by other processes — is stale, so an ordinary restart after a crash or reboot is never refused. Two exceptions keep a crash from unguarding a running broker: if the supervising CLI was killed before it could record its broker's pid, the broker's own connection.json in the claimed state directory still names a live process, and that reads as held; and until a start has recorded which child it spawned, anything still holding that generation's .hold file keeps the node guarded, because a process that has since execd into another binary is no longer anything the claim could identify. To run a second node on this machine alongside the live one, enroll a distinct node (agent-relay cloud enroll --name <other-node>) and start from that enrollment; node up --force takes the node over instead, evicting the live broker's delivery socket.

An explicit RELAY_NODE_ID is the identity the broker sends in node.register, so it is guarded on that basis alone — the CLI does not try to predict which of the broker's credential routes will resolve. A node token in the environment, one the broker has already cached, and one it mints for itself from workspace credentials all end in the same registration, and only --local-only, which registers nothing, is exempt. A start that turns out to have had no credential at all is refused for a node somebody else is serving, which costs one --force.

Because the claims are machine-global, they also give node down a way to point at a live broker it cannot see: run from the wrong directory it still reports Not running, but now lists the live nodes and the state directories serving them. Two brokers on different machines sharing one enrollment store (a synced home directory) are out of scope — nothing local can see the other host's pids.

workspace create, join, and switch select a named workspace globally and pin it to the current project. A changed selection records the old name, so an accidental create can be undone:

agent-relay workspace restore

To change only the workspace this project's broker will use on its next start, without changing the machine-global active workspace, use:

agent-relay workspace rebind default
agent-relay node down
agent-relay node up

rebind is also the supported recovery command for the conflict above: it writes the repository pin (which outranks the machine-global active workspace) and clears the project's stale enrolled-node association so the next start does not fight the conflict guard. It does not stop a running broker; restart the broker when you are ready to apply the new pin.

For detached startup failures, node up --background reports the child error when available and otherwise tells you to retry without --background; a child that already exited is no longer misreported as an unkillable half-started broker.

Local and remote fleet agents

The fleet command group lists and controls agents across all live nodes in the active project workspace:

agent-relay fleet nodes
agent-relay fleet nodes list --pretty
agent-relay fleet nodes list --name sf-mini --capability spawn:codex --pretty

# Exact-node placement uses the same agent-scoped Fleet action as the MCP tool.
agent-relay fleet spawn codex \
  --name api-worker \
  --task "Use https://agentrelay.com/skill, ACK over Relay, then wait for details." \
  --cwd /absolute/path/to/checkout \
  --node sf-mini

# Resume a known Claude/Codex CLI session on its origin node.
agent-relay fleet spawn codex \
  --name api-worker \
  --task "Resume over Relay and continue the prior task." \
  --node sf-mini \
  --session-ref <actual-codex-thread-id>

# No placement options: use the local broker and this exact working directory.
agent-relay fleet spawn codex --name api-worker --task "Review the current diff."

# Opt into automatic eligible-node placement.
agent-relay fleet spawn codex --name api-worker --task "Review the current diff." --auto-place

# Provision a fresh E2B node, require the current Relayfile workspace to mount
# at /workspace, wait for readiness, then spawn Codex there.
agent-relay fleet spawn codex \
  --sandbox \
  --sandbox-provider e2b \
  --name e2b-worker \
  --task "Review the current workspace and wait for follow-up."

# A uniquely placed sandbox worker can be attached without node or route flags.
agent-relay node agent attach e2b-worker --mode drive

agent-relay message dm send api-worker "Detailed task instructions"
# wait is the default: it queues for the recipient's next safe idle boundary and
# can remain unread while that recipient is busy. steer requests immediate
# injection and may interrupt active work. A send ID confirms enqueue only;
# use `message inbox get_readers <id>` to confirm that the recipient consumed it.
agent-relay message dm send api-worker "Please check Relay now." --mode steer
agent-relay message inbox check --limit 20
agent-relay fleet release api-worker --reason "Work accepted"

Commands use the workspace session pinned to the current project. Exact-node spawn and messaging operations also need an agent identity: pass --token or set RELAY_AGENT_TOKEN to the token returned by agent-relay agent register <lead-name>. fleet spawn --sandbox needs a Cloud login (agent-relay cloud login) but does not need an agent token: when one is absent, it creates and removes a short-lived launcher identity automatically.

Without placement options, fleet spawn connects to the local project's broker and passes the caller's exact directory, including a nested package, to the worker. Start the local broker with agent-relay node up if it is not running; a local connection failure never falls back to remote placement. --cwd selects a different local directory on this path. Model and channel options stay local. --auto-place, --node, and --sandbox select remote placement explicitly. Legacy invocations with an explicit --workspace-key/--wk, --token, --base-url, or --persona retain automatic fleet placement when no node or sandbox is selected. Ambient credentials and persisted Cloud routing do not change the local default. Workforce reporting metadata requires remote placement. Automatic placement and release need only the workspace key.

The sandbox path provisions a fresh hosted instance and makes the Relayfile mount mandatory by default. Inside a GitHub checkout, Relay infers the Git root, repository identity, exact HEAD, and caller-relative directory. Cloud uses the pinned workspace's connected GitHub credential to seed that revision into Relayfile, and the worker starts in the decoded source tree under /workspace/github/repos/<owner>/<repo>/contents. The long-running Relayfile daemon keeps the mounted source tree synchronized with the workspace while GitHub push events update the workspace's repository source. Use --checkout when a task needs a separate static Git clone; that mode keeps the live Relayfile mirror available separately. Use --sandbox-provider daytona or --sandbox-provider e2b to require an operator-enabled provider; omit the flag to let Cloud's sandbox router choose. Pass --no-sandbox-relayfile only when a deliberately bare sandbox is desired. If provisioning times out or the spawn fails, Relay asks Cloud to delete the newly created sandbox. Runs without a custom name use one sbx_<UUID> identity and the matching fleet-sandbox-<UUID> node name. Legacy custom --sandbox-name values remain supported when no --sandbox-id is supplied; in that mode Cloud receives no sandbox identity. When replaying with --sandbox-id <sbx_UUID> (lowercase RFC 4122 UUID), pass its matching deterministic --sandbox-name or let Relay derive it. If provisioning ends with an unknown outcome, rerun the command with the warning's --sandbox-id to replay the same Cloud identity instead of adopting another fleet node.

The live source profile includes tracked dotfiles, lockfiles, generated and binary files, large files within Relayfile's import limit, symlinks, and executable permissions. Relayfile never places .git in this tree. If a repository entry cannot be represented safely, spawn fails with the entry and corrective action instead of reporting a partial working tree.

Both live and checkout modes require a clean working tree whose exact HEAD is reachable from a configured GitHub remote. This prevents a remote worker from silently starting at a different revision. Commit and push local work before retrying when Relay reports dirty files or an unreachable commit.

With --checkout, sandbox provisioning also clones the attested HEAD under /srv/agent-workforce/<repo>. The checkout must have no tracked changes or untracked source files, and the exact commit must be reachable from an origin remote. Relay's generated .agentworkforce/relay/workspace-key.json, connection.json, and runtime.json metadata are permitted. Dirty checkouts and commits known to be ahead of their origin upstream fail locally. Detached commits must appear in an origin remote-tracking branch, and Cloud independently fetches and verifies the exact SHA before dispatch. An unreachable commit produces a push-and-retry error. The temporary isolated Relaycast credential stays in the machine store under ~/.agentworkforce/relay; the project file stores only a non-secret reference.

node agent attach <name> automatically routes to the unique live fleet node advertising that worker. If more than one live node advertises the name, the command refuses to guess; pass --node <node> explicitly. Supplying --broker-url, --api-key, or --state-dir, or setting a nonblank RELAY_BROKER_URL or RELAY_BROKER_API_KEY, keeps attach local and bypasses automatic Fleet routing. node agent message flush|hold|auto <name> uses the same unique-node lookup when no local broker selection is supplied. Fleet list and release commands reuse the persisted project route; if that remote session is unavailable, the command reports the routing failure instead of selecting a same-named local worker.

From a clean repository already pinned to a Relay workspace, the ordinary live path is:

agent-relay fleet spawn codex \
  --name cloud-zero-config \
  --task "Inspect this repository and report its current commit" \
  --sandbox
agent-relay node agent attach cloud-zero-config --mode drive
agent-relay fleet agent list
agent-relay fleet release cloud-zero-config

Invoking the live command from packages/web starts the worker at /workspace/github/repos/<owner>/<repo>/contents/packages/web. The repository source metadata is available beside contents under .relayfile, .skills is mounted from the same workspace, and no .git directory is written into the Relayfile mirror.

For a static Git checkout, opt in explicitly:

agent-relay fleet spawn codex \
  --name cloud-checkout \
  --task "Inspect this repository and report its current commit" \
  --sandbox \
  --checkout

In checkout mode, invoking spawn from packages/web places the worker in that same relative directory in the remote clone. In both modes, private repositories use the pinned workspace's connected GitHub access; a repository-access error means that connection must be granted access to the repository. No GitHub token or workspace key needs to be copied into the task, mount, or checkout.

With --checkout, the Git checkout and Relayfile mirror are separate trees. In the ordinary live mode, source files are decoded from Relayfile records without placing .git in the mirror. Workspace .skills are exposed through the agent CLIs' usual skill directories, and the worker's task context identifies the mirror and exact source revision.

Detaching leaves the worker running. Only one drive session can own a worker at a time; detach the current driver before driving it in another shell, or use --mode view to observe. Releasing a worker does not delete its sandbox. To resume its retained sandbox, repeat spawn with the reported --sandbox-id <id>; when using --checkout, the retained clone must still have the same clean HEAD. A failed resume preserves retained work. For a live Relayfile sandbox, reusing --sandbox-id intentionally re-materializes the exact clean, pushed HEAD from the current checkout before the provider resumes, so a new commit becomes the source tree for that retained sandbox. With --checkout, the retained static clone remains pinned to its original revision and the current checkout must still resolve to that same clean, pushed HEAD. Delete an unused sandbox in Cloud Fleet to stop future provider usage; monthly accounting reservations remain until their normal reset.

If the workspace is not pinned yet, use agent-relay workspace rebind <name> with an existing stored workspace. A missing or mismatched stored route credential requires rerunning sandbox provisioning for that workspace. --base-url, --workspace-id, --node, provider selection, and the static --checkout mode remain advanced overrides. For --cwd, local repo-relative paths are accepted to infer the sandbox repository; absolute remote paths are advanced overrides. Outside Git, plain --sandbox preserves the existing full-workspace Relayfile mount at /workspace.

Pins created before workspace IDs were recorded are resolved automatically through Cloud at spawn time. The key travels in an authenticated POST body, never a URL. Nested packages share the repository pin; an existing subproject pin or AGENT_RELAY_PROJECT remains an explicit workspace override.

Large workspaces can add only the other live subtrees an agent needs. Pass one or more explicit directory roots after --sandbox-relayfile-path; the inferred repository, its source metadata, and .skills remain mounted automatically. Cloud validates the /path/** form and materializes those roots before the agent starts:

agent-relay fleet spawn claude \
  --sandbox \
  --sandbox-relayfile-path '/live-review/run-123/**' \
  --name reviewer \
  --task 'Review the live draft under /workspace/live-review/run-123'

--session-ref is a real CLI resume, not a logical collaboration label. Pass the actual Claude session ID or Codex thread ID and target its origin node. --cwd must name an absolute directory that exists on the selected node. The node rejects the spawn if that directory cannot be resolved; it never falls back to the node process's own working directory. Omit it to start a new CLI session. The project’s Agent Relay workspace remains pinned independently until you explicitly create or select another workspace.

To run as a Cloud-managed node, first redeem a one-time enrollment token, then start the node:

agent-relay cloud enroll --token ocl_node_enr_...
agent-relay node up

With a stored agent-relay cloud login you can mint the token yourself instead. cloud workspaces lists the workspaces the login can use, and --workspace takes a name, a Cloud workspace UUID, or a unified rw_ ID:

agent-relay cloud workspaces
# 50587328-441d-4acb-b8f3-dbe1b3c5de99  chief  Chief HQ

agent-relay cloud enroll --workspace "Chief HQ"
agent-relay node up

agent-relay cloud whoami also prints the current organization and workspace IDs.

Cloud multiplayer rooms

Cloud room membership is scoped to one Relay workspace. Every v1 invite creates a trusted full room participant: they receive their own revocable Relaycast human credential and may use all ordinary agent-level collaboration actions. The workspace key itself is never shared, so owner-key administration and Agent Relay Cloud organization administration remain owner-only.

# Owner: invite and manage people in this workspace.
agent-relay cloud room invite \
  --workspace rw_7ccfea89 \
  --email [email protected] \
  --token-file ./teammate.room-invite
agent-relay cloud room invites --workspace rw_7ccfea89
agent-relay cloud room members --workspace rw_7ccfea89

# Share the owner-only token file over a secure channel. The invitee keeps the
# token out of shell history and process arguments.
# Tokens use the consumer-neutral relay_room_inv_ prefix followed by exactly
# 43 URL-safe characters.
read -rs ROOM_INVITATION_TOKEN
printf '%s' "$ROOM_INVITATION_TOKEN" |
  agent-relay cloud room accept --token-stdin
unset ROOM_INVITATION_TOKEN

# Trusted clients establish one stable session per device.
# --json intentionally includes the participant credential; capture it in
# memory and do not log or persist it.
agent-relay cloud room session \
  --workspace rw_7ccfea89 \
  --device-id client-macbook \
  --json

# Explicitly ending or replacing the device session revokes the old scoped token.
agent-relay cloud room revoke-session \
  --workspace rw_7ccfea89 \
  --device-id client-macbook

# Participants use their scoped token for agent-level Relaycast operations; an
# ambient owner workspace key is never consulted when --token is present.
agent-relay agent presence \
  --token at_live_... \
  --base-url https://cast.agentrelay.com

# Owner: revoke access and active room sessions.
agent-relay cloud room remove-member <membership-id> --workspace rw_7ccfea89

There is no room-specific integration grant or credential service. Connect the workspace provider through the existing Cloud integration API, then use the normal Relayfile workflow for setup, mounts, reads, and writebacks:

# Owner: discover or connect a provider through Cloud.
agent-relay cloud integration catalog
agent-relay cloud integration connect linear --workspace rw_7ccfea89
agent-relay cloud integration connections --workspace rw_7ccfea89

# Member clients use Relayfile directly, including its OAuth/backend selection
# and durable writeback queue.
relayfile integration available
relayfile integration connect linear
RELAYFILE_LOCAL_DIR="$PWD/.integrations" relayfile setup
RELAYFILE_LOCAL_DIR="$PWD/.integrations" relayfile status
RELAYFILE_LOCAL_DIR="$PWD/.integrations" relayfile writeback status

local remains as a deprecated hidden alias of node (it prints a one-time warning).

Node workflow runs use Relayflows for YAML, TypeScript, and Python workflow files.

Hosted equivalents live under agent-relay cloud ….

Packages

  • @agent-relay/sdk: messaging, delivery contracts, and actions.
  • @agent-relay/harness-driver: optional managed harness runtime.
  • agent-relay: CLI and MCP entry point.