gitea.wenil.tech is the old (internal-DNS-only) domain; the live host is gitea.bvrdo.online. Use a direct release-asset link so download works even while the instance ROOT_URL still points at the internal IP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12 KiB
Windows Setup and Run Guide
This guide covers running the Clawdmeter Windows daemon on native Windows hardware.
It includes the turnkey install-windows.ps1 bootstrap (tray icon + login autostart),
the manual-run fallback, and how to manage or remove autostart.
Prerequisites
| Requirement | Details |
|---|---|
| Native Windows | Must run on real Windows — not WSL. The script prints a warning and BLE will not work under WSL. |
| Python 3.11+ | Download from python.org if not already installed. Ensure "Add python.exe to PATH" is checked during install. |
| Claude Code installed | Install Claude Code and complete claude login so credentials exist on disk. |
| Clawdmeter powered on | The device must be powered on and in range before the daemon starts. |
| Paired with Windows Bluetooth | Pair the device once via Settings → Bluetooth & devices → Add device (see Pair the device). This is required — the device is a bonded BLE HID keyboard, so pairing enables its physical buttons and keeps a persistent connection that shows your last usage even when the daemon is stopped. |
Where are my credentials?
claude login writes the OAuth token to (first match wins):
%USERPROFILE%\.claude\.credentials.json— primary path (confirmed by Claude Code docs)%LOCALAPPDATA%\Claude\.credentials.json— fallback%APPDATA%\Claude\.credentials.json— fallback
The daemon probes these paths in order. You can also set CLAUDE_CREDENTIALS_PATH to an
absolute path or CLAUDE_CONFIG_DIR to a directory to override the search entirely.
Security note: The credentials file contains your OAuth token. Never share its contents or embed it in scripts. The daemon reads it from disk and uses it only as the API
Authorizationheader — the token is never written to any log, tooltip, or notification.
Pair the device (one time)
The Clawdmeter is a bonded BLE HID keyboard as well as a usage display — its firmware
enables bonding (NimBLEDevice::setSecurityAuth) and advertises the HID service so its
physical buttons act as a keyboard (Space / Shift+Tab). Pair it with Windows once,
before running the daemon:
- Put the device on its Bluetooth waiting screen (powered on, not yet connected).
- Open Settings → Bluetooth & devices → Add device → Bluetooth.
- Select Claude Controller and complete pairing.
Why this is required:
- Keyboard buttons — HID over BLE requires bonding on Windows. Without pairing, the device's buttons won't reach the PC.
- Persistent point-in-time view — once paired, Windows maintains the BLE link and auto-reconnects the device whenever it is in range. This is intentional: the device keeps showing your last-synced usage even after you Quit the daemon, as a glanceable point-in-time view. Quitting the daemon releases only its data connection — it does not drop the Windows pairing, so the device stays connected to Windows.
To undo, use Settings → Bluetooth & devices → (device) → Remove device. Removing the pairing disables the keyboard buttons.
Standalone executable — no Python required (recommended)
To run Clawdmeter on a machine without Python, use the single-file
Clawdmeter.exe. It bundles its own Python, the WinRT BLE stack and the
media-session reader, so nothing needs to be installed.
Download: the repo is private, so sign in to Gitea first, then download
Clawdmeter.exewith this direct link: https://gitea.bvrdo.online/wenil/clawdmeter/releases/download/v2.0-beta.1/Clawdmeter.exe — or browse all releases for the newest build.
- Pair the device with Windows once (see Pair the device).
- Get
Clawdmeter.exe— download it from the latest Gitea release, or build it yourself (below). - Double-click
Clawdmeter.exe. The tray icon appears and the watch starts updating within ~10 seconds. - To launch it automatically at every logon, right-click the tray icon →
Start at login. That registers the exe itself under
HKCU\Software\Microsoft\Windows\CurrentVersion\Run— no Python, no console window.
There is no console window; the exe logs to %LOCALAPPDATA%\Clawdmeter\daemon.log.
Building the exe
On a machine that does have Python (e.g. your dev box), from the repo root:
powershell -ExecutionPolicy Bypass -File build-exe.ps1
This creates dist\Clawdmeter.exe (~30–60 MB). The PyInstaller config lives in
clawdmeter.spec. The exe is intentionally not committed to git — distribute
it through a Gitea release.
SmartScreen / antivirus: unsigned PyInstaller executables are sometimes flagged by a generic heuristic (not a real detection). Until the exe is code-signed, you may need to allow it through SmartScreen ("More info → Run anyway"). Building from source sidesteps this entirely.
Setup from source (one time)
Use this if you prefer running from a Python checkout instead of the standalone exe above (e.g. on your dev box).
Open a PowerShell terminal and cd to the repository root.
1. Create a virtual environment
python -m venv .venv
2. Activate it
.venv\Scripts\Activate.ps1
If you see a scripts-execution-policy error, run:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Then repeat the Activate.ps1 step.
3. Install dependencies
pip install -r daemon\requirements-windows.txt
This installs bleak (WinRT BLE) and httpx (async HTTP for the Anthropic API).
Running the daemon
With the venv active and the Clawdmeter powered on:
python daemon\claude_usage_daemon_windows.py
Expected console output
[HH:MM:SS] === Claude Usage Tracker Daemon (BLE, Windows) ===
[HH:MM:SS] Poll interval: 60s
[HH:MM:SS] Scanning for 'Claude Controller' (8.0s)...
[HH:MM:SS] Found: XX:XX:XX:XX:XX:XX
[HH:MM:SS] Connecting to XX:XX:XX:XX:XX:XX...
[HH:MM:SS] Connected
[HH:MM:SS] Sending: {"s":42,"sr":180,"w":17,"wr":8820,"st":"active","ok":true}
- The device must be paired with Windows first (see Pair the device).
The daemon then connects over that existing link via
BleakScanner+BleakClient; it does not pop its own pairing dialog. - After
Connected, the daemon polls the Anthropic API immediately and sends the first payload within a few seconds of connect (warm token path). With a valid, non-expired token the device should leave its waiting screen and show session + weekly percentages within about 10 seconds of launch. - The daemon then re-polls the Anthropic API every 60 seconds while connected. If the device fires a refresh request (e.g., after a button press), an immediate re-poll occurs without waiting for the 60-second interval.
- The Now Playing screen updates on a separate, faster cadence: the daemon reads the Windows media session every 3 seconds and pushes an update the moment the track or play/pause state changes — so the watch reflects a song change within a few seconds, not at the next 60-second API poll. The cached usage data is re-sent with each of these updates, so the rate-limit / token screens never blank between polls.
- If the device disconnects or goes out of range, the daemon logs
Device disconnectedand re-scans automatically with exponential backoff (starting at 1 second, capped at 60 seconds).
Stopping
Press Ctrl+C in the terminal. The daemon logs Daemon stopping and exits cleanly.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Warning: running under Linux/WSL |
Running in WSL, not native Windows | Run from a native PowerShell or Command Prompt on Windows |
Scanning for 'Claude Controller'… Device not found |
Clawdmeter is off, out of range, or showing a non-Bluetooth screen | Power on the device and ensure it is on the Bluetooth waiting screen |
No token; skipping poll |
No credentials file found at any candidate path | Confirm claude login ran on this machine; check %USERPROFILE%\.claude\.credentials.json exists |
API HTTP 401 |
Token expired | Re-run claude login in a terminal to refresh the token, then restart the daemon |
Connection failed |
WinRT BLE initialisation issue | Ensure Windows Bluetooth is on; try toggling Bluetooth off/on in Windows Settings |
Tray icon, login autostart, and turnkey install
One-command install (recommended)
Copy the repo to a native Windows path first. Clone or copy this repository to a Windows location such as
%USERPROFILE%\Clawdmeter— not a WSL share (\\wsl$\...or\\wsl.localhost\...). Installing from the WSL share would point the virtual environment and the login-autostart entry at a path that disappears when WSL shuts down, defeating the whole point of the Windows daemon. The installer detects a WSL path and refuses to run, telling you how to relocate.Copy-Item -Recurse '\\wsl.localhost\Ubuntu\home\<you>\repos\Clawdmeter' "$env:USERPROFILE\Clawdmeter" cd "$env:USERPROFILE\Clawdmeter"
Run this once from the repository root in PowerShell (a native Windows path):
powershell -ExecutionPolicy Bypass -File install-windows.ps1
The script does four things in order and logs progress at each step:
- Creates a Python virtual environment at
.venv. - Installs dependencies from
daemon\requirements-windows.txt(bleak, httpx, pystray, Pillow). - Registers the tray app to launch automatically at login via
HKCU\Software\Microsoft\Windows\CurrentVersion\Run— per-user, no admin required. - Launches the tray app immediately (headless — no console window).
The script downloads nothing from the internet. It only installs the packages listed in
the in-repo daemon\requirements-windows.txt.
Tray icon and status
After install, the Clawdmeter icon appears in the Windows notification area:
| State | Icon bubble | Tooltip |
|---|---|---|
| Connected | green | Connected · last update HH:MM |
| Scanning | amber | Scanning… |
| Error | red | Error: token expired — run claude login |
Hover over the icon to see the current status tooltip. A notification fires once when the daemon first enters the Error state (e.g. after a token expiry).
Tray menu
Right-click the tray icon for the menu:
- Status header (non-clickable) — live status + last data sync time.
- Start at login (checkable toggle) — enables or disables autostart at runtime. Reflects the current registry state each time the menu opens.
- Quit — stops the daemon cleanly and exits with no lingering process. It releases the daemon's own data connection but does not drop the Windows Bluetooth pairing — the device stays connected to Windows and keeps showing your last-synced usage (point-in-time view).
Disabling or removing autostart
Use the tray menu toggle, or remove the registry value manually:
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v Clawdmeter /f
WSL independence
The daemon operates fully independently of WSL. The token is read from native Windows
credential paths (%USERPROFILE%\.claude\.credentials.json and fallbacks); BLE uses
the WinRT stack directly. Running wsl --shutdown does not affect the BLE link, and
the daemon starts correctly even in a fresh Windows session where WSL has never been
launched.
What is NOT covered here
- Code-signing the standalone
.exe(to avoid SmartScreen/AV prompts) — future - MAC-address cache / sleep-wake reconnect hardening — Phase 3