Commands

Most of what Sudo does is ordinary bash: ls, cat, grep, sed, find, jq, awk, diff, and python for anything longer than a one-liner. On top of that the sandbox adds the handful of things a text editor and grep cannot do: read the graph, compile a definition, describe a type, run stored code, and hand a set of edits over for approval.

help prints the whole layout, the command list, and which of them the current conversation may use.

The change loop

status

Which files this session has changed, added or deleted, compared against the live configuration.

diff [path...]

What changed in them, as a unified diff. With two file operands it diffs those two files instead, which is how "how does this endpoint differ from that one?" gets answered.

build [path...]

Parses every changed file back through the workspace's own importer and compiles its body against the execution scope it will actually run in. With no arguments it builds everything that changed.

This is the same parser and the same compiler the workspace uses to load a definition, which is what makes "it builds" mean "it will import". Diagnostics come back with the line and column of the code as written.

A schema and the code that uses it are allowed to build together, so adding a field and the endpoint that reads it is one coherent change rather than two that each fail on their own.

commit -m "message" [path...]

Stages the changed files as a reviewable diff and stops. Nothing is applied.

It refuses if any changed file does not build (--force exists, says so loudly in the output, and still needs your approval). It refuses outright in a session with Allow changes off, keeping the edits so the same command works once you turn the toggle on. With no file operands it commits everything that changed; with operands it commits only those.

A commit carries an id. If Sudo stages a newer commit while an older review card is still open, the card refuses rather than applying something nobody read.

revert <path>... | --all

Throws away the edits to those files and restores the live configuration.

Reading the workspace

graph <subcommand>

Read-only access to the workspace data, as the administrator who is chatting, skipping node types that are never returned to clients.

Subcommand What it returns
graph types every node type with its node count
graph stats <type> count, key, fields and a few example nodes
graph get <uid> [--edges] one node by UID
graph sample <type> [-n N] N nodes of a type (default 5)
graph search <text> [-t type] [-n N] a search, as the chatting admin would see it
graph edges <uid> a node's edges
graph history <uid> a node's version history

query '<chain>'

One graph query, written as the same fluent chain a code endpoint is written with:

query 'StartAt("Person").Out("Company", "worksAt").Take(10).Emit()'
query --methods          # every call the sandbox accepts, with its parameters
query -n 20 '<chain>'    # emit at most 20 nodes per section

The chain is interpreted, never compiled: the sandbox parses it and calls a reviewed list of IQuery methods whose arguments are literals. Three guards are applied before it runs, and none of them can be turned off from inside a chain: transactions are blocked, never-returnable node types are removed, and at most 50 nodes are emitted per section (a truncated section says so in its own entry rather than letting a partial answer read as the whole one).

See the graph query language for the chain itself.

type <name>

Documentation for a C# type or for a code-execution scope: the same page the code editor shows on hover. /docs holds the same pages as files.

uid

Node UIDs. A scheduled task, AI tool, prompt template or assistant needs a fresh UID in its file header; an endpoint, agent, skill or data node has one derived from its route, name or key and is not free to choose.

uid                        # one fresh UID
uid -n 5                   # five of them
uid endpoint /api/tickets  # the UID that route already has
uid agent "support-triage"

Running things

run <kind> <target>

Runs code the workspace already has, and captures what it logged into /proc/runs/<run-id>/. Available only in a session with Allow changes on, because running stored code is an action with effects.

run endpoint /api/tickets --body '{"status":"open"}'
run task "Nightly refresh"
run migration "Backfill product codes"
run reindex Ticket
run list                   # this session's runs

Each run leaves a folder behind: status, log, and output or error when there is one. Because /proc regenerates on every read, cat, grep and tail on those files show a long-running task as it progresses.

tasks <subcommand>

Sudo's own to-do list for the session, rendered to /session/todo.md:

tasks add "Add the endpoint" -c endpoints
tasks list
tasks done 2
tasks delete 3
tasks clear --done

The list outlives the conversation, which is what makes a multi-step change survive being picked up again the next day. Sudo is instructed to write the steps down before starting anything with more than one of them, and to mark each one done as he goes, so you can see where he is.

Working with files you staged

extract <file|uid> [--text] [-o path]

Re-reads a staged file live with the real extractor and prints it as markdown (--text for plain text). Use it when a file under /stage says nothing has been indexed for it yet. The result is remembered on the mount, so the file has it from then on.

file-stats <file> [--json]

What is actually in a file: size and line counts, and for a CSV or TSV the separator, the header row, and per column the type, the null count, uniqueness, distinct count, sample values and value distribution.

This is what to run before designing a schema or a connector for tabular data, instead of reading the rows and guessing.

What is deliberately missing

The networking command names are withheld rather than refused, so type curl, command -v curl and tab completion all agree that there is no such command. That way the day the underlying library grows one, this sandbox does not silently acquire it. watch is withheld for a different reason: it would spend the wall-clock budget re-running a command against a filesystem that cannot change underneath it.

© 2026 Curiosity. All rights reserved.