Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .vscode/settings.shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
// warrant a line limit
"editor.rulers": [150],

// Points the C# extension (OmniSharp or C# Dev Kit, whichever is installed) at the one solution file in the repository; without this, the
// extension has to guess which solution to load, and since "CLI.NET Core.slnx" lives in "source/" rather than at the repository root, and
// references the unit test project one level up in "tests/unit-tests" (see Architecture), that guess can miss the cross-directory project
// reference and report its files as not part of any opened project
"dotnet.defaultSolution": "source/CLI.NET Core.slnx",

// Maps file names to file types; this is required when Visual Studio Code does not correctly auto-detect file types based on file extension
"files.associations": {
".cspell.json": "jsonc",
"**/.vscode/*.json": "jsonc",
"dprint.json": "jsonc",
"LICENSE": "plaintext",
Expand Down
10 changes: 6 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ Start from [docs/developer-manual/architecture/overview.md](docs/developer-manua

The docs and this file are Markdown and are linted too.
- **Markdown headings are title case** at every level, in every file ([docs/developer-manual/conventions/markdown-style.md](docs/developer-manual/conventions/markdown-style.md)). Preserve the real casing of code spans, brand names (`dprint`), and acronyms.
- **Wrap code in backticks.** Every type or member name, file or directory path, package name, configuration key, and CLI flag is wrapped in backticks wherever it appears in prose — docs and commit messages alike ([Markdown Style](docs/developer-manual/conventions/markdown-style.md#wrap-code-in-backticks)). XML documentation comments are the one exception: they are XML, not Markdown, so use `<see cref="..."/>` for identifiers and `<c>` for code instead ([C# Style](docs/developer-manual/conventions/csharp-style.md)).
- **Prose uses periods, not semicolons.** In prose (docs, XML documentation comments, commit messages, this file) end each sentence with a period rather than joining two with a semicolon. Plain in-code comments (`//`) do the reverse: sentences are separated by semicolons and the last one takes no terminal punctuation ([docs/developer-manual/conventions/csharp-style.md](docs/developer-manual/conventions/csharp-style.md)).
- **C# structure**: file-scoped namespaces, an XML documentation comment (`<summary>`, `<param>`, `<returns>`) on every public and internal member, `<inheritdoc/>` for members that implement an interface or override a base member, `sealed` classes by default (composition over inheritance for anything that would otherwise need to extend a sealed framework type), explicit `this.` on member access, expression-bodied members where the implementation is a single expression, and `camelCase` private fields with no underscore. Full detail: [C# Style](docs/developer-manual/conventions/csharp-style.md).
- **C# structure**: file-scoped namespaces, an XML documentation comment (`<summary>`, `<param>`, `<returns>`) on **every member, including `private` ones** (not just public and internal — this is for readers of the source, not only consumers of the compiled output), `<inheritdoc/>` for members that implement an interface or override a base member, `sealed` classes by default (composition over inheritance for anything that would otherwise need to extend a sealed framework type), explicit `this.` on member access, expression-bodied members where the implementation is a single expression, and `camelCase` private fields with no underscore. Full detail: [C# Style](docs/developer-manual/conventions/csharp-style.md).
- **Nullable reference types and implicit usings are enabled everywhere.** Write genuinely null-safe code rather than silencing the analyzer.
- **Files and directories are kebab-case**, except well-known and tool-mandated names (`README.md`, `LICENSE`, `.editorconfig`, ...). Inside a C# project's own source tree, directories and files switch to PascalCase, one type per file. Full detail: [File Naming Conventions](docs/developer-manual/conventions/file-naming-conventions.md).
- **Every dependency is pinned to an exact version — never a range.** NuGet packages, dprint plugins, and the linter versions CI installs are all pinned exactly. Every C# project sets `RestorePackagesWithLockFile`, so a `PackageReference` version bump must be followed by `dotnet restore` and the resulting `packages.lock.json` change committed alongside it. Full detail: [Dependency Management](docs/developer-manual/conventions/dependency-management.md).
- **Every dependency is pinned to an exact version — never a range.** NuGet packages, dprint plugins, the linter versions CI installs, and the .NET SDK (`global.json`) are all pinned exactly. Every C# project sets `RestorePackagesWithLockFile`, so a `PackageReference` version bump must be followed by `dotnet restore` and the resulting `packages.lock.json` change committed alongside it. Full detail: [Dependency Management](docs/developer-manual/conventions/dependency-management.md).
- **Write commit messages by the rules** ([docs/developer-manual/conventions/commit-messages.md](docs/developer-manual/conventions/commit-messages.md)) — the 50/72 rule, a title-cased, past-tense subject, and a prose body. State whether AI was involved and, if it was, what exactly the AI did — this project is developed openly with AI assistance and the commit history is where that is tracked (see the "Use of AI" section of the [root README](README.md)). When you did any of the work, add the trailer this project uses (not a model-specific one):

```text
Expand All @@ -49,14 +50,15 @@ Start from [docs/developer-manual/architecture/overview.md](docs/developer-manua

## Conventions in Brief

Files use file-scoped namespaces and, in larger files, `#region` blocks (`Constructors`, `Private Fields`, `Public Methods`, and so on) to group members — small files skip regions entirely. Every public and internal member is documented with XML comments that explain *why*, not just what. Sealed types compose the framework types they wrap instead of inheriting from them. Markdown headings are title case everywhere, and prose ends sentences with periods; plain code comments do the reverse. Full detail: [docs/developer-manual/conventions/](docs/developer-manual/conventions/csharp-style.md).
Files use file-scoped namespaces and always group members into `#region` blocks (`Constructors`, `Private Fields`, `Public Methods`, and so on), even in small files, ordered constructors, constants, fields, properties, methods, then interface implementations (no access modifier in an interface-implementation region's name). Every member, including `private` ones, is documented with XML comments that explain *why*, not just what, and marks up keywords like `null` or `sealed` with `<see langword="..."/>`. Sealed types compose the framework types they wrap instead of inheriting from them. Markdown headings are title case everywhere, and prose ends sentences with periods; plain code comments do the reverse. Full detail: [docs/developer-manual/conventions/](docs/developer-manual/conventions/csharp-style.md).

## Keep the Documentation up to Date

**This is important.** Whenever you change, add, remove, or discover something about the project, update the relevant [`docs/`](docs/README.md) article **and** this `CLAUDE.md` in the same change:

- Keep the "When working on X" routing table above accurate.
- Keep the [docs index](docs/README.md) and the [Developer Manual index](docs/developer-manual/README.md) accurate — every article must be listed.
- Keep the [docs index](docs/README.md), the [Developer Manual index](docs/developer-manual/README.md), and the [User Manual index](docs/user-manual/README.md) accurate — every article must be listed.
- A change to the public API updates the User Manual (how consumers use it), not only the Developer Manual (how the codebase itself is built) — the two documents serve different audiences, and the same change often needs a separate edit to each.
- If a change introduces a topic that does not fit an existing article, add a new small, single-topic article, link it from the relevant index, and reference it here if relevant.
- If a change invalidates something a doc says, fix the doc — do not leave it stale.

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# CLI.NET Core

![CLI.NET Core Logo](design/readme-header-dark.png#gh-dark-mode-only) ![CLI.NET Core Logo](design/readme-header-light.png#gh-light-mode-only)
# ![CLI.NET Core](design/readme-header-dark.png#gh-dark-mode-only) ![CLI.NET Core](design/readme-header-light.png#gh-light-mode-only)

CLI.NET Core is a command line application framework in the style of ASP.NET Core. It allows you to define commands and command line arguments in much the same way you would define actions and arguments for a Web API in ASP.NET Core.

Expand All @@ -23,6 +21,10 @@ The project uses a set of linters and a code formatter to (1) find and correct p
- **[MarkdownLint](tests/linters/.markdownlint.yml)**, a linter for Markdown files, which ensures that the Markdown files are consistently formatted and standards are enforced.
- **[dprint](dprint.json)**, an unopinionated, configurable code formatter with plugins for many languages. This code formatter is used to format Markdown, JSON, XML, YAML, and TOML files in the project.

### Visual Studio Code

The project maintainer uses Visual Studio Code for the development of CLI.NET Core and the configuration is committed to the repository. To allow other developers to change the local configuration when using Visual Studio Code, the [Workspace Config+](https://marketplace.visualstudio.com/items?itemName=swellaby.workspace-config-plus) extension is used to manage the workspace configuration. Instead of having a single set of configuration files (`settings.json`, `tasks.json`, and `launch.json`), the project has shared configuration files (`settings.shared.json`, `tasks.shared.json`, and `launch.shared.json`) that are checked into source control, while allowing individual developers to override specific settings in their local configuration files (`settings.local.json`, `tasks.local.json`, and `launch.local.json`). The extension automatically merges the shared and local configuration files into a single configuration file that is used by Visual Studio Code, giving the local configuration files preference when there are conflicts. The extension is included in the list of recommended extensions (`.vscode/extensions.json`) and will be recommended by Visual Studio Code when opening the repository for the first time.

## Use of AI

This project is developed with the help of AI and I want to be fully transparent about that. The heart of the project — its architecture, its public API, and the implementation of its core — was and will continue to be written by hand, by me. AI is a tool that I use for the work around that core, never a substitute for it, and everything an AI produces is reviewed and, where necessary, rewritten by me before it is committed. Concretely, I use AI for the following kinds of tasks:
Expand Down
2 changes: 1 addition & 1 deletion docs/developer-manual/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The repository is organized into a few top-level directories:
- [`docs/`](../../README.md) — This documentation.
- [`design/`](../../../design/) — Logo and brand assets, and the [design guide](../../../design/DESIGN.md) that governs them.

Top-level files round out the repository: [`README.md`](../../../README.md) is the project's front door, [`CHANGELOG.md`](../../../CHANGELOG.md) records what changed in each version, [`CONTRIBUTORS.md`](../../../CONTRIBUTORS.md) lists everyone who has contributed, and [`LICENSE`](../../../LICENSE) is the full text of the license (see [Contributing](../contributing.md) for how these are kept up to date). [`CONTRIBUTING.md`](../../../CONTRIBUTING.md), [`CODE_OF_CONDUCT.md`](../../../CODE_OF_CONDUCT.md), and [`SECURITY.md`](../../../SECURITY.md) round out the community-facing files GitHub recognizes by name.
Top-level files round out the repository: [`README.md`](../../../README.md) is the project's front door, [`CHANGELOG.md`](../../../CHANGELOG.md) records what changed in each version, [`CONTRIBUTORS.md`](../../../CONTRIBUTORS.md) lists everyone who has contributed, and [`LICENSE`](../../../LICENSE) is the full text of the license (see [Contributing](../contributing.md) for how these are kept up to date). [`CONTRIBUTING.md`](../../../CONTRIBUTING.md), [`CODE_OF_CONDUCT.md`](../../../CODE_OF_CONDUCT.md), and [`SECURITY.md`](../../../SECURITY.md) round out the community-facing files GitHub recognizes by name. [`global.json`](../../../global.json) pins the exact .NET SDK version the repository builds with.

## Solution and Projects

Expand Down
2 changes: 2 additions & 0 deletions docs/developer-manual/conventions/commit-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ The subject is **title case** (see [Markdown Style](markdown-style.md)) and **pa

When present, the body explains what changed and why — the diff already shows what changed, so the *why* is what earns its place. It is written as prose paragraphs, bulleted or numbered lists, or a mix of both, freely intermixed (an opening paragraph followed by a list, followed by another paragraph, is fine). Whichever form it takes, it follows the same punctuation rule as the rest of the documentation: periods, not semicolons (see [Markdown Style](markdown-style.md)).

Code, file names, paths, and identifiers are wrapped in backticks, the same as in the documentation (see [Wrap Code in Backticks](markdown-style.md#wrap-code-in-backticks)). This applies even though most Git tools render commit messages as plain text: the backticks still mark the boundary between prose and literal code for a human reader.

## Disclosing AI Involvement

Every commit message states whether AI was involved in producing it and, if it was, what exactly the AI did — this project is developed openly with AI assistance, and the commit history is where that involvement is tracked (see the "Use of AI" section of the [root README](../../../README.md)). A commit written entirely by hand carries no such note. A commit where AI was involved:
Expand Down
Loading