The command line
What vike-cli is, what it deliberately is not, the ten verbs it dispatches, and which of the three surfaces over the platform to reach for.
vike-cli is one binary with ten verbs. It scaffolds a project, discloses what this box's settings
resolved to, inspects the credential store, lists what a strategy may call, ships backtests to a
data service, drives a running trading daemon from a terminal, and serves the same trading
vocabulary to an agent over MCP. Every verb is a sibling module under cmd exposing a
run(args) -> ExitCode, and the dispatcher in crates/vike-cli/src/lib.rs never grows command
logic — it only routes.
This section is the narrative half. It says what working at the command line is like and which verb answers which question; the CLI reference is the authority for every flag, every exit path and every error string, one page per verb.
The identity is negative
The most useful sentence about this binary is a list of what is not in it. vike-cli links no
DataFusion and no venue transport stack — no ureq, no tungstenite, no rustls, no signer.
That is not an accident of what has been written so far; it is the test every dependency in
crates/vike-cli/Cargo.toml is argued against, edge by edge, on the manifest row itself.
Three of those arguments are worth carrying, because they explain shapes you will meet later:
vike-opsandvike-bridge-coreare both takendefault-features = false. Their defaultfullfeatures carry the venue transport and signing stack, and restoring either would drag it into a laptop binary that never opens a venue socket.- the credential store is read through
vike-secrets, a crate with zero dependencies, rather than throughvike-bridge-core, the reader's historical home. AKEY=VALUEparser is not worth a TLS stack. - the client-order-id generator comes from
vike-modelrather thanvike-exec, its historical home.vike-execwould have added a multi-threaded async runtime and core-affinity to a binary whose whole identity is being light.
The consequence is the shape of everything else here: vike-cli asks services, it does not run
engines. A backtest is not computed in this process — the profile's TOML text is shipped to a
vike-datahub server sitting next to the tape, which
runs it and returns a compact report. Live orders are not placed by this process either — they are
commands sent to a running vike-tradehub node, whose
own control limits and risk gate are what actually enforce anything. The heavy history and the
authority both stay where they belong.
The ten verbs, by the job they do
crates/vike-cli/src/lib.rs's COMMANDS is the single source of truth for both the help text and
the unknown-command hint, so a new verb appears in --help for free. Grouped by what you are
trying to do rather than alphabetically:
| job | verbs |
|---|---|
| set the box up | init scaffolds user_data/; config show discloses every setting and where its value came from; config check judges the same tree and makes the exit code the product; secrets inspects the one credential store, and secrets set upserts one named key into it — the CLI's only credential writer, value from stdin or an environment variable, never argv |
| do research | indicators prints what a Rhai strategy can actually call; backtest, sweep and walkforward ship a profile to a data service and print what came back |
| run and watch | trade is the interactive REPL over a live node; strategy-status asks that node what it is running, read-only; mcp serves the same vocabulary to an agent |
Ten verbs is the whole surface. There is no clap dependency behind it: the flag grammar is
hand-rolled in crates/vike-cli/src/cmd/args.rs and shared by every verb, which is why
--flag value and --flag=value work everywhere and why a token beginning -- is a flag and
never a value everywhere. Global flags is that grammar's page.
What happens before any verb runs
Typing any subcommand runs the same three steps first — the first two inside
crates/vike-cli/src/lib.rs's resolve_policy, the third in run, which calls
install_user_indicators only once resolve_policy has returned. The order is load-bearing: a
refusal in step 1 returns before an indicator is ever compiled. Together they explain most of what
a fresh install does:
- A removed environment variable is refused.
vike_config::refuse_removed_envfails the process, naming the variable, the file that replaces it and the exact TOML line to write. It fires for every verb, including read-only ones — a stale variable is stale regardless of what you typed, and an operator who still exportsVIKE_MAX_ORDER_NOTIONALbelieves a ceiling is armed that nothing reads. <project>/settingsis resolved once, through the workspace's one startup sequence (vike_boot::boot). Every project-relative path any verb uses is derived from that single answer, sosecrets path,config showand a daemon on the same box cannot disagree about which project they are in.- Your own indicators are installed process-wide.
install_user_indicatorscompilesuser_data/indicators/*.rhaibefore dispatch, so a script run by any verb can call them. A file that fails to load is reported on stderr and never fails the command.
The credential store is the deliberate exception to "resolved once, up front": the dispatcher
opens it lazily and only for the three node-facing verbs — trade, mcp and strategy-status —
inside their own arms, through node_keyring, because those are the three that authenticate to a
node. A backtest has no business opening the file that holds every venue key on the box.
That is a statement about the dispatcher, not about the binary. Two verbs open the store because
the file is their subject, and they do it themselves rather than through the deferred boot:
secrets reads it directly (vike_secrets::resolve for list, a stat and a permissions check
for path, and set writes one key through the workspace's one upsert), and config does too — crates/vike-cli/src/cmd/config.rs's execute loads it before
it prints anything, to report the key COUNT, and config check classifies whether it is present,
absent or unreadable. So the honest answer to "which invocations touch secrets.env?" is: the
three node-facing verbs, plus the two whose job is to tell you about the file.
Diagnostics go to stderr, always
vike-cli mcp's stdout is a JSON-RPC protocol stream, and one stray line on it corrupts the
session. So every warning, every settings resolution and every rejected indicator goes to stderr —
in every verb, not just that one. It is also why vike-config returns its resolutions as data
rather than logging them: a library that writes to its caller's stderr cannot be linked by a binary
whose stdout is a protocol.
Which of the three surfaces
The platform has three faces over the same core concepts, and they are not ranked — each is best at something the others are bad at.
The desktop app
Charts, the DOM ladder, click-to-trade and the Studio — the surface for looking at something.
The command line
Reproducible, pipeable, scriptable, and the only one that runs over SSH on a box with no display.
The agent surface
The same trading vocabulary as MCP tools, for describing what you want instead of typing it.
Reach for the app when the question is visual — is this fill where I think it is, does this indicator look right on this chart. Reach for the CLI when the answer has to be repeatable, put in a shell script, or reached across an SSH connection to a server with no GUI. Reach for the agent surface when the loop is author, compile, backtest, adjust, and you would rather describe the strategy than write it. All three end up talking to the same daemon over the same authenticated protocol, and The daemon and the app is the page about that.
A first session
Empty install to a backtest report, one command at a time.
The trade REPL
Short verbs over a live node, with a preview in front of every write.
The agent door
What vike-cli mcp is, and where the tool reference lives.
Scripting it
--json, exit codes, and branching on them in a shell script.
When it goes wrong
The failures a fresh install actually hits, and what each one means.