gum-cli
$
npx mdskill add vchelaru/Gum/gum-cliExecute headless Gum project creation, validation, and code generation.
- Builds projects, validates elements, and generates C# code without a GUI.
- Depends on Gum.ProjectServices and integrates with GumCommon.
- Uses command parameters to determine specific actions like templates or output paths.
- Outputs human-readable reports or structured JSON data for CI pipelines.
SKILL.md
.github/skills/gum-cliView on GitHub ↗
--- name: gum-cli description: 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. --- # 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 | |---------|---------| | `gumcli new <path> [--template]` | Create a new project. Templates: `forms` (default, includes all Forms UI controls) or `empty` (minimal). | | `gumcli check <project.gumx> [--json]` | 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. | | `gumcli codegen <project.gumx> [--element <name>...]` | Generate C# code. Requires `ProjectCodeSettings.codsj`. Per-element error check gates generation. | | `gumcli codegen-init <project.gumx> [--force] [--csproj <path>]` | Auto-detect `.csproj`, derive namespace and output library, write `ProjectCodeSettings.codsj`. Use `--csproj` when the Gum project is not inside the MonoGame project directory. | | `gumcli fonts <project.gumx>` | 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:** - `ConsoleCodeGenLogger` — implements `ICodeGenLogger`, writes to stdout/stderr - `HeadlessNameVerifier` — implements `INameVerifier` for C# name validation ## Gum.ProjectServices The headless service library GumCli depends on. All logic lives here; the CLI just wires it together. **Key types:** | Type | Role | |------|------| | `ProjectLoader` / `IProjectLoader` | Loads `.gumx`; detects malformed XML; returns `ProjectLoadResult` with fatal errors and non-fatal `LoadErrors` | | `HeadlessErrorChecker` / `IHeadlessErrorChecker` | Validates base types, behaviors, parent refs, variable types. Delegates from tool's `ErrorChecker`. | | `ProjectCreator` / `IProjectCreator` | Creates blank projects with subfolder structure | | `FormsTemplateCreator` / `IFormsTemplateCreator` | Extracts embedded Forms template resources | | `HeadlessCodeGenerationService` | Orchestrates per-element code file generation | | `CodeGenerationAutoSetupService` | Walks up to find `.csproj`, derives `CodeProjectRoot`, namespace, output library | | `CodeOutputProjectSettingsManager` | Loads/saves `ProjectCodeSettings.codsj` | | `ErrorResult` | POCO: `ElementName`, `Message`, `Severity` (`Warning`/`Error`) | **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) - `codegen` iterates elements individually (not via `GenerateCodeForAllElements`) so it can run per-element error checks first; `GenerateCodeForAllElements` exists on `HeadlessCodeGenerationService` but the CLI does not call it - Only Screens and Components are generated; StandardElements are intentionally excluded - Errors (`ErrorSeverity.Error`) block generation for that element; warnings print to stderr but do not block - `ObjectFinder.Self` cache is managed at the CLI level (enabled before the loop, disabled in `finally`) - If `ProjectCodeSettings.codsj` is missing, `codegen` attempts `CodeGenerationAutoSetupService` auto-detection first and writes the settings file before continuing; exit code 2 only if auto-detection also fails - When `--element` is specified, `checkForMissing: true` is passed so `GenerateCodeForElement` auto-generates any referenced elements whose code files do not yet exist; full-run mode skips that check - `codegen-init` exits with code 2 (not 1) if settings already exist and `--force` is absent ## Key Files | File | Purpose | |------|---------| | `Tools/Gum.Cli/Program.cs` | Entry point, assembles RootCommand | | `Tools/Gum.Cli/Commands/` | One file per command | | `Gum.ProjectServices/ProjectLoader.cs` | Headless project loading | | `Gum.ProjectServices/HeadlessErrorChecker.cs` | All headless error checks | | `Gum.ProjectServices/CodeGeneration/HeadlessCodeGenerationService.cs` | Headless codegen orchestration | | `Gum.ProjectServices/CodeGeneration/CodeGenerator.cs` | Main codegen engine (~5400 lines) | | `Tests/Gum.Cli.Tests/` | CLI command tests | | `Tests/Gum.ProjectServices.Tests/` | Service layer tests (36 tests) | ## Testing Notes - `ObjectFinder` is a singleton — tests disable parallel execution (`TestAssemblyInitialize`) - `BaseTestClass` pre-populates `GumProjectSave` with standard elements and handles `ObjectFinder.Self` cleanup
More from vchelaru/Gum
- bump-nuget-versionBump the NuGet package versions for all 12 Gum projects (11 libraries + GumCli). Queries NuGet to check if a version exists for today, then sets the new version to YYYY.M.D.V where V increments from the latest published version today (or starts at 1). Creates a release branch named ReleaseCode_YYYY_M_D_V, commits the changes, and pushes. Run this before triggering the nuget release workflow.
- gum-docs-writingReference guide for writing Gum documentation in GitBook markdown. Load when writing or editing docs/ files, adding pages to SUMMARY.md, using GitBook hints/figures, linking between pages, or adding images.
- gum-forms-behaviorsCovers Gum's behaviors system and the design-time → runtime Forms wrapping lifecycle. Load this when working on BehaviorSave, ElementBehaviorReference, StandardFormsBehaviorNames, FormsUtilities.RegisterFromFileFormRuntimeDefaults, DefaultFromFileXxxRuntime classes, or when investigating why Forms properties cannot be set at design time in the Gum tool.
- gum-forms-controlsReference guide for Forms controls — classes inheriting from FrameworkElement. Load this when working on Button, CheckBox, ListBox, ComboBox, TextBox, ScrollViewer, or any class in Gum.Forms.Controls (or FlatRedBall.Forms.Controls). Also load when working on FrameworkElement itself, the Visual/InteractiveGue relationship, state machines, DefaultVisuals, or ReactToVisualChanged.
- gum-forms-default-visualsReference guide for Forms DefaultVisuals — the code-only visual classes that back Forms controls. Load when working on ButtonVisual, any *Visual class in DefaultVisuals/, Styling, DefaultFormsTemplates registration, or building custom code-only Forms visuals.
- gum-forms-itemscontrolReference guide for ItemsControl and ListBox — the Items/ListBoxItems relationship, templates, InnerPanel sync, and gotchas. Load this when working on ItemsControl, ListBox, ListBoxItem, VisualTemplate, FrameworkElementTemplate, Items collection behavior, ListBoxItems desync, or adding/removing items from a list box.
- gum-layout>
- gum-layout-engine>
- gum-localizationReference guide for Gum's runtime localization system — ILocalizationService, CSV/RESX loading, Text vs TextNoTranslate paths, Forms control localization patterns, and gotchas.
- gum-property-assignmentReference guide for how Gum applies variables and sets properties on renderables. Load this when working on ApplyState, SetProperty, SetVariablesRecursively, CustomSetPropertyOnRenderable, font loading, IsAllLayoutSuspended, or isFontDirty.