This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
TrackAudio is a cross-platform (macOS, Linux, Windows) Audio-For-VATSIM ATC client built as an Electron app with a C++ native backend. It connects to the VATSIM voice network, allowing air traffic controllers to transmit/receive on radio frequencies.
git submodule update --init --recursive backend/vcpkg
git submodule update --init --recursive backend/extern/afv-native
git submodule update --init --recursive backend/extern/libuiohook
pnpm run build:backend # Compile C++ native module
pnpm install # Install all dependencies (includes the built native module)pnpm run dev # Start Electron with hot-reload via electron-vitepnpm run build:backend # Recompile native module
pnpm install # Re-install updated .tgz package
pnpm run devpnpm run lint # ESLint with auto-fix
pnpm run format # Prettier formatting
pnpm run typecheck # TypeScript checking (both node and web targets)
pnpm run typecheck:node # TypeScript check for main/preload only
pnpm run typecheck:web # TypeScript check for renderer onlypnpm run build # typecheck + electron-vite build
pnpm run build:win # Package for Windows
pnpm run build:mac # Package for macOS
pnpm run build:linux # Package for LinuxThere is no test suite configured.
React UI (src/renderer/src/)
↕ IPC via context bridge
Electron Main Process (src/main/index.ts)
↕ Direct N-API calls + callback registration
C++ Native Module (backend/src/)
↕ afv-native SDK
VATSIM Voice Network
- React 18 + TypeScript with Vite bundling
- Zustand for state management with 4 stores:
radioStore— radio frequencies, rx/tx/xc state, PTT statussessionStore— connection state, callsign, network statusutilStore— VU meter, platform info, PTT key names, UI mode flagserrorStore— error messages and dialog state
- Bootstrap 5 + SCSS for styling
- Path alias:
@renderer/*→src/renderer/src/*
- Window management with mini-mode (Ctrl/Cmd+M) and always-on-top
- IPC handlers bridging renderer requests to native module calls
- Event queue system: buffers native events until renderer signals ready via
settings-ready - Configuration persistence via
electron-store - Auto-update system via
electron-updater
- Exposes
window.apiobject to renderer via Electron contextBridge - Two communication patterns:
- Invoke (request/response): renderer calls
window.api.someMethod()→ipcRenderer.invoke→ipcMain.handle→ native function → returns result - Events (push from native): C++ calls registered callback → main process broadcasts via
webContents.send→ renderer listens viawindow.api.on()
- Invoke (request/response): renderer calls
- Node-API (N-API v7) native addon compiled with cmake-js
- backend/src/main.cpp — N-API function exports and entry point
- backend/include/atcClientWrapper.h — Wrapper around afv-native SDK client
- backend/src/sdk.cpp — WebSocket/HTTP server (RestinIO) exposing radio state to external clients (e.g., Stream Deck plugins)
- backend/src/InputHandler.cpp — PTT key detection via libuiohook + joystick support
- backend/src/RemoteData.cpp — Fetches station/frequency data from VATSIM
- Dependencies managed via vcpkg (backend/vcpkg.json)
- Key external submodules:
afv-native(VATSIM voice SDK),libuiohook(input monitoring)
config.type.ts— Configuration interface used by both main process and renderercommon.ts— Frequency constants (UnicomFrequency, GuardFrequency)
- TypeScript/JS: Prettier with single quotes, 100-char width, no trailing commas
- Indentation: 2 spaces, LF line endings
- C++: clang-format (backend code)
- ESLint uses strict TypeScript checking (
strictTypeChecked+stylisticTypeChecked) - ESLint ignores:
backend/,node_modules/,dist/,build/,out/
- macOS: Requires Homebrew packages
pkg-configandutf8proc; window vibrancy used for transparency - Linux: Requires SFML dependencies and X11/XCB development libraries; audio backends: ALSA, JACK, PulseAudio
- Windows: Requires Visual Studio with "Desktop development with C++" workload and Python 3.11+