skip to content
$worker

shell

v0.9.2

Unix shell + filesystem worker — exec with denylist/timeout/output caps and background jobs; fs::ls|stat|mkdir|rm|chmod|mv|grep|sed|read|write with host jail, denylist, size caps, and sandbox-target forwarding

iiiverified
405 installs111 in 7d28 today
install
$iii worker add shell@0.9.2
  • macOS: arm64 · x64
  • Linux: arm64 · armv7 · x64

exact versions are immutable; binary and bundle artifacts are digest-pinned.

functions

29

coder::create-file

function

Create one or more files. Request shape: {"files": [{"path": "...", "content": "..."}]}. Per-file `overwrite` and `parents` flags; non-accessible paths return C211. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*.

request
  • filesobject[]required
    • contentstringrequired
    • modestring

      Octal permission bits as a string, e.g. "0644". Defaults to "0644".

    • overwriteboolean

      When false (the default), refuse to write if `path` already exists.

    • parentsboolean

      Create missing parent directories. Defaults to true so a single `coder::create-file` call can scaffold a fresh subtree.

    • pathstringrequired

      Path relative to the primary allowed root, or an absolute path inside any allowed root. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

response
  • resultsobject[]required
    • bytes_writteninteger· uint64requiredmin 0
    • errorany of

      Structured error for this entry. `code` is stable for programmatic branching (e.g. `"C217"` means already-exists; pass `overwrite=true` to replace). `message` carries the corrective action an LLM agent needs to make a successful second call.

      any of (2)
      variant 1
      • codestringrequired

        Stable error code, e.g. "C211". See the README error table.

      • messagestringrequired

        Human/LLM-readable message: problem + actual values + corrective next call.

      variant 2
      valuenull
    • pathstringrequired

      Canonical absolute path (resolved through the jail); the caller's input verbatim when resolution failed.

    • successbooleanrequired

coder::delete-file

function

Remove one or more paths. Request shape: {"paths": ["..."]}. Directories need `recursive: true`; missing paths are idempotent successes; recursive removal refuses to descend through non-accessible entries. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*.

request
  • pathsstring[]required

    Paths to remove. Each entry is relative to the primary allowed root, or an absolute path inside any allowed root. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

  • recursiveboolean

    Required for non-empty directories. Files and empty dirs ignore it.

response
  • resultsobject[]required
    • errorany of

      Structured error for this entry. `code` is stable for programmatic branching (e.g. `"C211"` for not-found-or-denied; `"C210"` for refusing to delete an allowed root). `message` carries the corrective action an LLM agent needs to make a successful second call.

      any of (2)
      variant 1
      • codestringrequired

        Stable error code, e.g. "C211". See the README error table.

      • messagestringrequired

        Human/LLM-readable message: problem + actual values + corrective next call.

      variant 2
      valuenull
    • pathstringrequired

      Canonical absolute path (resolved through the jail); the caller's input verbatim when resolution failed.

    • removedbooleanrequired
    • successbooleanrequired

coder::info

function

Report the coder jail: canonical allowed roots (primary first), per-file size caps, response budgets (max_output_bytes, batch_read_budget_bytes, search_response_budget_bytes), listing/search limits, the non-accessible glob patterns, and the default_exclude_globs noise filter applied by tree/search. Call this FIRST when unsure where coder may read or write, or when a path was rejected — paths outside every allowed root need the shell worker's shell::fs::* instead.

request
empty object
response
  • base_pathsstring[]required

    Canonical absolute paths of the allowed roots, in configuration order. The primary root (index 0) is where relative wire paths resolve; an absolute path is accepted when it canonicalises inside ANY of these. Paths outside every root are rejected — use `shell::fs::*` instead.

  • batch_read_budget_bytesinteger· uint64requiredmin 0

    Aggregate budget across a single `paths[]` batch call to `coder::read-file`, measured in bytes of returned content (after UTF-8 sanitization — invalid bytes expand to U+FFFD before being counted, so the cap bounds what the caller actually receives). Entries are collected in request order; each entry may consume up to `min(remaining_budget, max_read_bytes)`. An entry reached with zero remaining budget receives a per-entry C213 naming this key, its value, and the bytes already consumed, with recovery guidance. Budget topology: batch reads are governed by this key; single-path full reads by `max_output_bytes`; windowed reads by `max_read_bytes` applied per returned window — `max_read_bytes` is also the per-file IO ceiling for all of them.

  • default_exclude_globsstring[]required

    Noise-exclusion globs (root-relative, same matching as `non_accessible_globs`): matching paths (node_modules, .git, …) are omitted from `coder::search` results and pruned from `coder::tree` descent — the directory surfaces as a childless `truncated` stub. Hide-only — no access protection. Pass `use_default_excludes: false` on those calls to look inside.

  • list_default_page_sizeinteger· uint32requiredmin 0

    Default `page_size` used by `coder::list-folder` when the caller omits it.

  • list_max_page_sizeinteger· uint32requiredmin 0

    Hard cap on `page_size` accepted by `coder::list-folder`.

  • max_output_bytesinteger· uint64requiredmin 0

    Context budget for single-path FULL reads in `coder::read-file`, in bytes of returned content. Full reads larger than this return C213 with the file's size/line count and window/stat recovery guidance; a per-call `max_output_bytes` override is available on `coder::read-file` (clamped to `max_read_bytes`).

  • max_read_bytesinteger· uint64requiredmin 0

    Per-file IO ceiling for `coder::read-file`. Full reads of files larger than this are rejected with C213; windowed reads cap the returned window bytes instead, so larger files stay readable window by window. Also the ceiling for `coder::search` content scanning — larger files are silently skipped during search.

  • max_write_bytesinteger· uint64requiredmin 0

    Maximum bytes that `coder::create-file` or `coder::update-file` will accept for a single file write. Larger writes are rejected with C213.

  • non_accessible_globsstring[]required

    Glob patterns matched per root (root-relative). Files whose root-relative path matches are listable but not readable/writable/deletable/creatable; they return C211.

  • primary_rootstringrequired

    Convenience duplicate of `base_paths[0]` — the primary allowed root. Relative paths resolve against this directory.

  • search_default_max_line_bytesinteger· uint32requiredmin 0

    Per-line byte cap in `coder::search`: matching considers at most this many bytes of each line, and matched/context lines are truncated to it.

  • search_default_max_matchesinteger· uint32requiredmin 0

    Default `max_matches` used by `coder::search` when the caller omits it.

  • search_response_budget_bytesinteger· uint64requiredmin 0

    Aggregate byte budget for one `coder::search` response, measured in payload bytes (paths + matched text + context lines). When the budget is hit the response sets `truncated: true` — refine the query or add `include_globs`.

  • tree_default_depthinteger· uint32requiredmin 0

    Default `max_depth` used by `coder::tree` when the caller omits it.

  • tree_per_folder_limitinteger· uint32requiredmin 0

    Maximum entries returned per folder node by `coder::tree`; folders that exceed this are flagged `truncated`.

  • versionstringrequired

    Coder worker version (`CARGO_PKG_VERSION`).

coder::list-folder

function

Paginated single-folder listing, sorted by name. Entries carry only `name`; derive an entry's absolute path as the response's `path` + '/' + name. Non-accessible entries are still listed with a `non_accessible: true` flag. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*.

request
  • pageinteger· uint32min 0
  • page_sizeinteger· uint32min 0

    Capped by `config.list_max_page_size`; falls back to `config.list_default_page_size` when omitted.

  • pathstring

    Folder to list. Relative to the primary allowed root, or an absolute path inside any allowed root. Defaults to `.` (the primary root itself). Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

response
  • entriesobject[]required
    • kindstringrequiredenum: file, dir, symlink, other
    • mtimeinteger· int64required
    • namestringrequired

      Entry basename. The absolute path is derivable from the response's `path`: entry path = folder path + "/" + name.

    • non_accessiblebooleanrequired

      True if this entry matches `non_accessible_globs` — caller cannot read/write/delete it via `coder::*` even though it shows up here.

    • sizeinteger· uint64requiredmin 0
  • has_morebooleanrequired
  • pageinteger· uint32requiredmin 0
  • page_sizeinteger· uint32requiredmin 0
  • pathstringrequired

    Canonical absolute path of the listed folder (resolved through the jail). Entries carry only `name`; derive an entry's absolute path by joining: entry path = this path + "/" + name. Operations on derived paths re-validate through the jail.

  • totalinteger· uint64requiredmin 0

coder::move

function

Move or rename one or more paths inside the jail. Request shape: {"files": [{"from": "...", "to": "..."}]}. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*. Per-entry `overwrite` and `parents` flags. Same-root moves use a per-file-atomic rename; cross-root moves use copy+delete (files only — cross-root directory moves are unsupported, move files individually). Copy+delete is rollback-safe: if source deletion fails after a successful copy the copy is removed and the error names the failure; if rollback also fails the error names both states for manual cleanup.

request
  • filesobject[]required

    Entries to move. Each entry is processed independently so a single failure never aborts the rest.

    • fromstringrequired

      Source path: relative to the primary allowed root, or an absolute path inside any allowed root. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

    • overwriteboolean

      When false (the default), refuse to overwrite an existing destination. Pass `overwrite: true` to replace an existing file at `to`.

    • parentsboolean

      Create missing parent directories of the destination. Defaults to true.

    • tostringrequired

      Destination path: relative to the primary allowed root, or an absolute path inside any allowed root. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

response
  • resultsobject[]required
    • errorany of

      Structured error for this entry. `code` is stable for programmatic branching (e.g. `"C217"` means destination exists; pass `overwrite=true` to replace; `"C210"` for disallowed operations such as cross-root directory moves, moving a root itself, or a destination that is a directory — the message then names the corrected target path). `message` carries the corrective action an LLM agent needs to make a successful second call.

      any of (2)
      variant 1
      • codestringrequired

        Stable error code, e.g. "C211". See the README error table.

      • messagestringrequired

        Human/LLM-readable message: problem + actual values + corrective next call.

      variant 2
      valuenull
    • fromstringrequired

      Canonical absolute path of the source (resolved through the jail); the caller's input verbatim when resolution failed.

    • movedbooleanrequired

      True only when the move fully completed; false for a no-op self-move (`from` and `to` resolve to the same file).

    • successbooleanrequired
    • tostringrequired

      Canonical absolute path of the destination (resolved through the jail); the caller's input verbatim when resolution failed.

coder::read-file

function

Read a file window-first: probe with stat: true (size/mtime/mode plus total_lines, no content), then fetch just the lines you need with line_from/line_to (1-based, inclusive) — windows keep files larger than max_read_bytes readable window by window, with more_lines/total_lines reporting what remains. numbered: true prefixes each line with its absolute 1-based file line number, matching coder::update-file's line ops exactly. Full reads are budgeted by max_output_bytes (default 128 KiB; per-call override clamped to max_read_bytes) — an over-budget full read fails with a C213 carrying the file's size, line count, and the window/stat recovery calls. Batch mode: pass paths[] (XOR path) to read multiple files in one call — entries are processed in request order against batch_read_budget_bytes, measured in bytes of returned content (after UTF-8 sanitization); per-entry errors (C211/C213) leave other entries unaffected. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*. Non-accessible paths return C211.

request
  • line_frominteger· uint64min 1

    First line of the window, 1-based inclusive (must be >= 1; 0 is rejected with C210). Setting `line_from` and/or `line_to` switches to windowed mode: the file is streamed and only the requested lines are returned, so files larger than `max_read_bytes` stay readable slice by slice — the byte cap then applies to the returned window, never the file size. Defaults to 1 when only `line_to` is set. A window starting past EOF succeeds with empty content and reports the file's `total_lines`. Only valid in single-path mode (`path`); ignored when `paths` is set. Lines are 0x0A- or EOF-terminated segments; a trailing newline does not create a phantom line (same convention as `coder::update-file`).

  • line_tointeger· uint64min 1

    Last line of the window, 1-based inclusive. Must be >= `line_from` (C210 otherwise). Omit to read from `line_from` to end-of-file (still bounded by `max_read_bytes` on the returned bytes). Only valid in single-path mode (`path`); ignored when `paths` is set.

  • max_output_bytesinteger· uint64min 0

    Per-call override of the `max_output_bytes` config (default 131072) that budgets single-path FULL reads, measured in returned content bytes after UTF-8 conversion (numbered prefixes included). Values above `max_read_bytes` are silently clamped to it. When the full content would exceed the effective budget the call fails with a C213 naming the file's size and `total_lines` — recover by windowing with `line_from`/`line_to`, probing with `stat: true`, or raising this field. Full reads only: combining it with `line_from`/`line_to` is C210 (windows are bounded by `max_read_bytes` instead); ignored when `paths` is set (batch mode is governed by `batch_read_budget_bytes`).

  • numberedboolean

    When true every returned content line is prefixed `N→`, where N is the line's ABSOLUTE 1-based number in the file — a window starting at `line_from: 40` is numbered from 40, not 1. Numbers match `coder::update-file`'s 1-based line ops exactly, so you can go from a numbered read straight to a line edit. Prefix bytes count toward all byte caps and budgets (no hidden bypass). C210 with `stat: true` (no content to number). Batch entries take a per-entry `numbered` field instead; this top-level flag is ignored when `paths` is set.

  • pathstring

    Single file to read. Relative to the primary allowed root, or an absolute path inside any allowed root. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail. Mutually exclusive with `paths` (XOR): pass either `path` or `paths`, not both — C210 if both or neither is set.

  • pathsany of[]

    Batch of files (or windowed slices) to read in a single call. Each entry is either a plain path string (whole-file read) or an object `{path, line_from?, line_to?}` with per-entry window parameters. Entries are processed in request order against a shared `batch_read_budget_bytes` cap, measured in bytes of returned content (after UTF-8 sanitization) — see `coder::info` for the configured value. Results are returned in the `results` field; top-level fields are null. Mutually exclusive with `path` (XOR): pass either `path` or `paths`, not both — C210 if both or neither is set.

    any of (2)
    variant 1
    valuestring
    variant 2
    • line_frominteger· uint64min 1

      First line of the window, 1-based inclusive (must be >= 1; 0 is rejected with C210 for this entry). Defaults to 1 when only `line_to` is set.

    • line_tointeger· uint64min 1

      Last line of the window, 1-based inclusive. Must be >= `line_from` (C210 for this entry otherwise). Omit to read from `line_from` to EOF.

    • numberedboolean

      Prefix this entry's content lines with their absolute 1-based file line numbers (`N→`) — same semantics as the top-level `numbered` field. Prefix bytes are charged against `batch_read_budget_bytes`.

    • pathstringrequired

      File to read. Same jail rules as the top-level `path` field.

    • statboolean

      Per-entry metadata probe: same semantics as the top-level `stat` field — size/mode/mtime always, `total_lines`/`is_utf8` when the file fits `max_read_bytes`, content null, no batch budget consumed. C210 when combined with this entry's `line_from`/`line_to` or `numbered`.

  • statboolean

    Metadata probe — the cheap "how big is it" call. When true the response carries size/mode/mtime plus `total_lines` and `is_utf8` (both null when the file exceeds `max_read_bytes` — size/mode/mtime still populate, so stat on a huge file SUCCEEDS); `content` is null, `lines_returned` 0, `more_lines` false. Probe BEFORE reading an unknown file, then fetch just the slice you need with `line_from`/`line_to`. Mutually exclusive with `line_from`, `line_to`, `numbered`, and `max_output_bytes` (C210 — stat returns no content for them to act on). Batch entries take a per-entry `stat` field instead; this top-level flag is ignored when `paths` is set.

response
  • contentstring

    File content as a UTF-8 string — the whole file, or just the requested window when `line_from`/`line_to` was given (window lines keep their newline terminators). Binary content is returned with invalid bytes replaced by U+FFFD; use a future binary-aware function if exact bytes matter. **Single-path mode only; null when the request used `paths[]`.**

  • is_utf8boolean

    Whether `content` survived UTF-8 conversion without losing bytes. Reflects the RETURNED content only: a clean window inside an otherwise-binary file is still `true`. **Single-path mode only; null when the request used `paths[]`.**

  • lines_returnedinteger· uint64min 0

    Number of lines in `content`. For full reads this equals the file's total line count. **Single-path mode only; null when the request used `paths[]`.**

  • modeinteger· uint32min 0

    Unix permission bits (lower 9 bits of `st_mode`), e.g. 0o644. **Single-path mode only; null when the request used `paths[]`.**

  • more_linesboolean

    True when the file has content beyond what `content` includes: the window ended before EOF, or the byte budget cut the window short. Always false for full reads. **Single-path mode only; null when the request used `paths[]`.**

  • mtimeinteger· int64

    Last-modified time as a Unix epoch in seconds. **Single-path mode only; null when the request used `paths[]`.**

  • pathstring

    Canonical absolute path of the file read (resolved through the jail). **Single-path mode only; null when the request used `paths[]`.**

  • resultsobject[]

    Per-entry results for a batch `paths[]` request. **Present only when the request used `paths[]`; null in single-path mode.**

    • contentstring

      File content as a UTF-8 string — the whole file or the requested window. Binary bytes are replaced by U+FFFD (`is_utf8: false`). `null` on failure.

    • errorany of

      Structured error — present only when `success: false`.

      any of (2)
      variant 1
      • codestringrequired

        Stable error code, e.g. "C211". See the README error table.

      • messagestringrequired

        Human/LLM-readable message: problem + actual values + corrective next call.

      variant 2
      valuenull
    • is_utf8boolean

      Whether `content` survived UTF-8 conversion without losing bytes. `null` on failure.

    • lines_returnedinteger· uint64min 0

      Number of lines returned in `content`. `null` on failure.

    • modeinteger· uint32min 0

      Unix permission bits (lower 9 bits of `st_mode`), e.g. 0o644. `null` on failure.

    • more_linesboolean

      `true` when the file has content beyond what `content` includes (window ended before EOF, or byte budget cut the window short). `null` on failure.

    • mtimeinteger· int64

      Last-modified time as a Unix epoch in seconds. `null` on failure.

    • pathstringrequired

      Canonical absolute path of the file (resolved through the jail). If resolution failed, this echoes the caller's input verbatim.

    • sizeinteger· uint64min 0

      Size of the FILE in bytes (from metadata). `null` on failure or when the entry budget was exhausted before the file was opened.

    • successbooleanrequired

      `true` when the read succeeded (content/metadata fields are populated); `false` when an error occurred (only `error` is set).

    • total_linesinteger· uint64min 0

      Total lines in the file; present when the stream reached EOF during this entry's read. `null` when not traversed or on failure.

  • sizeinteger· uint64min 0

    Size of the FILE in bytes (from metadata) — not the size of `content`; in windowed mode the two differ. **Single-path mode only; null when the request used `paths[]`.**

  • total_linesinteger· uint64min 0

    Total number of lines in the file. Present only when the read traversed the whole file: always for full reads; for windowed reads only when the stream naturally reached EOF within the byte cap. Never computed by forcing an extra full scan — absent means the file was not fully traversed. **Single-path mode only; null when the request used `paths[]`.**

coder::search

function

Search file contents and/or paths. Supports literal or regex queries with include/exclude globs; non-accessible files are excluded from both content and path results. Only the FIRST match on each line is reported (one content match per matching line). Optional context_lines_before/context_lines_after (max 10) attach surrounding lines to each content match so many edits can go straight to coder::update-file with no read in between. Noise paths matching default_exclude_globs (.git, node_modules, target, … — coder::info lists them) are skipped by default; pass use_default_excludes: false to search inside them. Files larger than max_read_bytes are silently skipped during content scanning. Results are capped by max_matches AND a response byte budget (search_response_budget_bytes); when truncated is true, refine the query or add include_globs rather than paginate. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*.

request
  • context_lines_afterinteger· uint32min 0

    Lines of context to return AFTER each content match. Same max (10), truncation, and budget rules as `context_lines_before`; unset = 0.

  • context_lines_beforeinteger· uint32min 0

    Lines of context to return BEFORE each content match (same file only, in file order), max 10 — larger values are rejected with C210. With context lines many edit tasks can go straight from search output to coder::update-file with no read in between. Context lines are truncated to `max_line_bytes` like the matched text and count toward the response byte budget. Unset = 0.

  • exclude_globsstring[]

    Glob patterns (same relative-to-root matching) that exclude paths.

  • ignore_caseboolean
  • include_globsstring[]

    Glob patterns (matched against the path relative to its containing root) that paths must match to be considered. Empty = include everything.

  • max_line_bytesinteger· uint32min 0

    Bytes per line to consider when scanning content; longer lines are truncated for the match snippet.

  • max_matchesinteger· uint32min 0

    Optional explicit cap. Falls back to config when unset.

  • pathstring

    Folder scoping the walk. Relative to the primary allowed root, or an absolute path inside any allowed root. Defaults to `.` (the primary root itself). Globs are matched relative to the containing root; result paths are absolute regardless of this value. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

  • querystringrequired

    Pattern to search for. Treated as a regex when `regex: true`, otherwise as a literal substring.

  • regexboolean
  • search_contentboolean

    Search file contents (default true).

  • search_pathsboolean

    Search file paths (default true).

  • use_default_excludesboolean

    Apply the worker's `default_exclude_globs` config (noise paths like .git, node_modules, target, dist — call coder::info for the active list): the walk does not descend into matching directories and matching files are omitted from BOTH content and path results. Pass `false` to search inside them.

response
  • content_matchesobject[]required
    • afterstring[]

      Context lines immediately after the matched line — same file only, in file order, each truncated to `max_line_bytes`. Omitted when empty (no `context_lines_after` requested, or the match is at the end of the file).

    • beforestring[]

      Context lines immediately before the matched line — same file only, in file order, each truncated to `max_line_bytes`. Omitted when empty (no `context_lines_before` requested, or the match is at the start of the file).

    • columninteger· uint32requiredmin 0
    • lineinteger· uint32requiredmin 0
    • pathstringrequired

      Absolute path under the canonical parent; symlinks at the entry itself are not resolved. Operations on it re-validate through the jail.

    • textstringrequired

      Matched line; truncated to `max_line_bytes` and never spans newlines.

  • path_matchesobject[]required
    • pathstringrequired

      Absolute path under the canonical parent; symlinks at the entry itself are not resolved. Operations on it re-validate through the jail.

  • truncatedbooleanrequired

    True if results were cut off — either match list hit the `max_matches` cap, or the response hit the `search_response_budget_bytes` byte budget. When true, refine the query or add include_globs rather than paginate.

coder::tree

function

Recursive directory snapshot bounded by `max_depth` and a `per_folder_limit`. Slim wire shape: nodes carry only `name` — the root node's path IS the response's top-level `path`; derive any child's path as parent path + '/' + name. Folders that hit the limit are flagged `truncated` and the caller is pointed at coder::list-folder for pagination. Noise directories matching default_exclude_globs (.git, node_modules, target, … — coder::info lists them) appear as childless `truncated` stubs; pass use_default_excludes: false to descend into them. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*.

request
  • max_depthinteger· uint32min 0

    Maximum depth to descend; the root node is depth 0.

  • pathstring

    Base folder for the snapshot. Relative to the primary allowed root, or an absolute path inside any allowed root. Defaults to `.` (the primary root itself). Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

  • per_folder_limitinteger· uint32min 0

    Maximum children listed per folder. When more exist, the folder is flagged `truncated` and callers should switch to `coder::list-folder`.

  • use_default_excludesboolean

    Apply the worker's `default_exclude_globs` config (noise folders like .git/node_modules/target — call `coder::info` for the active list). Excluded directories still appear as childless nodes flagged `truncated` with reason "default_exclude"; excluded files are omitted. Pass `false` to list everything.

response
  • pathstringrequired

    Canonical absolute path of the requested folder (resolved through the jail). Nodes carry only `name`, and the root node's path IS this `path` — do not join the root's `name` onto it; derive children by joining from here: child path = parent path + "/" + name. Operations on derived paths re-validate through the jail.

  • rootall ofrequired

    Root node of the snapshot; its `name` is the folder's basename.

    all of (1)
    variant 1
    • childrenunknown[]
    • kindstringrequiredenum: file, dir, symlink, other
    • mtimeinteger· int64required
    • namestringrequired

      Entry basename. The ROOT node's path is the response's top-level `path` itself; every other node's path derives by joining from there: child path = parent path + "/" + name.

    • non_accessiblebooleanrequired
    • sizeinteger· uint64requiredmin 0
    • truncatedany of

      Set on directories whose `children` was capped at `per_folder_limit`, whose subtree was cut off by `max_depth`, or which matched `default_exclude_globs` (reason "default_exclude").

      … expand 2 nested
      any of (2)
      variant 1
      • hintstringrequired
      • reasonstringrequired

        Reason this folder was truncated: hit `per_folder_limit`, cut off by `max_depth`, or matched `default_exclude_globs` (`default_exclude`).

      • showninteger· uint32requiredmin 0

        Number of children actually returned.

      • totalinteger· uint32min 0

        Total number of children eligible for listing in the folder, counted after default-exclude filtering (only populated when `reason == "per_folder_limit"`; for depth truncation we don't peek into the folder).

      variant 2
      valuenull

coder::update-file

function

Apply batched line-oriented and regex edits across one or more files. Request shape: {"files": [{"path": "...", "ops": [...]}]}. Line ops: { op: 'insert', at_line, content } | { op: 'remove', from_line, to_line } | { op: 'update_lines', from_line, to_line, content } — 1-based, inclusive, applied bottom-up. Regex op: { op: 'replace', pattern, replacement, ignore_case?, dot_matches_newline?, expect_matches? } runs on the file body after line ops. Replace large regions WITHOUT quoting them: two short anchors joined by .*? with dot_matches_newline: true — always prefer wildcards over pasting the block into the pattern. expect_matches: 1 turns a silent multi-site clobber into a safe pre-write C210; expect_matches: 0 asserts absence. In `replacement`, $1/${name} are capture references and a literal $ must be written $$ (JS/TS template literals: `Hello, $${name}!`); undefined references fail pre-write with C210. Each file commits atomically via temp + rename. On success each applied line op returns a bounded post-apply echo (±2 context lines); regex replace ops return up to 5 per-match-site echoes (first + last line of each replaced region, inner lines elided) — verify from the echoes instead of re-reading the file. Paths are relative to the primary allowed root or absolute inside any allowed root (coder::info lists them); for host paths outside the jail use shell::fs::*.

request
  • filesobject[]required
    • opsone of[]required
      one of (4)
      variant 1
      • at_lineinteger· uint32requiredmin 0
      • contentstringrequired
      • opstringrequiredenum: insert
      variant 2
      • from_lineinteger· uint32requiredmin 0
      • opstringrequiredenum: remove
      • to_lineinteger· uint32requiredmin 0
      variant 3
      • contentstringrequired
      • from_lineinteger· uint32requiredmin 0
      • opstringrequiredenum: update_lines
      • to_lineinteger· uint32requiredmin 0
      variant 4
      • dot_matches_newlineboolean

        When true, `.` in `pattern` also matches `\n`, so a short anchored pattern like `"fn parse_config\\(.*?\\n\\}"` replaces a whole multi-line region without quoting it — prefer two short anchors joined by `.*?` over pasting the block into the pattern. Without this flag (the default), `.` does not cross newlines and a multi-line pattern silently matches nothing.

      • expect_matchesinteger· uint64min 0

        Expected number of matches for this op. When set and the actual count differs, this FILE fails with C210 and nothing is written to it (other files in the batch still apply). Set `expect_matches: 1` to make a targeted read-free edit safe — a mismatch means the pattern is anchored too loosely or matches nothing. Set `expect_matches: 0` to assert ABSENCE: the op succeeds only when nothing matches (the replacement is unused). Omit to replace all matches unconditionally.

      • ignore_caseboolean
      • opstringrequiredenum: replace
      • patternstringrequired
      • replacementstringrequired

        Substitution text for each match. Capture references expand: `$1`/`${1}` by index (`$0` is the whole match) and `$name`/`${name}` by name. A literal `$` MUST be written `$$` — JS/TS template literals in a replacement are the classic collision: write `Hello, $${name}!` to output `Hello, ${name}!`. Unbraced references consume the longest `[0-9A-Za-z_]` run, so `$1a` means a group named "1a", NOT group 1 then "a" (use `${1}a`). A reference to a group the pattern does not define fails pre-write with C210 — nothing is written. References are validated even when the replacement goes unused (e.g. `expect_matches: 0`): the replacement must be well-formed even when unused.

    • pathstringrequired

      Path relative to the primary allowed root, or an absolute path inside any allowed root. Call `coder::info` to see the allowed roots. Paths outside every allowed root are rejected — use the shell worker's `shell::fs::*` for host paths outside the jail.

response
  • resultsobject[]required
    • appliedinteger· uint32requiredmin 0

      Number of operations applied (only meaningful when `success`).

    • echoesobject[]required

      Per-op bounded post-apply echoes for edit verification; each applied op returns a snapshot of the affected region (±2 context lines) so the caller can confirm the edit landed at the right position without receiving the full file body. See `OpEcho` for field semantics. Empty on failure. Always present on the wire.

      • elidedinteger· uint64min 0

        Number of middle lines elided from a large region: for line ops, set when the affected region exceeded the per-echo cap; for replace sites, the count of inner lines between the region's echoed first and last line (set when the region spans >2 lines).

      • from_lineinteger· uint64requiredmin 0

        1-based line number of the first echoed line (after all ops applied).

      • linesstring[]required

        The echoed lines, post-apply. When the region is large, middle lines are elided and `elided` is set to indicate how many were skipped.

      • op_indexinteger· uint32requiredmin 0

        Index of the op in the request's ops array (0-based).

      • total_replacementsinteger· uint64min 0

        Total number of replacements the regex op made across the whole file (set only on replace-op site echoes, duplicated on each site). Sites are capped at 5 — when more matched, this count is the only record of the extras.

    • echoes_truncatedbooleanrequired

      True when the total echo budget (~4 KiB) was exhausted before all op echoes could be emitted. Use `coder::read-file` to inspect the full result if needed. Always present on the wire.

    • errorany of

      Structured error for this entry. `code` is stable for programmatic branching (e.g. `"C211"` for not-found-or-denied; `"C210"` for bad input such as overlapping ops). `message` carries the corrective action an LLM agent needs to make a successful second call.

      any of (2)
      variant 1
      • codestringrequired

        Stable error code, e.g. "C211". See the README error table.

      • messagestringrequired

        Human/LLM-readable message: problem + actual values + corrective next call.

      variant 2
      valuenull
    • new_line_countinteger· uint64requiredmin 0

      Final line count after applying (only meaningful when `success`).

    • pathstringrequired

      Canonical absolute path (resolved through the jail); the caller's input verbatim when resolution failed.

    • successbooleanrequired

shell::config-status

function

Report the last configuration hot-reload outcome: last_outcome (applied|rejected), last_error, and rejected_reloads (count since boot). A rejected outcome or non-zero count means a stored config was refused and shell is enforcing an older policy than the central store. Takes no arguments.

request
empty object
response
  • last_errorstring

    Build error from the most recent rejected reload (why it was refused).

  • last_outcomeone ofrequired

    Outcome of the most recent hot-reload attempt, exposed via `shell::config-status`.

    one of (2)
    variant 1
    valuestringenum: applied
    variant 2
    valuestringenum: rejected
  • rejected_reloadsinteger· uint64requiredmin 0

    Cumulative count of rejected reloads since boot (never reset).

shell::exec

function

Run a command in the foreground and return its full output. Put the program name in `command` (string) and arguments in `args` (string[]) — do NOT pass argv as an array in `command`. `timeout_ms` is capped at the configured max; negative/fractional values fall back to the default. `target` defaults to the host; pass { kind: "sandbox", sandbox_id } to run in a microVM. Optional host-only `cwd` scopes this call to a directory (jail-confined exactly like shell::fs::* paths; escaping it is S215), optional `env` (object) sets per-call values for ANY key except PATH/IFS/HOME/LD_*/DYLD_* or other loader/lookup and interpreter-startup keys (those reject S210 unconditionally) — and optional host-only `stdin` (string) is written to the program's standard input (use it for `tee`, `patch`, or any stdin filter instead of a shell heredoc). cwd/env/stdin on a sandbox target reject S210. Backend errors return { code, message }; common: S216 host exec error, S300 VM boot failed, S200 in-VM failure. argv-parse and denylist rejections are plain-string messages naming the violation.

request
  • argsstring[]

    Arguments passed to the program, in order. Every element must be a string; non-string elements are rejected by index. `None` (or `args: null` / absent) means "tokenize `command` via shell-words"; `Some(_)` (including the empty vec) means "use args verbatim, no shell-words." See `parse_argv` in `crate::exec::host`.

  • commandstringrequired

    Program name (bare, PATH-resolved) or a path to an executable. Must be a string — split arguments into `args`, do not pass argv as an array here.

  • cwdstring

    Optional working directory for this call (host target only). Confined to the fs jail exactly like `shell::fs::*` paths: jail-relative when `fs.host_roots` are set (else absolute), canonicalized, and must resolve inside a jail root and miss the denylist — a path that escapes returns S215. Must already exist and be a directory. Omit to use the configured `working_dir` (unchanged default). Rejected (S210) on a sandbox target.

  • envobject

    Optional per-call environment values (host target only). Deny-only: a key may be set to ANY value except an exec-hijacking key (PATH, IFS, HOME, LD_*/DYLD_*, and other loader/lookup and interpreter-startup keys — see DANGEROUS_ENV_KEYS), which is rejected unconditionally (`env.allow` plays no role here — that list only gates which vars get forwarded from the worker's own environment). Supplying a dangerous key rejects the WHOLE call (S210) naming the offending key; the env is never silently dropped. Values override what would otherwise be forwarded for that key. Rejected (S210) on a sandbox target.

  • stdinstring

    Optional bytes written to the program's standard input, followed by EOF. Use this to pipe content to a command that reads stdin (`tee`, `patch`, `cat`, a filter) instead of wrapping it in a shell heredoc. Omit to leave stdin closed (`/dev/null`, the default). HOST target only — rejected (S210) on a sandbox target, like cwd/env.

  • targetall of

    Where to run the command. Defaults to the host worker; pass `{ kind: "sandbox", sandbox_id }` to forward the call to a microVM.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
  • timeout_msinteger· uint64min 0

    Per-call timeout override, milliseconds. Capped at `cfg.max_timeout_ms`. Negative or fractional values silently fall back to `cfg.default_timeout_ms` (loose wire semantic, preserved on purpose).

response
  • duration_msinteger· uint64requiredmin 0
  • exit_codeinteger· int32
  • stderrstringrequired
  • stderr_truncatedbooleanrequired
  • stdoutstringrequired
  • stdout_truncatedbooleanrequired
  • timed_outbooleanrequired

shell::exec_bg

function

Spawn a command as a background job; returns { job_id, argv } immediately. Same payload as shell::exec (command + args, do NOT pass argv as an array), including the optional host-only `cwd` (jail-confined; escape is S215), `env` (any key except PATH/IFS/HOME/LD_*/DYLD_* or other loader/lookup and interpreter-startup keys, rejected unconditionally), and `stdin` (string written to the job's stdin); violations and cwd/env/stdin on a sandbox target reject with an S210 message. Poll with shell::status, terminate with shell::kill, list with shell::list. Host background jobs ignore the per-call timeout_ms and run until they exit or shell::kill terminates them; set the operator config `max_bg_timeout_ms` (0 = unbounded, the default) to force-kill a runaway job after that long. Spawn-time failures (argv-parse, denylist, cwd/env gating, spawn, concurrency cap) are plain-string messages naming the violation; once spawned, per-job failures surface through shell::status (the job record's status/stderr), not this call's return.

request
  • argsstring[]

    Arguments passed to the program. See [`ExecRequest::args`]. `None` (or `args: null` / absent) means "tokenize `command` via shell-words"; `Some(_)` (including the empty vec) means "use args verbatim, no shell-words." See `parse_argv` in `crate::exec::host`.

  • commandstringrequired

    Program name. See [`ExecRequest::command`].

  • cwdstring

    Optional working directory for this job (host target only). Same jail confinement and rules as [`ExecRequest::cwd`]: canonicalized, must resolve inside a jail root (S215 on escape) and be an existing directory. Rejected (S210) on a sandbox target.

  • envobject

    Optional per-call environment values (host target only). Same gating as [`ExecRequest::env`]: deny-only, rejecting only an exec-hijacking key (PATH, IFS, HOME, LD_*/DYLD_*, and other loader/lookup and interpreter-startup keys — see DANGEROUS_ENV_KEYS); any violation rejects the whole call (S210). Rejected (S210) on a sandbox target.

  • stdinstring

    Optional bytes written to the job's standard input, then EOF. See [`ExecRequest::stdin`]. HOST target only — rejected (S210) on a sandbox target.

  • targetall of

    Where to run. See [`ExecRequest::target`].

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
  • timeout_msinteger· uint64min 0

    Per-call timeout. Host-targeted background jobs IGNORE `timeout_ms`; sandbox-targeted ones forward it through `cfg.resolve_timeout`.

response
  • argvstring[]required
  • job_idstringrequired

shell::fs::chmod

function

Change permissions. `mode` is an octal string like "0644". `uid`/`gid` optionally chown. `recursive: true` walks the tree (symlinks skipped). Returns { entries_changed, path, recursive }. Errors return { code, message }; common: S210 bad mode, S211 not found, S215 jail/denylist.

request
  • gidinteger· uint32min 0

    Optional chown to this numeric gid.

  • modestringrequired

    Octal permission string, e.g. "0755".

  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • recursiveboolean

    Apply mode/owner change to all files under the path recursively.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
  • uidinteger· uint32min 0

    Optional chown to this numeric uid.

response
  • entries_changedinteger· uint64requiredmin 0

    Number of filesystem entries whose mode/owner changed.

  • pathstring

    The path that was targeted. Empty for sandbox targets.

  • recursiveboolean

    Whether the change was applied recursively. Host only.

shell::fs::grep

function

Search file contents. `pattern` is a Rust regex (RE2-like). `recursive` defaults true. `include_glob`/`exclude_glob` filter paths. Returns { matches, truncated }. Errors return { code, message }; common: S217 bad regex, S215 jail/denylist.

request
  • exclude_globstring[]

    Glob filters excluding file paths from the search.

  • ignore_caseboolean

    Match pattern case-insensitively.

  • include_globstring[]

    Glob filters restricting which file paths are searched.

  • max_line_bytesinteger· uint64min 0

    Skip lines longer than this many bytes (default 4 096).

  • max_matchesinteger· uint64min 0

    Stop collecting matches after this many results (default 10 000).

  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • patternstringrequired

    Rust regex (RE2-like) matched against each line.

  • recursiveboolean

    Descend into subdirectories (default true).

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • matchesobject[]required

    All collected match locations up to `max_matches`.

    • contentstringrequired
    • lineinteger· uint64requiredmin 0
    • pathstringrequired
  • truncatedbooleanrequired

    True when the result was capped by `max_matches` or `max_line_bytes`.

shell::fs::ls

function

List directory contents. `path` is relative to the primary fs jail root (the first fs.host_roots entry) when set, otherwise absolute. `target` defaults to host; pass { kind: "sandbox", sandbox_id } to run in a microVM. Errors return { code, message }; common: S210 bad path, S211 not found, S212 not a directory, S215 jail/denylist.

request
  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • entriesobject[]required

    Metadata for each entry in the directory.

    • is_dirbooleanrequired
    • is_symlinkbooleanrequired
    • modestringrequired
    • mtimeinteger· int64required
    • namestringrequired
    • sizeinteger· uint64requiredmin 0

shell::fs::mkdir

function

Create a directory. `mode` is an octal string like "0755". `parents: true` creates missing parents and is idempotent. Returns { created, path, already_existed }. Errors return { code, message }; common: S210 bad mode, S213 exists, S215 jail/denylist.

request
  • modestring

    Octal permission string, e.g. "0755".

  • parentsboolean

    Create missing parent directories.

  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • already_existedboolean

    True when the path already existed and `parents` was set. Host only; sandbox targets default this to false (not a signal there).

  • createdbooleanrequired

    True when a new directory was created; false when it already existed (only possible with `parents: true`, which is idempotent).

  • pathstring

    The directory path that was targeted. Empty for sandbox targets.

shell::fs::mv

function

Move/rename a path. `overwrite: true` allows replacing an existing dst. Returns { moved, src, dst, overwrote }. Errors return { code, message }; common: S211 src not found, S213 dst exists, S215 jail/denylist.

request
  • dststringrequired

    Destination path; jail-relative when fs.host_roots are set, else absolute.

  • overwriteboolean

    Replace an existing destination instead of returning an error.

  • srcstringrequired

    Source path; jail-relative when fs.host_roots are set, else absolute.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • dststring

    Destination path. Empty for sandbox targets.

  • movedbooleanrequired

    True when the move/rename succeeded.

  • overwroteboolean

    True when an existing destination was overwritten. Host only (sandbox targets default this to false, not a signal there). Best-effort: derived from a pre-rename existence check, so under a concurrent writer racing the destination it may under-report (and an `overwrite:false` move can still replace a file created in that window).

  • srcstring

    Source path. Empty for sandbox targets.

shell::fs::read

function

Stream a file from a path. Returns a ContentRef the caller reads from, plus size/mode/mtime. Errors return { code, message }; common: S211 not found, S212 path is a directory, S215 jail/denylist, S218 file exceeds max_read_bytes, S216 channel/IO error.

request
  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • contentall ofrequired

    Channel reference for streaming the file content back to the caller.

    all of (1)
    variant 1
    • access_keystringrequired

      Secret key that authorises access to this channel.

    • channel_idstringrequired

      Opaque identifier for the open stream channel.

    • directionall of

      Direction of data flow: "read" (consume) or "write" (produce).

      … expand 1 nested
      all of (1)
      variant 1
      valuestringenum: read, write
  • modestringrequired

    Octal permission string of the file, e.g. "0644".

  • mtimeinteger· int64required

    Last-modified time as a Unix timestamp (seconds).

  • sizeinteger· uint64requiredmin 0

    File size in bytes at the time of the read.

shell::fs::rm

function

Remove a path. `recursive: true` is required to delete a non-empty directory. Returns { removed, path, was_present }. Errors return { code, message }; common: S211 not found, S214 dir not empty (pass recursive), S215 jail/denylist.

request
  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • recursiveboolean

    Required to delete a non-empty directory.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • pathstring

    The path that was targeted. Empty for sandbox targets.

  • removedbooleanrequired

    True when the path was removed.

  • was_presentboolean

    True when the path existed before removal. Host only; sandbox targets default this to false, which does NOT mean the path was absent.

shell::fs::sed

function

Find-and-replace across files. `pattern` is a Rust regex by default (set regex:false for a literal). Provide either `files` (explicit list) or `path` (+ recursive). Returns { results, total_replacements }. Errors return { code, message }; common: S217 bad regex, S211 not found, S215 jail/denylist.

request
  • exclude_globstring[]

    Glob filters excluding file paths from editing.

  • filesstring[]

    Explicit list of file paths to edit; provide either this or `path`, not both.

  • first_onlyboolean

    Replace only the first match per file instead of all matches.

  • ignore_caseboolean

    Match pattern case-insensitively.

  • include_globstring[]

    Glob filters restricting which file paths are edited.

  • pathstring

    Root path to walk for files; used with `recursive`, `include_glob`, `exclude_glob`.

  • patternstringrequired

    Rust regex by default; set regex:false for a literal string.

  • recursiveboolean

    Descend into subdirectories when `path` is set (default true).

  • regexboolean

    Treat pattern as a regex (default true) or a literal string (false).

  • replacementstringrequired

    String to substitute for each match.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • resultsobject[]required

    Per-file replacement details.

    • errorstring
    • pathstringrequired
    • replacementsinteger· uint64requiredmin 0
    • successbooleanrequired
  • total_replacementsinteger· uint64requiredmin 0

    Sum of replacements made across all files.

shell::fs::stat

function

Stat a single path (jail-relative when fs.host_roots are set). Returns the entry's type, size, mode, and mtime. Errors return { code, message }; common: S211 not found, S215 jail/denylist.

request
  • pathstringrequired

    Jail-relative when fs.host_roots are set, else absolute.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • is_dirbooleanrequired
  • is_symlinkbooleanrequired
  • modestringrequired
  • mtimeinteger· int64required
  • namestringrequired
  • sizeinteger· uint64requiredmin 0

shell::fs::write

function

Write a file. Simplest form: { path, content: "text" } — `content` as a plain STRING is written inline (host target only), no streaming channel needed. For large/streamed payloads or a sandbox target, pass `content` as a ContentRef { channel_id, access_key, direction } from a write stream channel you opened through the engine's streaming layer (inline strings reject S210 on a sandbox target). To write several files at once, pass `files: [{ path, content, mode?, parents? }, ...]` instead of the single-file fields (host target, inline content) — the response then carries per-file results in `files`. `mode` is octal (default "0644"); `parents: true` creates missing parents. Errors return { code, message }; common: S210 bad mode/payload or inline-on-sandbox, S215 jail/denylist, S218 payload exceeds max_write_bytes, S216 channel/IO error.

request
  • contentany of

    Single-file content: a plain string written inline (host target only), OR a ContentRef { channel_id, access_key, direction } for an open write stream channel. Omit when using `files`.

    any of (2)
    variant 1
    any of (2)
    variant 1
    valuestring
    variant 2
    all of (1)
    variant 1
    • access_keystringrequired

      Secret key that authorises access to this channel.

    • channel_idstringrequired

      Opaque identifier for the open stream channel.

    • directionall of

      Direction of data flow: "read" (consume) or "write" (produce).

      … expand 1 nested
      all of (1)
      variant 1
      valuestringenum: read, write
    variant 2
    valuenull
  • filesobject[]

    Batch form: write several files in one call. When present, the single-file fields (`path`/`content`/`mode`/`parents`) must be omitted.

    • contentall ofrequired

      Inline string (recommended) or a streaming ContentRef.

      all of (1)
      variant 1
      any of (2)
      variant 1
      valuestring
      variant 2
      all of (1)
      variant 1
      • access_keystringrequired

        Secret key that authorises access to this channel.

      • channel_idstringrequired

        Opaque identifier for the open stream channel.

      • directionall of

        Direction of data flow: "read" (consume) or "write" (produce).

        … expand 1 nested
        all of (1)
        variant 1
        valuestringenum: read, write
    • modestring

      Octal permission string, e.g. "0644".

    • parentsboolean

      Create missing parent directories.

    • pathstringrequired

      Jail-relative when fs.host_roots are set, else absolute.

  • modestring

    Octal permission string for the single-file form, e.g. "0644". `Option` (not a defaulted `String`) so the batch-form check can tell "caller omitted mode" from "caller sent a mode" and reject the latter instead of silently dropping it. Defaults to "0644" in the single-file path. Omit when using `files` (each entry carries its own `mode`).

  • parentsboolean

    Create missing parent directories (single-file form). `Option` for the same reason as `mode` — so a top-level `parents` sent alongside `files` is rejected, not ignored. Defaults to `false`. Omit when using `files`.

  • pathstring

    Single-file form: the path to write. Jail-relative when fs.host_roots are set, else absolute. Omit when using `files`.

  • targetall of

    host (default) or { kind: "sandbox", sandbox_id }.

    all of (1)
    variant 1
    one of (2)
    variant 1
    • kindstringrequiredenum: host
    variant 2
    • kindstringrequiredenum: sandbox
    • sandbox_idstring· uuidrequired
response
  • bytes_writteninteger· uint64requiredmin 0

    Bytes written: this file for a single write; the sum across `files` for a batch write.

  • filesobject[]

    Per-file results for a batch (`files: [...]`) write; empty for a single-file write.

    • bytes_writteninteger· uint64requiredmin 0

      Bytes written to this file.

    • pathstringrequired

      Path of the written file.

  • pathstringrequired

    Path written for a single write; empty for a batch (see `files`).

shell::kill

function

Terminate a running background job by job_id (the UUID from shell::exec_bg). Errors return { code, message }; common: S211 no such job, S216 kill/signal delivery failure.

request
  • job_idstringrequired
response
  • job_idstringrequired
  • killedbooleanrequired
  • reasonstring
  • statusstringrequiredenum: running, finished, killed, failed

shell::list

function

List background jobs (running + recently completed). Takes no arguments.

request
empty object
response
  • countinteger· uintrequiredmin 0
  • jobsobject[]required
    • exit_codeinteger· int32
    • finished_at_msinteger· uint64min 0
    • idstringrequired
    • started_at_msinteger· uint64requiredmin 0
    • statusstringrequiredenum: running, finished, killed, failed
    • stderr_truncatedbooleanrequired
    • stdout_truncatedbooleanrequired

shell::on-config-change

function

Internal: reload the security policy + fs backend on configuration change.

request
  • idstring

    Configuration id that changed (advisory; the handler re-fetches the value). Schema-only: kept to publish a typed request schema; the handler ignores it.

response
  • okbooleanrequired

shell::status

function

Fetch the full record (status, exit_code, timing) of a background job by job_id. Errors return { code, message }; common: S211 no such job.

request
  • job_idstringrequired
response
  • jobobjectrequired
    • argvstring[]required
    • exit_codeinteger· int32
    • finished_at_msinteger· uint64min 0
    • idstringrequired
    • started_at_msinteger· uint64requiredmin 0
    • statusstringrequiredenum: running, finished, killed, failed
    • stderrstringrequired
    • stderr_truncatedbooleanrequired
    • stdoutstringrequired
    • stdout_truncatedbooleanrequired

shell::workspace::list

function

Console-only workspace picker control plane: list child directories under an existing host directory. Returns canonical paths and never returns files.

request
  • page_sizeinteger· uintmin 0
  • pathstringrequired
response
  • entriesobject[]required
    • kindstringrequiredenum: dir
    • namestringrequired
    • pathstringrequired
  • pathstringrequired

shell::workspace::roots

function

Console-only workspace picker control plane: return canonical host directory anchors that an operator can browse before choosing a per-session working directory.

request
empty object
response
  • rootsstring[]required

shell::workspace::validate

function

Console-only workspace picker control plane: validate that `path` is an existing host directory and return its canonical path.

request
  • pathstringrequired
response
  • pathstringrequired

triggers

0
no triggers registered