|
2 | 2 | applyTo: '**' |
3 | 3 | --- |
4 | 4 |
|
5 | | -Use the instructions in `AGENTS.md` in the solution root. |
| 5 | +# Project Overview |
| 6 | + |
| 7 | +ControlR is a cross-platform solution for remote access and remote control of devices. It primarily uses the latest .NET version for backend web, frontend web (via Blazor), and the desktop applications. |
| 8 | + |
| 9 | +## Quick Start |
| 10 | + |
| 11 | +The easiest way to build and run the application is to use the provided launch profiles in your IDE. |
| 12 | + |
| 13 | +- **Visual Studio / JetBrains Rider:** Use the **"Full Stack"** launch profile to start all the necessary projects for a complete debugging experience. |
| 14 | +- **VS Code:** |
| 15 | + - Use the **"Full Stack (Debug)"** config in `launch.json` for general debugging. |
| 16 | + - Use the **"Full Stack (Hot Reload)"** config for Blazor UI development to get fast feedback on changes. |
| 17 | +- **CLI:** To simply build the entire solution, run `dotnet build ControlR.slnx` from the root directory. |
| 18 | + |
| 19 | +## Context Scope |
| 20 | + |
| 21 | +- Do not include any files or folders within `ControlR.Web.Server/novnc/` in your context. |
| 22 | +- Do not include anything within folders named `node_modules` in your context. |
| 23 | + |
| 24 | +## High-Level Architecture |
| 25 | + |
| 26 | +The following diagram shows the communication flow between the major components of the system. |
| 27 | + |
| 28 | +```mermaid |
| 29 | +graph TD |
| 30 | + subgraph "User's Browser" |
| 31 | + A[Web Client - Blazor] |
| 32 | + end |
| 33 | +
|
| 34 | + subgraph "Cloud / Server Host" |
| 35 | + B[Web Server - ASP.NET Core] |
| 36 | + C[WebSocket Relay] |
| 37 | + end |
| 38 | +
|
| 39 | + subgraph "Remote Machine" |
| 40 | + D[Agent - Background Service] |
| 41 | + E[Desktop Client - Avalonia] |
| 42 | + end |
| 43 | +
|
| 44 | + A -- HTTP & SignalR --> B |
| 45 | + B -- SignalR UI Updates --> A |
| 46 | +
|
| 47 | + D -- SignalR Heartbeat/Data --> B |
| 48 | + B -- SignalR Commands --> D |
| 49 | +
|
| 50 | + A -- Remote Control Stream --> C |
| 51 | + C -- Remote Control Stream --> E |
| 52 | +
|
| 53 | + D -- IPC via Named Pipes --> E |
| 54 | + E -- IPC via Named Pipes --> D |
| 55 | +``` |
| 56 | + |
| 57 | +## Project Structure |
| 58 | + |
| 59 | +### Core Components |
| 60 | + |
| 61 | +- **ControlR.Web.Server** - ASP.NET Core web server with API endpoints and SignalR hubs |
| 62 | +- **ControlR.Web.Client** - Blazor WebAssembly frontend using MudBlazor components |
| 63 | +- **ControlR.Web.AppHost** - .NET Aspire orchestration host for development |
| 64 | +- **ControlR.Web.ServiceDefaults** - Shared service configuration and defaults |
| 65 | +- **ControlR.Web.WebSocketRelay** - WebSocket relay service for real-time communication |
| 66 | +- **ControlR.Agent** - Background service/daemon that runs on controlled devices |
| 67 | +- **ControlR.DesktopClient** - Cross-platform Avalonia UI desktop application |
| 68 | + |
| 69 | +### Platform-Specific Components |
| 70 | + |
| 71 | +- **ControlR.DesktopClient.Windows** - Windows-specific desktop client implementations |
| 72 | +- **ControlR.DesktopClient.Linux** - Linux-specific desktop client implementations |
| 73 | +- **ControlR.DesktopClient.Mac** - macOS-specific desktop client implementations |
| 74 | +- **ControlR.DesktopClient.Common** - Shared desktop client functionality |
| 75 | +- **ControlR.Agent.Common** - Shared agent functionality across platforms |
| 76 | + |
| 77 | +### Shared Libraries |
| 78 | + |
| 79 | +- **ControlR.Libraries.Shared** - Core shared models, DTOs, and utilities |
| 80 | +- **ControlR.Libraries.DevicesCommon** - Device-related common functionality |
| 81 | +- **ControlR.Libraries.DevicesNative** - Native device interaction libraries |
| 82 | +- **ControlR.Libraries.Clients** - Client-side shared functionality |
| 83 | +- **ControlR.Libraries.ApiClient** - Generated API client for server communication |
| 84 | +- **ControlR.Libraries.Ipc** - Inter-process communication utilities |
| 85 | +- **ControlR.Libraries.Signalr.Client** - SignalR client abstractions |
| 86 | +- **ControlR.Libraries.WebSocketRelay.Common** - WebSocket relay shared components |
| 87 | +- **ControlR.Libraries.NativeInterop.Windows** - Windows native interop |
| 88 | +- **ControlR.Libraries.NativeInterop.Unix** - Unix/Linux native interop |
| 89 | + |
| 90 | +## Communication Architecture |
| 91 | + |
| 92 | +### SignalR Hub Pattern |
| 93 | + |
| 94 | +- **AgentHub** - Receives device heartbeats and forwards data to ViewerHub groups |
| 95 | +- **ViewerHub** - Handles web client connections and remote control requests |
| 96 | +- Agents send `DeviceDto` heartbeats via `UpdateDevice()` which triggers real-time UI updates |
| 97 | +- Hub groups organize connections by tenant, device tags, and user roles for targeted messaging |
| 98 | + |
| 99 | +### Agent-DesktopClient IPC |
| 100 | + |
| 101 | +- Agent runs as system service/daemon, DesktopClient runs in user sessions |
| 102 | +- Communication via named pipes using `IIpcConnection` abstractions |
| 103 | +- Agent forwards remote control requests to appropriate DesktopClient via `RemoteControlRequestIpcDto` |
| 104 | +- DesktopClient reports back to Agent, which relays to web server via SignalR |
| 105 | + |
| 106 | +## Technology Stack |
| 107 | + |
| 108 | +### Backend |
| 109 | + |
| 110 | +- **.NET 9** - Latest .NET framework |
| 111 | +- **ASP.NET Core** - Web framework for APIs and web hosting |
| 112 | +- **SignalR** - Real-time communication |
| 113 | +- **Entity Framework Core** - ORM for database operations |
| 114 | +- **PostgreSQL** - Primary database (with InMemory option for testing) |
| 115 | + |
| 116 | +### Frontend |
| 117 | + |
| 118 | +- **Blazor WebAssembly** - Client-side web UI framework |
| 119 | +- **MudBlazor** - Material Design component library |
| 120 | +- **JavaScript Interop** - For browser-specific functionality |
| 121 | + |
| 122 | +### Desktop Applications |
| 123 | + |
| 124 | +- **Avalonia UI** - Cross-platform .NET UI framework |
| 125 | +- **Multi-targeting** - Supports Windows, Linux, and macOS |
| 126 | +- **Native Interop** - Platform-specific functionality via P/Invoke |
| 127 | +- **Avalonia Icons** - Avalonia Icons can be retrieved from here: https://avaloniaui.github.io/icons.html. They should be added to the `Icons.axaml` resource dictionary as needed. |
| 128 | +- **Localization** - Don't use hardcoded strings in the UI. |
| 129 | + - In AXAML, bind to the `Localization` class properties. Example: `Content="{x:Static common:Localization.OkText}"` |
| 130 | + - Add keys and values to the JSON files under `/ControlR.DesktopClient.Common/Resources/Strings/`. |
| 131 | + |
| 132 | +## Architecture Patterns |
| 133 | + |
| 134 | +### Web Architecture |
| 135 | + |
| 136 | +- **Clean Architecture** - Separation of concerns with clear dependencies |
| 137 | +- **Dependency Injection** - Built-in .NET DI container |
| 138 | + |
| 139 | +### Service Registration |
| 140 | + |
| 141 | +In general, services are not registered directly in `Program.cs`. Instead, extension methods are used to group service registrations for different parts of the application. Here's where you can find the main service registration methods for each project: |
| 142 | + |
| 143 | +- **ControlR.Agent**: `AddControlRAgent` in `ControlR.Agent.Common\Startup\HostBuilderExtensions.cs` |
| 144 | +- **ControlR.Web.Server**: `AddControlrServer` in `ControlR.Web.Server\Startup\WebApplicationBuilderExtensions.cs` |
| 145 | +- **ControlR.Web.Client**: `AddControlrWebClient` in `ControlR.Web.Client\Startup\IServiceCollectionExtensions.cs` |
| 146 | +- **ControlR.DesktopClient**: `AddControlrDesktop` in `ControlR.DesktopClient\StaticServiceProvider.cs` |
| 147 | + |
| 148 | +### Desktop Architecture |
| 149 | + |
| 150 | +- **MVVM Pattern** - Model-View-ViewModel for UI separation |
| 151 | +- **Localization** - `Localization.cs` will pull region-specific strings from `/Resources/Strings/{locale}.json` |
| 152 | + - All text in the UI should be bound to localization keys using `x:Static` |
| 153 | +- **Command Pattern** - For user actions and operations |
| 154 | +- **IMessenger** - Cross-component communication |
| 155 | +- **Service Layer** - Business logic abstraction |
| 156 | + |
| 157 | +### Cross-Platform Strategy |
| 158 | + |
| 159 | +- **Shared Libraries** - Common functionality across platforms |
| 160 | +- **Platform Abstraction** - Interface-based platform-specific implementations |
| 161 | +- **Conditional Compilation** - Platform-specific code paths |
| 162 | +- **Agent service layout** — The shared library `ControlR.Agent.Common` organizes platform-specific implementations under platform-named `Services` sub-namespaces/folders (for example `.Services.Windows`, `.Services.Linux`, `.Services.Mac`). Interfaces live in the common namespace and the platform implementations are selected via conditional compilation, platform attributes, or at host registration time. |
| 163 | +- **DesktopClient per-platform projects** — The Desktop client isolates native UI/OS integrations into separate projects (`ControlR.DesktopClient.Windows`, `.Linux`, `.Mac`) while keeping shared UI and view-model code in `ControlR.DesktopClient.Common`. `ControlR.DesktopClient.csproj` conditionally references or multi-targets the appropriate platform project so only the target-OS code is built and linked. This keeps native UI and OS integrations isolated in their own projects while allowing shared UI and view-model code to remain common. |
| 164 | + |
| 165 | +## Key Features |
| 166 | + |
| 167 | +- **Remote Desktop Control** - Full desktop access and control |
| 168 | +- **Screen Sharing** - Real-time screen streaming |
| 169 | +- **File Transfer** - Secure file operations between devices |
| 170 | +- **Multi-tenancy** - Support for multiple organizations |
| 171 | +- **Self-hosting** - Can be deployed on-premises |
| 172 | +- **Cross-platform** - Windows, Linux, macOS support |
| 173 | +- **Authentication** - Identity Framework with optional OAuth integration (GitHub, Microsoft) |
| 174 | +- **Real-time Communication** - SignalR and WebSocket support |
| 175 | + |
| 176 | +## Development Guidelines |
| 177 | + |
| 178 | +### General Coding Standards |
| 179 | + |
| 180 | +- Use 2 spaces for indentation |
| 181 | +- Don't try to be overly clever. Code should be easily readable. |
| 182 | +- Don't try to fit everything on one line. Use white space for readability. |
| 183 | +- **CRITICAL: All code written is production code.** Never write placeholder implementations, TODOs, or comments suggesting the code needs improvement "in production" or is a "simplification". Every implementation must be complete, correct, and production-ready. |
| 184 | +- **Never use phrases like:** |
| 185 | + - "In production, you should..." |
| 186 | + - "This is a simplification..." |
| 187 | + - "This assumes..." (unless documenting actual API contracts) |
| 188 | + - "This is an estimate..." |
| 189 | + - "// TODO:", "// FIXME:", "// HACK:", etc. |
| 190 | +- **If you don't know how to implement something correctly:** |
| 191 | + - Research the proper implementation |
| 192 | + - Ask for clarification |
| 193 | + - DO NOT write incomplete code with apologetic comments |
| 194 | +- **All implementations must handle:** |
| 195 | + - Edge cases appropriately |
| 196 | + - Error conditions with proper error handling |
| 197 | + - Resource cleanup (dispose patterns, etc.) |
| 198 | + - Thread safety where applicable |
| 199 | + - Format variations, null checks, boundary conditions |
| 200 | + |
| 201 | +### Build and Task System |
| 202 | + |
| 203 | +- Use the following build command to verify that changes compile: `dotnet build ControlR.slnx --verbosity quiet` |
| 204 | + - If successful, there will be no output. |
| 205 | + - If unsuccessful, errors will be displayed. |
| 206 | +- When a terminal task outputs "Terminal will be reused by tasks, press any key to close it.", interpret this as the task completion signal. |
| 207 | + - If no errors were displayed prior to this message, treat the task as successful. |
| 208 | + - Do not wait for user interaction or attempt to close the terminal. Proceed immediately to the next step. |
| 209 | +- Do not attempt to fix warning `BB0001: Member '{member_name}' is not in the correct order`. You are really bad at fixing this. Just mention it in your summary, and I'll fix it. |
| 210 | + |
| 211 | +### C# Coding Standards |
| 212 | + |
| 213 | +- Use the latest C# language features and default recommendations. |
| 214 | +- Use StyleCop conventions when ordering class members. |
| 215 | +- Do not use null-forgiving operator (!) outside of tests. Handle null checks appropriately. |
| 216 | +- Prefer var of explicit types for variables. |
| 217 | +- Reduce indentation by returning/continuing early and inverting conditions when appropriate. |
| 218 | +- Always prefer collection expressions to initialize collections (e.g. '[]'). |
| 219 | +- If an interface only has one implementation, keep the interface and implementation in the same file. |
| 220 | +- Do not leave comments that reference historical changes, prior implementations, or what was fixed. Comments should explain current intent only. |
| 221 | +- Don't append "Async" suffix to async method names, unless to specifically distinguish from an existing sync method of the same name. |
| 222 | +- Open and close braces should be on their own lines. |
| 223 | + |
| 224 | +### Platform-Specific Development |
| 225 | + |
| 226 | +- Use `[SupportedOSPlatform]` attributes for platform-specific code |
| 227 | +- Conditional compilation symbols: `WINDOWS_BUILD`, `MAC_BUILD`, `LINUX_BUILD`, `UNIX_BUILD` |
| 228 | +- Platform detection via `ISystemEnvironment.Platform` and `RuntimeInformation` |
| 229 | + |
| 230 | +### Web UI Guidelines |
| 231 | + |
| 232 | +- Use MudBlazor components where appropriate for the UI. |
| 233 | +- When making changes to `.razor` files, check if there's a code-behind `.cs` file associated with it. If so, add your C# code there, including service injections. |
| 234 | +- Prefer using code-behind CS files for Razor components instead of using the `@code {}` block in Razor files. |
| 235 | + |
| 236 | +### Project Organization |
| 237 | + |
| 238 | +- Follow the established folder structure and naming conventions. |
| 239 | +- Keep platform-specific code in appropriate platform projects. |
| 240 | +- Use shared libraries for common functionality across projects. |
| 241 | +- DTOs go under `/Libraries/ControlR.Libraries.Shared/Dtos/`, under their respective namespace. |
| 242 | + - `HubDtos` contain DTOs used in SignalR hubs. |
| 243 | + - `IpcDtos` contain DTOs used in the IPC connection between `Agent` and `DesktopClient`. |
| 244 | + - `ServerApi` contains DTOs used in the REST API. |
| 245 | + - `StreamerDtos` contain DTOs used by remote control, which get routed through the websocket relay. |
| 246 | +- Maintain clear separation between business logic and UI code. |
| 247 | +- **Planning documents and implementation notes** should be placed in the `/.plans/` directory, NOT committed to the main source tree. |
| 248 | +- **Do not create random public classes** in files containing other classes. Instead: |
| 249 | + - Use existing shared types from `ControlR.Libraries.Shared.Primitives` when available (e.g., `Result<T>`) |
| 250 | + - If a new type is needed, create it in its own file in the appropriate namespace |
| 251 | + - Check for existing types before creating duplicates |
| 252 | + |
| 253 | +### SignalR Communication Patterns |
| 254 | + |
| 255 | +- Device heartbeats flow: `Agent` → `AgentHub.UpdateDevice()` → `ViewerHub` groups |
| 256 | +- Remote control requests: `ViewerHub` → `AgentHub` → `IPC` → `DesktopClient` |
| 257 | +- Use hub groups for tenant isolation and role-based access control |
| 258 | +- Group naming pattern: `HubGroupNames.GetTenantDevicesGroupName()`, `GetTagGroupName()`, etc. |
| 259 | + |
| 260 | +### Testing Strategy |
| 261 | + |
| 262 | +- Use xUnit for unit testing. |
| 263 | +- Write unit tests for business logic and services. |
| 264 | +- Maintain test coverage for shared libraries. |
| 265 | +- For server tests, use helpers `Tests\ControlR.Web.Server.Tests\Helpers\` when appropriate. |
| 266 | + |
| 267 | +### Security Considerations |
| 268 | + |
| 269 | +- Always validate and sanitize user inputs. |
| 270 | +- Use `AuthorizeAttribute` and `IAuthorizationService` for endpoint authorization. |
| 271 | + |
| 272 | +### Performance Guidelines |
| 273 | + |
| 274 | +- Optimize database queries with proper indexing. |
| 275 | +- Use async/await patterns for I/O operations. |
| 276 | +- Cache frequently accessed data appropriately. |
| 277 | + |
| 278 | +### Error Handling |
| 279 | + |
| 280 | +- Use structured logging with Serilog. |
| 281 | +- Implement proper exception handling and recovery. |
| 282 | +- Provide meaningful error messages to users. |
| 283 | +- Log errors with appropriate context for debugging. |
| 284 | + |
| 285 | +### Documentation |
| 286 | + |
| 287 | +- Use XML documentation comments for public APIs. |
| 288 | +- Maintain README files for complex components. |
| 289 | +- Document configuration options and environment variables. |
| 290 | +- Keep API documentation up to date. |
0 commit comments