Skip to main content
Every simforge command keeps the same contract, so a script or an agent can drive it without parsing prose.

stdout: one JSON document

A command prints exactly one JSON document on stdout. JSON is the default; --json asks for it explicitly, and --pretty indents the same document for people. Nothing else is ever written to stdout.

stderr: a structured error

When a command fails it prints one JSON line on stderr:
  • code is stable: key your handling on it. Never parse reason, which is for people.
  • hint says what to do next, often the exact command.
  • path names the input at fault, and detail carries structured context, when there are any.
  • httpStatus and requestId are there when the SimForge host refused a request: quote the requestId to support, which traces the request by it.
login also writes event lines ({"event": …}, never a code) on stderr while it waits: the URL and code a person must approve. runtime install and maps pull write {"event": "distribution.download.progress", "bytes": {"done": …, "total": …}, "percent": …} lines as they download, at each tenth of the archive and at least every 30 seconds. A command that waits on a cloud run (--cloud --wait, runs watch) writes {"event": "run.progress", "runId": …, "status": …, "jobs": [{"kind", "status", "progress", "queue"}], "elapsedSeconds": …, "message": …} when it first reads the run, whenever the run or a job changes, and at least every 30 seconds. Saving a scenario file as a hosted revision (the first --cloud run or dry run of its content) writes {"event": "revision.freeze", "draftId": …, "simulation": …, "elapsedSeconds": …, "message": …} when it starts and each time the host answers that its authoritative simulation (queued or running) is still going.

Exit codes

The command surface as data

simforge --help prints a compact index: every command with a one-line summary. simforge <command> --help prints one command: its arguments and flags with types, allowed values, ranges, defaults, which ones are required or exclude each other, and the global flags it takes. simforge help --json [command] prints the full schema of every command, or of one subtree. An unknown flag is an error (unknown_flag), except after the scenario of render, simulate and preview, whose trailing arguments are runtime options: check those against the command’s help. The same document is published at /docs/cli.json and rendered as the command reference. A failure on stderr is one simforge.error/v1 line: {code, path?, reason, hint, detail?, httpStatus?, requestId?}. hint says what to do next; for an invalid value it quotes the allowed values or range and names the command’s --help. detail carries structured extras only. A request the hosted API refuses (an HTTP 4xx answer, such as budget_exceeded or insufficient_scope) exits 2 with the API’s own code; a server failure exits 1.

Common error codes

Codes for a specific area are on its page: sign-in and runtime, cloud.