Gum gum-cli
Reference guide for GumCli — the headless command-line tool for Gum projects. Load this when working on gumcli commands (new, check, codegen, codegen-init), Gum.ProjectServices, HeadlessErrorChecker, ProjectLoader, HeadlessCodeGenerationService, CodeGenerationAutoSetupService, or the FormsTemplateCreator.
install
source · Clone the upstream repo
git clone https://github.com/vchelaru/Gum
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/vchelaru/Gum "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/gum-cli" ~/.claude/skills/vchelaru-gum-gum-cli && rm -rf "$T"
manifest:
.claude/skills/gum-cli/SKILL.mdsource content
GumCli Reference
What It Is
GumCli (
gumcli) is a cross-platform .NET 8.0 console app that lets developers create, validate, and generate code for Gum projects without the WPF editor. Primary use cases: CI pipelines, scripting, editor integrations.
Location:
Tools/Gum.Cli/
Depends on: Gum.ProjectServices → GumCommon
Commands
| Command | Purpose |
|---|---|
| Create a new project. Templates: (default, includes all Forms UI controls) or (minimal). |
| Validate all elements (.gusx, .gutx, .gucx) that belong to the project. Human-readable or JSON output. Use this for post-write validation of any element file, not just the .gumx. |
| Generate C# code. Requires . Per-element error check gates generation. |
| Auto-detect , derive namespace and output library, write . Use when the Gum project is not inside the MonoGame project directory. |
| Generate missing bitmap font files (.fnt + .png). Windows-only (bmfont.exe). |
Exit codes: 0 = success, 1 = errors found / generation blocked, 2 = load failure, bad args, or non-Windows (fonts).
Architecture
Program.cs ├── NewCommand → ProjectCreator / FormsTemplateCreator ├── CheckCommand → ProjectLoader → HeadlessErrorChecker ├── CodegenCommand → ProjectLoader → HeadlessErrorChecker (gates) → HeadlessCodeGenerationService ├── CodegenInitCommand → CodeGenerationAutoSetupService └── FontsCommand → ProjectLoader → HeadlessFontGenerationService (Windows-gated)
Each command class has a static
Create() returning a System.CommandLine Command with handler, then a static Execute() doing the work.
CLI-specific adapters:
— implementsConsoleCodeGenLogger
, writes to stdout/stderrICodeGenLogger
— implementsHeadlessNameVerifier
for C# name validationINameVerifier
Gum.ProjectServices
The headless service library GumCli depends on. All logic lives here; the CLI just wires it together.
Key types:
| Type | Role |
|---|---|
/ | Loads ; detects malformed XML; returns with fatal errors and non-fatal |
/ | Validates base types, behaviors, parent refs, variable types. Delegates from tool's . |
/ | Creates blank projects with subfolder structure |
/ | Extracts embedded Forms template resources |
| Orchestrates per-element code file generation |
| Walks up to find , derives , namespace, output library |
| Loads/saves |
| POCO: , , (/) |
Non-obvious:
HeadlessErrorChecker is not a duplicate of the tool's ErrorChecker — the tool's ErrorChecker delegates to HeadlessErrorChecker. Zero duplication by design.
HeadlessErrorChecker accepts a second constructor overload taking IEnumerable<IAdditionalErrorSource> for extensibility; the CLI uses the single-argument overload.
HeadlessNameVerifier only implements real logic in IsValidCSharpName; all other INameVerifier methods return true unconditionally. This is intentional — the CLI only needs C# name validation for codegen.
ProjectLoader runs DetectSilentlyDroppedContent after deserialization to catch incorrect XML element names (e.g., <States> instead of <State>, <InstanceSave> instead of <Instance>) that XmlSerializer silently ignores. Without this, AI-generated files with wrong structure load as empty elements with no error.
CodeGenerationAutoSetupService detects MonoGame vs non-MonoGame projects by scanning for <PackageReference Include="MonoGame.Framework. or nkast.Xna.Framework in the .csproj, then sets OutputLibrary accordingly. Namespace falls back to the .csproj filename (dots/dashes/spaces replaced with underscores) when <RootNamespace> is absent.
CodeGenerationAutoSetupService has two Run overloads: Run(gumxFilePath) for auto-detection, and Run(gumxFilePath, explicitCsprojPath) for when the caller already knows the .csproj path. The explicit overload validates the file exists and skips directory walking entirely; all namespace/OutputLibrary derivation logic is shared via the private BuildResultFromCsprojDirectory helper.
Font files are named like
Font18Arial.fnt and Font18Arial_0.png (size+name convention, zero-indexed). Always use gumcli fonts <project.gumx> to generate missing bitmap fonts — never create .fnt files manually.
Codegen Flow (non-obvious details)
iterates elements individually (not viacodegen
) so it can run per-element error checks first;GenerateCodeForAllElements
exists onGenerateCodeForAllElements
but the CLI does not call itHeadlessCodeGenerationService- Only Screens and Components are generated; StandardElements are intentionally excluded
- Errors (
) block generation for that element; warnings print to stderr but do not blockErrorSeverity.Error
cache is managed at the CLI level (enabled before the loop, disabled inObjectFinder.Self
)finally- If
is missing,ProjectCodeSettings.codsj
attemptscodegen
auto-detection first and writes the settings file before continuing; exit code 2 only if auto-detection also failsCodeGenerationAutoSetupService - When
is specified,--element
is passed socheckForMissing: true
auto-generates any referenced elements whose code files do not yet exist; full-run mode skips that checkGenerateCodeForElement
exits with code 2 (not 1) if settings already exist andcodegen-init
is absent--force
Key Files
| File | Purpose |
|---|---|
| Entry point, assembles RootCommand |
| One file per command |
| Headless project loading |
| All headless error checks |
| Headless codegen orchestration |
| Main codegen engine (~5400 lines) |
| CLI command tests |
| Service layer tests (36 tests) |
Testing Notes
is a singleton — tests disable parallel execution (ObjectFinder
)TestAssemblyInitialize
pre-populatesBaseTestClass
with standard elements and handlesGumProjectSave
cleanupObjectFinder.Self