Wheelhouse docs

Every click shows its commands#

Before a Wheelhouse editor changes anything, it renders the exact set and delete commands it would run, in the spelling the router's own CLI accepts, with a copy button. Nothing is hidden behind the form: the commands are the change, and staging them is the only thing the button does. This is the property that makes the rest of the product checkable — a screen that shows you its commands cannot quietly do something else, because you can read the commands, copy them, and run them yourself.

What you see, and where#

WhereWhat it renders
Any editor's CLI panelThe commands that this form, as currently filled in, would stage.
An empty pageThe commands that would populate it, instead of the words "no data" — the third of the four rules in docs/ui.md.
The Commit Bar's working diffEvery staged operation, one per line, marked + for a set and for a delete, plus one block headed Copy into a configure session.
The Config tree page, All commandsThe whole running configuration as set lines.
GET /api/stagedThe same lines as JSON, in a commands array beside the structured ops.

The Commit Bar's list is the one that matters most, because it is the last thing you see before a commit — ui/src/components/CommitBar.tsx.

One spelling, rendered twice#

The commands are produced independently in two places: by the agent, for GET /api/staged and for the audit log, and by the browser, for the diff you are looking at. Both have to spell a path the same way or the preview would not be the command that ran.

The rule both implement: a path element containing a space, a tab, a single quote or a double quote is wrapped in single quotes with embedded single quotes escaped, which is what the router's own tab completion produces. The comment in format.ts records why a double quote is included — description WAN "primary" left bare is two shell words, so the preview would not have been the command.

An empty path element is spelled '' and refused before it can be staged: POST /api/stage answers 400 for an operation with no path, or with an empty element in one, rather than letting it fail later at commit with a message that does not name the request (agent/main.go, handleStage).

Taking the commands to a terminal#

The lines are ordinary configuration commands. On the router:

bash
ssh vyos@<router>
configure
set interfaces ethernet eth1 description 'primary uplink'
set interfaces ethernet eth1 address 203.0.113.2/24
bash
compare        # the same diff the Commit Bar was showing you
commit
exit

That round trip is the point. If a page's CLI panel and the router's own compare disagree, the page is wrong, and you have a bug report with the evidence in it.

What the commands do not cover#

Every operation Wheelhouse stages is a set or a delete against the configuration tree. There is no second, out-of-tree control plane in the shipped agent: it imports no netlink library and never runs a program — grep -rn "os/exec" agent/ finds nothing, and agent/go.mod lists five direct dependencies, none of them netlink. Everything reaches the router over its HTTP API.

Two more honest limits:

  • A set is not a validation. The commands are what the router will be asked to run. Whether it accepts them is decided at commit, and a rejected commit returns the router's own words — see The Commit Bar.
  • A rendered command can contain a secret. A pre-shared key you just typed appears in the diff, because a preview that shows you [redacted] for your own change is not a preview. It is redacted for anyone below the operator role (agent/main.go, the redactSecrets(RoleOperator, …) wrapper on GET /api/staged).

See also#

Checked against#

agent/staging.go · agent/main.go · agent/go.mod · ui/src/lib/format.ts · ui/src/components/CommitBar.tsx · ui/src/components/ui.tsx · docs/ui.md · PLAN.md §4

Updated 2026-09-02 concepts cli transparency