host.file_ops

Posix remote file-management mixin.

Mimics the unix CLI (test/ls/mkdir/rm/cp/mv/cat) over the host’s shell via oneshot(). These manage files already on / between locations on the host — complementary to put/get (which move files local↔remote). Shared by the posix-shell hosts (UnixHost, LocalHost, DockerContainerHost).

These are a family capability, not part of the universal Host Protocol — an embedded host implements only the subset its filesystem supports.

class otto.host.file_ops.PosixFileOps

Bases: object

Mixin: unix-CLI-style remote file management for posix-shell hosts.

async exists(path: str | Path) bool

Return True when path exists on the host (test -e).

async ls(path: Annotated[str | Path, Arg(variadic=False, elem_type=None, name=None, help=None)] = '.', all: bool = False) list[str]

List entry names in path (ls -1; all adds -A for dotfiles).

async mkdir(path: str | Path, parents: bool = True) tuple[Status, str]

Create directory path (mkdir; parents adds -p).

async rm(path: str | Path, recursive: bool = False, force: bool = False) tuple[Status, str]

Remove path (rm; recursive-r, force-f).

async cp(src: str | Path, dst: str | Path, recursive: bool = False) tuple[Status, str]

Copy src to dst on the host (cp; recursive-r).

async mv(src: str | Path, dst: str | Path) tuple[Status, str]

Move/rename src to dst on the host (mv).

async read_file(path: str | Path) str

Return the text contents of path.

Reads via base64 — the exact inverse of write_file()’s base64 transport — so content round-trips byte-exact regardless of trailing newlines, trailing whitespace, or shell metacharacters (oneshot’s per-line rstrip/rejoin would otherwise corrupt them). Raises FileNotFoundError when the read fails (missing path, permissions).

async write_file(path: str | Path, data: str, append: bool = False) tuple[Status, str]

Write data to path (overwrite, or append).

The payload is base64-encoded on the wire, so arbitrary content (newlines, quotes, shell metacharacters) is transferred safely. Sent with log=False so large bodies don’t flood the log.