Copy concrete localhost commands and look up selection, lifecycle, operation, output, and exit behavior.
The commands below use the checked getting-started config, its slack service,
seeded dev world, Ada user, and general channel.
Terminal one:
pnpm exec localhost devTerminal two:
pnpm exec localhost seed
pnpm exec localhost describe slack --instance dev --json
pnpm exec localhost exec slack --help
pnpm exec localhost exec slack create-user --instance dev --name Grace --json
pnpm exec localhost exec slack send-message --instance dev \
--input-json '{"channel":"general","from":"Ada","text":"ready"}' --json
pnpm exec localhost logs slack --instance dev --tail 50 --jsonUse pnpm exec localhost so the project's installed package supplies the binary. dev stays in the
foreground, binds only loopback, acquires the storage lock, and creates an empty persistent dev
world if none exists. The second terminal uses authenticated control commands; application traffic
continues through plugin connection values and provider-shaped routes.
pnpm exec localhost --config ./localhost.config.ts doctor --json
pnpm exec localhost instance list --config ./localhost.config.ts --json
LOCALHOST_INSTANCE=dev pnpm exec localhost describe slack --json
pnpm exec localhost describe slack --instance dev --json| Selector | Rule |
|---|---|
No --config | Walk upward from the working directory; use the first supported config. |
--config ./localhost.config.ts | Resolve that path from the working directory; skip discovery. It may appear before or after the command. |
| No instance selector | Target dev. |
LOCALHOST_INSTANCE=review | Change the process default. |
--instance dev | Override both defaults for that command. |
Help-only invocations do not load config. Commands that need a project stop when config loading
fails; doctor records that issue and continues read-only inspection. Control commands compare the
running fingerprint with the resolved config and stop before mutation on mismatch. Restart dev
after editing config.
Create, reset, and destroy always require an explicit ID argument. LOCALHOST_INSTANCE does not
make destructive targets implicit.
localhost describe [service] [--instance id] [--json]
localhost exec <service> --help
localhost exec <service> <operation> [generated flags | --input-json object] [--instance id] [--json]Operation commands come from the selected running plugin's metadata. describe lists services or
one service's operation schemas. exec slack --help converts keys such as createUser to
create-user and displays the input accepted by the installed plugin version.
pnpm exec localhost exec slack create-user --name Lin --admin=false --json
pnpm exec localhost exec slack send-message \
--channel general --from Ada --text ready --json
pnpm exec localhost exec slack send-message \
--input-json '{"channel":"general","from":"Ada","text":"ready"}' --json| Input shape | CLI form |
|---|---|
| Flat strings, finite numbers, safe integers, booleans, or repeatable non-boolean scalar arrays | Generated long flags |
| Nested, union, referenced, dynamic, repeated boolean, or runtime-option collision | One complete object through --input-json |
Boolean flags accept an omitted value as true or an explicit --admin=false. Repeated arrays
repeat the same flag. --input-json works as a complete object and cannot be combined with generated
input flags. Invalid JSON, a non-object value, an unknown flag, or schema failure exits as input
failure; the CLI does not guess another operation.
Operations are privileged local controls. They arrange or inspect a world; they do not replace the application's provider-shaped request boundary. See Operations and emulated APIs.
pnpm exec localhost instance create review
pnpm exec localhost instance list --json
pnpm exec localhost seed --instance review
pnpm exec localhost instance reset review
pnpm exec localhost instance reset review --seed
pnpm exec localhost instance destroy review| Grammar | Transition |
|---|---|
instance create <id> [--seed] | Create a persistent empty world; seed before readiness only when requested. |
instance list [--json] | Read lifecycle, persistence, seed, service, and clock summaries. |
seed [--instance id] | Seed an existing eligible world once. |
instance reset <id> [--seed] | Replace the named world; empty unless seed is requested. |
instance destroy <id> | Remove the named world. |
Mutations print short acknowledgements and have no --json variant. They do not prompt. Resolve the
ID before automation. Reset is replacement, not automatic reseeding; destroy is not an archive.
pnpm exec localhost env --instance dev --format dotenv
pnpm exec localhost env --instance dev --format json
pnpm exec localhost run --instance dev -- pnpm testenv prints the plugin-owned application projection. Dotenv is the default; JSON uses --format json, not --json. run overlays that projection on one directly spawned child, inherits stdio,
forwards SIGHUP/SIGINT/SIGTERM while it owns the child, and returns the child's exit code. Everything
after --, including child flags named --config or --instance, belongs to the child.
Connection names override inherited values. Runtime discovery metadata and the control token are never injected.
pnpm exec localhost clock status --instance dev --json
pnpm exec localhost clock advance 2h --instance dev --json
pnpm exec localhost logs slack --instance dev --tail 50 --json
pnpm exec localhost doctor --json| Command | Result |
|---|---|
clock status | Current mode and RFC 3339 instance time. |
clock advance <duration> | One durable time window after configured services reconcile it. |
logs [service] | Bounded request, operation, delivery, and plugin logs. |
doctor | Read-only config, runtime-discovery, stored-manifest, service-version, and pending-trash report. |
logs defaults to 50 entries; --tail accepts 0 through 1000. Its droppedEntries field tells
you whether older or oversized evidence is absent. Correlation IDs identify one boundary, not a
whole scenario.
doctor does not create directories, start a daemon, repair manifests, or remove trash. A report
with status: "issues" still exits successfully; automation must inspect status and issues. An
absent runtime is expected before dev starts.
The first two entries are owner-approved documentation-first contracts awaiting implementation review; the remaining entries are source-verified in the current CLI.
| Grammar | Effect |
|---|---|
localhost init | Create a minimal config and ignore local runtime state. |
localhost demo clone <name> [directory] | Copy and install a named standalone demo without overwriting files. |
localhost dev [--host host] [--port port] | Start the foreground loopback runtime. |
localhost describe [service] [--instance id] [--json] | Read service and operation metadata. |
localhost exec <service> [operation] ... | Discover or invoke one plugin operation. |
localhost instance create <id> [--seed] | Create a persistent isolated world. |
localhost instance list [--json] | List known worlds. |
localhost instance reset <id> [--seed] | Replace a world, empty by default. |
localhost instance destroy <id> | Destroy the named world. |
localhost seed [--instance id] | Apply configured seed once. |
localhost env [--instance id] [--format dotenv|json] | Render application connection values. |
localhost run [--instance id] -- <command...> | Run one child with connection values. |
localhost logs [service] [--instance id] [--tail n] [--json] | Read bounded logs. |
localhost clock status [--instance id] [--json] | Read instance time. |
localhost clock advance <duration> [--instance id] [--json] | Advance and reconcile instance time. |
localhost doctor [--json] | Inspect project and stored runtime state without repair. |
With --json, success writes exactly one valid JSON value plus a newline to stdout. Diagnostics and
dev readiness use stderr. A failed JSON command leaves stdout empty. Without --json, strings are
written directly and other values as indented JSON. Operation output is the validated control
response, not parsed plugin process output.
| Exit | Meaning |
|---|---|
2 | CLI usage or validated input failure |
3 | Config, discovery, transport, protocol, or control-authentication failure |
4 | Missing instance, service, or operation |
5 | Lifecycle conflict, committed mutation failure, or idle timeout |
10 | Other plugin, runtime, lifecycle, or unexpected failure |
130 | CLI interruption |
Direct control failures render error: <message> on stderr and append a boundary correlation ID
when supplied. A missing instance instead gets target-specific existing IDs and an exact
localhost instance create <id> hint; that CLI-owned guidance omits the original correlation ID.
The CLI does not expose structured error details. Use ControlApiError from the programmatic client
when recovery needs fields such as a committed clock window.
After a run child starts, its exit code is passed through, including signal-derived 129, 130,
or 143.
The control API lives below /_/v1. Only /_/v1/health is unauthenticated; every other endpoint
requires the current daemon token. This Bash example keeps it in one shell variable and clears it:
localhost_control_token="$(< .localhost2137/control-token)"
curl --silent http://127.0.0.1:2137/_/v1/instances \
--header "authorization: Bearer $localhost_control_token"
unset localhost_control_tokenSuccess uses { "data": ... }. Failure uses an error object with code, message,
correlationId, and sometimes details. JSON mutations also require a JSON content type and exact
shape. Prefer connectRuntime from localhost2137/client outside shell automation.
Read the token again after daemon restart. Never expose it to browser code, application processes, logs, traces, or build artifacts. Local security model defines the trust boundary.