stellar is the command line of Stellar Control, for operators, procedure authors and CI. It works
on a configuration repository (check, lock, compile, dry runs), talks to the API of a cell
(telecommands, runs, alarms, passes, files), and to NATS directly for a few commands.
cargo install --path tooling/cli # installs `stellar`
stellar --help
stellar <command> --helpCommon options#
Connection to the API#
Every command that talks to the API takes these options:
| Option | Environment | Default | Meaning |
|---|---|---|---|
--api <url> | STELLAR_API | http://localhost:8080 | API of the MCS, http:// or https:// |
--as <user> | USER | operator | Identity declared to the API (X-Stellar-User), where the environment accepts declared identities |
--role <roles> | STELLAR_ROLE | none | Roles declared with it, comma-separated (operator,supervisor) |
--token <jwt> | STELLAR_TOKEN | the session of stellar login | OIDC token, preferred to the declared identity; without it, the session of stellar login for this API, if any |
--api-ca <file> | STELLAR_API_CA | system roots | CA certificates (PEM) the certificate of an https:// API is checked against |
See Identity and Roles.
Connection to NATS#
stellar compile --publish and stellar sim connect to NATS directly:
| Option | Environment | Meaning |
|---|---|---|
--nats-credentials <file> | STELLAR_NATS_CREDENTIALS | Credentials file (JWT and seed) |
--nats-ca <file> | STELLAR_NATS_CA | CA certificates (PEM): TLS only |
--nats-cert <file> | STELLAR_NATS_CERT | Client certificate (PEM), for mTLS; requires --nats-key |
--nats-key <file> | STELLAR_NATS_KEY | Private key of the client certificate; requires --nats-cert |
Global configuration#
check, lock, compile, generate and run --dry take --config <file> (STELLAR_CONFIG): the
global configuration, for the compilation parameters
(executor.default_retry, derived.max_window) and, for a dry run, executor.ack_timeout.
Defaults apply without it.
Exit codes#
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | The outcome is a failure: compilation errors, a telecommand not VERIFIED nor COMPLETE, a run that failed, a transfer not verified, a timeout of watch, a refused send, a simulator error |
| 2 | The command could not do its job: invalid arguments, unreadable file, API or NATS unreachable, a request refused by the API (its errors are printed as error[<code>]: <message> with help:) |
Configuration repository#
stellar check#
stellar check [REPOSITORY] [--locked] [--format human|json] [--config FILE]Compiles the catalogues, topology, steps, procedures and simulations of a repository, prints the diagnostics, then what must be validated again.
| Argument or option | Default | Meaning |
|---|---|---|
REPOSITORY | . | Repository root |
--locked | off | Also fail when steps or procedures must be validated again: the check of merge requests |
--format | human | human: rendered diagnostics on standard error and a summary; json: one JSON object per line on standard output, diagnostics (with LSP positions) then revalidations {"revalidate", "library", "name", "reasons"} |
Exits with 1 on an error, and with --locked on a pending validation.
Checked 5 catalogues, 1 library, the topology, 2 simulations (6 steps, 9 procedures): 0 errors, 0 warnings.stellar fetch#
stellar fetch [REPOSITORY] [--update]Fetches the packages of other repositories declared in stellar.yaml into the cache
(STELLAR_CACHE), through git, and writes their commit and hash to packages.lock. A package
already locked stays at its commit, its files checked again; --update takes the current commit
of each tag or revision. The only command of the repository that reaches the network. See
Several repositories.
stellar lock#
stellar lock [REPOSITORY] [--config FILE]Rewrites the stellar.lock of every library from the current sources: it records the validation
of the steps and procedures. Refuses (exit 1) while the repository has errors. See
Libraries and Validation.
stellar compile#
stellar compile [REPOSITORY] [--output FILE] [--publish NATS_URL] [--config FILE] [NATS options]Compiles the snapshot, writes it to --output (default <hash>.ir in the current directory) and
prints its hash on standard output. With --publish, stores it in the stellar_ir object store of
that NATS server and makes it the current configuration (stellar_config, key current, with
$USER as publisher). Exit 1 on compilation errors.
stellar compile examples/config --publish tls://nats.example.org:4222 \
--nats-credentials ci.creds --nats-ca ca.pemstellar schema#
stellar schema <KIND>Prints the JSON Schema of a file or message kind, for editors, CI and components written in other languages.
| Kind | Schema of |
|---|---|
catalogue | A catalogue of a platform |
library | The manifest of a step library (package.yaml) |
repository | The manifest of the repository (stellar.yaml): packages of other repositories |
topology | The topology |
simulation | A simulation of a target |
registration, registration-reply | A registration of an instance, and its reply |
heartbeat | A heartbeat |
status | The reply to the status control verb |
semantic-tc | A telecommand to encode |
tc-event | A transition of a telecommand |
run-event | An event of a run |
bindings | The links bound to an instance |
sample, raw-sample | A measure sample; a raw value decoded by a driver |
throughput | A throughput report of a gateway |
alarm-event, alarm-record, alarm-command | A transition, the current state, a command of an operator on an alarm |
pass | A pass of a target over a ground station |
schedule, schedule-rule | A run scheduled on a pass; a recurring rule |
transfer | A file transfer |
stellar generate#
stellar generate driver <CATALOGUE> -o <DIR> [--software NAME] [--version VERSION] [common options]
stellar generate client <LIBRARY> -o <DIR> [common options]
common options: [--repository DIR] [--lang python] [--check] [--config FILE]
stellar generate simulation <CATALOGUE> [--name NAME] [-o FILE] [--force] [--repository DIR] [--config FILE]Generates Python code from the compiled repository: driver, the typed skeleton of a driver of a
catalogue; client, typed functions launching the procedures of a library through the API.
simulation writes the simulation of a platform from its catalogue, simulations/<name>.yaml
(<package>-sim by default), after checking each telecommand plays as its catalogue verifies it;
an existing file is kept without --force. See
A simulation written from the catalogue.
| Argument or option | Default | Meaning |
|---|---|---|
CATALOGUE | driver: catalogue package (lab-psu), or lab-psu@1.0.0 among several versions | |
LIBRARY | client: library of steps and procedures (platform-v3-steps) | |
-o, --output | required | Output directory, a Python package |
--software | the catalogue package | driver: name of the driver software |
--version | 0.1.0 | driver: version of the driver software |
--repository | . | Configuration repository |
--lang | python | Language of the SDK (Python only) |
--check | off | Write nothing; fail when the generated modules do not match the configuration (CI) |
--config | STELLAR_CONFIG | Global configuration |
The generator's files (_generated.py, and the __init__.py of a client) are written every
time; the developer's (__init__.py, driver.py, test_driver.py of a driver) only when
missing. Exits with 1 when the repository has errors or, with --check, a generated file is not
up to date; with 2 for an unknown catalogue or library.
stellar generate driver lab-psu --repository examples/config -o lab_psu --software scpi-psu
stellar generate client platform-v3-steps --repository examples/config -o platform_v3_steps --checkSee Code Generators.
Telecommands and values#
stellar send#
stellar send <TARGET> <TELECOMMAND> [NAME=VALUE]... [--instance I] [--link L] [--environment E] [API options]Submits a direct telecommand and follows its acknowledgements until its final state. Succeeds on
VERIFIED or COMPLETE; any other final state, or a refusal, exits with 1.
| Argument or option | Meaning |
|---|---|
TARGET | Target (sim-1) |
TELECOMMAND | ping (name unique in the platform), tcu.ping or tcu[TCU1].ping |
NAME=VALUE | Arguments: true, false, a number, or text (voltage=100 V, mode=SAFE_MODE, hexadecimal bytes) |
--instance | Instance of a multi-instance component, when not written in the telecommand |
--link | Link, when not the default one |
--environment | Environment, which selects the parameters of the link; required when the link overrides them by environment and the target is engaged in several |
stellar send sim-1 'tcu[TCU1].ping'
stellar send sim-1 'tcu[TCU1].set_anode_voltage' 'voltage=100 V' 'ramp=20 V/s'
stellar send flatsat-1 tcu.ping --instance TCU2 --link direct
stellar send obc-flatsat-1 ping --environment IVVSee Direct Telecommands and Values.
stellar encode and stellar decode#
stellar encode <TARGET> <TELECOMMAND> [NAME=VALUE]... [--instance I] [--link L] [--environment E] [--driver D] [--hex] [API options]
stellar decode <TARGET> [FRAME_HEX] [--file F | --text T] [--link L] [--environment E] [--driver D] [API options]Ask a driver what it makes of a telecommand or a frame, sending and publishing nothing: the
driver bound to the link, or the one named with --driver (a driver being developed). encode
resolves the telecommand like stellar send and prints the frame (a hexadecimal dump, and the
text of a text protocol); --hex prints the frame alone. decode takes the frame in
hexadecimal (spaces allowed), from a file, or as text, and prints each sample with its raw value
and its value calibrated by the catalogue. See
Checking a driver on a running MCS.
stellar encode sim-1 'tcu[TCU1].set_anode_voltage' 'voltage=200 V' --environment AIT
stellar encode psu-lab-2 set_voltage 'voltage=28 V' --environment AIT --hex
stellar decode psu-lab-2 --text 'VOLT 27.9;CURR 0.5;OUTP 1'
stellar decode sat1-fm --file frame.bin --link nominalstellar watch#
stellar watch <TARGET> [MEASURE]... [--until VALUE] [--timeout SECONDS] [API options]
stellar watch <RUN_ID> [API options]With a target, prints the current values, then each update. With a run identifier (a ULID),
follows the run like stellar run (see below).
| Argument or option | Meaning |
|---|---|
MEASURE | tcu[TCU1].responding (one instance), tcu.responding (every instance) or responding (any component); every measure without |
--until | Stop with success once a watched value equals this (true, STANDBY, 28.0) |
--timeout | Give up after this many seconds, exit 1 |
stellar watch sim-1 'tcu[TCU1].anode_voltage'
stellar watch sim-1 'tcu[TCU1].mode' --until SAFE_MODE --timeout 30stellar monitor#
stellar monitor [API options]The MCS live in the terminal, through the API like the web console:
| Panel | Content | Source |
|---|---|---|
| Targets | Each target, ready (green) or not (red), held by a run (⚑), its platform | GET /v1/topology, every 2 s |
| Values | The current values of the target chosen, with their time | GET /v1/targets/{target}/values/watch |
| Runs in progress | Procedure, targets, step, or suspended, or waiting for an answer | GET /v1/runs, every 2 s |
| Alarms | Every alarm not NORMAL, critical in red | GET /v1/alarms, at once on a transition (/v1/alarms/watch) |
| Telecommands | Each telecommand from the start of the monitor, one line, its last state and why it failed | GET /v1/tc/watch |
↑/↓ (or k/j) choose the target, q, Esc or Ctrl-C quit. A cut WebSocket is taken up
again; with stellar login, the session is renewed as for any command.
stellar monitor --api https://ada-1.control.stellar-systems.euModes and parameters#
stellar mode#
stellar mode <TARGET> [MODE] [API options]Without MODE, prints the mode the target is in, where it comes from, and the modes of the
topology:
sim-1: Survival (set by run 01JA2Z… at 2026-10-02T10:16:03Z)
modes: Nominal, SurvivalThe origin is default for the default mode never set, set by <operator> at <time>, or set by run <id> at <time> after a configure. A topology without modes prints
sim-1: the topology declares no modes.
With MODE, records that the target is in that mode (PUT /v1/targets/{target}/mode), as the
identity of the command. Nothing is sent to the target: a configure in a procedure applies a
mode. Refused while a run holds the target (mode::target-held), or for a mode the topology does
not declare (mode::unknown); a refusal exits with 2.
stellar parameters#
stellar parameters <TARGET> [--environment ENV] [API options]Prints the parameters of the components of the target: the value in its current mode, the value in each mode, and the readback with whether it matches:
sim-1: mode Nominal
tcu[TCU1].operating_mode "STANDBY" [Nominal="STANDBY", Survival="SAFE_MODE"] read "STANDBY" ok
tcu[TCU2].anode_voltage 180.0 V [Nominal=180.0, Survival=0.0] read 0.0 DIFFERSValues are printed as JSON (an enum value in quotes), in the unit of the parameter.
A readback line ends with ok, DIFFERS (outside the tolerance of the parameter), no verdict
without a value, or not read yet. --environment selects the overrides of an environment, when
the target is engaged in several; the only environment of the target otherwise.
See Modes and Parameters.
Runs#
stellar run#
stellar run <REQUEST> [--detach] [API options]
stellar run --dry <REQUEST> [--repository DIR] [--nats-server BIN] [--seed N] [--speed X] [--report FILE] [--config FILE]Launches a run from a request file (YAML: run, environment, targets, inputs, and
library when several libraries have a procedure of that name), then follows its log until the
end; succeeds when the procedure passes. Warnings of the API (a run that may outlast the pass in
progress) are printed on standard error. While the run waits for an operator, the follow-up prints
the command to type (stellar answer <run> yes|no|<value>…).
| Option | Default | Meaning |
|---|---|---|
--detach | off | Print the run identifier and return without following it |
--dry | off | Dry run: a local NATS server, the components and a simulated target per role, on the snapshot of the local repository; environment and targets are ignored |
--repository | . | Configuration repository of a dry run |
--nats-server | nats-server (STELLAR_NATS_SERVER) | nats-server binary of a dry run |
--seed | that of each simulation | Seed of the simulations of a dry run |
--speed | 1 | Speed of the simulated time of a dry run (2 runs the simulations twice as fast) |
--report | none | File to write the HTML report of a dry run to |
--on-decision | fail | How a dry run answers a decision: fail (the if failed blocks run, the run ends failed), skip, replay (3 times at most), abort, ask on the terminal |
--fault | — | A fault to switch on during a dry run, ROLE:FAULT[@[STEP+]DELAY][~OFF] (chamber:vacuum_leak@Plateau+10s~60s), after the faults of the request; repeatable. See Faults scheduled by a run |
A dry run gives each role a target dry-<role>, played by the simulation of the repository
whose platform has the version of the library — or, when simulations/ has none, by one written
on the fly from its catalogue (as stellar generate simulation does) — in a SIM environment
without human orchestration; the values of its parameters in each mode are those of a target of
the same platform in the topology. It is the CI of a procedure repository:
stellar run --dry runs/hot-standby.yaml --repository . --report report.htmlSee Running Procedures and Simulated Targets.
stellar status#
stellar status <RUN_ID> [API options]Prints the procedure, the step running or last run, and the state: running, suspended, or
finished: PASSED|FAILED with the reason; and the question or decision waiting, with its step.
stellar answer#
stellar answer <RUN_ID> <ANSWER> [--path STEP] [API options]Answers the question or decision the run waits for, found in its state unless --path names the
step. yes confirms, no refuses, replay, skip, fail or abort answer a decision, anything else
is a typed value (parsed as JSON when it can be: 27.9, true, else text such as "27.9 V").
stellar suspend, stellar resume, stellar abort#
stellar suspend <RUN_ID> [API options]
stellar resume <RUN_ID> [--choice replay|skip|fail|abort] [API options]
stellar abort <RUN_ID> [API options]Suspend at the end of the current instruction (the leases are released); resume, replay-ing the
step where the run stopped (default), skip-ping it, fail-ing it (its if failed blocks run), or
abort-ing; abort for good. See
Questions, Decisions and Control.
stellar report#
stellar report <RUN_ID> [-o|--output FILE] [API options]Gets the HTML test report of a run, to a file or the standard output. See Evidence and Reports.
Alarms#
stellar alarms [--target T] [--all] [API options]
stellar alarms [--target T] watch
stellar alarms ack <TARGET> <ALARM>
stellar alarms shelve <TARGET> <ALARM> --for <DURATION>
stellar alarms unshelve <TARGET> <ALARM>| Command | Effect |
|---|---|
alarms | The alarms not NORMAL or shelved; --all every alarm recorded; --target those of one target |
alarms watch | Prints every transition from now, in order |
alarms ack | Acknowledges an alarm: tcu[TCU1].anode_voltage, or eps.undervoltage without instance |
alarms shelve | Shelves an alarm for a bounded duration (30 min, 2h, at most alarms.max_shelve): no reaction while shelved |
alarms unshelve | Ends the shelving |
--target, --all and the API options go before the subcommand. See
Alarm Handling.
Passes and schedules#
stellar passes#
stellar passes [--target T] [--all] [API options]
stellar passes import <FILE>Lists the passes not over yet (--all: those over too), with the gateway checked for each.
import writes the passes of a file as the feeder named by --as (or the token): with a
replace_window: {source, target, from, to} header, it sends a complete snapshot of that window
and prints what was written and cancelled.
replace_window: {source: provider, target: sat1-fm, from: 2026-10-02T00:00:00Z, to: 2026-10-03T00:00:00Z}
passes:
- id: gs-a-2026-10-02T1014Z-sat1
target: sat1-fm
station: gs-a
aos: 2026-10-02T10:14:32Z
los: 2026-10-02T10:24:05Z
max_elevation: 47.3 deg
status: bookedSee Passes.
stellar schedules#
stellar schedules [--pass P] [--all] [API options]
stellar schedules add <FILE>
stellar schedules cancel <ID>
stellar schedules validate <ID>
stellar schedules rules
stellar schedules remove-rule <ID>| Command | Effect |
|---|---|
schedules | The schedules not final; --all also fired, missed and cancelled; --pass those of one pass |
schedules add | Schedules the runs of a file (schedule: with id, pass, start, run, targets, inputs) and writes its recurring rules (rules: with target and filter) |
schedules cancel | Cancels a schedule not started |
schedules validate | Validates the plan of a schedule, as a supervisor |
schedules rules | Lists the recurring rules |
schedules remove-rule | Removes a rule; the schedules it made remain |
See Scheduling.
Files#
| Command | Effect |
|---|---|
stellar files <TARGET> [--refresh] | The on-board directory from the last listing; --refresh sends the listing telecommand first and waits (up to 10 s) for the new listing |
stellar download <TARGET> <FILE_ID> [--priority N] [--wait] | Downloads the current generation of a file, as last listed; --priority (default 0, higher first); --wait follows it and succeeds when VERIFIED or PROCESSED |
stellar transfers [--target T] | The file transfers |
stellar put <FILE> | Stores a content to upload; prints its SHA-256 (the value of a file input of a run) and size |
See File Transfers.
Simulated targets#
stellar sim [--nats URL] [NATS options] faults <GATEWAY>
stellar sim [--nats URL] [NATS options] fault <GATEWAY> <NAME> on|off
stellar sim check <SIMULATION> [--repository DIR] [--config FILE]faults and fault talk to a simulated gateway over NATS (--nats, STELLAR_NATS_URL, default
nats://localhost:4222): they list its fault scenarios and whether each is active, or switch one.
They exit with 1 when the simulator refuses.
check needs neither NATS nor a running simulator: it checks a simulation of the repository
(simulations/<SIMULATION>.yaml) against its catalogue, each telecommand sent alone to the engine
and its verifications evaluated in simulated time, and prints a verdict per telecommand; it exits
with 1 when one fails. stellar generate simulation writes a simulation from a catalogue and runs
the same check. See Simulated Targets.
stellar sim fault sim-gw-1 tcu_silent on
stellar sim check lab-psu-sim --repository examples/configIdentity#
| Command | Effect |
|---|---|
stellar login [API options] | Signs in at the identity provider of the API (device authorization: a code to approve in a browser) and keeps the session in ~/.config/stellar/credentials; the commands to that API then use it, renewed by itself |
stellar logout [API options] | Forgets the session of the API |
stellar auth dev-key <SEED> [--jwks FILE] | Creates a key of the development identity provider (benches and tests only) and prints its JWK set, or writes it to --jwks |
stellar auth dev-token --key SEED --sub SUB [--role R]... [--ttl S] [--issuer I] [--audience A] | Prints a development token; --ttl in seconds, 8 h by default |
stellar auth nats-creds <FILE> [API options] | Writes NATS credentials of follow-up (run events, alarm transitions), exchanged against the token of --token |
See Identity and Roles and NATS Accounts and Credentials.
In CI#
# Merge requests of a configuration repository
- stellar check . --locked
- stellar run --dry runs/hot-standby.yaml --repository . --report report.html
# Default branch
- stellar compile . --publish "$STELLAR_NATS_URL"