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 (` passes

Source: this website