Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Part XI: The .Design CLI + Interactive TUI

Overview

The CMF provides two interfaces for developers:

  1. Standard CLI -- non-interactive commands for scripting, CI pipelines, and quick scaffolding. Similar to dotnet ef, dotnet new, or ng generate.
  2. Interactive TUI -- a terminal-based modeling session using Spectre.Console. Visual designers for aggregates, features, workflows, and requirements with live code preview.

Both are packaged as a single .NET global tool:

dotnet tool install --global Cmf.Cli

After installation, the cmf command is available system-wide.


Standard CLI Commands

Command Hierarchy

Diagram

cmf new -- Scaffold a New Project

Creates a complete solution structure from a template.

cmf new MyStore --template ecommerce

Templates available:

Template What It Creates Use Case
ecommerce Catalog, Ordering, Identity contexts; Product, Order, Customer aggregates Online store
blog Content, Editorial contexts; BlogPost, Category, Author aggregates Publishing platform
saas Tenancy, Subscription, Identity contexts; Tenant, Plan, User aggregates Multi-tenant SaaS

Generated structure:

MyStore/
├── MyStore.sln
├── Directory.Build.props              ← Quality gates config, analyzer settings
├── .editorconfig                      ← REQ diagnostic severities
├── src/
│   ├── MyStore.Requirements/          ← Empty Feature/Epic stubs per template
│   │   ├── MyStore.Requirements.csproj
│   │   ├── Epics/
│   │   └── Features/
│   ├── MyStore.SharedKernel/          ← Domain value types
│   │   ├── MyStore.SharedKernel.csproj
│   │   └── Result.cs
│   ├── MyStore.Specifications/        ← Empty, waiting for specs
│   │   └── MyStore.Specifications.csproj
│   ├── MyStore.Lib/                   ← Domain model (aggregates, entities)
│   │   ├── MyStore.Lib.csproj
│   │   └── Ordering/
│   ├── MyStore.Infrastructure.Postgres/  ← EF Core + generated repos
│   │   └── MyStore.Infrastructure.Postgres.csproj
│   ├── MyStore.Server/                ← ASP.NET host (API + admin + routing)
│   │   ├── MyStore.Server.csproj
│   │   └── Program.cs
│   └── MyStore.Client/               ← Blazor WASM (page widgets)
│       └── MyStore.Client.csproj
├── test/
│   └── MyStore.Tests/                 ← Test scaffolds
│       └── MyStore.Tests.csproj
└── .github/
    └── workflows/
        └── build.yml                  ← CI pipeline with quality gates

cmf add aggregate -- Create an Aggregate

cmf add aggregate Order --context Ordering

Creates src/MyStore.Lib/Ordering/Order.cs:

namespace MyStore.Lib.Ordering;

[AggregateRoot("Order", BoundedContext = "Ordering")]
public partial class Order
{
    [EntityId]
    public partial OrderId Id { get; }

    // TODO: Add [Property] and [Composition] members
    // TODO: Add [Invariant] methods returning Result

    [Invariant("Order must have a valid state")]
    private Result IsValid()
        => Result.Success(); // Placeholder -- replace with real invariant
}

Also creates src/MyStore.Lib/Ordering/OrderId.cs:

namespace MyStore.Lib.Ordering;

public readonly record struct OrderId(Guid Value)
{
    public static OrderId New() => new(Guid.NewGuid());
}

cmf add command -- Create a Command

cmf add command PlaceOrder --target Order

Creates src/MyStore.Lib/Ordering/Commands/PlaceOrderCommand.cs:

namespace MyStore.Lib.Ordering.Commands;

[Command("PlaceOrder", AggregateRoot = "Order")]
public partial record PlaceOrderCommand
{
    // TODO: Add [Property] members for command data
}

cmf add event -- Create a Domain Event

cmf add event OrderPlaced --source Order

Creates src/MyStore.Lib/Ordering/Events/OrderPlacedEvent.cs:

namespace MyStore.Lib.Ordering.Events;

[DomainEvent("OrderPlaced", SourceAggregate = "Order")]
public partial record OrderPlacedEvent
{
    // TODO: Add [Property] members for event payload
}

cmf add feature -- Create a Feature Requirement

cmf add feature OrderFulfillment --epic DomainModelingEpic

Creates src/MyStore.Requirements/Features/OrderFulfillmentFeature.cs:

namespace MyStore.Requirements.Features;

using MyStore.Requirements.Epics;

/// <summary>
/// Feature: Order Fulfillment
/// Add acceptance criteria as abstract methods returning
/// AcceptanceCriterionResult.
/// </summary>
public abstract record OrderFulfillmentFeature
    : Feature<DomainModelingEpic>
{
    public override string Title => "Order Fulfillment";
    public override RequirementPriority Priority
        => RequirementPriority.Medium;
    public override string Owner => "team";

    // TODO: Add acceptance criteria as abstract methods
    // Example:
    // public abstract AcceptanceCriterionResult OrderCanBePlaced(
    //     UserId customer, ProductId product, int quantity);
}

cmf add story -- Create a Story

cmf add story ProcessPayment --feature OrderFulfillmentFeature

Creates src/MyStore.Requirements/Stories/ProcessPaymentStory.cs:

namespace MyStore.Requirements.Stories;

using MyStore.Requirements.Features;

public abstract record ProcessPaymentStory
    : Story<OrderFulfillmentFeature>
{
    public override string Title => "Process Payment";
    public override RequirementPriority Priority
        => RequirementPriority.Medium;
    public override string Owner => "team";

    // TODO: Add acceptance criteria as abstract methods
}

cmf add saga -- Create a Saga

cmf add saga OrderFulfillment

Creates src/MyStore.Lib/Sagas/OrderFulfillmentSaga.cs:

namespace MyStore.Lib.Sagas;

[Saga("OrderFulfillment")]
public partial class OrderFulfillmentSaga
{
    // TODO: Add [SagaStep] methods with compensating actions
    // Example:
    // [SagaStep(1, Command = "ReserveInventory",
    //     CompensateWith = "ReleaseInventory")]
    // public partial void Step1_ReserveInventory();
}

cmf generate -- Run Source Generation Pipeline

cmf generate

Explicitly triggers all pipeline stages (equivalent to dotnet build but with verbose stage output):

[Stage 0] Metamodel Registration
  Registered: AggregateRoot, Entity, ValueObject, ContentPart,
              AdminModule, PageWidget, Workflow, Feature, Story...

[Stage 1] DSL Validation & Collection
  Found: 3 aggregates, 2 content types, 1 workflow, 4 features
  Validated: 0 errors, 2 warnings (DDD100: Order has no invariants)

[Stage 2] Core Generation
  Generated: Order.g.cs, OrderBuilder.g.cs, OrderConfiguration.g.cs
  Generated: Product.g.cs, ProductBuilder.g.cs, ProductConfiguration.g.cs
  Generated: RequirementRegistry.g.cs (4 features, 12 ACs)

[Stage 3] Cross-Cutting Generation
  Generated: OrdersAdminModule.g.razor, ProductsAdminModule.g.razor
  Generated: OrdersController.g.cs, ProductsController.g.cs
  Generated: EditorialWorkflowStateMachine.g.cs

[Stage 4] Traceability & Diagnostics
  Generated: TraceabilityMatrix.g.cs
  REQ301: OrderFulfillmentFeature.OrderCanBePlaced has no [Verifies] test

Build succeeded. 47 files generated. 1 warning.

cmf validate -- Check Metamodel Constraints Without Generating

cmf validate

Runs Stage 0 and Stage 1 only. Validates all MetaConstraints. Does not generate code.

Validating metamodel constraints...

  Order (AggregateRoot)
    MustHaveId:        PASS (has [EntityId] property)
    MustHaveInvariant: WARN (0 [Invariant] methods)

  OrderLine (Entity)
    MustBeComposed:    PASS (reachable from Order via [Composition])

  BlogPost (AggregateRoot)
    MustHaveId:        PASS
    MustHaveInvariant: PASS (1 invariant)

Validation complete: 0 errors, 1 warning.

cmf migrate -- Generate EF Core Migrations

cmf migrate --name InitialCreate

Wrapper around dotnet ef migrations add with CMF-aware configuration:

Running: dotnet ef migrations add InitialCreate
  --project src/MyStore.Infrastructure.Postgres
  --startup-project src/MyStore.Server

Migration 'InitialCreate' created.
  Tables: Orders, OrderLines, Products, BlogPosts
  Owned types: ShippingAddress (embedded in Orders)

cmf report -- Generate Reports

# Markdown requirement hierarchy
cmf report requirements

# Traceability matrix (markdown, JSON, or CSV)
cmf report traceability --format markdown
cmf report traceability --format json
cmf report traceability --format csv

# Coverage statistics
cmf report coverage

cmf report requirements output:

# Requirements Hierarchy

## Epic: DomainModelingEpic
- **OrderFulfillmentFeature** (3 ACs) [High]
  - ProcessPaymentStory (2 ACs) [Medium]
  - ShipOrderStory (1 AC) [Medium]
- **InventoryManagementFeature** (2 ACs) [Medium]

## Epic: ContentManagementEpic
- **BlogContentFeature** (2 ACs) [High]

Total: 2 epics, 3 features, 3 stories, 10 ACs

cmf report traceability --format markdown output:

# Traceability Matrix

| Requirement | AC | Spec Method | Implementation | Tests | Coverage |
|-------------|-----|-------------|----------------|-------|----------|
| OrderFulfillmentFeature | OrderCanBePlaced | IOrderFulfillmentSpec.PlaceOrder | OrderService.PlaceOrder | 2 | 91% |
| OrderFulfillmentFeature | OrderCanBeCancelled | IOrderFulfillmentSpec.CancelOrder | OrderService.CancelOrder | 1 | 78% |
| OrderFulfillmentFeature | OrderTotalIsCorrect | IOrderFulfillmentSpec.CalculateTotal | OrderService.CalculateTotal | 3 | 95% |

cmf report coverage output:

Requirement Coverage Report
===========================

Overall: 8/10 ACs covered (80%)

OrderFulfillmentFeature:     3/3 ACs (100%)  ████████████████████
InventoryManagementFeature:  1/2 ACs ( 50%)  ██████████░░░░░░░░░░
BlogContentFeature:          2/2 ACs (100%)  ████████████████████
ProcessPaymentStory:         1/2 ACs ( 50%)  ██████████░░░░░░░░░░
ShipOrderStory:              1/1 ACs (100%)  ████████████████████

Interactive TUI: cmf design

The interactive TUI launches a terminal-based modeling session using Spectre.Console. It provides visual designers for the four core CMF activities: domain modeling, feature definition, workflow configuration, and compliance monitoring.

cmf design

TUI Screen Flow

Diagram

Main Menu

┌─────────────────────────────────────────────────────────┐
│                    CMF Design Studio                     │
│                   MyStore (ecommerce)                    │
├─────────────────────────────────────────────────────────┤
│                                                         │
│   > [1] Aggregate Designer     3 aggregates defined     │
│     [2] Feature Wizard         4 features, 12 ACs       │
│     [3] Workflow Builder       1 workflow, 4 stages      │
│     [4] Requirement Dashboard  80% AC coverage           │
│                                                         │
│     [Q] Quit                                            │
│                                                         │
├─────────────────────────────────────────────────────────┤
│  Last build: 2s ago | 0 errors | 2 warnings             │
└─────────────────────────────────────────────────────────┘

Aggregate Designer

The Aggregate Designer provides a tree view of all aggregates in the solution. Selecting an aggregate opens editors for properties, compositions, and invariants, with a live code preview panel.

┌─ Aggregate Designer ────────────────────────────────────┐
│                                                         │
│  Aggregates                   │ Properties              │
│  ─────────                    │ ──────────              │
│  ▼ Ordering Order                   │
│    > Order ◄                  │                         │
│      └─ OrderLine             │ [EntityId] OrderId Id   │
│      └─ PaymentDetails        │ [P] DateTime OrderDate  │
│      └─ ShippingAddress (VO)  │ [P] OrderStatus Status  │
│  ▼ Catalog                    │ [C] List<OrderLine>     │
│    > Product                  │ [C] PaymentDetails      │
│  ▼ Identity                   │ [C] ShippingAddress     │
│    > Customer                 │ [A] CustomerId          │
│                               │                         │
│  [A]dd  [E]dit  [D]elete     │ 4 Invariants defined    │
│                                                         │
├─ Live Code Preview ─────────────────────────────────────┤
│                                                         │
│  [AggregateRoot("Order", BoundedContext = "Ordering")]  │
│  public partial class Order                             │
│  {                                                      │
│      [EntityId]                                         │
│      public partial OrderId Id { get; }                 │
│                                                         │
│      [Property("OrderDate", Required = true)]           │
│      public partial DateTime OrderDate { get; }         │
│                                                         │
│      [Composition]                                      │
│      public partial IReadOnlyList<OrderLine> Lines ...  │
│      ...                                                │
│  }                                                      │
│                                                         │
├─ Generated EF Core ─────────────────────────────────────┤
│  builder.ToTable("Orders");                             │
│  builder.HasKey(x => x.Id);                             │builder.HasMany(x => x.Lines).OnDelete(Cascade);      │builder.OwnsOne(x => x.ShippingAddress, sa => {        │
│      sa.Property(a => a.Street).HasMaxLength(200);      │
│  });                                                    │
│                                                         │
│  [P]roperty  [C]omposition  [I]nvariant  [B]ack        │
└─────────────────────────────────────────────────────────┘

Interactions:

  • Arrow keys navigate the aggregate tree
  • [A]dd opens a prompt: "Add property, composition, or association?"
  • Adding a property prompts for name, type, required, max length
  • The Live Code Preview updates in real-time as properties are added
  • The Generated EF Core panel shows what the source generator will produce
  • [I]nvariant opens the invariant editor

Adding a property:

┌─ Add Property ──────────────────────────────────────────┐
│                                                         │
│  Name:     [Notes                    ]                  │
│  Type:     [string                   ]  (tab: suggest)  │
│  Required: [x] Yes  [ ] No                              │
│  MaxLength: [500                     ]                  │
│                                                         │
│  Preview:                                               │
│  [Property("Notes", Required = true, MaxLength = 500)]  │
│  public partial string Notes { get; }                   │
│                                                         │
│  [Enter] Confirm   [Esc] Cancel                         │
└─────────────────────────────────────────────────────────┘

Feature Wizard

The Feature Wizard provides guided creation of epics, features, stories, and tasks with acceptance criteria prompts.

┌─ Feature Wizard ────────────────────────────────────────┐
│                                                         │
│  Step 1 of 3: Select or Create Epic                     │
│                                                         │
│  Existing Epics:                                        │
│  > DomainModelingEpic         (5 features)              │
│    ContentManagementEpic      (2 features)              │
│    [+] Create New Epic                                  │
│                                                         │
│  [Enter] Select   [N]ew Epic   [Esc] Cancel             │
└─────────────────────────────────────────────────────────┘

After selecting an epic:

┌─ Feature Wizard ────────────────────────────────────────┐
│                                                         │
│  Step 2 of 3: Define Feature                            │
│  Parent: DomainModelingEpic                             │
│                                                         │
│  Name:     [InventoryManagement      ]                  │
│  Title:    [Inventory tracking and stock management  ]  │
│  Priority: [High        ] (Critical/High/Medium/Low)    │
│  Owner:    [warehouse-team           ]                  │
│                                                         │
│  [Enter] Next: Define Acceptance Criteria               │
└─────────────────────────────────────────────────────────┘

Acceptance criteria definition:

┌─ Feature Wizard ────────────────────────────────────────┐
│                                                         │
│  Step 3 of 3: Acceptance Criteria                       │
│  Feature: InventoryManagementFeature                    │
│                                                         │
│  Defined ACs:                                           │
│  1. StockIsDecrementedOnOrder(ProductId, int quantity)  │
│  2. OutOfStockPreventsOrder(ProductId)                  │
│                                                         │
│  Add AC:                                                │
│  Method name: [LowStockAlertSent              ]        │
│  Parameters:                                            │
│    1. [ProductId product    ] [+] Add param             │
│    2. [int threshold        ]                           │
│    3. [Email alertRecipient ]                           │
│                                                         │
│  Preview:                                               │
│  public abstract AcceptanceCriterionResult              │
│      LowStockAlertSent(                                 │
│          ProductId product,                              │
│          int threshold,                                  │
│          Email alertRecipient);                          │
│                                                         │
│  [Enter] Add AC   [F]inish Feature   [Esc] Cancel       │
└─────────────────────────────────────────────────────────┘

On finish, the wizard generates the feature file and opens it in the configured editor:

Created: src/MyStore.Requirements/Features/InventoryManagementFeature.cs
  Epic: DomainModelingEpic
  ACs: StockIsDecrementedOnOrder, OutOfStockPreventsOrder, LowStockAlertSent
Opening in editor...

Workflow Builder

The Workflow Builder provides a visual editor for workflow stages, transitions, and gates -- all in the terminal.

┌─ Workflow Builder ──────────────────────────────────────┐
│                                                         │
│  Workflow: EditorialWorkflow (BlogPost)                 │
│                                                         │
│  Stages:                                                │
│  ┌───────┐    ┌────────┐    ┌─────────────┐    ┌─────┐ │
│  │ Draft ├───>│ Review ├───>│ Translation ├───>│ Pub │ │
│  └───┬───┘    └────┬───┘    └──────┬──────┘    └─────┘ │
│      │             │               │                    │
│      └─────────────┘               │                    │
│        (reject: back               │                    │
│         to Draft)                  │                    │
│                    └───────────────┘                    │
│                      (reject: back                      │
│                       to Review)                        │
│                                                         │
│  Gates:                                                 │
│  Draft -> Review:      RequiresRole("editor")           │
│  Review -> Translation: RequiresRole("reviewer")        │
│  Translation -> Pub:    AllLocalesComplete               │
│                         RequiresRole("publisher")        │
│                                                         │
│  [S]tage  [T]ransition  [G]ate  [B]ack                  │
└─────────────────────────────────────────────────────────┘

Adding a gate:

┌─ Add Gate ──────────────────────────────────────────────┐
│                                                         │
│  Transition: Review -> Translation                      │
│                                                         │
│  Gate type:                                             │
│  > RequiresRole                                         │
│    AllLocalesComplete                                   │
│    RequirementCompliance                                │
│    CustomExpression                                     │
│                                                         │
│  Selected: RequiresRole                                 │
│  Role: [reviewer              ]                         │
│                                                         │
│  Preview:                                               │
│  [Gate("ReviewApproval", RequiresRole = "reviewer")]    │
│                                                         │
│  [Enter] Confirm   [Esc] Cancel                         │
└─────────────────────────────────────────────────────────┘

The RequirementCompliance gate type links workflow transitions to requirement coverage:

Gate type: RequirementCompliance
Feature: [OrderFulfillmentFeature    ]
MinCoverage: [80            ] %

Preview:
[Gate("QualityCheck",
    RequirementCompliance = typeof(OrderFulfillmentFeature),
    MinCoverage = 80)]
// Blocks transition unless 80% of ACs have passing tests

Requirement Dashboard

The Requirement Dashboard displays compliance status across all features, with drill-down into individual ACs.

┌─ Requirement Dashboard ─────────────────────────────────┐
│                                                         │
│  Overall Coverage: 8/10 ACs (80%)                       │
│  ████████████████░░░░                                    │
│                                                         │
│  Feature                    ACs   Tested  Coverage      │
│  ─────────────────────────  ────  ──────  ────────      │
│  OrderFulfillmentFeature     3      3     100%  ████    │InventoryManagement         2      1      50%  ██░░    │
│> BlogContentFeature          2      2     100%  ████    │ProcessPaymentStory         2      1      50%  ██░░    │ShipOrderStory              1      1     100%  ████    │
│                                                         │
├─ BlogContentFeature (2/2 ACs) ──────────────────────────┤
│                                                         │
│  AC: BlogPostCanBeCreated                               │
│    Spec:  IBlogContentSpec.CreatePost        [OK]       │
│    Impl:  BlogService.CreatePost             [OK]       │
│    Tests: 2 passing                          [OK]       │
│    Coverage: 91%                             [OK]       │
│                                                         │
│  AC: BlogPostCanBePublished                             │
│    Spec:  IBlogContentSpec.PublishPost        [OK]       │
│    Impl:  BlogService.PublishPost             [OK]       │
│    Tests: 1 passing                          [OK]       │
│    Coverage: 85%                             [OK]       │
│                                                         │
│  [Enter] Drill down   [R]efresh   [B]ack                │
└─────────────────────────────────────────────────────────┘

Untested ACs view:

┌─ Untested Acceptance Criteria ──────────────────────────┐
│                                                         │
│  The following ACs have no [Verifies] test:             │
│                                                         │
│  1. InventoryManagement.OutOfStockPreventsOrder         │
│     Spec: IInventorySpec.PreventOutOfStock    [OK]      │
│     Impl: InventoryService.PreventOutOfStock  [OK]      │
│     Tests: NONE                               [!!]      │
│                                                         │
│  2. ProcessPaymentStory.RefundIsProcessed               │
│     Spec: IPaymentSpec.ProcessRefund          [OK]      │
│     Impl: PaymentService.ProcessRefund        [OK]      │
│     Tests: NONE                               [!!]      │
│                                                         │
│  Action: These ACs need [Verifies] test methods.        │
│  Run: cmf add test --feature InventoryManagement        │
│       cmf add test --story ProcessPaymentStory          │
│                                                         │
│  [B]ack                                                 │
└─────────────────────────────────────────────────────────┘

Live Code Preview

The live code preview is a panel that appears in every designer. As the developer models (adds properties, compositions, ACs), the panel shows the C# code that will be generated -- both the developer-authored code and the source-generated output.

The preview uses a two-column layout:

┌─ You Write ─────────────────────┬─ Compiler Generates ──────────────┐
│                                 │                                    │
│ [AggregateRoot("Order")]        │ // Order.g.cs                     │public partial class Orderpublic partial class Order         │
│ {                               │ {                                  │
│   [EntityId]                    │   private OrderId _id;             │
│   public partial OrderId Id;    │   public partial OrderId Id        │
│                                 │       => _id;                      │
│   [Composition]                 │                                    │
│   public partial                │   private readonly                 │
│     IReadOnlyList<OrderLine>    │     List<OrderLine> _lines = [];   │
│     Lines { get; }              │   public partial                   │
│                                 │     IReadOnlyList<OrderLine>       │
│   [Invariant("...")]            │     Lines => _lines.AsReadOnly();  │
│   private Result HasLines()     │                                    │
│     => Lines.Count > 0public Result                    │
│       ? Result.Success()        │     EnsureInvariants()             │
│       : Result.Failure("...");  │       => Result.Aggregate(         │
│ }                               │           HasLines());             │
│                                 │ }                                  │
│                                 │                                    │
│                                 │ // OrderBuilder.g.cs               │
│                                 │ public class OrderBuilder { ... }  │
│                                 │                                    │
│                                 │ // OrderConfiguration.g.cs         │
│                                 │ builder.ToTable("Orders");         │
│                                 │ builder.HasKey(x => x.Id);        │
│                                 │ builder.HasMany(x => x.Lines)     │
│                                 │   .OnDelete(Cascade);              │
└─────────────────────────────────┴────────────────────────────────────┘

CLI Architecture

Technology Stack

Component Technology Role
CLI framework System.CommandLine Command parsing, help text, tab completion
TUI rendering Spectre.Console Tables, trees, panels, prompts, progress bars
Code generation Roslyn Workspace API Read and write .cs files, trigger compilation
Template engine dotnet new templates cmf new scaffolding
File watching FileSystemWatcher Live preview updates in TUI

How the CLI Interacts with the Compilation

The CLI does not duplicate the source generator logic. Instead, it uses the Roslyn Workspace API to:

  1. Open the solution (MSBuildWorkspace.Create().OpenSolutionAsync())
  2. Read the compiled model (same SemanticModel the generators use)
  3. Present the model visually in the TUI
  4. Write new .cs files when the developer adds entities/features
  5. Trigger dotnet build to re-run generators
  6. Read the updated model and refresh the TUI

This means the TUI always reflects the same model that the source generators see. There is no separate configuration file, no separate data model. The .cs files ARE the model.

Diagram

Summary

The CMF CLI provides two complementary interfaces:

Interface Commands Audience Use Case
Standard CLI cmf new, cmf add, cmf generate, cmf validate, cmf migrate, cmf report All developers, CI pipelines Scripting, automation, quick scaffolding
Interactive TUI cmf design Developers and architects Visual modeling, exploration, compliance review

Both interfaces operate on the same source of truth: the .cs files in the project. The CLI writes files and triggers dotnet build. The TUI reads the Roslyn compilation model and presents it visually. The source generators run identically whether the developer uses the CLI, the TUI, or edits files directly in their IDE.

No separate configuration format. No YAML. No JSON schema. The C# code is the model, and the tool is a lens for viewing and editing it.