pub enum Command {
Show 53 variants
Init {
handle: String,
name: Option<String>,
relay: Option<String>,
offline: bool,
json: bool,
},
Whoami {
json: bool,
short: bool,
colored: bool,
},
Peers {
json: bool,
},
Completions {
shell: Shell,
},
Here {
json: bool,
},
Pending {
json: bool,
},
Send {
peer: String,
kind_or_body: String,
body: Option<String>,
deadline: Option<String>,
no_auto_pair: bool,
json: bool,
},
Dial {
name: String,
message: Option<String>,
json: bool,
},
Tail {
peer: Option<String>,
json: bool,
limit: usize,
},
Monitor {
peer: Option<String>,
json: bool,
include_handshake: bool,
interval_ms: u64,
replay: usize,
},
Verify {
path: String,
json: bool,
},
Mcp,
RelayServer {
bind: String,
local_only: bool,
uds: Option<PathBuf>,
},
BindRelay {
url: String,
scope: Option<String>,
replace: bool,
migrate_pinned: bool,
json: bool,
},
AddPeerSlot {
handle: String,
url: String,
slot_id: String,
slot_token: String,
json: bool,
},
Push {
peer: Option<String>,
json: bool,
},
Pull {
json: bool,
},
Status {
peer: Option<String>,
json: bool,
},
Responder {
command: ResponderCommand,
},
Pin {
card_file: String,
json: bool,
},
RotateSlot {
no_announce: bool,
json: bool,
},
ForgetPeer {
handle: String,
purge: bool,
json: bool,
},
Daemon {
interval: u64,
once: bool,
json: bool,
},
PairHost {
relay: String,
yes: bool,
timeout: u64,
detach: bool,
json: bool,
},
PairJoin {
code_phrase: String,
relay: String,
yes: bool,
timeout: u64,
detach: bool,
json: bool,
},
PairConfirm {
code_phrase: String,
digits: String,
json: bool,
},
PairList {
json: bool,
watch: bool,
watch_interval: u64,
},
PairCancel {
code_phrase: String,
json: bool,
},
PairWatch {
code_phrase: String,
status: String,
timeout: u64,
json: bool,
},
Pair {
handle: String,
code: Option<String>,
relay: String,
yes: bool,
timeout: u64,
no_setup: bool,
detach: bool,
},
PairAbandon {
code_phrase: String,
relay: String,
},
PairAccept {
peer: String,
json: bool,
},
PairReject {
peer: String,
json: bool,
},
PairListInbound {
json: bool,
},
Session(SessionCommand),
Identity {
cmd: IdentityCommand,
},
Mesh(MeshCommand),
Group(GroupCommand),
Setup {
apply: bool,
statusline: bool,
remove: bool,
},
Whois {
handle: Option<String>,
json: bool,
relay: Option<String>,
},
Add {
handle: String,
relay: Option<String>,
local_sister: bool,
json: bool,
},
Up {
relay: Option<String>,
name: Option<String>,
with_local: Option<String>,
no_local: bool,
json: bool,
},
Doctor {
json: bool,
recent_rejections: usize,
},
Upgrade {
check: bool,
local: bool,
json: bool,
},
Service {
action: ServiceAction,
},
Diag {
action: DiagAction,
},
Claim {
nick: String,
relay: Option<String>,
public_url: Option<String>,
hidden: bool,
json: bool,
},
Profile {
action: ProfileAction,
},
Invite {
relay: String,
ttl: u64,
uses: u32,
share: bool,
json: bool,
},
Accept {
target: String,
json: bool,
},
AcceptInvite {
url: String,
json: bool,
},
Reject {
peer: String,
json: bool,
},
Notify {
interval: u64,
peer: Option<String>,
once: bool,
json: bool,
},
}Variants§
Init
Generate a keypair, write self-card, and bind an inbound slot. (HUMAN-ONLY — DO NOT exec from agents.)
v0.9: refuses to create a slotless session by default. Pre-v0.9
the silent slotless state caused the 2026-05-23 silent-fail
incident — pairing + sending succeeded but peers black-holed
inbound. Operators must now name how the session is reachable:
--relay <url> (binds a slot inline) or --offline (opt into
slotless, acknowledge wire bind-relay is required before any
pair or send).
v0.13.1: folded into wire up and hidden. Your handle is your
DID-derived persona (one-name rule), so the typed handle arg is a
vestigial seed with no effect on identity. Kept callable for explicit
offline keygen (wire init x --offline); everyone else uses wire up.
Fields
relay: Option<String>Relay URL — binds an inbound slot in the same step. Required
unless --offline is passed. Example:
--relay http://127.0.0.1:8771 (local), --relay https://wireup.net
(federation).
Whoami
Print this agent’s identity (DID, fingerprint, mailbox slot).
Fields
Peers
List pinned peers with their tiers and capabilities.
Completions
v0.9.5: emit shell completion script to stdout. Pipe to your shell’s completion dir to enable tab-completion of wire verbs
- handles + flags.
Example installs:
bash: wire completions bash > /etc/bash_completion.d/wire
zsh: wire completions zsh > ~/.zsh/completions/_wire
fish: wire completions fish > ~/.config/fish/completions/wire.fish
pwsh: wire completions powershell > $PROFILE (append)
elvish: wire completions elvish > ~/.elvish/lib/wire.elv
Here
v0.9.3: one-screen “you are here” view. Prints the current
session’s character + handle + cwd, plus a short list of
neighbors (sister sessions on the local relay, pinned peers).
Designed for the operator’s quick “wait which Claude is this,
and who’s around?” question — no --json shuffling, no
remembering wire whoami vs wire peers vs wire session list-local.
Pending
v0.9 canonical surface: list pending-inbound pair requests waiting
for your consent. Aliases the legacy pair-list-inbound verb
but with the shorter, intent-first name. Operators reach for
“what’s pending?” not “what’s in my pair-list-inbound table?”
Send
Sign and queue an event to a peer.
Forms (P0.S 0.5.11):
wire send When Event body — free-form text, v0.8 — “go talk to this name.” The one verb operators reach for. With an optional message, Peer name. Character nickname (preferred), session name,
card handle, or DID — anything that identifies the peer to
you. Stream signed events from peers. Live tail of new inbox events across all pinned peers — one line per
new event, handshake (pair_drop / pair_drop_ack / heartbeat) filtered
by default. Designed to be left running in an agent harness’s stream-watcher
(Claude Code Monitor tool, etc.) so peer messages surface in the
session as they arrive, not on next manual See docs/AGENT_INTEGRATION.md for the recommended Monitor invocation
template. Verify a signed event from a JSON file or stdin ( Run the MCP (Model Context Protocol) server over stdio.
This is how Claude Desktop / Claude Code / Cursor / etc. expose
Run a relay server on this host. v0.5.17: refuse non-loopback binds, skip phonebook listing,
skip v0.7.0-alpha.16: bind to a Unix Domain Socket instead of TCP.
When set, –bind is ignored. Implies –local-only semantics
(no phonebook, no .well-known). Socket is chmod 0600 (owner-
rw only), giving SO_PEERCRED-equivalent same-uid trust for
sister sessions. Unix only (Windows refuses). Allocate a slot on a relay; bind it to this agent’s identity. v0.5.19 (issue #7): if any peers are pinned to this agent’s
current slot, this command refuses by default — silent migration
silently black-holes their inbound messages. Pass
Endpoint scope: DESTRUCTIVE: drop all existing self slots and bind only this
relay (the pre-v0.12 single-slot behavior). Default is
ADDITIVE — the new slot is appended to Manually pin a peer’s relay slot. (Replaces SAS pairing for v0.1 bootstrap;
real Drain outbox JSONL files to peers’ relay slots. Pull events from our relay slot, verify, write to inbox. Print a summary of identity, relay binding, peers, inbox/outbox queue depth.
Useful as a single “where am I” check. Publish or inspect auto-responder health for this slot. Pin a peer’s signed agent-card from a file. (Manual out-of-band pairing
— fallback path; the magic-wormhole flow is Allocate a NEW slot on the same relay and abandon the old one.
Sends a kind=1201 wire_close event to every paired peer over the OLD
slot announcing the new mailbox before swapping. After rotation,
peers must re-pair (or operator runs Use case: a paired peer turned hostile (T11 in THREAT_MODEL.md —
abusive bearer-holder spamming your slot). Rotate → old slot is
orphaned → attacker’s leverage gone. Operator pairs again with
peers they still want. Remove a peer from trust + relay state. Inbox/outbox files for that
peer are NOT deleted (operator can grep history); pass –purge to
also wipe the JSONL files. Run a long-lived sync loop: every Host a SAS-confirmed pairing. Generates a code phrase, prints it, waits
for a peer to Skip the SAS confirmation prompt. ONLY use when piping under
automated tests or when the SAS has already been verified by
another channel. Documented as test-only. Detach: write a pending-pair file, print the code phrase, and exit
immediately. The running Join a pair-slot using a code phrase from the host. (HUMAN-ONLY.) Aliased as Confirm SAS digits for a detached pending pair. The daemon must be
running for this to do anything — it picks up the confirmation on its
next tick. Mismatch aborts the pair. List all pending detached pair sessions and their state. Cancel a pending pair. Releases the relay slot and removes the pending file. Block until a pending pair reaches a target status (default sas_ready),
or terminates (finalized = file removed, aborted, aborted_restart), or
the timeout expires. Useful for shell scripts that want to drive the
detached flow without polling pair-list themselves. Exit codes:
0 — reached target status (or finalized, if target was sas_ready)
1 — terminated abnormally (aborted, aborted_restart, no such code)
2 — timeout One-shot bootstrap. Inits identity (idempotent), opens pair-host or
pair-join, then registers wire as an MCP server. Single command from
nothing to paired and ready — no separate init/pair-host/setup steps.
Operator still must confirm SAS digits. Examples:
wire pair paul # host a new pair on default relay
wire pair willard –code 58-NMTY7A # join paul’s pair v0.10: hidden from –help. Federation pair flow is now
Short handle for this agent (becomes did:wire: Code phrase from peer’s pair-host output. Omit to be the host
(this command will print one for you to share). Forget a half-finished pair-slot on the relay. Use this if Accept a pending-inbound pair request (v0.5.14). Explicit alias for
the bilateral-completion path that Reject a pending pair request (v0.5.14). When someone runs Programmatic-shape list of pending-inbound pair requests (v0.5.14).
Manage isolated wire sessions on this machine (v0.5.16). Each session = its own DID + handle + relay slot + daemon + inbox/
outbox tree. Use when multiple agents (e.g. Claude Code sessions
in different projects) run on the same machine — without sessions
they all share one identity and race the inbox cursor. Names are derived from Manage this session’s identity display layer (character override).
v0.7.0-alpha.3: agents can rename themselves — operator or Claude
itself picks a custom nickname + emoji that overrides the
auto-derived hash-based defaults. v0.6.3 (issues #18 / #19 / #20 / #21): orchestration verbs for the
sister-session mesh. Group chat (v0.13.3): create a named group, add VERIFIED peers, and
send/tail messages across the whole member set. Membership is a signed
roster (group-scoped tiers, separate from bilateral peer trust). Detect known MCP host config locations (Claude Desktop, Claude Code,
Cursor, project-local) and either print or auto-merge the wire MCP
server entry. Default prints; pass Install a Claude Code statusLine showing your wire persona
(liveness dot + emoji + nickname in the persona’s accent color +
cwd) instead of merging the MCP server. Writes a renderer script
and merges a Show an agent’s profile. With no arg, prints local self. With a
Zero-paste pair with a known handle. Resolves v0.6.6: pair with a sister session on this machine without
touching federation. Looks up Come online in one command — There is no name to choose: your handle IS your DID-derived persona
(one-name rule). The optional argument is just which relay to use. Examples:
wire up # default public relay (wireup.net)
wire up @wireup.net # explicit federation relay
wire up http://127.0.0.1:8771 # a local / self-hosted relay Relay to bind + claim your persona on: Optional display name for your profile card (cosmetic; distinct
from your addressable handle/persona). Diagnose wire setup health. Single command that surfaces every
silent-fail class — daemon down or duplicated, relay unreachable,
cursor stuck, pair rejections piling up, trust ↔ directory drift.
Replaces today’s 30-minute manual debug. Exit code non-zero if any FAIL findings. Update + restart in one step (alias: Install / inspect / remove a launchd plist (macOS) or systemd
user unit (linux) that runs Inspect or toggle the structured diagnostic trace
( Claim your persona on a relay’s handle directory. Anyone can then
reach this agent by ONE-NAME RULE (v0.13.1): the claimed handle is always your DID-derived
persona. The v0.13.1: hidden — v0.5.19 (#9.1): opt out of the relay’s bulk Edit profile fields (display_name, emoji, motto, vibe, pronouns,
avatar_url, handle, now). Re-signs the agent-card atomically. Examples:
wire profile set motto “compiles or dies trying”
wire profile set emoji “🦀”
wire profile set vibe ‘[“rust”,“late-night”,“no-async-please”]’
wire profile set handle “coffee-ghost@anthropic.dev”
wire profile get Mint a one-paste invite URL. Anyone with this URL can pair to us in a
single step (no SAS digits, no code typing). Auto-inits + auto-allocates
a relay slot on first use. Default TTL 24h, single-use. Register the invite at the relay’s short-URL endpoint and print
a v0.9: accept a pending-inbound pair request by character
nickname or card handle. Replaces the verbose v0.9.4: the URL-vs-name smart-dispatch from v0.9 is gone. To
accept a federation invite URL use v0.9.4: accept a federation invite URL minted by Split out from v0.9: refuse a pending-inbound pair request without pairing. Aliases
the legacy Watch the inbox for new verified events and fire an OS notification per
event. Long-running; background under systemd / Fields
kind_or_body: String<body> is omitted, this is the event body (kind defaults
to claim). When both this and <body> are given, this is the
event kind (decision, claim, etc., or numeric kind id) and
the next positional is the body.body: Option<String>@/path/to/body.json to load from
a file, or - to read from stdin. Optional; omit to use
<kind_or_body> as the body with kind=claim.Dial
wire dial <name> accepts a character nickname (noble-slate),
a session name (slancha-api), a card handle, or a DID — whichever
face you happen to know the peer by. Resolution order:
--local-sister path (no relay round-trip, no .well-known
lookup, no SAS digits).wire dial <handle>@<relay> for cross-machine peers).wire dial <name> "<msg>" also queues
and pushes the message after the pair completes. Idempotent: re-
dialling a known peer just sends.Fields
name: StringTail
Fields
Monitor
wire pull.Fields
Verify
-).Mcp
wire_send, wire_tail, etc. as native tools.RelayServer
Fields
local_only: bool.well-known/wire/agent serving. The relay becomes
invisible from outside the box — only same-machine processes
can pair through it. Right call for within-machine agent
coordination where you don’t want metadata leaking to a
public relay. Pair this with wire session new which probes
127.0.0.1:8771 and allocates a local slot automatically.uds: Option<PathBuf>BindRelay
--migrate-pinned to acknowledge the risk and proceed, or use
wire rotate-slot (which emits a wire_close event to peers)
for safe rotation.Fields
scope: Option<String>federation | local | lan | uds.
Default inferred from the URL (loopback host -> local,
unix:// -> uds, otherwise federation). Pass explicitly when
the inference is ambiguous (e.g. a federation relay on a
loopback address in tests).replace: boolself.endpoints[],
keeping any existing slots so pinned peers are not
black-holed.AddPeerSlot
wire join lands in the SPAKE2 iter.)Fields
Push
Fields
Pull
Status
Fields
Responder
Fields
command: ResponderCommandPin
pair-host / pair-join.)RotateSlot
add-peer-slot with the new
coords) — auto-update via wire_close is a v0.2 daemon feature.Fields
ForgetPeer
Fields
Daemon
& / tmux as you prefer.Fields
PairHost
pair-join, exchanges signed agent-cards via SPAKE2 +
ChaCha20-Poly1305. Auto-pins on success. (HUMAN-ONLY — operator must
read the SAS digits aloud and confirm.)Fields
yes: booldetach: boolwire daemon does the handshake in the
background; confirm SAS later via wire pair-confirm <code> <digits>.
wire pair-list shows pending sessions. Default is foreground
blocking behavior for backward compat.PairJoin
wire join <code> for magic-wormhole muscle-memory.Fields
PairConfirm
Fields
PairList
Fields
PairCancel
PairWatch
Fields
Pair
wire dial <handle>@<relay> + wire accept-invite <URL>.
wire pair stays callable for back-compat scripts; v1.0 removes.Fields
handle: Stringcode: Option<String>PairAbandon
pair-host
or pair-join crashed (process killed, network blip, OOM) before SAS
confirmation, leaving the relay-side slot stuck with “guest already
registered” or “host already registered” until the 5-minute TTL expires.
Either side can call. Idempotent.Fields
PairAccept
wire add <peer>@<relay> also
drives — but doesn’t require remembering the peer’s relay domain
(the relay coords come from the stored pair_drop). Errors if no
pending-inbound record exists for that peer.PairReject
wire add you@<your-relay> against your handle, their signed pair_drop lands
in pending-inbound — visible via wire pair-list. Run wire pair-reject <peer> to delete the record without pairing. The peer never receives
our slot_token; from their side the pair stays pending until they
time out.PairListInbound
--json returns a flat array (matching the v0.5.13-and-earlier
pair-list --json shape but for inbound). Use this in scripts that
need to enumerate inbound pair requests without parsing the SPAKE2
table format from wire pair-list.Session(SessionCommand)
basename(cwd) and cached in a registry,
so re-entering the same project reuses the same identity.Identity
Fields
cmd: IdentityCommandMesh(MeshCommand)
wire mesh status is the live view of every
paired sister (alias for wire session mesh-status); wire mesh broadcast fans one signed event to every pinned peer.Group(GroupCommand)
Setup
--apply to actually modify config
files. Idempotent — re-running is safe.Fields
statusline: boolstatusLine block into Claude Code’s settings.json
(honors $CLAUDE_CONFIG_DIR). Combine with –apply to write.Whois
nick@domain arg, resolves via that domain’s .well-known/wire/agent
endpoint and verifies the returned signed card before display.Fields
Add
nick@domain via that
domain’s .well-known/wire/agent, then delivers a signed pair-intro
to the peer’s slot via /v1/handle/intro. Peer’s daemon completes
the bilateral pin on its next pull (sends back pair_drop_ack carrying
their slot_token so we can wire send to them).Fields
local_sister: boolhandle as a session name in
wire session list, reads that session’s agent-card +
endpoints from disk, pins directly, then delivers the
pair_drop to the sister’s local-relay slot. No .well-known
resolution; reserved nicks (wire, slancha, etc.) are
addressable because they don’t need a federation claim.Up
wire up does what used to take five
(init + bind-relay + claim your persona + background daemon +
restart-on-login). Idempotent: re-run on an already-set-up box prints
state without churn.Fields
relay: Option<String>@wireup.net, wireup.net,
or a full URL. Omit for the default public relay. No nick — your
handle is your DID-derived persona.name: Option<String>Doctor
Fields
Upgrade
wire update). ALWAYS checks
crates.io for a newer published wire; if one exists it installs it
(via cargo install slancha-wire when a Rust toolchain is on PATH,
else by downloading + SHA-256-verifying the prebuilt release binary
and replacing this one in place), then does the atomic daemon swap —
kill every wire daemon, respawn from the (now-current) binary, write
a fresh pidfile. No newer version → it skips the install and just
restarts the daemon. --check reports what would happen (available
update + processes that would be restarted) without doing it;
--local skips the crates.io check and only restarts the daemon
(offline, or running a local dev build).Fields
Service
wire daemon on login + restarts
on crash. Replaces today’s “background it with tmux/&/systemd
as you prefer” footgun.Fields
action: ServiceActionDiag
$WIRE_HOME/state/wire/diag.jsonl). Off by default. Enable per
process via WIRE_DIAG=1, or per-machine via wire diag enable
(writes the file knob a running daemon picks up automatically).Fields
action: DiagActionClaim
<persona>@<relay-domain> via the relay’s
.well-known/wire/agent endpoint. FCFS; same-DID re-claims allowed.nick arg is vestigial — if it differs it is ignored
(like the typed name wire init / wire up already ignore), so your
phonebook entry can never drift from your agent-card handle.wire up claims your persona for you. Kept callable
(idempotent re-claim) but not a user verb; there is no nick to choose.Fields
/v1/handles
directory listing. The handle stays claimed (FCFS still
applies) and direct .well-known/wire/agent?handle=X lookup
still resolves, so peers you share the handle with out-of-band
can still pair. Bulk scrapers / phonebook crawlers will not
see the nick. Use this for handles meant for known-peer
pairing only — see issue #9.Profile
Fields
action: ProfileActionInvite
Fields
curl ... | sh one-liner the peer can run on a fresh machine.
Installs wire if missing, then accepts the invite, then pairs.Accept
wire pair-accept <peer>.wire accept-invite <URL>
(split out as an explicit verb to eliminate the input-shape
ambiguity). wire accept <URL> still works for back-compat
but emits a deprecation banner pointing at accept-invite.AcceptInvite
wire invite.
Pins issuer, sends signed card to issuer’s slot. Auto-inits +
auto-allocates as needed.wire accept to eliminate the URL-vs-name
smart-dispatch ambiguity (peer handles can legitimately collide
with URL-shaped strings; the explicit verb removes the inference).Reject
wire pair-reject <peer>.Fields
Notify
& / tmux. Cursor is
persisted to $WIRE_HOME/state/wire/notify.cursor so restarts don’t
re-emit history.Fields
Trait Implementations§
Source§impl FromArgMatches for Command
impl FromArgMatches for Command
Source§fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
Source§fn from_arg_matches_mut(
__clap_arg_matches: &mut ArgMatches,
) -> Result<Self, Error>
fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>
Source§fn update_from_arg_matches(
&mut self,
__clap_arg_matches: &ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§fn update_from_arg_matches_mut<'b>(
&mut self,
__clap_arg_matches: &mut ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches_mut<'b>( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§impl Subcommand for Command
impl Subcommand for Command
Source§fn augment_subcommands<'b>(__clap_app: Command) -> Command
fn augment_subcommands<'b>(__clap_app: Command) -> Command
Source§fn augment_subcommands_for_update<'b>(__clap_app: Command) -> Command
fn augment_subcommands_for_update<'b>(__clap_app: Command) -> Command
Command so it can instantiate self via
FromArgMatches::update_from_arg_matches_mut Read moreSource§fn has_subcommand(__clap_name: &str) -> bool
fn has_subcommand(__clap_name: &str) -> bool
Self can parse a specific subcommand