# How to Understand the Code Flow of Wand Enhancer: A Complete Technical Guide

> Understand the Wand Enhancer code flow. This technical guide details the three-stage pipeline: ASAR extraction, script injection, and WebSocket communication on port 3223.

- Repository: [k1tbyte/Wand-Enhancer](https://github.com/k1tbyte/Wand-Enhancer)
- Tags: technical-guide
- Published: 2026-07-13

---

**Wand Enhancer bridges a .NET WPF patcher with an Electron web-panel through a three-stage pipeline that extracts ASAR archives, injects bridge scripts, and establishes WebSocket communication on port 3223.**

To understand the code flow of Wand Enhancer, you must trace how the **k1tbyte/Wand-Enhancer** repository coordinates between its C# WPF frontend and TypeScript Electron backend. The architecture follows a clear sequence: the WPF application initializes the UI, the patcher modifies the target ASAR bundle, and the Electron renderer establishes bidirectional IPC with the injected bridge.

## Stage 1: Application Startup and WPF Initialization

The execution begins in the .NET layer where the WPF application sets up global handlers and presents the main interface.

### Entry Point and Global Setup

In [`WandEnhancer/Program.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/WandEnhancer/Program.cs), the `Main` method serves as the single entry point. It instantiates a WPF `App` class, configures global exception handlers, and launches `MainWindow`. This ensures that any unhandled exceptions in the patching process are captured before the UI renders.

### View-Model Architecture

The [`MainWindowVm.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/MainWindowVm.cs) file in `WandEnhancer/View/MainWindow/` implements the view-model pattern that drives all user interactions. It maintains the log list displayed in the UI and handles commands such as **Patch** and **Launch Remote Panel**. When a user initiates a patch, the view-model coordinates the transition from UI interaction to file system operations.

## Stage 2: ASAR Extraction and Patching

Once the user clicks **Patch**, the flow shifts from the WPF layer to low-level ASAR manipulation using the embedded `AsarSharp` library.

### Extraction Logic

The patcher utilizes [`AsarSharp/Utils/NativeMethods.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarSharp/Utils/NativeMethods.cs) to extract `resources/app.asar` from the target Wand installation. The extraction process creates a temporary directory structure where the archive contents are unpacked for manipulation. According to the source code, the extractor handles both the packed ASAR and its unpacked counterpart directories.

### Script Injection and Configuration

After extraction, the patcher copies `web-panel/dist/bridge.cjs` into the extracted ASAR under the `remote-panel/` folder. It also copies the default renderer scripts from `web-panel/dist/renderer-scripts/` into `remote-panel/renderer-scripts/`.

Custom user scripts specified in `PatchConfig.CustomScriptPaths` are injected at this stage as well. This configuration allows users to extend functionality without modifying core bridge files. The patching logic then repacks the modified directory back into `resources/app.asar`.

## Stage 3: Electron Bridge and Remote UI Communication

With the patched ASAR in place, the Electron side initializes and establishes the communication layer between the Wand client and the remote web interface.

### Bridge Constants and Protocol

The bridge runtime configuration resides in [`web-panel/bridge/src/constants.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/constants.ts). This file defines the WebSocket port (`3223`), HTTP/WS endpoints, and IPC channel names used throughout the application. **Port alignment** is critical: the C# side assumes the bridge listens on port 3223, so any modification must be synchronized in this constants file.

Message contracts are strictly typed through [`web-panel/protocol/messages.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/protocol/messages.ts) and validated via [`web-panel/protocol/validation.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/protocol/validation.ts). The JSON schema in [`web-panel/protocol/web-contract.json`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/protocol/web-contract.json) serves as the authoritative reference for all WebSocket payloads.

### Renderer Scripts and IPC

Upon launch, the Electron panel loads [`web-panel/bridge/scripts/default/installed-apps-sync.js`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/scripts/default/installed-apps-sync.js). This default renderer script performs three essential functions:

- Subscribes to Wand’s IPC services to monitor installed games
- Builds a snapshot of the current game library
- Handles remote commands via the `remote_command` channel

The script communicates with the WPF backend through the `ipcRenderer` module, forwarding game-status events and executing play/stop commands received from the remote UI.

## Critical Implementation Details

Several architectural constraints govern how components interact across the stack.

- **Port Alignment**: The C# patcher and TypeScript bridge must agree on port 3223 as defined in [`constants.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/constants.ts). Mismatches break the WebSocket connection.

- **Development Guards**: All mock data is wrapped in `import.meta.env.DEV` checks, ensuring production builds exclude demonstration content.
- **Storage Abstraction**: Direct `localStorage` access is prohibited in favor of [`web-panel/src/shared/storage.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/src/shared/storage.ts), which centralizes JSON serialization and error handling.
- **Pro Activation**: Pro-state patches rewrite three service methods and the Redux reducer within the ASAR patch pipeline, as documented in [`AGENTS.md`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AGENTS.md), to maintain subscription flags across language changes.

## Code Examples

The following snippets demonstrate the transition points between architecture layers.

**Starting a patch from the WPF UI (C#):**

```csharp
// Inside MainWindowVm.cs – invoked by the “Patch” button
public async Task PatchAsync()
{
    var extractor = new AsarSharp.AsarExtractor();
    await extractor.ExtractAllAsync(@"resources/app.asar", @"temp/extracted");
    // Copy bridge and scripts (pseudo-code, actual copy logic lives in PatchVectorsPopup)
    File.Copy(@"web-panel/dist/bridge.cjs", @"temp/extracted/remote-panel/bridge.cjs", true);
    // Re-pack the ASAR
    await extractor.PackAsync(@"temp/extracted", @"resources/app.asar");
}

```

**Subscribing to installed apps in the renderer (TypeScript):**

```typescript
import { ipcRenderer } from 'electron';
import { sendMessage } from '../bridge';
import type { GameSnapshot } from '../protocol/messages';

ipcRenderer.on('wand-remote-installed-apps', (_event, apps: GameSnapshot[]) => {
  // Update UI store
  store.dispatch({ type: 'SET_INSTALLED_APPS', payload: apps });
});

// Request a fresh snapshot on start-up
sendMessage('hello', { request: 'installed_apps' });

```

**Sending a remote play command:**

```typescript
// From the UI when the user clicks “Play”
sendMessage('remote_command', {
  command: 'play',
  gameId: selectedGame.id,
});

```

## Summary

- **Entry Point**: [`Program.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/Program.cs) initializes the WPF application and global exception handlers.
- **View-Model**: [`MainWindowVm.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/MainWindowVm.cs) coordinates UI actions and delegates patching operations.
- **ASAR Manipulation**: [`AsarSharp/Utils/NativeMethods.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarSharp/Utils/NativeMethods.cs) handles extraction and repacking of the target archive.
- **Script Injection**: Bridge files and custom scripts are copied into `remote-panel/` during the patch phase.
- **Communication Layer**: The bridge uses [`constants.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/constants.ts) (port 3223) and [`web-contract.json`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-contract.json) for typed message exchange.
- **Renderer Logic**: [`installed-apps-sync.js`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/installed-apps-sync.js) manages game state synchronization and remote command execution.
- **Storage**: All persistence flows through [`web-panel/src/shared/storage.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/src/shared/storage.ts) rather than direct `localStorage` access.

## Frequently Asked Questions

### What is the entry point for the Wand Enhancer application?

The execution begins in [`WandEnhancer/Program.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/WandEnhancer/Program.cs), where the `Main` method creates the WPF `App` instance, configures global exception handlers, and opens `MainWindow`. This serves as the bridge between the operating system and the WPF view-model architecture.

### How does the patcher modify the Wand client ASAR archive?

The patcher uses [`AsarSharp/Utils/NativeMethods.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarSharp/Utils/NativeMethods.cs) to extract `resources/app.asar`, copies `web-panel/dist/bridge.cjs` and renderer scripts into a `remote-panel/` subdirectory, and repacks the archive. Custom scripts from `PatchConfig.CustomScriptPaths` are also injected during this process.

### Which file defines the WebSocket port for the remote panel?

The port is defined in [`web-panel/bridge/src/constants.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/constants.ts) as `3223`. This value must remain synchronized with the C# side expectations; changing it requires updates in both the TypeScript bridge configuration and the WPF patcher logic.

### Where should I store configuration data in the web panel?

All `localStorage` operations must route through [`web-panel/src/shared/storage.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/src/shared/storage.ts). This abstraction layer handles JSON serialization and prevents direct access to the browser storage API, ensuring consistent data handling across the application.