{"owner":"reactiveui","repo":"ReactiveUI","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# CLAUDE.md\n\nThis file is the single source of truth for AI/agent assistance in this repository (Claude Code, GitHub Copilot, and other coding agents). It consolidates build/test commands, architecture context, coding standards, and AOT guidance.\n\nIf there is any conflict between other agent instruction files and this file, follow **CLAUDE.md**.\n\n---\n\n## Repository Orientation\n\n- **Repository root**\n- **Primary working directory for build/test:** `./src`\n- **Main solution:** `src/reactiveui.slnx`\n- **Benchmarks solution:** `Benchmarks/ReactiveUI.Benchmarks.sln`\n- **Integration tests:** `integrationtests/` (platform-specific solutions; not required for most tasks)\n\n### Full Clone Required\n\n**CRITICAL:** Use a full, recursive clone. Shallow clones can fail because build/versioning relies on git history. If a clone has already been done you must use the unshallow commit command in git.\n\n```bash\ngit clone --recursive https://github.com/reactiveui/reactiveui.git\n````\n\n---\n\n## Solution Format: SLNX\n\nThis repository uses **SLNX** (XML-based solution format) instead of legacy `.sln`.\n\n* Introduced in Visual Studio 2022 17.10+\n* Rider 2024.1+ support\n* Works with `dotnet build/test` the same way `.sln` does\n* Main file: `src/reactiveui.slnx`\n\n---\n\n## Build Environment Requirements\n\n### Required SDKs\n\n* .NET **8.0**, **9.0**, **10.0** SDKs (all required)\n\n### Workload Restore (Required)\n\n**CRITICAL:** Platform workloads must be restored or the build will fail. Run from the `./src` directory.\n\n```powershell\ndotnet --info\n\ncd src\ndotnet workload restore\ncd ..\n```\n\n### Restore & Build\n\n**CRITICAL:** Run build/test commands from `./src` unless the command explicitly uses `src/`-prefixed paths.\n\n```powershell\ncd src\n\ndotnet restore reactiveui.slnx\n\ndotnet build reactiveui.slnx -c Release\ndotnet build reactiveui.slnx -c Release -warnaserror\n\ndotnet clean reactiveui.slnx\n```\n\n### Windows Requirements\n\nBuilding the full solution requires **Windows** due to Windows-only target frameworks (WPF, WinUI, .NET Framework). Non-Windows builds may fail; this is expected. In non-Windows environments, focus on documentation, targeted library changes, or analysis that does not require full compilation.\n\n---\n\n## Testing: Microsoft Testing Platform (MTP) + TUnit\n\nThis repo uses **Microsoft Testing Platform (MTP)** with **TUnit**. This differs from VSTest.\n\n* MTP is configured via `global.json`\n* Additional test settings in `testconfig.json`\n* Test projects enable `TestingPlatformDotnetTestSupport` in `Directory.Build.props`\n\n**Key rule:** TUnit/MTP arguments go **after** `--`.\n\n### Testing Best Practices\n\n* **Do NOT use `--no-build`**. Always build before testing to avoid stale binaries.\n* To see test output, use `--output Detailed` **before** `--`.\n* Repository configuration runs tests **non-parallel** (`\"parallel\": false` in `testconfig.json`) to avoid interference.\n\n### Test Commands (run from `./src`)\n\n```powershell\ncd src\n\n# Run all tests\ndotnet test --solution reactiveui.slnx -c Release\n\n# Run tests for a specific project\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj\n\n# Run with code coverage (Microsoft Code Coverage)\ndotnet test --solution reactiveui.slnx --coverage --coverage-output-format cobertura\n\n# Detailed output (place BEFORE --)\ndotnet test --solution reactiveui.slnx -- --output Detailed\ndotnet test --solution reactiveui.slnx --coverage --coverage-output-format cobertura -- --report-trx --output Detailed\n\n# List tests\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --list-tests\n\n# Fail fast\ndotnet test --solution reactiveui.slnx -- --fail-fast\n\n# Limit parallelism if needed (even though repo defaults non-parallel)\ndotnet test --solution reactiveui.slnx -- --maximum-parallel-tests 4\n```\n\n### TUnit `--treenode-filter` Syntax\n\nPattern: `/{AssemblyName}/{Namespace}/{ClassName}/{TestMethodName}`\n\nExamples:\n\n```powershell\n# Single test\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/*/*/MyTestMethod\"\n\n# All tests in class\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/*/MyClassName/*\"\n\n# All tests in namespace\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/MyNamespace/*/*\"\n\n# Filter by property (e.g., Category)\ndotnet test --solution reactiveui.slnx -- --treenode-filter \"/*/*/*/*[Category=Integration]\"\n```\n\nSee: [https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test?tabs=dotnet-test-with-mtp](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test?tabs=dotnet-test-with-mtp)\nTUnit flags reference: [https://tunit.dev/docs/reference/command-line-flags](https://tunit.dev/docs/reference/command-line-flags)\n\n---\n\n## Key Configuration Files\n\n* `src/global.json` — sets `\"Microsoft.Testing.Platform\"` runner\n* `src/testconfig.json` — test execution settings (parallel false, coverage format, etc.)\n* `src/Directory.Build.props` — repository-wide build configuration (incl. `TestingPlatformDotnetTestSupport`)\n* `.github/copilot-instructions.md` — may exist, but should defer to this `agent.md`\n\n---\n\n## Architecture Overview\n\nReactiveUI is a cross-platform MVVM framework built on Rx.NET and functional reactive programming principles.\n\n### Core Library (`src/ReactiveUI/`)\n\n* `ReactiveObject/` — reactive `INotifyPropertyChanged` base\n* `ReactiveCommand/` — observable command pipelines\n* `Activation/` — view/viewmodel activation lifecycle\n* `Bindings/` — one-way/two-way binding infrastructure\n* `Expression/` — expression tree analysis for observation (`WhenAnyValue`)\n* `Routing/` — navigation/routing\n* `Interactions/` — request/response patterns\n* `Builder/` — DI and service registration patterns\n\n### Platform Extensions\n\nExamples:\n\n* `ReactiveUI.Wpf/`, `ReactiveUI.WinUI/`, `ReactiveUI.Maui/`, `ReactiveUI.AndroidX/`,\n  `ReactiveUI.Blazor/`, `ReactiveUI.Winforms/`, `ReactiveUI.Testing/`, etc.\n\n### Scheduler Abstraction\n\n* Prefer `RxSchedulers` (AOT-friendly, avoids reflection/AOT attribute propagation)\n* Use `RxApp` only when required (e.g., unit test scheduler detection)\n\nSee `docs/RxSchedulers.md`.\n\n---\n\n## AOT Guidance (Critical)\n\nThis repository targets net8.0+ and supports AOT/trimming scenarios.\n\n### Primary Rule: Avoid Reflection Paths\n\nPrefer strongly-typed and source-generator-friendly approaches. Avoid reflection-heavy patterns that require trimming/AOT attributes.\n\n### Attributes: Use Only If Necessary\n\n* Avoid introducing DAC/RDC/RUC attributes unless required.\n* If an attribute is required, apply it directly (no `#if NET6_0_OR_GREATER` guards). Polyfills are available.\n\nExample (only when truly needed):\n\n```csharp\nprivate static object CreateInstance(\n    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]\n    Type type)\n{\n    return Activator.CreateInstance(type)!;\n}\n```\n\n### Suppressions: Last Resort Only — Never Without Human Approval\n\n**Do NOT add any suppression without explicit human approval.** This covers `[SuppressMessage]`, `[UnconditionalSuppressMessage]`, `#pragma warning`, and `.editorconfig` severity changes. A suppression is a true last resort, used only when a warning genuinely cannot be resolved by fixing the code without harming the design.\n\nBefore suppressing anything:\n\n1. **Fix the underlying issue first.** Most analyzer warnings indicate a real fix. For example, `S3398` (\"method should be moved\") means *move the method into the type that uses it* — never suppress it. `SA****` (StyleCop) must always be fixed, never suppressed.\n2. **If you believe a suppression is genuinely unavoidable, stop and ask the human.** Present the specific analyzer ID, why it cannot be fixed in code, and the proposed justification. Wait for explicit approval.\n3. **Only after approval**, apply it with minimal scope, the specific ID, and a clear `Justification`.\n\n---\n\n## Code Style & Quality Requirements\n\n**CRITICAL:** Follow ReactiveUI contribution guidelines:\n[https://www.reactiveui.net/contribute/index.html](https://www.reactiveui.net/contribute/index.html)\n\n### Enforced Tooling\n\n* `.editorconfig` formatting/naming conventions\n* StyleCop analyzers (build fails on violations)\n* Roslynator analyzers\n* Analysis level: latest\n* Warnings treated as errors (notably nullable and CS4014)\n* **Public APIs require XML documentation**, including protected methods on public types.\n\n### C# Style Rules (High-level)\n\n* Allman braces\n* 4 spaces, no tabs\n* Explicit visibility\n* Private/internal fields: `_camelCase`, `readonly` where possible, `static readonly` order\n* File-scoped namespaces preferred; using directives outside namespace and sorted\n* Use C# keywords (`int`, `string`) rather than BCL types\n* Prefer modern C# features where appropriate (nullable, pattern matching, switch expressions, records, init, target-typed new, etc.)\n* Use `nameof()` over string literals\n* Avoid `this.` unless necessary\n* Use `var` when it improves readability\n\nIf a specific file already follows a local style, adhere to existing file conventions.\n\n---\n\n## Zero Pragma Policy (Critical)\n\n**No `#pragma warning disable`** in production code.\n\n* **StyleCop warnings (SA****) must be fixed**, never suppressed.\n* **No analyzer warning (CA****, S**** Sonar, RCS**** Roslynator, IL**** trimming/AOT, etc.) may be suppressed without explicit human approval** — see \"Suppressions: Last Resort Only\" above. Fix the code first; if a suppression seems unavoidable, stop and ask.\n\nExample:\n\n```csharp\n// WRONG\n#pragma warning disable CA1062\npublic void MyMethod(object parameter)\n{\n    parameter.ToString();\n}\n#pragma warning restore CA1062\n\n// CORRECT\npublic void MyMethod(object parameter)\n{\n    ArgumentNullException.ThrowIfNull(parameter);\n    parameter.ToString();\n}\n\n// LAST RESORT ONLY\n[SuppressMessage(\"Microsoft.Design\", \"CA1062:ValidateArgumentsOfPublicMethods\",\n    Justification = \"TUnit guarantees non-null parameters from data sources.\")]\npublic async Task MyTest(IConverter converter, int expectedValue)\n{\n    var result = converter.GetValue();\n    await Assert.That(result).IsEqualTo(expectedValue);\n}\n```\n\n---\n\n## Testing Guidelines\n\n* Use TUnit + Microsoft Testing Platform\n* Write unit tests for new features and bug fixes\n* Prefer existing patterns in:\n\n  * `src/tests/ReactiveUI.Tests/`\n  * `src/tests/ReactiveUI.AOTTests/`\n* Use `ReactiveUI.Testing` utilities for reactive code\n\n---\n\n## Common Development Patterns\n\n### ViewModel Skeleton\n\n```csharp\npublic class SampleViewModel : ReactiveObject\n{\n    private string? _name;\n    private readonly ObservableAsPropertyHelper<bool> _isValid;\n\n    public SampleViewModel()\n    {\n        _isValid = this.WhenAnyValue(x => x.Name)\n            .Select(name => !string.IsNullOrWhiteSpace(name))\n            .ToProperty(this, nameof(IsValid));\n\n        SubmitCommand = ReactiveCommand.CreateFromTask(\n            ExecuteSubmit,\n            this.WhenAnyValue(x => x.IsValid));\n    }\n\n    public string? Name\n    {\n        get => _name;\n        set => this.RaiseAndSetIfChanged(ref _name, value);\n    }\n\n    public bool IsValid => _isValid.Value;\n\n    public ReactiveCommand<Unit, Unit> SubmitCommand { get; }\n\n    private async Task ExecuteSubmit(CancellationToken cancellationToken)\n    {\n        // Implementation\n    }\n}\n```\n\n### RxSchedulers (Preferred)\n\n```csharp\npublic IObservable<string> GetData()\n{\n    return Observable.Return(\"data\")\n        .ObserveOn(RxSchedulers.MainThreadScheduler);\n}\n```\n\n### WhenAnyValue\n\n```csharp\nthis.WhenAnyValue(\n        x => x.FirstName,\n        x => x.LastName,\n        (first, last) => $\"{first} {last}\")\n    .Subscribe(fullName => { /* handle */ });\n\nthis.WhenAnyValue(x => x.IsLoading)\n    .Where(isLoading => !isLoading)\n    .Subscribe(_ => { /* handle */ });\n```\n\n### ObservableAsPropertyHelper\n\n```csharp\nprivate readonly ObservableAsPropertyHelper<decimal> _total;\npublic decimal Total => _total.Value;\n\n_total = this.WhenAnyValue(\n        x => x.Quantity,\n        x => x.Price,\n        (qty, price) => qty * price)\n    .ToProperty(this, nameof(Total));\n```\n\n---\n\n## What to Avoid\n\n* Reflection-heavy implementations in core paths\n* Expression trees in hot paths without caching\n* Platform-specific code in `src/ReactiveUI/` core library\n* Breaking public APIs without proper versioning and documentation\n"},"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file is the single source of truth for AI/agent assistance in this repository (Claude Code, GitHub Copilot, and other coding agents). It consolidates build/test commands, architecture context, coding standards, and AOT guidance.\n\nIf there is any conflict between other agent instruction files and this file, follow **CLAUDE.md**.\n\n---\n\n## Repository Orientation\n\n- **Repository root**\n- **Primary working directory for build/test:** `./src`\n- **Main solution:** `src/reactiveui.slnx`\n- **Benchmarks solution:** `Benchmarks/ReactiveUI.Benchmarks.sln`\n- **Integration tests:** `integrationtests/` (platform-specific solutions; not required for most tasks)\n\n### Full Clone Required\n\n**CRITICAL:** Use a full, recursive clone. Shallow clones can fail because build/versioning relies on git history. If a clone has already been done you must use the unshallow commit command in git.\n\n```bash\ngit clone --recursive https://github.com/reactiveui/reactiveui.git\n````\n\n---\n\n## Solution Format: SLNX\n\nThis repository uses **SLNX** (XML-based solution format) instead of legacy `.sln`.\n\n* Introduced in Visual Studio 2022 17.10+\n* Rider 2024.1+ support\n* Works with `dotnet build/test` the same way `.sln` does\n* Main file: `src/reactiveui.slnx`\n\n---\n\n## Build Environment Requirements\n\n### Required SDKs\n\n* .NET **8.0**, **9.0**, **10.0** SDKs (all required)\n\n### Workload Restore (Required)\n\n**CRITICAL:** Platform workloads must be restored or the build will fail. Run from the `./src` directory.\n\n```powershell\ndotnet --info\n\ncd src\ndotnet workload restore\ncd ..\n```\n\n### Restore & Build\n\n**CRITICAL:** Run build/test commands from `./src` unless the command explicitly uses `src/`-prefixed paths.\n\n```powershell\ncd src\n\ndotnet restore reactiveui.slnx\n\ndotnet build reactiveui.slnx -c Release\ndotnet build reactiveui.slnx -c Release -warnaserror\n\ndotnet clean reactiveui.slnx\n```\n\n### Windows Requirements\n\nBuilding the full solution requires **Windows** due to Windows-only target frameworks (WPF, WinUI, .NET Framework). Non-Windows builds may fail; this is expected. In non-Windows environments, focus on documentation, targeted library changes, or analysis that does not require full compilation.\n\n---\n\n## Testing: Microsoft Testing Platform (MTP) + TUnit\n\nThis repo uses **Microsoft Testing Platform (MTP)** with **TUnit**. This differs from VSTest.\n\n* MTP is configured via `global.json`\n* Additional test settings in `testconfig.json`\n* Test projects enable `TestingPlatformDotnetTestSupport` in `Directory.Build.props`\n\n**Key rule:** TUnit/MTP arguments go **after** `--`.\n\n### Testing Best Practices\n\n* **Do NOT use `--no-build`**. Always build before testing to avoid stale binaries.\n* To see test output, use `--output Detailed` **before** `--`.\n* Repository configuration runs tests **non-parallel** (`\"parallel\": false` in `testconfig.json`) to avoid interference.\n\n### Test Commands (run from `./src`)\n\n```powershell\ncd src\n\n# Run all tests\ndotnet test --solution reactiveui.slnx -c Release\n\n# Run tests for a specific project\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj\n\n# Run with code coverage (Microsoft Code Coverage)\ndotnet test --solution reactiveui.slnx --coverage --coverage-output-format cobertura\n\n# Detailed output (place BEFORE --)\ndotnet test --solution reactiveui.slnx -- --output Detailed\ndotnet test --solution reactiveui.slnx --coverage --coverage-output-format cobertura -- --report-trx --output Detailed\n\n# List tests\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --list-tests\n\n# Fail fast\ndotnet test --solution reactiveui.slnx -- --fail-fast\n\n# Limit parallelism if needed (even though repo defaults non-parallel)\ndotnet test --solution reactiveui.slnx -- --maximum-parallel-tests 4\n```\n\n### TUnit `--treenode-filter` Syntax\n\nPattern: `/{AssemblyName}/{Namespace}/{ClassName}/{TestMethodName}`\n\nExamples:\n\n```powershell\n# Single test\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/*/*/MyTestMethod\"\n\n# All tests in class\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/*/MyClassName/*\"\n\n# All tests in namespace\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/MyNamespace/*/*\"\n\n# Filter by property (e.g., Category)\ndotnet test --solution reactiveui.slnx -- --treenode-filter \"/*/*/*/*[Category=Integration]\"\n```\n\nSee: [https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test?tabs=dotnet-test-with-mtp](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test?tabs=dotnet-test-with-mtp)\nTUnit flags reference: [https://tunit.dev/docs/reference/command-line-flags](https://tunit.dev/docs/reference/command-line-flags)\n\n---\n\n## Key Configuration Files\n\n* `src/global.json` — sets `\"Microsoft.Testing.Platform\"` runner\n* `src/testconfig.json` — test execution settings (parallel false, coverage format, etc.)\n* `src/Directory.Build.props` — repository-wide build configuration (incl. `TestingPlatformDotnetTestSupport`)\n* `.github/copilot-instructions.md` — may exist, but should defer to this `agent.md`\n\n---\n\n## Architecture Overview\n\nReactiveUI is a cross-platform MVVM framework built on Rx.NET and functional reactive programming principles.\n\n### Core Library (`src/ReactiveUI/`)\n\n* `ReactiveObject/` — reactive `INotifyPropertyChanged` base\n* `ReactiveCommand/` — observable command pipelines\n* `Activation/` — view/viewmodel activation lifecycle\n* `Bindings/` — one-way/two-way binding infrastructure\n* `Expression/` — expression tree analysis for observation (`WhenAnyValue`)\n* `Routing/` — navigation/routing\n* `Interactions/` — request/response patterns\n* `Builder/` — DI and service registration patterns\n\n### Platform Extensions\n\nExamples:\n\n* `ReactiveUI.Wpf/`, `ReactiveUI.WinUI/`, `ReactiveUI.Maui/`, `ReactiveUI.AndroidX/`,\n  `ReactiveUI.Blazor/`, `ReactiveUI.Winforms/`, `ReactiveUI.Testing/`, etc.\n\n### Scheduler Abstraction\n\n* Prefer `RxSchedulers` (AOT-friendly, avoids reflection/AOT attribute propagation)\n* Use `RxApp` only when required (e.g., unit test scheduler detection)\n\nSee `docs/RxSchedulers.md`.\n\n---\n\n## AOT Guidance (Critical)\n\nThis repository targets net8.0+ and supports AOT/trimming scenarios.\n\n### Primary Rule: Avoid Reflection Paths\n\nPrefer strongly-typed and source-generator-friendly approaches. Avoid reflection-heavy patterns that require trimming/AOT attributes.\n\n### Attributes: Use Only If Necessary\n\n* Avoid introducing DAC/RDC/RUC attributes unless required.\n* If an attribute is required, apply it directly (no `#if NET6_0_OR_GREATER` guards). Polyfills are available.\n\nExample (only when truly needed):\n\n```csharp\nprivate static object CreateInstance(\n    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]\n    Type type)\n{\n    return Activator.CreateInstance(type)!;\n}\n```\n\n### Suppressions: Last Resort Only — Never Without Human Approval\n\n**Do NOT add any suppression without explicit human approval.** This covers `[SuppressMessage]`, `[UnconditionalSuppressMessage]`, `#pragma warning`, and `.editorconfig` severity changes. A suppression is a true last resort, used only when a warning genuinely cannot be resolved by fixing the code without harming the design.\n\nBefore suppressing anything:\n\n1. **Fix the underlying issue first.** Most analyzer warnings indicate a real fix. For example, `S3398` (\"method should be moved\") means *move the method into the type that uses it* — never suppress it. `SA****` (StyleCop) must always be fixed, never suppressed.\n2. **If you believe a suppression is genuinely unavoidable, stop and ask the human.** Present the specific analyzer ID, why it cannot be fixed in code, and the proposed justification. Wait for explicit approval.\n3. **Only after approval**, apply it with minimal scope, the specific ID, and a clear `Justification`.\n\n---\n\n## Code Style & Quality Requirements\n\n**CRITICAL:** Follow ReactiveUI contribution guidelines:\n[https://www.reactiveui.net/contribute/index.html](https://www.reactiveui.net/contribute/index.html)\n\n### Enforced Tooling\n\n* `.editorconfig` formatting/naming conventions\n* StyleCop analyzers (build fails on violations)\n* Roslynator analyzers\n* Analysis level: latest\n* Warnings treated as errors (notably nullable and CS4014)\n* **Public APIs require XML documentation**, including protected methods on public types.\n\n### C# Style Rules (High-level)\n\n* Allman braces\n* 4 spaces, no tabs\n* Explicit visibility\n* Private/internal fields: `_camelCase`, `readonly` where possible, `static readonly` order\n* File-scoped namespaces preferred; using directives outside namespace and sorted\n* Use C# keywords (`int`, `string`) rather than BCL types\n* Prefer modern C# features where appropriate (nullable, pattern matching, switch expressions, records, init, target-typed new, etc.)\n* Use `nameof()` over string literals\n* Avoid `this.` unless necessary\n* Use `var` when it improves readability\n\nIf a specific file already follows a local style, adhere to existing file conventions.\n\n---\n\n## Zero Pragma Policy (Critical)\n\n**No `#pragma warning disable`** in production code.\n\n* **StyleCop warnings (SA****) must be fixed**, never suppressed.\n* **No analyzer warning (CA****, S**** Sonar, RCS**** Roslynator, IL**** trimming/AOT, etc.) may be suppressed without explicit human approval** — see \"Suppressions: Last Resort Only\" above. Fix the code first; if a suppression seems unavoidable, stop and ask.\n\nExample:\n\n```csharp\n// WRONG\n#pragma warning disable CA1062\npublic void MyMethod(object parameter)\n{\n    parameter.ToString();\n}\n#pragma warning restore CA1062\n\n// CORRECT\npublic void MyMethod(object parameter)\n{\n    ArgumentNullException.ThrowIfNull(parameter);\n    parameter.ToString();\n}\n\n// LAST RESORT ONLY\n[SuppressMessage(\"Microsoft.Design\", \"CA1062:ValidateArgumentsOfPublicMethods\",\n    Justification = \"TUnit guarantees non-null parameters from data sources.\")]\npublic async Task MyTest(IConverter converter, int expectedValue)\n{\n    var result = converter.GetValue();\n    await Assert.That(result).IsEqualTo(expectedValue);\n}\n```\n\n---\n\n## Testing Guidelines\n\n* Use TUnit + Microsoft Testing Platform\n* Write unit tests for new features and bug fixes\n* Prefer existing patterns in:\n\n  * `src/tests/ReactiveUI.Tests/`\n  * `src/tests/ReactiveUI.AOTTests/`\n* Use `ReactiveUI.Testing` utilities for reactive code\n\n---\n\n## Common Development Patterns\n\n### ViewModel Skeleton\n\n```csharp\npublic class SampleViewModel : ReactiveObject\n{\n    private string? _name;\n    private readonly ObservableAsPropertyHelper<bool> _isValid;\n\n    public SampleViewModel()\n    {\n        _isValid = this.WhenAnyValue(x => x.Name)\n            .Select(name => !string.IsNullOrWhiteSpace(name))\n            .ToProperty(this, nameof(IsValid));\n\n        SubmitCommand = ReactiveCommand.CreateFromTask(\n            ExecuteSubmit,\n            this.WhenAnyValue(x => x.IsValid));\n    }\n\n    public string? Name\n    {\n        get => _name;\n        set => this.RaiseAndSetIfChanged(ref _name, value);\n    }\n\n    public bool IsValid => _isValid.Value;\n\n    public ReactiveCommand<Unit, Unit> SubmitCommand { get; }\n\n    private async Task ExecuteSubmit(CancellationToken cancellationToken)\n    {\n        // Implementation\n    }\n}\n```\n\n### RxSchedulers (Preferred)\n\n```csharp\npublic IObservable<string> GetData()\n{\n    return Observable.Return(\"data\")\n        .ObserveOn(RxSchedulers.MainThreadScheduler);\n}\n```\n\n### WhenAnyValue\n\n```csharp\nthis.WhenAnyValue(\n        x => x.FirstName,\n        x => x.LastName,\n        (first, last) => $\"{first} {last}\")\n    .Subscribe(fullName => { /* handle */ });\n\nthis.WhenAnyValue(x => x.IsLoading)\n    .Where(isLoading => !isLoading)\n    .Subscribe(_ => { /* handle */ });\n```\n\n### ObservableAsPropertyHelper\n\n```csharp\nprivate readonly ObservableAsPropertyHelper<decimal> _total;\npublic decimal Total => _total.Value;\n\n_total = this.WhenAnyValue(\n        x => x.Quantity,\n        x => x.Price,\n        (qty, price) => qty * price)\n    .ToProperty(this, nameof(Total));\n```\n\n---\n\n## What to Avoid\n\n* Reflection-heavy implementations in core paths\n* Expression trees in hot paths without caching\n* Platform-specific code in `src/ReactiveUI/` core library\n* Breaking public APIs without proper versioning and documentation\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md\n\nThis file is the single source of truth for AI/agent assistance in this repository (Claude Code, GitHub Copilot, and other coding agents). It consolidates build/test commands, architecture context, coding standards, and AOT guidance.\n\nIf there is any conflict between other agent instruction files and this file, follow **CLAUDE.md**.\n\n---\n\n## Repository Orientation\n\n- **Repository root**\n- **Primary working directory for build/test:** `./src`\n- **Main solution:** `src/reactiveui.slnx`\n- **Benchmarks solution:** `Benchmarks/ReactiveUI.Benchmarks.sln`\n- **Integration tests:** `integrationtests/` (platform-specific solutions; not required for most tasks)\n\n### Full Clone Required\n\n**CRITICAL:** Use a full, recursive clone. Shallow clones can fail because build/versioning relies on git history. If a clone has already been done you must use the unshallow commit command in git.\n\n```bash\ngit clone --recursive https://github.com/reactiveui/reactiveui.git\n````\n\n---\n\n## Solution Format: SLNX\n\nThis repository uses **SLNX** (XML-based solution format) instead of legacy `.sln`.\n\n* Introduced in Visual Studio 2022 17.10+\n* Rider 2024.1+ support\n* Works with `dotnet build/test` the same way `.sln` does\n* Main file: `src/reactiveui.slnx`\n\n---\n\n## Build Environment Requirements\n\n### Required SDKs\n\n* .NET **8.0**, **9.0**, **10.0** SDKs (all required)\n\n### Workload Restore (Required)\n\n**CRITICAL:** Platform workloads must be restored or the build will fail. Run from the `./src` directory.\n\n```powershell\ndotnet --info\n\ncd src\ndotnet workload restore\ncd ..\n```\n\n### Restore & Build\n\n**CRITICAL:** Run build/test commands from `./src` unless the command explicitly uses `src/`-prefixed paths.\n\n```powershell\ncd src\n\ndotnet restore reactiveui.slnx\n\ndotnet build reactiveui.slnx -c Release\ndotnet build reactiveui.slnx -c Release -warnaserror\n\ndotnet clean reactiveui.slnx\n```\n\n### Windows Requirements\n\nBuilding the full solution requires **Windows** due to Windows-only target frameworks (WPF, WinUI, .NET Framework). Non-Windows builds may fail; this is expected. In non-Windows environments, focus on documentation, targeted library changes, or analysis that does not require full compilation.\n\n---\n\n## Testing: Microsoft Testing Platform (MTP) + TUnit\n\nThis repo uses **Microsoft Testing Platform (MTP)** with **TUnit**. This differs from VSTest.\n\n* MTP is configured via `global.json`\n* Additional test settings in `testconfig.json`\n* Test projects enable `TestingPlatformDotnetTestSupport` in `Directory.Build.props`\n\n**Key rule:** TUnit/MTP arguments go **after** `--`.\n\n### Testing Best Practices\n\n* **Do NOT use `--no-build`**. Always build before testing to avoid stale binaries.\n* To see test output, use `--output Detailed` **before** `--`.\n* Repository configuration runs tests **non-parallel** (`\"parallel\": false` in `testconfig.json`) to avoid interference.\n\n### Test Commands (run from `./src`)\n\n```powershell\ncd src\n\n# Run all tests\ndotnet test --solution reactiveui.slnx -c Release\n\n# Run tests for a specific project\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj\n\n# Run with code coverage (Microsoft Code Coverage)\ndotnet test --solution reactiveui.slnx --coverage --coverage-output-format cobertura\n\n# Detailed output (place BEFORE --)\ndotnet test --solution reactiveui.slnx -- --output Detailed\ndotnet test --solution reactiveui.slnx --coverage --coverage-output-format cobertura -- --report-trx --output Detailed\n\n# List tests\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --list-tests\n\n# Fail fast\ndotnet test --solution reactiveui.slnx -- --fail-fast\n\n# Limit parallelism if needed (even though repo defaults non-parallel)\ndotnet test --solution reactiveui.slnx -- --maximum-parallel-tests 4\n```\n\n### TUnit `--treenode-filter` Syntax\n\nPattern: `/{AssemblyName}/{Namespace}/{ClassName}/{TestMethodName}`\n\nExamples:\n\n```powershell\n# Single test\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/*/*/MyTestMethod\"\n\n# All tests in class\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/*/MyClassName/*\"\n\n# All tests in namespace\ndotnet test --project tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj -- --treenode-filter \"/*/MyNamespace/*/*\"\n\n# Filter by property (e.g., Category)\ndotnet test --solution reactiveui.slnx -- --treenode-filter \"/*/*/*/*[Category=Integration]\"\n```\n\nSee: [https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test?tabs=dotnet-test-with-mtp](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test?tabs=dotnet-test-with-mtp)\nTUnit flags reference: [https://tunit.dev/docs/reference/command-line-flags](https://tunit.dev/docs/reference/command-line-flags)\n\n---\n\n## Key Configuration Files\n\n* `src/global.json` — sets `\"Microsoft.Testing.Platform\"` runner\n* `src/testconfig.json` — test execution settings (parallel false, coverage format, etc.)\n* `src/Directory.Build.props` — repository-wide build configuration (incl. `TestingPlatformDotnetTestSupport`)\n* `.github/copilot-instructions.md` — may exist, but should defer to this `agent.md`\n\n---\n\n## Architecture Overview\n\nReactiveUI is a cross-platform MVVM framework built on Rx.NET and functional reactive programming principles.\n\n### Core Library (`src/ReactiveUI/`)\n\n* `ReactiveObject/` — reactive `INotifyPropertyChanged` base\n* `ReactiveCommand/` — observable command pipelines\n* `Activation/` — view/viewmodel activation lifecycle\n* `Bindings/` — one-way/two-way binding infrastructure\n* `Expression/` — expression tree analysis for observation (`WhenAnyValue`)\n* `Routing/` — navigation/routing\n* `Interactions/` — request/response patterns\n* `Builder/` — DI and service registration patterns\n\n### Platform Extensions\n\nExamples:\n\n* `ReactiveUI.Wpf/`, `ReactiveUI.WinUI/`, `ReactiveUI.Maui/`, `ReactiveUI.AndroidX/`,\n  `ReactiveUI.Blazor/`, `ReactiveUI.Winforms/`, `ReactiveUI.Testing/`, etc.\n\n### Scheduler Abstraction\n\n* Prefer `RxSchedulers` (AOT-friendly, avoids reflection/AOT attribute propagation)\n* Use `RxApp` only when required (e.g., unit test scheduler detection)\n\nSee `docs/RxSchedulers.md`.\n\n---\n\n## AOT Guidance (Critical)\n\nThis repository targets net8.0+ and supports AOT/trimming scenarios.\n\n### Primary Rule: Avoid Reflection Paths\n\nPrefer strongly-typed and source-generator-friendly approaches. Avoid reflection-heavy patterns that require trimming/AOT attributes.\n\n### Attributes: Use Only If Necessary\n\n* Avoid introducing DAC/RDC/RUC attributes unless required.\n* If an attribute is required, apply it directly (no `#if NET6_0_OR_GREATER` guards). Polyfills are available.\n\nExample (only when truly needed):\n\n```csharp\nprivate static object CreateInstance(\n    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]\n    Type type)\n{\n    return Activator.CreateInstance(type)!;\n}\n```\n\n### Suppressions: Last Resort Only — Never Without Human Approval\n\n**Do NOT add any suppression without explicit human approval.** This covers `[SuppressMessage]`, `[UnconditionalSuppressMessage]`, `#pragma warning`, and `.editorconfig` severity changes. A suppression is a true last resort, used only when a warning genuinely cannot be resolved by fixing the code without harming the design.\n\nBefore suppressing anything:\n\n1. **Fix the underlying issue first.** Most analyzer warnings indicate a real fix. For example, `S3398` (\"method should be moved\") means *move the method into the type that uses it* — never suppress it. `SA****` (StyleCop) must always be fixed, never suppressed.\n2. **If you believe a suppression is genuinely unavoidable, stop and ask the human.** Present the specific analyzer ID, why it cannot be fixed in code, and the proposed justification. Wait for explicit approval.\n3. **Only after approval**, apply it with minimal scope, the specific ID, and a clear `Justification`.\n\n---\n\n## Code Style & Quality Requirements\n\n**CRITICAL:** Follow ReactiveUI contribution guidelines:\n[https://www.reactiveui.net/contribute/index.html](https://www.reactiveui.net/contribute/index.html)\n\n### Enforced Tooling\n\n* `.editorconfig` formatting/naming conventions\n* StyleCop analyzers (build fails on violations)\n* Roslynator analyzers\n* Analysis level: latest\n* Warnings treated as errors (notably nullable and CS4014)\n* **Public APIs require XML documentation**, including protected methods on public types.\n\n### C# Style Rules (High-level)\n\n* Allman braces\n* 4 spaces, no tabs\n* Explicit visibility\n* Private/internal fields: `_camelCase`, `readonly` where possible, `static readonly` order\n* File-scoped namespaces preferred; using directives outside namespace and sorted\n* Use C# keywords (`int`, `string`) rather than BCL types\n* Prefer modern C# features where appropriate (nullable, pattern matching, switch expressions, records, init, target-typed new, etc.)\n* Use `nameof()` over string literals\n* Avoid `this.` unless necessary\n* Use `var` when it improves readability\n\nIf a specific file already follows a local style, adhere to existing file conventions.\n\n---\n\n## Zero Pragma Policy (Critical)\n\n**No `#pragma warning disable`** in production code.\n\n* **StyleCop warnings (SA****) must be fixed**, never suppressed.\n* **No analyzer warning (CA****, S**** Sonar, RCS**** Roslynator, IL**** trimming/AOT, etc.) may be suppressed without explicit human approval** — see \"Suppressions: Last Resort Only\" above. Fix the code first; if a suppression seems unavoidable, stop and ask.\n\nExample:\n\n```csharp\n// WRONG\n#pragma warning disable CA1062\npublic void MyMethod(object parameter)\n{\n    parameter.ToString();\n}\n#pragma warning restore CA1062\n\n// CORRECT\npublic void MyMethod(object parameter)\n{\n    ArgumentNullException.ThrowIfNull(parameter);\n    parameter.ToString();\n}\n\n// LAST RESORT ONLY\n[SuppressMessage(\"Microsoft.Design\", \"CA1062:ValidateArgumentsOfPublicMethods\",\n    Justification = \"TUnit guarantees non-null parameters from data sources.\")]\npublic async Task MyTest(IConverter converter, int expectedValue)\n{\n    var result = converter.GetValue();\n    await Assert.That(result).IsEqualTo(expectedValue);\n}\n```\n\n---\n\n## Testing Guidelines\n\n* Use TUnit + Microsoft Testing Platform\n* Write unit tests for new features and bug fixes\n* Prefer existing patterns in:\n\n  * `src/tests/ReactiveUI.Tests/`\n  * `src/tests/ReactiveUI.AOTTests/`\n* Use `ReactiveUI.Testing` utilities for reactive code\n\n---\n\n## Common Development Patterns\n\n### ViewModel Skeleton\n\n```csharp\npublic class SampleViewModel : ReactiveObject\n{\n    private string? _name;\n    private readonly ObservableAsPropertyHelper<bool> _isValid;\n\n    public SampleViewModel()\n    {\n        _isValid = this.WhenAnyValue(x => x.Name)\n            .Select(name => !string.IsNullOrWhiteSpace(name))\n            .ToProperty(this, nameof(IsValid));\n\n        SubmitCommand = ReactiveCommand.CreateFromTask(\n            ExecuteSubmit,\n            this.WhenAnyValue(x => x.IsValid));\n    }\n\n    public string? Name\n    {\n        get => _name;\n        set => this.RaiseAndSetIfChanged(ref _name, value);\n    }\n\n    public bool IsValid => _isValid.Value;\n\n    public ReactiveCommand<Unit, Unit> SubmitCommand { get; }\n\n    private async Task ExecuteSubmit(CancellationToken cancellationToken)\n    {\n        // Implementation\n    }\n}\n```\n\n### RxSchedulers (Preferred)\n\n```csharp\npublic IObservable<string> GetData()\n{\n    return Observable.Return(\"data\")\n        .ObserveOn(RxSchedulers.MainThreadScheduler);\n}\n```\n\n### WhenAnyValue\n\n```csharp\nthis.WhenAnyValue(\n        x => x.FirstName,\n        x => x.LastName,\n        (first, last) => $\"{first} {last}\")\n    .Subscribe(fullName => { /* handle */ });\n\nthis.WhenAnyValue(x => x.IsLoading)\n    .Where(isLoading => !isLoading)\n    .Subscribe(_ => { /* handle */ });\n```\n\n### ObservableAsPropertyHelper\n\n```csharp\nprivate readonly ObservableAsPropertyHelper<decimal> _total;\npublic decimal Total => _total.Value;\n\n_total = this.WhenAnyValue(\n        x => x.Quantity,\n        x => x.Price,\n        (qty, price) => qty * price)\n    .ToProperty(this, nameof(Total));\n```\n\n---\n\n## What to Avoid\n\n* Reflection-heavy implementations in core paths\n* Expression trees in hot paths without caching\n* Platform-specific code in `src/ReactiveUI/` core library\n* Breaking public APIs without proper versioning and documentation\n","category":"root","tokens":3088}]}