rig-tools 0.45.0

Coding tools for Rig agents: read, write, edit, search and shell, and the file and process helpers they share.
Documentation

rig-tools

Coding tools for Rig agents:

Tool What it does
read A text file's lines, with an offset and limit
write A whole file, written atomically
edit Several exact (or whitespace- and quote-tolerant) replacements, applied in order, all or nothing, answered with the changed lines' numbers and those lines, with a few around each, as they now are
search A regex over the tree as git ignores it, hidden files too when asked or when the glob names one, or the names of the files with a match (every file for an empty pattern); find returns the hits as data, render shows them
list A directory's files as git ignores them, down to a depth, optionally matching a glob, hidden files as for search
shell sh -c in its own process group, as a Launcher starts it, with a timeout (at most max_timeout, ten minutes by default), stdout and stderr interleaved line by line without terminal escape codes such as colours, and an optional OutputLimit that keeps both ends of a long output and the first and last errors from between
delete, move A file removed, or moved or renamed

Tools publish facts beside their text (such as FilesChanged), and every tool acts on a Workspace: this machine (Local) or another. The pieces the tools are built from, such as checkpoints, the overlay workspace and process groups, are listed in the crate docs.

remote reaches other machines through a transport: a command that runs its last argument, a shell line, there with the remote user's shell, keeps stdout and stderr apart and ends with 255 when it failed itself, as ssh HOST and koh exec HOST --sh do. Remote is such a machine's workspace, and Hosts wraps one so that a path written HOST:PATH, as scp reads it, is that host's and every other path stays the inner workspace's:

use std::sync::Arc;
use rig_tools::process::Launcher;
use rig_tools::remote::{Hosts, Remote};
use rig_tools::workspace::Local;
use rig_tools::Read;

let koh = ["koh", "exec", "bench", "--sh"];
let ssh = ["ssh", "-o", "BatchMode=yes", "dev@box"];
let hosts = Hosts::new(
    Arc::new(Local),
    [
        Remote::new("bench", koh, Launcher::default())?,
        Remote::new("box", ssh, Launcher::default())?,
    ],
);
// `read` of `bench:~/strata/src/lib.rs` reads that file on bench.
let read = Read { workspace: Arc::new(hosts), ..Read::default() };

Each file operation there is one short sh script through the transport, at most two at once per host; a read whose transport failed (exit 255) is sent once more, a write never: when a write's transport ends some other way, such as a link dropped mid-write, the file is hashed there again and the error says whether the write happened, and edit forgets the text it kept of that file. A read of some lines of a file over 50 KB is sent only those lines; a smaller file comes whole. An edit of a file read (any part of it, when it is that small), or edited before, is one call that writes only if the file still holds the text it was made from. A shell command there runs as a local transport process: its timeout stops that process (SIGTERM, then SIGKILL), and whether the command on the other machine stops with it is the transport's doing (ssh without a terminal leaves it running until it next writes).

Every tool then takes such paths: read, edit and write a file there, search with path: "bench:~/strata", shell with cwd: "bench:~/strata", and the paths they print and publish keep the HOST: form.

The tools run on the file system and processes, so the crate is native only. The rig-harness coding agent registers them.