ZyrisDocs

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

CapabilityVersionToolsImplementation
terminal3open, open_stream, read, screen, write, resize, close, execzyris-terminal — PtyTerminal
file_io3stat, list, read, read_stream, write, edit, remove, mkdirzyris-fs — LocalFileIo
input1type_text, key, move_to, click, scrollzyris-input — EnigoInput
screen_capture1list_displays, screenshotzyris-screen — HostScreenCapture
browser_chrome1targets, send—
file_transfer1send_to, inbox_listzyris-transfer — LocalFileTransfer
peer_transfer1push_offer, pullzyris-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

Cargo.toml
[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-screen captures over xcap, or zwlr_screencopy on wlroots compositors. It is pure Rust off Linux; on Linux it needs the display development packages to build.
  • zyris-input drives the keyboard and pointer through a pinned fork of enigo. Its manifest explicitly sets publish = 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?;

On this page