vike-cli config
Two verbs over one settings directory: show discloses every setting and where its value came from, check judges the same tree and makes the exit code the product.
config has two verbs. They read the same directory through the same loader and differ in
what they produce.
usage: vike-cli config <verb> [options]
verbs:
show every setting, its effective value, and WHERE that value came from
check validate this box's settings tree + credential store; the EXIT CODE is the product
run `vike-cli config <verb> --help` for a verb's own optionsshow's product is a table; its exit code says only whether the loader refused, so nothing there
can be put in front of a daemon. check's product is the exit code, which is what the shipped
deploy/*.service units put in an ExecStartPre= (crates/vike-cli/src/cmd/config.rs,
crates/vike-cli/src/cmd/config_check.rs).
config show — provenance
usage: vike-cli config show [--json] [--filter <substr>] [--changed-only] [--section files|env|all]| flag | meaning |
|---|---|
--section | which half to print. files = the settings TOMLs; env = the environment-variable registry; all (default) = both. The env half is several hundred rows, and the question that motivated the files half — did my policy.toml get read? — should not require scrolling past them |
--filter <substr> | case-insensitive substring match on the setting name or key, or on the reading crate or file, so --filter reconcile, --filter bridges/okx and --filter policy all work |
--changed-only | only rows something actually configured — the "what have I set?" view |
--json | one object carrying the settings directory, the per-file status, both row sets and the loader's warnings |
The files half covers <project>/settings/{policy,config,preferences,flags}.toml, and its
provenance is exact: an origin is decided by key presence in a parsed layer, so a policy.toml
that sets a key to the same number as the code default still reports policy.toml. That half is why
the command exists in this shape — a risk ceiling can only be set in a file, and until this existed
nothing anywhere printed whether that file had been read. A typo'd filename, or a directory
resolved from the wrong project, produced a silently uncapped node. See
settings and policy.
The env half is the registry of every environment variable the workspace reads. Precedence
there is process env > the credential store > documented default, and the printed source is
the store that won, not the highest store that merely holds a key. Presence wins, not
non-emptiness: an exported NAME= overrides the store with an empty string and is reported honestly.
`source` is what the stores support; `READS` is what the reader does
Most consumers read exactly one store, so a source word alone would assert a provenance the tool
cannot verify. Each row therefore prints READS: env for a direct env::var, caller-map for a
map the caller supplies, unknown for a computed name. A row whose value came only from the
credential store while its reader calls env::var is named in a warning under the table — a real
case that used to print a flat, confident dotenv. The Layer column is not that signal: it
records where a read lives, not which store it consults.
Every row in the files half also carries READ, and the cell names the binary where one can
be derived. Attributing a value to a file and printing its origin asserts the value is in force;
when nothing reads it, that assertion is positive confirmation of something false. A clean install
found five keys in exactly that state, and a later one on a headless box found three more reporting
READ: yes whose only reader is the GUI, which will never run there. A NO is followed by what
reads the key's environment variable instead; policy.* keys are exempt, having their own gate.
The default env table discloses which venues and tiers this box holds credentials for
The registry declares the whole {VENUE}_{TIER}_API_* grid, so the table names every one of
those keys and marks each <set> or <unset>. No value can leak: redaction happens inside the
resolver rather than in either printer, so --json cannot leak what the tables hide, and a
secret-shaped row prints <set>/<unset> while still reporting its true source. --changed-only is
the wrong instinct here and reads like the right one — it keeps precisely the rows something set, so
on this table it prints exactly that list. The narrow view for a paste is --filter.
Store keys matching no registry row print as a complement under the env table — credential-shaped ones counted and never named, everything else named outright — because a typo'd variable used to look exactly like one that was never set.
config check — the pre-flight
usage: vike-cli config check [--json] [--strict]
--json the same report as one JSON object
--strict promote every WARNING to a failure. For an operator asking `is this box fully
configured?`, NOT for a systemd ExecStartPre= — it refuses a paper deployment
over an absent-but-legitimate configuration
exit 0 = nothing is broken; exit 1 = something the operator believes is configured is notThe three levels are not severities anyone tuned. Each row is an argument, decided by the same rule startup preflight applies: refuse when a silent difference would leave the operator believing a protection is armed when it is not; degrade when "unconfigured" is a legitimate state the operator may have chosen.
| finding | level |
|---|---|
| a removed environment variable is set | fail — the operator asked for a ceiling and does not have it |
| a settings file fails to load | fail — the same refusal a daemon performs |
| the credential store exists and cannot be read | warn, or fail when this box is armed for live |
VIKE_SETTINGS_DIR names a path that is not a directory | fail — set-but-unhonoured |
| no settings directory at all | warn — the ordinary state of a fresh clone and of CI |
| the credential store is absent | ok — absent credentials are the live gate |
| the store is readable beyond its owner | warn — a finding is never a refusal |
a pre-one-store <project>/.env beside an absent store | warn |
The absent-store row is what makes the verb installable at all: every shipped unit is a paper deployment with an empty store, so failing there would make a correct fresh install unstartable.
The one arming-aware row reads two independent sources and never the credential store — the
store is the thing that could not be read. One is the venue-scoped arming table over the process
environment; the other is the resolved flags.tradehub_live, which is node-scoped and so speaks for
the switchless venues that pick their tier from a credential prefix inside the unreadable file. A
settings tree that did not load yields an undetermined verdict, which refuses: answering "not
armed" from a missing signal is the bug this row exists to catch. See
risk and arming.
Output is OK/WARN/FAIL per finding, then N error(s), M warning(s)., followed by a verdict
sentence when anything failed or warned. On failure one line also goes to stderr, so
journalctl -p err catches an ExecStartPre= refusal without anyone reading the whole report; the
report stays on stdout whatever the verdict.
On one shipped layout --strict calls a correct install an error
A recorder needs no credentials, so its runbook creates a <project>/.env and no secrets.env.
Absent store plus a <project>/.env is exactly the pair the legacy-store warning fires on — a
pre-one-store leftover and a systemd EnvironmentFile are the same file to anything that does not
read it. So --strict there exits 1 with a single credential store warning. That is audit mode
being literal; the units run the default disposition.
Both verbs answer --help on stdout with exit 0, at the verb level and at the show/check level
alike — see global flags. For the credential store itself,
vike-cli secrets is the surface that names keys.
init
Scaffold the user-content directory with runnable examples in every folder, print the map, and never overwrite something you edited.
secrets
Inspection of the one credential store — where it is, which key names it holds, which accounts those names resolve to, an empty grid to start one from — and the one narrow writer: set a single key, value from stdin or an environment variable, never from the command line.