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.

It compiles against the workspace as this change set leaves it, not only against what the workspace holds today. Code naming an endpoint, AI tool, agent, skill, prompt template, AI assistant or secret the same change set adds compiles; code still naming one it removes does not. That is what lets a schema and the connector that fills it, or an agent and the AI tool that calls it, be one coherent change rather than two that each fail on their own.

The pending definitions decide what compiles during a check and never what runs — they still have to be imported for real before they exist. A draft that compiled against a file you then rejected stops compiling the next time it is checked, which is the answer you want.

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

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

It builds the whole change set first, the same way build does, and refuses if any changed file fails (--force exists, says so loudly in the output, and still needs your approval). It refuses outright for an administrator whose account may only read the workspace, keeping the edits. 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.

Approving the commit is itself a turn in the conversation: once the workspace has taken it, a message in your voice names the commit and how many files are live, and carries any notes you typed while reviewing. Without it the session — whose shell the apply has just reset to the live configuration — would go on offering a change that has already landed. A discarded commit says nothing, so silence is not approval.

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 to an administrator who may change the workspace, because running stored code is an action with effects — as much of one as a commit.

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.