cfu CLI Reference
cfu is the Confµgami command-line tool.
Use it to validate configuration and definition files, inspect the workspace, view configurations and definitions as a tree, export merged configurations, format files, generate
schemas and code, and run the editor and AI integration servers.
Started without a command, it opens an interactive terminal UI (cfu tui).
This reference covers all commands.
Usage
cfu$ cfu <command> [options] [PATH]...
A PATH argument is a start path, a file or a directory cfu searches upward from for the enclosing workspace root.
Most commands then process that whole workspace, not just the given paths, so you rarely need to name individual files.
Every PATH defaults to the current directory.
Global Options
These options are accepted by every command:
-v, --verbose <LEVEL>-
Changes the log level to one of
Error,Warn,Info,Debug,Trace. -q, --quiet-
Disables all log messages.
--no-auto-update-
Disables the background check for a newer release on startup. The auto-update currently works only inside the Vector network.
The
CONFUGAMI_AUTO_UPDATEenvironment variable set tofalse,0, oroffdisables the check for every call, and a.confunext to the executable disables it for that installation, see Automatic Updates. --color <auto|always|never>-
When to color the output.
auto, the default, colors only while the output is a terminal,alwayscolors into a pipe or a file too, andneverkeeps it plain.The
NO_COLORenvironment variable set to any non-empty value disables color as well, but an explicit--colorwins over it. The machine-readable formats on stdout are never colored. -h, --help-
Prints the built-in help.
cfu <command> -hshows the help of a command. -V, --version-
Prints the installed version of
cfu.
Every command that processes the workspace also accepts:
-t, --continuous-
Runs the command repeatedly whenever a definition, configuration, or
.confufile in the workspace changes. Unrelated files are ignored, so a build or a log write triggers nothing. Useful as a live validation loop next to your editor.
The diagnostic-reporting commands cfg validate, def validate, and format additionally accept:
--output-format <text|json|sarif>-
Renders the diagnostics as a machine-readable report on stdout instead of the human text on stderr. Defaults to
text, the human diagnostics.jsonis a flat diagnostic list,sarifa SARIF 2.1.0 log that CI code scanning turns into inline annotations on the changed lines.A machine-readable format replaces the diagnostic text, it does not duplicate it, so
--output-format jsonpipes straight into a JSON tool. The progress and summary lines stay on stderr either way, as does the error the command fails with.Positions are 1-based lines and byte columns, like the printed
file:line:col, and paths are relative to the directorycfuwas started in, which is what the CI annotators match against. The report is written for a failed run too, which is the run a pipeline cares about, and agrees with the exit code.sarifsetsexecutionSuccessfulto false only for a run that failed without a finding to explain it, such as one with nothing to validate.formatreports the syntax errors of files it cannot parse, and with--checkthe files that are not formatted.
The validating commands cfg validate and def validate additionally accept:
-D, --deny <warnings|infos>-
Treats the diagnostics of that severity as errors, so a run that only reports them still fails. Without the flag only errors fail a run.
warningsdenies every warning,infosdenies every diagnostic, the informational ones included.The gate is evaluated after every validation stage reported, so one run lists everything that has to be fixed instead of one stage per run. The failure names the count and the flag, so a denied run stays distinguishable from a run with real errors.
$ cfu cfg validate --output-format sarif . > cfu.sarif
$ cfu cfg validate -D warnings .
Command: cfg validate
Validates the configuration files of the discovered CfgSpaces against their definitions and prints diagnostics with file, line, and column. The definitions are validated first, so a broken definition fails the run before any configuration is checked.
$ cfu cfg validate [OPTIONS] [PATH]...
$ cfu cfg validate -t .
Accepts -t, --continuous, --output-format, and -D, --deny.
Remember that a clean run only covers the files that were discovered; use cfu workspace list to confirm what that is.
Command: cfg export-merged
Exports the merged configuration of a CfgSpace as a single configuration file. It validates first and writes nothing while the definition or the configuration has errors. This is the resolved view your consuming software sees after cross-file merging and the fastest way to answer "who set this value?".
$ cfu cfg export-merged [OPTIONS] [PATH]...
Unlike the other commands, the start path here selects what is exported: it has to resolve to a single CfgSpace, and a path spanning more than one is an error.
-o, --output <OUTPUT>-
The merged configuration file to write to, or if not specified the JSON output is written to stdout. The file extension selects the format:
.jsonwrites strict JSON,.json5writes human readable JSON5. Any other file extension is an error. --with-origin-
Adds
_originannotations, so every value records the file and the position it came from. See Origin Annotations for the format. --with-type-
Adds a
$typewith the definition type path to every element below the definition roots, for a tool that maps the output back to its types without loading the definition. A union element carries the type of its member. Requires--with-origin.
Accepts -t, --continuous.
$ cfu cfg export-merged --with-origin .
Command: cfg inspect
Prints the merged configuration of every discovered CfgSpace as a tree: the entities and structs with their values, and the required properties that no file configures. It is the non-interactive form of what the terminal UI draws, so it pipes, greps, and diffs.
$ cfu cfg inspect [OPTIONS] [PATH]...
--at <PATH>-
Shows only the elements at this instance path, for example
/PhotonDef/Photon/Lamp1. The path is matched as a prefix and case-insensitively, so a path that names a list prints every element in it. A path that matches nothing is an error. --depth <N>-
Prints at most
Nlevels below each shown element. Unlimited by default;--depth 0reduces the output to one line per CfgSpace root, which is the survey of a large workspace. --origin-
Appends the file name and line each value comes from. In a mergeable configuration this is the file that won the merge for that value, so it answers "who set this?" without exporting anything.
Accepts -t, --continuous.
Values are printed in full, and a required property that nothing configures shows as a [Missing] row with its multiplicity and type.
A configuration with errors is printed anyway and the command then fails: a broken configuration is exactly when the tree is worth looking at.
Use cfu cfg validate for the diagnostics themselves.
$ cfu cfg inspect --origin .
CfgSpace: /work/lights
PhotonDef [Configuration] base.cfg.json5, tuning.cfg.json5
└── Photon [Entity]
├── Brightness = 80 tuning.cfg.json5:4
├── lamps (2 x Lamp) [List]
│ ├── Lamp1 (Lamp) [Entity] base.cfg.json5:7
│ └── Lamp2 (Lamp) [Entity] base.cfg.json5:11
└── mount (1..1 Mount) [Missing]
Command: def list
Lists the definitions of the workspace with their configuration file mode and their file.
$ cfu def list [OPTIONS] [PATH]...
Accepts -t, --continuous.
The listed name is the definitionName, which is the value a configuration binds to with $definition, not the file name.
The mode is the definition’s configurationFileMode, so the list also answers whether a configuration of that definition may be split across files.
$ cfu def list .
Name FileMode File
Photon MultipleFiles /work/defs/Photon.def.json5
TurnIndicator SingleFile /work/defs/TurnIndicator.def.json5
Command: def validate
Validates the definition files of the workspace and prints diagnostics with file, line, and column.
Configuration development rarely needs it directly (cfg validate checks the definitions anyway), but it isolates definition problems from configuration problems.
$ cfu def validate [OPTIONS] [PATH]...
Accepts -t, --continuous, --output-format, and -D, --deny.
Command: def inspect
Prints the resolved definitions as a tree: the entities, structs, and unions with their multiplicity, and every parameter with its type, range, and default. This is the definition the configuration author has to fill in.
$ cfu def inspect [OPTIONS] [PATH]...
--def <NAME>-
Inspects only this definition, named by its
definitionName(the$definitionvalue). All definitions of the workspace by default. An unknown name is an error that lists the known ones. --at <PATH>-
Shows only the elements at this type path, for example
PhotonDef::Photon::Lamp. Matched as a prefix and case-insensitively. --depth <N>-
Prints at most
Nlevels below each shown element.
Accepts -t, --continuous.
$ cfu def inspect --def PhotonDef --depth 2 .
PhotonDef (1.0) [Definition] Photon.def.json5
└── photon (0..1 PhotonDef::Photon) [Entity]
├── brightness 0..1 u8 [0..100] default 50
├── mode 1..1 enum (Eco | Full)
└── lamps (0..* PhotonDef::Photon::Lamp) [Entity]
Command: def generate
Generates JSON Schemas and language bindings from definition files. The surrounding workflow is described in the developer manual, Code Generation.
$ cfu def generate [OPTIONS] [PATH]...
-i, --definition <DEFINITION>-
The definition to generate: a definition name or a path to a
.deffile or directory. Paths are resolved relative to the current working directory and are not used for workspace discovery; the definition must be part of the workspace. May be given multiple times; at least one is required. --schema-output <DIR>-
When set, generates JSON Schemas into this directory.
--rust-code-output <PATH>-
Output directory for generated Rust code, or the
.rsfile to write. --rust-opt-derive-serialize-
Adds serde::Serialize to the derived traits.
--python-code-output <PATH>-
Output directory for generated Python code, or the
.pyfile to write. --python-output-style <STYLE>-
Python output style,
chiisaiorforge. Defaults tochiisaiwhen--python-code-outputis set.
Accepts -t, --continuous.
$ cfu def generate -i SensorEcu --rust-code-output ./generated/rust .
Command: format
Formats .cfg, .def, and .confu files into the canonical Confµgami style.
$ cfu format [OPTIONS] [PATH]...
--check-
Reports files that are not formatted and exits with an error instead of changing them. Meant for CI.
Accepts -t, --continuous and --output-format.
Command: init
Scaffolds a new workspace in the current directory: a .confu workspace root, an .editorconfig for JSON/JSON5, and an example definition plus a matching configuration.
It runs git init unless the directory or an ancestor is already a git repository, then formats and validates the created files.
The command refuses to run when the directory already contains a .confu.
$ cfu init [--name <DefinitionName>]
--name sets the definition name for the example files (UpperCamelCase, default Example).
Command: support
Creates a support package for a bug report or feature request: a cfu-supportPackage-<unixtime>.zip in the current directory.
It bundles the discovered .cfg/.def/.confu files (external definitions land under .externals/) together with the local exec and crash logs from ~/.confugami and a
.confugami/cfu-support-info.json5 snapshot of the current environment.
The path of the created package is printed to stderr.
Once the package is written, those local logs are pruned to the most recent exec and crash log, so the next package is not dominated by already-reported logs.
$ cfu support [PATH]...
Command: tui
Opens the interactive terminal UI on the workspace of the given paths.
This is the default command: a bare cfu is cfu tui ..
$ cfu tui [PATH]...
$ cfu tui ../other-workspace
It is a read-only viewer with one tab per area:
-
the workspace overview,
-
the configurations,
-
the definitions as tree of definitions,
-
and the diagnostics of the whole workspace.
The bottom line of the UI lists the available keys.
Ctrl+F opens a fuzzy search, matched like the workspace symbols of the editor integration, with one tab per area:
-
Configurations: the configuration elements of the CfgSpace selected on the Configurations tab, and their parameters, by name, entity name, and id,
-
CfgSpaces: the discovered CfgSpaces, by path,
-
Definitions: the types of the definitions, their elements and parameters, by type name, each type listed once with its type path.
←→ or Tab switch between them, the query stays.
Enter on the CfgSpace selector opens it on its CfgSpaces tab, to pick another CfgSpace or All CfgSpaces by name.
Selecting a hit switches to the tab that shows it and selects the element there, expanding the tree as needed.
The UI refreshes the workspace on its own: it reloads whenever a definition, configuration, or .confu file changes.
o adds the origin of every value, the file name and line it was merged from, as a column of the parameter pane.
With the output redirected (a pipe or a file, for example in CI) there is no terminal to draw on, so cfu prints its help.
Command: workspace list
Shows the discovered workspace roots, CfgSpaces, and the .cfg/.def/.confu folder tree.
$ cfu workspace list [OPTIONS] [PATH]...
Accepts -t, --continuous.
This is the discovery check: after creating a new configuration file, confirm it appears here. A file that is not listed is not validated, see Pitfalls.
Command: lsp
Starts the Language Server Protocol server for editor integration. Editors launch this themselves; you do not run it by hand. See Setting Up the IDE.
$ cfu lsp --stdio
Command: mcp
Starts the Model Context Protocol server for LLM and agent integration, or installs it into an editor’s MCP configuration.
$ cfu mcp --stdio [--no-auto-update]
$ cfu mcp --install [CLIENT]... [--global]
--stdio-
Starts the MCP server communicating over stdio. Editors and agents launch it this way; run it yourself only to test the server.
--install [CLIENT]…-
Installs the server registration instead of starting it. Optional client names are
claude,copilot,opencode, andintellij; the default installs for Claude Code and GitHub Copilot.An existing registration is reported as updated and the config file is backed up to
<file>.bakbefore it is rewritten. A registration that already matches is left untouched, so re-running the install is free of side effects. --global-
With
--install, targets the user-level (global) configuration instead of the project.
$ cfu mcp --install claude
cfu mcp --help prints the manual registration snippets for each supported client.
The written registration launches the server with --no-auto-update, so a server the editor keeps open for a whole session does not replace its own binary underneath itself, see
Automatic Updates.
Command: server
Starts a local HTTP server that serves the definition and configuration models as JSON and pushes live updates over Server-Sent Events whenever the input files change.
$ cfu server [OPTIONS] [PATH]...
-p, --port <PORT>-
Port to listen on. Defaults to
8787. If the port is already in use, a free port is chosen automatically and printed on startup.
The endpoints are:
- GET /def/model - the parsed definition model
- GET /cfg/model - the merged configuration model
- GET /cfg/export - the configuration graph export
- GET /events - Server-Sent Events stream for live updates
The same server can run inside the language server (LSP) instead, see Setting Up the IDE.
Command: completions
Prints a shell completion script for cfu to stdout.
Install it once and Tab completes the nested subcommands and the long option names.
It also puts commands you did not know exist in front of you.
The script is a snapshot of the version that generated it, so evaluate it from your shell startup file to have it rebuilt at every shell start.
$ cfu completions <SHELL>
SHELL is one of bash, elvish, fish, powershell, or zsh.
~/.bashrceval "$(cfu completions bash)"
$PROFILEcfu completions powershell | Out-String | Invoke-Expression
zsh, fish, and elvish take the same line with their own name and startup file.
A static file (cfu completions bash > /etc/bash_completion.d/cfu) works too, but has to be regenerated after every upgrade.
Exit Status
- 0
-
cfuexecuted successfully. - 1
-
An error was detected during execution.
A reader that closes the output pipe early, as head, grep -m1 and a pager do, ends the run with status 0 and no further output.
The remaining diagnostics are dropped with the pipe, so a script that decides on the exit status has to read the whole output, or take the machine-readable report of
--output-format instead.