# Contributing to Terminal.Gui

> **📘 This document is the single source of truth for all contributors (humans and AI agents) to Terminal.Gui.**

Welcome! This guide provides everything you need to know to contribute effectively to Terminal.Gui, including project structure, build instructions, coding conventions, testing requirements, and CI/CD workflows.

## Table of Contents

- [Project Overview](#project-overview)
- [Building and Testing](#building-and-testing)
- [Coding Conventions](#coding-conventions)
- [Testing Requirements](#testing-requirements)
- [API Documentation Requirements](#api-documentation-requirements)
- [Pull Request Guidelines](#pull-request-guidelines)
- [CI/CD Workflows](#cicd-workflows)
- [Repository Structure](#repository-structure)
- [Branching Model](#branching-model)
- [Key Architecture Concepts](#key-architecture-concepts)
- [What NOT to Do](#what-not-to-do)
- [Additional Resources](#additional-resources)

---

## Project Overview

**Terminal.Gui** is a cross-platform UI toolkit for creating console-based graphical user interfaces in .NET. It's a large codebase (~1,050 C# files) providing a comprehensive framework for building interactive console applications with support for keyboard and mouse input, customizable views, and a robust event system.

**Key characteristics:**
- **Language**: C# (net8.0)
- **Platform**: Cross-platform (Windows, macOS, Linux)
- **Architecture**: Console UI toolkit with driver-based architecture
- **Version**: v2 (Alpha), v1 (maintenance mode)
- **Branching**: GitFlow model (v2_develop is default/active development)

---

## Building and Testing

### Required Tools

- **.NET SDK**: 8.0.0 (see `global.json`)
- **Runtime**: .NET 8.x (latest GA)
- **Optional**: ReSharper/Rider for code formatting (honor `.editorconfig` and `Terminal.sln.DotSettings`)

### Build Commands (In Order)

**ALWAYS run these commands from the repository root:**

1. **Restore packages** (required first, ~15-20 seconds):
   ```bash
   dotnet restore
   ```

2. **Build solution** (Debug, ~50 seconds):
   ```bash
   dotnet build --configuration Debug --no-restore
   ```
   - Expect ~326 warnings (nullable reference warnings, unused variables, etc.) - these are normal
   - 0 errors expected

3. **Build Release** (for packaging):
   ```bash
   dotnet build --configuration Release --no-restore
   ```

### Test Commands

**Two test projects exist:**

1. **Non-parallel tests** (depend on static state, ~10 min timeout):
   ```bash
   dotnet test Tests/UnitTests --no-build --verbosity normal
   ```
   - Uses `Application.Init` and static state
   - Cannot run in parallel
   - Includes `--blame` flags for crash diagnostics

2. **Parallel tests** (can run concurrently, ~10 min timeout):
   ```bash
   dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
   ```
   - No dependencies on static state
   - **Preferred for new tests**

3. **Integration tests**:
   ```bash
   dotnet test Tests/IntegrationTests --no-build --verbosity normal
   ```

### Common Build Issues

#### Issue: Build Warnings
- **Expected**: None warnings (~100 currently).
- **Action**: Don't add new warnings; fix warnings in code you modify

#### Issue: NativeAot/SelfContained Build
- **Solution**: Restore these projects explicitly:
  ```bash
  dotnet restore ./Examples/NativeAot/NativeAot.csproj -f
  dotnet restore ./Examples/SelfContained/SelfContained.csproj -f
  ```

### Running Examples

**UICatalog** (comprehensive demo app):
```bash
dotnet run --project Examples/UICatalog/UICatalog.csproj
```

---

## Coding Conventions

### Code Style Tenets

1. **Six-Year-Old Reading Level** - Readability over terseness
2. **Consistency, Consistency, Consistency** - Follow existing patterns ruthlessly
3. **Don't be Weird** - Follow Microsoft/.NET conventions
4. **Set and Forget** - Rely on automated tooling
5. **Documentation is the Spec** - API docs are source of truth

### Code Formatting

**⚠️ CRITICAL - These rules MUST be followed in ALL new or modified code:**

- **Do NOT add formatting tools** - Use existing `.editorconfig` and `Terminal.sln.DotSettings`
- Format code with:
  1. ReSharper/Rider (`Ctrl-E-C`)
  2. JetBrains CleanupCode CLI tool (free)
  3. Visual Studio (`Ctrl-K-D`) as fallback
- **Only format files you modify**
- Follow `.editorconfig` settings (e.g., braces on new lines, spaces after keywords)
- 4-space indentation
- No trailing whitespace
- File-scoped namespaces
- **ALWAYS use explicit types** - Never use `var` except for built-in simple types (`int`, `string`, `bool`, `double`, `float`, `decimal`, `char`, `byte`)
  ```csharp
  // ✅ CORRECT - Explicit types
  View view = new () { Width = 10 };
  MouseEventArgs args = new () { Position = new Point(5, 5) };
  List<View?> views = new ();
  var count = 0;  // OK - int is a built-in type
  var name = "test";  // OK - string is a built-in type
  
  // ❌ WRONG - Using var for non-built-in types
  var view = new View { Width = 10 };
  var args = new MouseEventArgs { Position = new Point(5, 5) };
  var views = new List<View?>();
  ```

- **ALWAYS use target-typed `new ()`** - Use `new ()` instead of `new TypeName()` when the type is already declared
  ```csharp
  // ✅ CORRECT - Target-typed new
  View view = new () { Width = 10 };
  MouseEventArgs args = new ();
  
  // ❌ WRONG - Redundant type name
  View view = new View() { Width = 10 };
  MouseEventArgs args = new MouseEventArgs();
  ```

**⚠️ CRITICAL - These conventions apply to ALL code - production code, test code, examples, and samples.**

---

## Testing Requirements

### Code Coverage

- **Never decrease code coverage** - PRs must maintain or increase coverage
- Target: 70%+ coverage for new code
- **Coverage collection**:
- Centralized in `TestResults/` directory at repository root
- Collected only on Linux (ubuntu-latest) runners in CI for performance
- Windows and macOS runners skip coverage collection to reduce execution time
- Coverage reports uploaded to Codecov automatically from Linux runner
- CI monitors coverage on each PR

### Test Patterns

- **Parallelizable tests preferred** - Add new tests to `UnitTestsParallelizable` when possible
- **Avoid static dependencies** - Don't use `Application.Init`, `ConfigurationManager` in tests
- **Don't use `[AutoInitShutdown]`** - Legacy pattern, being phased out
- **Make tests granular** - Each test should cover smallest area possible
- Follow existing test patterns in respective test projects

### Test Configuration

- `xunit.runner.json` - xUnit configuration
- `coverlet.runsettings` - Coverage settings (OpenCover format)

---

## API Documentation Requirements

**All public APIs MUST have XML documentation:**

- Clear, concise `<summary>` tags
- Use `<see cref=""/>` for cross-references
- Add `<remarks>` for context
- Include `<example>` for non-obvious usage
- Complex topics → `docfx/docs/*.md` files
- Proper English and grammar - Clear, concise, complete. Use imperative mood.

---

## Pull Request Guidelines

### PR Requirements

- **Title**: "Fixes #issue. Terse description". If multiple issues, list all, separated by commas (e.g. "Fixes #123, #456. Terse description")
- **Description**: 
  - Include "- Fixes #issue" for each issue near the top
  - **ALWAYS** include instructions for pulling down locally at end of Description
  - Suggest user setup a remote named `copilot` pointing to your fork
  - Example:
    ```markdown
    # To pull down this PR locally:
    git remote add copilot <your-fork-url>
    git fetch copilot <branch-name>
    git checkout copilot/<branch-name>
    ```
- **Coding Style**: Follow all coding conventions in this document for new and modified code
- **Tests**: Add tests for new functionality (see [Testing Requirements](#testing-requirements))
- **Coverage**: Maintain or increase code coverage
- **Scenarios**: Update UICatalog scenarios when adding features
- **Warnings**: **CRITICAL - PRs must not introduce any new warnings**
  - Any file modified in a PR that currently generates warnings **MUST** be fixed to remove those warnings
  - Exception: Warnings caused by `[Obsolete]` attributes can remain
  - Expected baseline: ~326 warnings (mostly nullable reference warnings, unused variables, xUnit suggestions)
  - Action: Before submitting a PR, verify your changes don't add new warnings and fix any warnings in files you modify

---

## CI/CD Workflows

The repository uses multiple GitHub Actions workflows. What runs and when:

### 1) Build Solution (`.github/workflows/build.yml`)

- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`); supports `workflow_call`
- **Runner/timeout**: `ubuntu-latest`, 10 minutes
- **Steps**:
- Checkout and setup .NET 8.x GA
- `dotnet restore`
- Build Debug: `dotnet build --configuration Debug --no-restore -property:NoWarn=0618%3B0612`
- Build Release (library): `dotnet build Terminal.Gui/Terminal.Gui.csproj --configuration Release --no-incremental --force -property:NoWarn=0618%3B0612`
- Pack Release: `dotnet pack Terminal.Gui/Terminal.Gui.csproj --configuration Release --output ./local_packages -property:NoWarn=0618%3B0612`
- Restore NativeAot/SelfContained examples, then restore solution again
- Build Release for `Examples/NativeAot` and `Examples/SelfContained`
- Build Release solution
- Upload artifacts named `build-artifacts`, retention 1 day

### 2) Build & Run Unit Tests (`.github/workflows/unit-tests.yml`)

- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`)
- **Matrix**: Ubuntu/Windows/macOS
- **Timeout**: 15 minutes per job
- **Process**:
1. Calls build workflow to build solution once
2. Downloads build artifacts
3. Runs `dotnet restore` (required for `--no-build` to work)
4. **Performance optimizations**:
   - Disables Windows Defender on Windows runners (significant speedup)
   - Collects code coverage **only on Linux** (ubuntu-latest) for performance
   - Windows and macOS skip coverage collection to reduce test time
   - Increased blame-hang-timeout to 120s for Windows/macOS (60s for Linux)
5. Runs two test jobs:
   - **Non-parallel UnitTests**: `Tests/UnitTests` with blame/diag flags; `xunit.stopOnFail=false`
   - **Parallel UnitTestsParallelizable**: `Tests/UnitTestsParallelizable` with blame/diag flags; `xunit.stopOnFail=false`
6. Uploads test logs and diagnostic data from all runners
7. **Uploads code coverage to Codecov only from Linux runner**

**Test results**: All tests output to unified `TestResults/` directory at repository root

### 3) Build & Run Integration Tests (`.github/workflows/integration-tests.yml`)

- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`)
- **Matrix**: Ubuntu/Windows/macOS
- **Timeout**: 15 minutes
- **Process**:
1. Calls build workflow
2. Downloads build artifacts
3. Runs `dotnet restore`
4. **Performance optimizations** (same as unit tests):
   - Disables Windows Defender on Windows runners
   - Collects code coverage **only on Linux**
   - Increased blame-hang-timeout to 120s for Windows/macOS
5. Runs IntegrationTests with blame/diag flags; `xunit.stopOnFail=true`
6. Uploads logs per-OS
7. **Uploads coverage to Codecov only from Linux runner**

### 4) Publish to NuGet (`.github/workflows/publish.yml`)

- **Triggers**: push to `v2_release`, `v2_develop`, and tags `v*`(ignores `**.md`)
- Uses GitVersion to compute SemVer, builds Release, packs with symbols, and pushes to NuGet.org using `NUGET_API_KEY`

### 5) Build and publish API docs (`.github/workflows/api-docs.yml`)

- **Triggers**: push to `v1_release` and `v2_develop`
- Builds DocFX site on Windows and deploys to GitHub Pages when `ref_name` is `v2_release` or `v2_develop`


### Replicating CI Locally

```bash
# Full CI sequence:
dotnet restore
dotnet build --configuration Debug --no-restore
dotnet test Tests/UnitTests --no-build --verbosity normal
dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
dotnet build --configuration Release --no-restore
```

---

## Repository Structure

### Root Directory Files

- `Terminal.sln` - Main solution file
- `Terminal.sln.DotSettings` - ReSharper code style settings
- `.editorconfig` - Code formatting rules (111KB, extensive)
- `global.json` - .NET SDK version pinning
- `Directory.Build.props` - Common MSBuild properties
- `Directory.Packages.props` - Central package version management
- `GitVersion.yml` - Version numbering configuration
- `CONTRIBUTING.md` - This file - contribution guidelines (source of truth)
- `AGENTS.md` - Pointer to this file for AI agents
- `README.md` - Project documentation

### Main Directories

**`/Terminal.Gui/`** - Core library (496 C# files):
- `App/` - Application lifecycle (`Application.cs` static class, `SessionToken`, `MainLoop`)
- `Configuration/` - `ConfigurationManager` for settings
- `Drivers/` - Console driver implementations (`Dotnet`, `Windows`, `Unix`, `Fake`)
- `Drawing/` - Rendering system (attributes, colors, glyphs)
- `Input/` - Keyboard and mouse input handling
- `ViewBase/` - Core `View` class hierarchy and layout
- `Views/` - Specific View subclasses (Window, Dialog, Button, ListView, etc.)
- `Text/` - Text manipulation and formatting
- `FileServices/` - File operations and services

**`/Tests/`**:
- `UnitTests/` - Non-parallel tests (use `Application.Init`, static state)
- `UnitTestsParallelizable/` - Parallel tests (no static dependencies) - **Preferred**
- `IntegrationTests/` - Integration tests
- `StressTests/` - Long-running stress tests (scheduled daily)
- `coverlet.runsettings` - Code coverage configuration

**`/Examples/`**:
- `UICatalog/` - Comprehensive demo app for manual testing
- `Example/` - Basic example
- `NativeAot/`, `SelfContained/` - Deployment examples
- `ReactiveExample/`, `CommunityToolkitExample/` - Integration examples

**`/docfx/`** - Documentation source:
- `docs/` - Conceptual documentation (deep dives)
- `api/` - Generated API docs (gitignored)
- `docfx.json` - DocFX configuration

**`/Scripts/`** - PowerShell build utilities (requires PowerShell 7.4+)

**`/.github/workflows/`** - CI/CD pipelines (see [CI/CD Workflows](#cicd-workflows))

---

## Branching Model

### GitFlow Model

- `v2_develop` - Default branch, active development
- `v2_release` - Stable releases, matches NuGet
- `v1_develop`, `v1_release` - Legacy v1 (maintenance only)

---

## Key Architecture Concepts

**⚠️ CRITICAL - Contributors should understand these concepts before starting work.**

See `/docfx/docs/` for deep dives on:

- **Application Lifecycle** - How `Application.Init`, `Application.Run`, and `Application.Shutdown` work
- **View Hierarchy** - Understanding `View`, `Toplevel`, `Window`, and view containment
- **Layout System** - Pos, Dim, and automatic layout
- **Event System** - How keyboard, mouse, and application events flow
- **Driver Architecture** - How console drivers abstract platform differences
- **Drawing Model** - How rendering works with Attributes, Colors, and Glyphs

Key documentation:
- [View Documentation](https://gui-cs.github.io/Terminal.Gui/docs/View.html)
- [Events Deep Dive](https://gui-cs.github.io/Terminal.Gui/docs/events.html)
- [Layout System](https://gui-cs.github.io/Terminal.Gui/docs/layout.html)
- [Keyboard Handling](https://gui-cs.github.io/Terminal.Gui/docs/keyboard.html)
- [Mouse Support](https://gui-cs.github.io/Terminal.Gui/docs/mouse.html)
- [Drivers](https://gui-cs.github.io/Terminal.Gui/docs/drivers.html)

---

## What NOT to Do

- ❌ Don't add new linters/formatters (use existing)
- ❌ Don't modify unrelated code
- ❌ Don't remove/edit unrelated tests
- ❌ Don't break existing functionality
- ❌ Don't add tests to `UnitTests` if they can be parallelizable
- ❌ Don't use `Application.Init` in new tests
- ❌ Don't decrease code coverage
- ❌ **Don't use `var` for anything but built-in simple types** (use explicit types)
- ❌ **Don't use redundant type names with `new`** (**ALWAYS PREFER** target-typed `new ()`)
- ❌ **Don't introduce new warnings** (fix warnings in files you modify; exception: `[Obsolete]` warnings)

---

## Additional Resources

- **Full Documentation**: https://gui-cs.github.io/Terminal.Gui
- **API Reference**: https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.App.html
- **Deep Dives**: `/docfx/docs/` directory
- **Getting Started**: https://gui-cs.github.io/Terminal.Gui/docs/getting-started.html
- **Migrating from v1 to v2**: https://gui-cs.github.io/Terminal.Gui/docs/migratingfromv1.html
- **Showcase**: https://gui-cs.github.io/Terminal.Gui/docs/showcase.html

---

**Thank you for contributing to Terminal.Gui!** 🎉
