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
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ Bring the user in when:

Anti-pattern: don't keep flipping the code on the same style point. Flip the rule once and stick to the rule.

## Communicating with the User

- **Reference every pull request as a clickable link.** When you mention a PR - in chat, a summary, or a report - render it as a markdown link to the PR (`[#123](https://github.com/<owner>/<repo>/pull/123)`), never a bare `#123`. The same applies to issues and commits.
Comment thread
ptr727 marked this conversation as resolved.
- **Ask for input as a numbered list.** When you need the user to decide or answer, present the questions - and any options - as a numbered list so they can reply per number. A single inline question is fine; two or more are always numbered.

## Workflow YAML Conventions

These conventions describe the target state. New and modified workflows must respect them; the rest of the repo is expected to be brought up to the same standard. Sweep PRs that apply a rule everywhere are welcome when a rule changes.
Expand Down Expand Up @@ -240,6 +245,12 @@ The CI lint job runs these tools (workflow YAML and Markdown), but run them loca

When pulling a public image fails on a Docker-Desktop/WSL credential-helper error (`docker-credential-desktop.exe: exec format error`), retry with an empty Docker config: `DOCKER_CONFIG=$(mktemp -d) docker run ...` after writing `{}` to `$DOCKER_CONFIG/config.json`.

## Supported Development Platforms

- **Cross-platform by default - Windows + macOS + Linux.** Linux runs natively (a Linux desktop, or SSH/remote into a Linux host), through a devcontainer on Windows or macOS, or through WSL2 on Windows - the devcontainer and WSL routes carry their own nuances (mounts, path translation, SSH-agent forwarding) but deliver the same toolchain. Editing is cross-platform through the GUI regardless of where code runs. Assume this default.
- **A repo's platform ceiling is set by its dependencies, not tooling effort; decide it per repo before writing dev tooling.** Narrow below the default only for a hard runtime ceiling - the code can only execute or test on one platform (e.g. a Home Assistant integration is Linux-only: HA Core has POSIX-only dependencies and will not run natively on Windows, so even maximal tooling yields only lint-only there). The narrowing axis is where code *executes* for dev and testing - native, SSH-remote, container, or CI - never where editing happens.
- **Record a narrowed platform and its reason in the repo** (README/AGENTS) so the restriction reads as a deliberate dependency ceiling, not an omission.

## Devcontainer

Contributors commit to this repo with signed commits; the SSH-signing setup lives in [docs/ssh-signing.md](./docs/ssh-signing.md), host prerequisites in [docs/host-setup.md](./docs/host-setup.md), and devcontainer SSH-agent forwarding in [docs/devcontainer.md](./docs/devcontainer.md). This repo ships no application toolchain; the per-language devcontainer definitions it once used are kept as reference under [`catalog/snippets/devcontainer/`](./catalog/snippets/devcontainer/).
Expand Down
12 changes: 5 additions & 7 deletions CODESTYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Note: Code snippets are illustrative examples only. Replace namespaces/types to
global using System;
global using System.Net.Http;
global using System.Threading.Tasks;
global using Serilog;
global using Microsoft.Extensions.Logging;
```

2. **Usings placement**: Outside namespace, sorted with `System` directives first
Expand Down Expand Up @@ -245,15 +245,13 @@ Follow the scope hierarchy in [Analyzer Diagnostics and Suppressions][analyzer-d

#### Error Handling and Logging

1. **Serilog logging**: Use structured logging
1. **Structured logging**: Use structured message templates - Serilog is the **application's** concrete backend; a library never references it (see item 2)

```csharp
logger.Error(exception, "{Function}", function);
logger.LogError(exception, "{Function}", function);
```

2. **Library log configuration**: Libraries must expose logging configuration
- Provide options or settings to supply an `ILoggerFactory` and/or `ILogger`
- Offer a global fallback logger for static usage when needed
2. **Libraries log through abstractions, never a concrete backend.** A NuGet **library** depends only on `Microsoft.Extensions.Logging.Abstractions` and exposes an `ILoggerFactory` seam - a settable global factory defaulting to `NullLoggerFactory` (fallback `NullLogger.Instance`) with `SetFactory`/`TrySetFactory`, and/or an `ILoggerFactory`/`ILogger` parameter in its API. It must **not** reference Serilog or any sink - that forces a logging framework on every consumer and drags in AOT-incompatible dependencies. The consuming **application** owns the concrete logger (Serilog is fine there), bridges it to `ILoggerFactory` (e.g. `SerilogLoggerFactory` from `Serilog.Extensions.Logging`), and injects it. Reference: `LanguageTags` - `LogOptions` in the library; the CLI's `LoggerFactory` builds the Serilog-backed factory and injects it via `LogOptions.SetFactory`.
Comment thread
ptr727 marked this conversation as resolved.

3. **CallerMemberName**: Use for automatic function name tracking

Expand Down Expand Up @@ -294,7 +292,7 @@ Follow the scope hierarchy in [Analyzer Diagnostics and Suppressions][analyzer-d

#### Testing Conventions

1. **Framework**: xUnit with AwesomeAssertions
1. **Framework**: **xUnit v3 or later** (the `xunit.v3` package, never the legacy v2 `xunit` package) with **AwesomeAssertions** for every assertion; native xUnit asserts (`Assert.Equal`, `Assert.True`, ...) are not allowed - use the fluent `.Should()` API

```csharp
[Fact]
Expand Down