shell
v0.3.6Unix 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
- macOS: arm64 · x64
- Linux: arm64 · armv7 · x64
exact versions are immutable; binary and bundle artifacts are digest-pinned.
full markdown
/workers/shell.md?version=0.3.6. paste it into an llm prompt or pipe it through curl from a worker.install
configuration
- allowed_env:
- PATH
- HOME
- LANG
- LC_ALL
- TERM
allowlist:
- ls
- cat
- pwd
- echo
- grep
- wc
- head
- tail
- sort
- uniq
- cut
- date
- whoami
- hostname
- which
- jq
- uname
- df
- du
- ps
- printenv
- basename
- dirname
default_timeout_ms: 10000
denylist_patterns:
- rm\s+-rf\s+/
- :\(\)\s*\{\s*:\|
- mkfs
- dd\s+if=
- shutdown
- reboot
- /etc/passwd
- /etc/shadow
- \bfind\b[^|;&]*-exec(dir)?\b
- \bawk\b[^|;&]*system\s*\(
- \bsed\b[^|;&]*(-i\b|\be\b)
- \bcurl\b[^|;&]*(file://|-o\s|--output-dir\b|-F\s+@)
- \bgit\b[^|;&]*(--upload-pack|--receive-pack|core\.pager|core\.hooksPath|GIT_SSH_COMMAND)
- \b(node|python3?)\b[^|;&]*\s-(e|c)\b
- \bnpm\b[^|;&]*\brun\b
fs:
allow_unjailed: false
denylist_paths:
- /etc/passwd
- /etc/shadow
host_root: /tmp
max_read_bytes: 16777216
max_write_bytes: 16777216
inherit_env: false
job_retention_secs: 3600
max_concurrent_jobs: 16
max_output_bytes: 1048576
max_timeout_ms: 30000
sandbox:
enabled: true
working_dir: nulldependencies
readme
shell
Run allowlisted Unix commands, background jobs, and structured filesystem operations from the iii engine, on the host or forwarded into a sandbox microVM.
Install
iii worker add shellSandbox-targeted execution and shell::fs::* forwarding need the iii-sandbox worker; iii worker add shell does not pull it in. To surface shell::* to LLM agents, pair with iii-directory:
iii worker add iii-sandbox
iii worker add iii-directoryConfigure
Settings load from a YAML file passed with --config (default ./config.yaml). The worker refuses to start unless fs.host_root is set, or fs.allow_unjailed: true is explicitly opted in, because an unset root exposes the whole host filesystem behind only the advisory denylist.
max_timeout_ms: 30000 # hard cap; per-call timeout_ms is clamped to this
default_timeout_ms: 10000 # applied when the caller omits timeout_ms
max_output_bytes: 1048576 # 1 MiB; stdout/stderr past this set *_truncated
inherit_env: false # when false, only allowed_env keys are forwarded
allowed_env: [PATH, HOME, LANG, LC_ALL, TERM]
# exec gate. argv[0] is matched by basename or exact path; an empty
# allowlist means open. denylist_patterns are advisory regex over
# argv.join(" "), a tripwire for honest mistakes only.
allowlist: [ls, cat, pwd, echo, grep, wc, head, tail, sort, uniq, cut, date]
denylist_patterns:
- "rm\\s+-rf\\s+/"
- "mkfs"
max_concurrent_jobs: 16 # exec_bg past this is rejected
job_retention_secs: 3600 # finished jobs pruned after this
fs:
host_root: /tmp # jail root for shell::fs::*; required (see above)
allow_unjailed: false # opt-in to running with host_root unset
max_read_bytes: 16777216 # 0 = unlimited
max_write_bytes: 16777216 # 0 = unlimited
denylist_paths: [/etc/passwd, /etc/shadow]
sandbox:
enabled: true # false -> every target: sandbox call returns S210Host shell::exec is not a security boundary: any allowlisted interpreter (sh, node, python3) can construct a denylisted token at runtime and bypass the regex. Run untrusted input with target: { kind: "sandbox", sandbox_id }, which forwards through the iii-sandbox microVM. The allowlist and denylist still apply on top of either backend.
Quick start
import { registerWorker } from 'iii-sdk'
const iii = registerWorker(process.env.III_URL ?? 'ws://127.0.0.1:49134')
const result = await iii.trigger({
function_id: 'shell::exec',
payload: { command: 'echo', args: ['hello'] },
})
console.log(result)The example runs on the host. The same payload retargets at a microVM with target: { kind: 'sandbox', sandbox_id: '. The other entry points are shell::exec_bg, shell::status, shell::kill, shell::list, plus the shell::fs::* family (ls, stat, read, write, grep, sed, mkdir, rm, chmod, mv).
Functions
| Function | Purpose |
|---|---|
shell::exec |
Run an allowlisted command in the foreground; returns stdout, stderr, exit code, and timing. Blocks until exit or timeout. |
shell::exec_bg |
Spawn an allowlisted command as a background job; returns { job_id, argv } immediately. Host-targeted jobs ignore timeout_ms (end via shell::kill or natural exit); sandbox jobs honor it. |
shell::status |
Fetch one job's full record: state, exit code, and captured stdout/stderr. not_found means the id never existed or aged out past job_retention_secs. |
shell::list |
Enumerate current jobs as lightweight summaries; argv, stdout, and stderr are redacted. |
shell::kill |
Terminate a running background job by job_id. Sandbox jobs cannot be hard-killed: the record flips to killed but the in-VM process runs until its timeout_ms (or sandbox::stop). |
shell::fs::ls |
List a directory's entries with structured metadata. |
shell::fs::stat |
Read one path's metadata (size, mode, symlink flag). |
shell::fs::mkdir |
Create a directory, optionally with missing parents. |
shell::fs::rm |
Remove a file or directory, optionally recursive. |
shell::fs::chmod |
Change a path's mode, and optionally its uid/gid. |
shell::fs::mv |
Rename or move one path within the jail. |
shell::fs::grep |
Recursive regex search across a tree; returns structured matches. Keys are singular include_glob/exclude_glob; the case flag is ignore_case. |
shell::fs::sed |
Regex find-and-replace across one file or many. |
shell::fs::write |
Stream bytes into a file through an SDK channel; writes via a temp file and renames atomically. No inline content field. |
shell::fs::read |
Stream a file's bytes out through an SDK channel. For an inline read on the web surface, use the harness::fs::read_inline wrapper instead. |
Every shell::fs::* call accepts the same optional target as exec, so host and sandbox share one wire shape.
Errors
Returned error bodies carry a stable code field. Allowlist and denylist rejections come back as a plain message (command ', command matches denylist: ) rather than an S-code.
| Code | Meaning |
|---|---|
S200 |
In-VM execution failure on a sandbox target. |
S210 |
Invalid request: non-absolute path, empty command or pattern, bad octal mode, malformed payload, or sandbox.enabled: false on a sandbox-targeted call. |
S211 |
Path not found. |
S212 |
Wrong file type for the operation (for example, a file where a directory was expected). |
S213 |
Path already exists. |
S214 |
Directory not empty (non-recursive rm). |
S215 |
Path escapes host_root, hits fs.denylist_paths, or permission denied. |
S216 |
Generic shell-internal failure: host spawn error, channel error, or a bad engine response. |
S217 |
Invalid regex passed to grep/sed. |
S218 |
fs.max_read_bytes / fs.max_write_bytes cap exceeded. |
S300 |
Sandbox VM boot failed (needs a virtualization host: Apple Silicon or /dev/kvm). |
Troubleshooting
fs.host_root is unset ... refusing to start unjailed: setfs.host_rootto a directory, or setfs.allow_unjailed: true.command ': the basename of' not in allowlist argv[0]is not in a non-emptyallowlist. Add it, or empty the list to allow anything.S215 path escapes host_rooton a path inside the jail: a symlink in the path resolves outside the jail. Resolve it yourself, or move the target insidehost_root.S300on a sandbox target: the host cannot boot microVMs. Sandbox execution requires Apple Silicon or/dev/kvm.- Worker never connects: the engine is not running or not bound on the configured
--url. Start the engine first; the default WebSocket port is 49134.
For the threat model, streaming wire shapes, and contributor build steps, see ARCHITECTURE.md.
License
Apache 2.0 — see LICENSE.
api reference (json)
{
"functions": [
{
"description": "Stat a path on host or sandbox",
"metadata": {},
"name": "shell::fs::stat",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"is_dir": {
"type": "boolean"
},
"is_symlink": {
"type": "boolean"
},
"mode": {
"type": "string"
},
"mtime": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"size": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"is_dir",
"is_symlink",
"mode",
"mtime",
"name",
"size"
],
"title": "FsEntry",
"type": "object"
}
},
{
"description": "Find-and-replace on host or sandbox",
"metadata": {},
"name": "shell::fs::sed",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FsSedFileResult": {
"properties": {
"error": {
"type": [
"string",
"null"
]
},
"path": {
"type": "string"
},
"replacements": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"success": {
"type": "boolean"
}
},
"required": [
"path",
"replacements",
"success"
],
"type": "object"
}
},
"properties": {
"results": {
"items": {
"$ref": "#/definitions/FsSedFileResult"
},
"type": "array"
},
"total_replacements": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"results",
"total_replacements"
],
"title": "SedResponse",
"type": "object"
}
},
{
"description": "Kill a running background job",
"metadata": {},
"name": "shell::kill",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"job_id": {
"type": "string"
}
},
"required": [
"job_id"
],
"title": "KillRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"JobStatus": {
"enum": [
"running",
"finished",
"killed",
"failed"
],
"type": "string"
}
},
"properties": {
"job_id": {
"type": "string"
},
"killed": {
"type": "boolean"
},
"reason": {
"type": [
"string",
"null"
]
},
"status": {
"$ref": "#/definitions/JobStatus"
}
},
"required": [
"job_id",
"killed",
"status"
],
"title": "KillResponse",
"type": "object"
}
},
{
"description": "Stream a file to a host path or sandbox via StreamChannelRef",
"metadata": {},
"name": "shell::fs::write",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"bytes_written": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"path": {
"type": "string"
}
},
"required": [
"bytes_written",
"path"
],
"title": "WriteResponse",
"type": "object"
}
},
{
"description": "Spawn an allowlisted command as a background job. Same payload shape as shell::exec; returns { job_id, argv } immediately. Poll with shell::status, terminate with shell::kill, list with shell::list. Do NOT pass argv as an array in 'command' — use 'command' (string) + 'args' (string[]).",
"metadata": {},
"name": "shell::exec_bg",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Target": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"host"
],
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"sandbox"
],
"type": "string"
},
"sandbox_id": {
"format": "uuid",
"type": "string"
}
},
"required": [
"kind",
"sandbox_id"
],
"type": "object"
}
]
}
},
"description": "Wire request for `shell::exec_bg`. Same shape as [`ExecRequest`]; documented separately so the engine publishes a distinct schema per function.",
"properties": {
"args": {
"default": null,
"description": "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`.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"command": {
"description": "Program name. See [`ExecRequest::command`].",
"type": "string"
},
"target": {
"allOf": [
{
"$ref": "#/definitions/Target"
}
],
"default": {
"kind": "host"
},
"description": "Where to run. See [`ExecRequest::target`]."
},
"timeout_ms": {
"default": null,
"description": "Per-call timeout. Host-targeted background jobs IGNORE `timeout_ms`; sandbox-targeted ones forward it through `cfg.resolve_timeout`.",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"required": [
"command"
],
"title": "ExecBgRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"argv": {
"items": {
"type": "string"
},
"type": "array"
},
"job_id": {
"type": "string"
}
},
"required": [
"argv",
"job_id"
],
"title": "ExecBgResponse",
"type": "object"
}
},
{
"description": "Recursive regex search on host or sandbox",
"metadata": {},
"name": "shell::fs::grep",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FsMatch": {
"properties": {
"content": {
"type": "string"
},
"line": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"path": {
"type": "string"
}
},
"required": [
"content",
"line",
"path"
],
"type": "object"
}
},
"properties": {
"matches": {
"items": {
"$ref": "#/definitions/FsMatch"
},
"type": "array"
},
"truncated": {
"type": "boolean"
}
},
"required": [
"matches",
"truncated"
],
"title": "GrepResponse",
"type": "object"
}
},
{
"description": "Remove a path on host or sandbox",
"metadata": {},
"name": "shell::fs::rm",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"removed": {
"type": "boolean"
}
},
"required": [
"removed"
],
"title": "RmResponse",
"type": "object"
}
},
{
"description": "Change permissions on host or sandbox",
"metadata": {},
"name": "shell::fs::chmod",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"updated": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"updated"
],
"title": "ChmodResponse",
"type": "object"
}
},
{
"description": "Create a directory on host or sandbox",
"metadata": {},
"name": "shell::fs::mkdir",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"created": {
"type": "boolean"
}
},
"required": [
"created"
],
"title": "MkdirResponse",
"type": "object"
}
},
{
"description": "Move/rename a path on host or sandbox",
"metadata": {},
"name": "shell::fs::mv",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"moved": {
"type": "boolean"
}
},
"required": [
"moved"
],
"title": "MvResponse",
"type": "object"
}
},
{
"description": "Run an allowlisted command in the foreground and return its full output. Payload: { command: string (program name), args?: string[], timeout_ms?: number, target?: { kind: 'host'|'sandbox', sandbox_id?: string } }. Returns { stdout, stderr, exit_code, duration_ms, timed_out, stdout_truncated, stderr_truncated }. Do NOT pass argv as an array in 'command' — split program and arguments across the two fields.",
"metadata": {},
"name": "shell::exec",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Target": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"host"
],
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"sandbox"
],
"type": "string"
},
"sandbox_id": {
"format": "uuid",
"type": "string"
}
},
"required": [
"kind",
"sandbox_id"
],
"type": "object"
}
]
}
},
"description": "Wire request for `shell::exec`. The schema is published to the engine's tool listing so callers see field types up front instead of guessing from the description.",
"properties": {
"args": {
"default": null,
"description": "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`.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"command": {
"description": "Program name (matched against the allowlist by basename or exact path). Must be a string — split arguments into `args`, do not pass argv as an array here.",
"type": "string"
},
"target": {
"allOf": [
{
"$ref": "#/definitions/Target"
}
],
"default": {
"kind": "host"
},
"description": "Where to run the command. Defaults to the host worker; pass `{ kind: \"sandbox\", sandbox_id }` to forward the call to a microVM."
},
"timeout_ms": {
"default": null,
"description": "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).",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"required": [
"command"
],
"title": "ExecRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"duration_ms": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"exit_code": {
"format": "int32",
"type": [
"integer",
"null"
]
},
"stderr": {
"type": "string"
},
"stderr_truncated": {
"type": "boolean"
},
"stdout": {
"type": "string"
},
"stdout_truncated": {
"type": "boolean"
},
"timed_out": {
"type": "boolean"
}
},
"required": [
"duration_ms",
"stderr",
"stderr_truncated",
"stdout",
"stdout_truncated",
"timed_out"
],
"title": "ExecResponse",
"type": "object"
}
},
{
"description": "List all background jobs",
"metadata": {},
"name": "shell::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"JobStatus": {
"enum": [
"running",
"finished",
"killed",
"failed"
],
"type": "string"
},
"JobSummary": {
"description": "`shell::list` returns one `JobSummary` per record. argv, stdout, and stderr are deliberately omitted: the global JOBS map is process-wide and has no per-caller scope, so any caller could otherwise read every other caller's command line and captured output (which may embed credentials). Full records remain reachable via `shell::status <job_id>` — the random UUID acts as an unguessable capability for that record.",
"properties": {
"exit_code": {
"format": "int32",
"type": [
"integer",
"null"
]
},
"finished_at_ms": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"id": {
"type": "string"
},
"started_at_ms": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"status": {
"$ref": "#/definitions/JobStatus"
},
"stderr_truncated": {
"type": "boolean"
},
"stdout_truncated": {
"type": "boolean"
}
},
"required": [
"id",
"started_at_ms",
"status",
"stderr_truncated",
"stdout_truncated"
],
"type": "object"
}
},
"properties": {
"count": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"jobs": {
"items": {
"$ref": "#/definitions/JobSummary"
},
"type": "array"
}
},
"required": [
"count",
"jobs"
],
"title": "ListResponse",
"type": "object"
}
},
{
"description": "Get status of a background job",
"metadata": {},
"name": "shell::status",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"job_id": {
"type": "string"
}
},
"required": [
"job_id"
],
"title": "StatusRequest",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"JobRecord": {
"properties": {
"argv": {
"items": {
"type": "string"
},
"type": "array"
},
"exit_code": {
"format": "int32",
"type": [
"integer",
"null"
]
},
"finished_at_ms": {
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"id": {
"type": "string"
},
"started_at_ms": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"status": {
"$ref": "#/definitions/JobStatus"
},
"stderr": {
"type": "string"
},
"stderr_truncated": {
"type": "boolean"
},
"stdout": {
"type": "string"
},
"stdout_truncated": {
"type": "boolean"
}
},
"required": [
"argv",
"id",
"started_at_ms",
"status",
"stderr",
"stderr_truncated",
"stdout",
"stdout_truncated"
],
"type": "object"
},
"JobStatus": {
"enum": [
"running",
"finished",
"killed",
"failed"
],
"type": "string"
}
},
"properties": {
"job": {
"$ref": "#/definitions/JobRecord"
}
},
"required": [
"job"
],
"title": "StatusResponse",
"type": "object"
}
},
{
"description": "List directory contents on host or sandbox",
"metadata": {},
"name": "shell::fs::ls",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FsEntry": {
"properties": {
"is_dir": {
"type": "boolean"
},
"is_symlink": {
"type": "boolean"
},
"mode": {
"type": "string"
},
"mtime": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"size": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"is_dir",
"is_symlink",
"mode",
"mtime",
"name",
"size"
],
"type": "object"
}
},
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FsEntry"
},
"type": "array"
}
},
"required": [
"entries"
],
"title": "LsResponse",
"type": "object"
}
},
{
"description": "Stream a file from a host path or sandbox via StreamChannelRef",
"metadata": {},
"name": "shell::fs::read",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AnyValue"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ContentDirection": {
"enum": [
"read",
"write"
],
"type": "string"
},
"ContentRef": {
"description": "Wire-identical mirror of `iii_sdk::channels::StreamChannelRef`. The SDK type lacks `JsonSchema` in 0.11.3, which would block typed registration of `shell::fs::write`/`read`.",
"properties": {
"access_key": {
"type": "string"
},
"channel_id": {
"type": "string"
},
"direction": {
"allOf": [
{
"$ref": "#/definitions/ContentDirection"
}
],
"default": "read"
}
},
"required": [
"access_key",
"channel_id"
],
"type": "object"
}
},
"properties": {
"content": {
"$ref": "#/definitions/ContentRef"
},
"mode": {
"type": "string"
},
"mtime": {
"format": "int64",
"type": "integer"
},
"size": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"content",
"mode",
"mtime",
"size"
],
"title": "ReadResponseWire",
"type": "object"
}
}
],
"triggers": []
}