// ZWIRE-HOST — ENGINEERING REPORT

Single static Rust binary · two transports, one dispatcher · 70 commands · also a library · macOS · Linux · Windows

Docs

>_EXECUTIVE SUMMARY

zwire-host is a single self-contained Rust binary (~500 KB, no Python, no psutil) that exposes the local machine to any app over one JSON message protocol. It began as the Chrome native-messaging host for the zwire HUD and became a universal local endpoint: it also runs as a local-socket daemon speaking newline-delimited JSON, so browser extensions, tmux, emacs, desktop apps, plugins, shell scripts and any language reach the same capabilities.

Two transports feed one dispatcher (src/session.rs): a native-messaging stdio framing and a local-socket daemon (Unix domain socket on macOS/Linux, named pipe on Windows). Every capability — sysinfo, filesystem crawl/watch/tail, exec, background jobs, process tools, a pub/sub bus that federates across TCP-peered hosts, PTY terminals and a per-app kv store — is reachable over either transport, and the crate is also a zwire_host library so sibling hosts can embed it.

v0.3.21
Version
30
src .rs files
10,473
Source lines
70
Protocol commands
2
Transports
18
Capabilities
15
Dependencies
3
Platforms

~ARCHITECTURE

One dispatcher, many transports. A per-connection Session holds the connection's PTYs, sysinfo stream and bus/peer links; dropping it tears every one down, so a client disconnect never leaks a shell, a thread, a subscriber or a stale link. Requests carry an optional id echoed on the reply so one connection multiplexes many in-flight requests, streams and terminals.

LayerImplementation
Native messaginglittle-endian u32 length + JSON body on stdin/stdout; the default when the browser launches the binary
Local-socket daemonserve speaks newline-delimited JSON over a Unix domain socket (0600 under a 0700 dir) on macOS/Linux, or a per-user named pipe on Windows (via interprocess)
DispatcherSession::handle routes one decoded request to the capability modules and either replies (RPC) or sets up a background stream; both transports drive it identically
Streamssysinfo, fs_watch, fs_tail, PTY output and bus pub frames are pushed asynchronously, keyed by the request id
PeeringTCP-peered daemons federate the bus single-hop (star and full-mesh without loops); inbound TCP is gated by a shared --token, local Unix clients are trusted
Librarythe crate is zwire_host too; default-features = false drops sysinfo + portable-pty for embedders that only need fs/exec/kv/bus/jobs/watch

&COMMAND SURFACE

66 host commands, all reachable over both transports — the surface SURFACE_VERBS advertises on App::open("zwire")->verbs(), alongside the 100 browser.* verbs the Chromium HUD executes. The hello reply advertises which capability tags were compiled in so a client can feature-test.

Every verb declares a reversibility class, published as rev: inverse (a compensation exists), pure (reads only — runs but is not journaled), or irreversible (the default). While a transaction is open every reversible call is journaled; txn_abort compensates the journal in reverse order and fires the txn-aborted hook event, and calling an irreversible verb is refused at call time with verb not reversible: <id> so a chain fails fast instead of stranding itself half-undone. Compensation for browser.* verbs is replayed by the HUD service worker, which captured each step's pre-state; the host contributes the order.

The bus is scriptable everywhere and transactional only where a compensation genuinely exists — most of the surface is irreversible, deliberately. No host command is ever inverse: the journal records a step's verb and args, never its pre-state, so fs_write, kv_set, clipboard_set, the hooks_* writers and exec have nothing to restore from. A browser.* verb qualifies only when the HUD journal can observe all of its effects — it watches tab created / removed / moved / detached / pinned / muted / url / activated / zoomed and window created, and replays a matching set of inverse ops. Verbs outside that vocabulary (window state and bounds, tab groups, downloads, bookmarks, the reading list, browsing data, extension management) journal nothing, so classing one inverse would produce an abort reporting a clean revert having restored nothing. Every deliberately irreversible verb is listed with its reason in tests/rev_coverage.rs, whose coverage gate fails when a verb reaches the surface unclassified.

GroupCommands
Discovery, log & kvhello, ping, hostinfo, hostlog, kv_set, kv_get, kv_merge, kv_del, kv_keys
System statssysinfo_once, sysinfo_start, sysinfo_stop, meter_stream
Filesystemfs_read, fs_write, fs_append, fs_list, fs_walk, fs_stat, fs_mkdir, fs_rm
Watch & tailfs_watch, fs_tail, watch_stop, watch_list
Exec & OSexec, open, clipboard_get, clipboard_set, notify
Background jobsjob_start, job_list, job_result, job_poll
Process toolsps, kill, which
Pub/sub bussub, unsub, pub
Host-to-host peeringpeers, peer, peer_connect, remote
PTY terminalspty_spawn, pty_write, pty_resize, pty_kill
Lifecycle hookshooks_list, hooks_events, hooks_save, hooks_delete, hooks_set_enabled, hooks_get_script, hooks_set_script, hooks_script_path, hooks_test_run, hook_fire
stryke scripting & LSPstryke_run, stryke_lsp_start, stryke_lsp_send, stryke_lsp_stop
Transactionstxn_begin, txn_commit, txn_abort
Legacy zwire bridgeget + scheme/ui keys over ~/.zwire/hud-scheme and ~/.zwire/hud-ui.json

/SECURITY MODEL

The Unix-socket daemon is created 0600 under a 0700 directory, so only the owning user can reach exec/fs/pty. Socket location resolves from $ZWIRE_HOST_SOCK, else $XDG_RUNTIME_DIR/zwire-host.sock, else ~/.zwire/host.sock. Local Unix-socket clients are trusted and never authenticate. Inbound TCP peers must auth/peer_hello with a shared --token (or $ZWIRE_HOST_TOKEN) before anything privileged runs, and federation is single-hop so a forwarded event is delivered locally but not re-forwarded — no loops across star or fully-meshed topologies.


$CI GATES

GateCommand
fmtcargo fmt --all --check
clippycargo clippy --all-targets -- -D warnings
docRUSTDOCFLAGS=-D warnings cargo doc --no-deps
testcargo test (exercises the protocol over both transports)

CI runs the four canonical polish gates on Ubuntu + macOS + Windows. The umbrella MenkeTechnologiesMeta repo additionally pins this crate's metadata across its gate suite — LICENSE present + canonical MIT text, authors/repository/homepage fields, and these docs pages.


#PROJECT METADATA

ItemValue
Version0.3.21
LicenseMIT
Binary size~500 KB (release: opt-level = "z", LTO, stripped, panic = "abort")
Dependenciesserde, serde_json, toml, base64, sysinfo (optional), portable-pty (optional), tauri (optional), interprocess (Windows only)
Featuressysinfo-caps (live stats + ps/kill), pty (terminals); both default-on, both droppable for a light embed
PlatformsmacOS · Linux · Windows (all three in CI; battery reporting macOS-only via pmset)
Consumerszwire (native-messaging), zpwrchrome-host (library embed)
AuthorMenkeTechnologies
Repositorygithub.com/MenkeTechnologies/zwire-host
Meta umbrellaMenkeTechnologiesMeta