The native operator connection
Native operator connection
Desktop calls Stado's HTTP APIs. It does not search PATH for a Stado command, start that command, or fall back to it when an API request fails. Hosts, Services, Releases, Products, Databases, Inference, Cloudflare routes, Vast, Scratch targets and credential inspection use the same selected source as the console. Existing typed registry, convergence and storage APIs remain separate from the operator command API.
The command API is POST /api/operator/run, with Content-Type: application/json and X-Stado-Action: operator-command. A read request such
as {"args":["database","list","--json"]} carries no mutation confirmation.
A reviewed change adds "confirmation":"RUN_MUTATION". For example the
Databases declaration corresponds to stado database declare NAME --engine postgres --scope read --consumer CONSUMER --json. The server refuses an
unconfirmed write with HTTP 403 before executing it. Any top-level command the
CLI's own clap tree declares is reachable; a family it does not declare is
refused. Command words below the family are read against the same tree: a
word that names no command at its level, before the first option or a
command's own positional arguments, is refused with HTTP 400 as stado <words> has no command "<word>"; it declares: <its commands>, before any
judgement or run. Whether a request only reads is judged by a model through Oko's
schema-bound call (oko gateway object) from the argv and the command's own
help: the answer is one object whose choice is READ or CHANGES, with its
reason, bound to a strict JSON Schema, so --dry-run, --check or --apply
count as that command's help says;
--help and --version are reads by the parser's own answer. A request whose
judgement could not be obtained is treated as a change, the cause is written to
the service's log, and the confirmation is required. Loopback retains local
trust; remote access uses the operator's authorized Wisent session.
Receipts retain the operation's exit code, stdout, stderr and refusal. A missing exit code is not converted to zero. Truncated output is not accepted as a complete result. Connection and API failures identify the requested endpoint and operation; installing a local CLI is not their fallback. Responses from a previously selected source are not shown as the new source's results. A mutation already accepted by the server is not undone by switching sources.
Service declarations send their JSON in the request's input field and use
$INPUT in the argument array. Desktop does not pass a Mac-local temporary
filename to a remote service. Secret standard input remains the separate
stdin field. A request whose arguments name $INPUT and carry no input
is refused with HTTP 400 (args name $INPUT but the request carries no input to stage), never run on an empty file. The receipt's structured member is
the command's stdout parsed as JSON, or null when the command printed
anything else; the text is always in stdout.
Every operation runs a CLI path the console declares, and those paths are
checked against the CLI twice. The API refuses a request whose words name no
command, stado <words> has no command "<word>"; it declares: <commands>
(HTTP 400), before anything runs. And Stado --operation-paths prints every
operation's group, id, path, fixed arguments and the options its fields pass
(options) as JSON and exits before a window opens;
tests/desktop_api/operation_paths.rs runs each path's --help through the
built stado (the Desktop executable named by STADO_TEST_DESKTOP_BIN) and
names every operation whose path the CLI does not have, and every option an
operation passes that the command's help does not name (`
Source: this website