# How to Contribute to the OpenClaw Windows Node Project: A Complete Developer Guide

> Learn how to contribute to the openclaw-windows-node project. Follow our developer guide to fork the repo, build the solution, add tests, and submit a PR for x64 and ARM64.

- Repository: [openclaw/openclaw-windows-node](https://github.com/openclaw/openclaw-windows-node)
- Tags: how-to-guide
- Published: 2026-06-06

---

**To contribute to the openclaw-windows-node project, fork the repository on GitHub, install the .NET 10 SDK and WebView2 Runtime, build the solution using `dotnet build`, create unit tests in the appropriate test directories, and submit a pull request that passes the continuous integration checks for both x64 and ARM64 architectures.**

The **openclaw-windows-node** repository is a C# monorepo maintained by OpenClaw that hosts the Windows system-tray application, a shared .NET client library, and a command-line interface for interacting with OpenClaw gateways. Contributing to this project requires understanding its multi-project structure, build matrix requirements, and WebSocket-based architecture.

## Setting Up Your Development Environment

Before writing code, install the mandatory prerequisites and verify your local build chain.

### Install Prerequisites

The project requires the **.NET 10 SDK** and the **WebView2 Runtime** for the WinUI 3 tray application:

```powershell

# Install .NET 10 SDK

winget install Microsoft.DotNet.SDK.10

# Install WebView2 Runtime (required for the tray UI)

winget install Microsoft.WebView2

```

### Fork and Clone the Repository

Follow the standard fork-branch workflow:

```bash
git clone https://github.com/<YOUR_USERNAME>/openclaw-windows-node.git
cd openclaw-windows-node

```

### Verify the Build

Restore NuGet packages and compile the solution located at the repository root:

```bash
dotnet restore
dotnet build

```

The solution file `openclaw-windows-node.slnx` references all sub-projects, including `src/OpenClaw.Tray.WinUI/`, `src/OpenClaw.Shared/`, and `src/OpenClaw.Cli/`.

## Understanding the Monorepo Structure

The repository organizes functionality into distinct sub-projects. Choose your target based on the contribution type:

- **OpenClaw.Tray.WinUI** (`src/OpenClaw.Tray.WinUI/`): WinUI 3 system-tray application ("Molty" UI). Entry point is [`App.xaml.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/App.xaml.cs). Build with `dotnet build src/OpenClaw.Tray.WinUI`.
- **OpenClaw.Shared** (`src/OpenClaw.Shared/`): Lightweight .NET client library that communicates with OpenClaw gateways over WebSocket. Key file is [`OpenClawGatewayClient.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/OpenClawGatewayClient.cs). Build with `dotnet build src/OpenClaw.Shared`.
- **OpenClaw.Cli** (`src/OpenClaw.Cli/`): Command-line interface that reuses tray settings to send `chat.send` messages. Entry point is [`Program.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/Program.cs). Build with `dotnet build src/OpenClaw.Cli`.
- **OpenClaw.SetupEngine** (`src/OpenClaw.SetupEngine/`): First-run onboarding wizard logic and setup-code decoder.

## Running and Testing Changes Locally

### Launch the Tray Application

For UI development, use the isolated launch script to prevent interference with your production `%APPDATA%` settings:

```powershell
.\run-app-local.ps1

```

This script runs the unpackaged tray app with a temporary profile, allowing multiple work-trees to run side-by-side.

### Test the CLI

The CLI uses the same settings file (`%APPDATA%\OpenClawTray\settings.json`) as the tray app:

```bash
dotnet run --project src/OpenClaw.Cli -- --help

```

### Execute Unit Tests

Add tests to the appropriate suite and run the full matrix:

- **Shared library tests**: Located at `tests/OpenClaw.Shared.Tests/` (e.g., [`WindowsNodeClientTests.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/WindowsNodeClientTests.cs)).
- **Tray helper tests**: Located at `tests/OpenClaw.Tray.Tests/`.

Run all tests with:

```bash
dotnet test

```

The CI pipeline (defined in [`.github/workflows/ci.yml`](https://github.com/openclaw/openclaw-windows-node/blob/main/.github/workflows/ci.yml)) executes this same command.

### Validate Multi-Architecture Builds

Since the project ships x64 and ARM64 binaries, test both locally:

```powershell

# x64 build

dotnet build src/OpenClaw.Tray.WinUI -r win-x64

# ARM64 build (requires ARM64 host or emulator)

dotnet build src/OpenClaw.Tray.WinUI -r win-arm64

```

## Contributing Code Changes

### Extending the Gateway Client

When modifying [`OpenClawGatewayClient.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/OpenClawGatewayClient.cs), respect the **reconnection/back-off logic** implemented in lines 48-58 of that file. To add a new WebSocket event type:

1. Declare the model in [`src/OpenClaw.Shared/Models.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/src/OpenClaw.Shared/Models.cs).
2. Add an event handler field: `public event EventHandler<MyNewEventData>? MyNewEvent;`.
3. Update the `ListenForMessagesAsync` switch statement to deserialize the JSON payload and invoke the event.

Example implementation:

```csharp
// 1. Model declaration
public class MyNewEventData
{
    public string Property { get; set; } = string.Empty;
}

// 2. Event field in OpenClawGatewayClient.cs
public event EventHandler<MyNewEventData>? MyNewEvent;

// 3. Deserialization in ListenForMessagesAsync
if (eventType == "my_new_event")
{
    var data = JsonSerializer.Deserialize<MyNewEventData>(json);
    MyNewEvent?.Invoke(this, data!);
}

```

### UI Thread Safety

The tray UI requires marshaling updates onto the UI thread via `DispatcherQueue.TryEnqueue()`. Reference [`src/OpenClaw.Tray.WinUI/Chat/OpenClawChatDataProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/src/OpenClaw.Tray.WinUI/Chat/OpenClawChatDataProvider.cs) for examples of safely raising UI events from background WebSocket threads.

### Icon and Resource Management

When working with the system tray, ensure proper **GDI handle cleanup** in [`src/OpenClaw.Tray.WinUI/Helpers/IconHelper.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/src/OpenClaw.Tray.WinUI/Helpers/IconHelper.cs). Always call `DestroyIcon` to prevent handle leaks that prevent the tray icon from appearing.

## Submitting Your Contribution

### Branch and Commit Workflow

1. Create a feature branch: `git checkout -b feature/my-new-feature`.
2. Follow conventional commit styles (e.g., `feat:`, `fix:`, `docs:`).
3. Update documentation in `docs/` or [`DEVELOPMENT.md`](https://github.com/openclaw/openclaw-windows-node/blob/main/DEVELOPMENT.md) if you modify architecture or add environment variables.

### Pull Request Requirements

The PR template requires:
- A description of the change and its motivation.
- Link to relevant issues (e.g., `Fixes #123`).
- Documentation updates.

CI automatically validates:
- Build success for both x64 and ARM64.
- Unit test passage (`dotnet test`).
- Code signing (for tagged releases only).

## Debugging Common Development Issues

| Symptom | Root Cause | Resolution |
|---------|-------------|------------|
| **Tray icon never appears** | GDI handle leak in [`IconHelper.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/IconHelper.cs) | Verify `DestroyIcon` is called; see [`DEVELOPMENT.md`](https://github.com/openclaw/openclaw-windows-node/blob/main/DEVELOPMENT.md) section *GDI Handle Management*. |
| **WebView2 fails to load** | Missing runtime or architecture mismatch | Confirm WebView2 is installed (`winget list Microsoft.WebView2`) and binary RID matches (`win-x64` vs `win-arm64`). |
| **Gateway connection loops** | Invalid token or URL | Check `%APPDATA%\OpenClawTray\settings.json` for `gatewayUrl` and `gatewayToken`; test with `curl http://localhost:18789/health`. |
| **Local test failures only** | Hard-coded temp paths | Use `Path.GetTempPath()` instead of `%LOCALAPPDATA%` to ensure test isolation. |

## Summary

- The **openclaw-windows-node** monorepo contains three main components: a WinUI 3 tray app (`OpenClaw.Tray.WinUI`), a WebSocket client library (`OpenClaw.Shared`), and a CLI (`OpenClaw.Cli`).
- Install **.NET 10 SDK** and **WebView2 Runtime** before building.
- Use `.\run-app-local.ps1` to test the tray UI without affecting production settings.
- Add unit tests to `tests/OpenClaw.Shared.Tests/` or `tests/OpenClaw.Tray.Tests/` and run `dotnet test` before submitting.
- Validate both **x64** and **ARM64** builds when modifying UI code.
- Follow the reconnection logic patterns in [`OpenClawGatewayClient.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/OpenClawGatewayClient.cs) when adding new gateway events.
- Submit PRs against the upstream repository; CI handles signing and installer generation automatically when version tags are pushed.

## Frequently Asked Questions

### What are the minimum prerequisites to build openclaw-windows-node?

You need the **.NET 10 SDK** and the **Microsoft WebView2 Runtime**. Install both via Windows Package Manager (`winget install Microsoft.DotNet.SDK.10` and `winget install Microsoft.WebView2`), then run `dotnet build` at the repository root.

### Which sub-project should I modify for my contribution?

Modify **OpenClaw.Shared** (`src/OpenClaw.Shared/`) if you are adding new WebSocket event types or authentication logic. Modify **OpenClaw.Tray.WinUI** (`src/OpenClaw.Tray.WinUI/`) for UI features, hotkeys, or deep-link handling. Modify **OpenClaw.Cli** (`src/OpenClaw.Cli/`) for command-line validation or formatting improvements.

### How do I add a new WebSocket event type to the gateway client?

Declare the data model in [`src/OpenClaw.Shared/Models.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/src/OpenClaw.Shared/Models.cs), add an `event EventHandler<T>?` field in [`OpenClawGatewayClient.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/OpenClawGatewayClient.cs), and extend the `ListenForMessagesAsync` switch statement to deserialize and fire the event. See the **Architecture Overview** section in [`DEVELOPMENT.md`](https://github.com/openclaw/openclaw-windows-node/blob/main/DEVELOPMENT.md) for the exact pattern.

### Do I need to sign the binaries before submitting a pull request?

No. Azure Trusted Signing occurs automatically in the CI pipeline when maintainers push semantic version tags (e.g., `v1.2.3`). Contributors only need to ensure the code builds and passes `dotnet test` locally; the [`.github/workflows/ci.yml`](https://github.com/openclaw/openclaw-windows-node/blob/main/.github/workflows/ci.yml) workflow handles signing and installer generation.