Standard capabilities
The catalogue of capabilities every Zyris consumer understands, and the reference crates that implement them.
zyris-caps declares a set of capabilities that agents and clients already know how to use. It
contains declarations only — the traits, descriptors and generated clients — with no tokio, no
OS dependencies and nothing that touches a disk or a display. Implementations live in separate
crates, and a node adds the ones it wants to serve.
Enable the caps feature to reach the catalogue as zyris::caps.
To reuse these implementations, see Capability addons for dependency
setup, composition with custom tools, platform requirements and the zyris-capkit migration.
The catalogue
| Capability | Version | Tools | Implementation |
|---|---|---|---|
terminal | 3 | open, open_stream, read, screen, write, resize, close, exec | zyris-terminal — PtyTerminal |
file_io | 3 | stat, list, read, read_stream, write, edit, remove, mkdir | zyris-fs — LocalFileIo |
input | 1 | type_text, key, move_to, click, scroll | zyris-input — EnigoInput |
screen_capture | 1 | list_displays, screenshot | zyris-screen — HostScreenCapture |
browser_chrome | 1 | targets, send | — |
file_transfer | 1 | send_to, inbox_list | zyris-transfer — LocalFileTransfer |
peer_transfer | 1 | push_offer, pull | zyris-transfer — LocalPeerTransfer |
file_transfer is what an agent calls to send a file or read the inbox; peer_transfer is the
exchange two nodes have with each other to move the bytes, directly over
zyris-p2p rather than through the server.
Serving files and a shell
[dependencies]
zyris = { git = "https://github.com/attacca-cc/zyris-protocol", features = ["caps", "tls-ring"] }
zyris-fs = { git = "https://github.com/attacca-cc/zyris-protocol" }
zyris-terminal = { git = "https://github.com/attacca-cc/zyris-protocol" }use zyris::caps::{FileIoServer, TerminalServer};
use zyris::{Node, NodeKind};
use zyris_fs::LocalFileIo;
use zyris_terminal::PtyTerminal;
let node = Node::builder()
.name("workstation")
.kind(NodeKind::Desktop)
.capability(FileIoServer(LocalFileIo::rooted("/home/me/work")))
.capability(TerminalServer(PtyTerminal::rooted("/home/me/work")))
.build()?;Take every zyris crate from the same place
The implementation crates depend on zyris-core. Mixing a git zyris with a crates.io
zyris-fs links two different runtimes, and their types will not match. Until the next release,
take all of them from git as above.
terminal
PtyTerminal spawns a shell behind a real pseudo-terminal and keeps its output in a per-session ring
buffer, feeding the same bytes to a vt100 screen model — so read returns the stream while
screen renders the grid, and neither consumes the other. exec is the one-shot side: no PTY, a
bounded run, and on timeout the whole process tree is killed, not just the shell. Sessions are capped,
and one nobody has touched for ten minutes is swept away.
file_io
LocalFileIo is backed by the filesystem of the machine the node runs on. read is unary and
returns at most 128 KiB, setting truncated when the file continues; pass the next offset to walk
the rest, or use read_stream, which has no ceiling.
The root is a default, not a jail
rooted(..) says where a relative path starts. An absolute path still addresses the whole
filesystem, and .. climbs out. That is deliberate — an agent working in a checkout sometimes has to
read a sibling directory — so a node that needs a boundary enforces one itself, in front of these
types, where it can see its own policy. zyris_caps::resolve_under is the resolution every
implementation shares.
zyris-code shows one way to fence a node: it refuses calls outside the directory it was started in unless the user allows them.
Desktop capabilities
screen_capture and input share one coordinate space: a position read off a screenshot goes
straight into input.move_to. Serve them together — an agent that can see but not act, or act but
not see, is guessing.
zyris-screencaptures overxcap, orzwlr_screencopyon wlroots compositors. It is pure Rust off Linux; on Linux it needs the display development packages to build.zyris-inputdrives the keyboard and pointer through a pinned fork ofenigo. Its manifest explicitly setspublish = false: packaging a version-plus-git dependency drops the git revision, so a registry release would not preserve the fork's behavior. Use the git workspace.
A headless node should not build either; both link the display stack.
See the detailed guides for screen capture, input, and direct transfers for backend selection, coordinates, permissions and peer trust.
Consuming the catalogue
The same crate gives callers typed clients — TerminalClient, FileIoClient and so on — which is
what makes a client cheap to build: it depends on declarations only.
use zyris::caps::{FileIo, FileIoClient}; // the trait brings the client's methods into scope
let files: FileIoClient = conn.wait_capability(std::time::Duration::from_secs(5)).await?;
let entries = files.list("/var/log".into()).await?;