wristpull

Install it yourself

From clone to dashboard in three commands

The primary way is the Docker stack on Linux: one image runs the dashboard and every command — the watch over USB, the band over Bluetooth, the phone over ADB. The host needs neither Python nor uv. A guided setup script does the whole thing and asks only for what's missing.

Python 3.14SQLiteDocker + Caddy (HTTPS)libmtpBLE via bleakTextual TUIMIT licenceCI on Linux · macOS · Windows

Clone and run the setup

The script builds the image, writes the environment, installs the udev rule (import on plug-in) and sets up the dashboard — asking before every change.

$ git clone https://github.com/one7two99/wristpull.git ~/dev/wristpull
$ cd ~/dev/wristpull
$ contrib/bin/wristpull-setup

First import

Watch on the cable, or the band in Bluetooth range — either alone already works.

$ contrib/bin/wristpull import garmin
$ contrib/bin/wristpull pull strap

Look at your data

The dashboard is already running for your home network; the terminal UI is one command.

$ contrib/bin/wristpull tui   # or: open the dashboard on your phone

Optional: rescue your history and meet the coach

$ contrib/bin/wristpull import garmin-export ~/Downloads/<your-garmin-export>.zip
$ contrib/bin/wristpull coach profile --wizard
$ contrib/bin/wristpull coach daily --dry-run   # read the prompt before anything is sent

Every detail — Gadgetbridge setup, the morning routine, backups and moving machines — is documented in the README and docs/.

Which machine fits

Platforms and devices

PlatformHowWhat works
Linux (laptop, mini-PC, home server)Docker stack — the reference setupEverything: watch, band, phone, dashboard, coach, automation
macOS / WindowsNative install (Python + uv)Everything except container automation — Docker there can't reach USB/Bluetooth
Your phoneBrowserThe dashboard, from your home network
DevicePathStatus
Garmin fēnix 6X ProUSB cableverified daily
Amazfit Helio StrapBluetooth, no phoneverified daily
Other Garmin watchesUSB (FIT files)should work — reports welcome
Anything Gadgetbridge readsvia the Gadgetbridge appimport works; parsers grow per device
Your old Garmin accountaccount export (zip)full history import

For the data people

It's just SQLite

Twenty documented tables, UTC timestamps plus local dates on every row, raw files archived beside them. Bring polars, pandas, Grafana or a plain shell:

$ sqlite3 ~/Health/wristpull/wristpull.sqlite \
  "SELECT local_date, steps, resting_hr, sleep_score
   FROM daily_summary
   ORDER BY local_date DESC LIMIT 14"

Markdown + CSV exports for any date range are one command — sized to paste into an AI chat.

For the careful

Built like infrastructure

  • Raw files immutable, SHA-256-deduplicated, never deleted on the device
  • Dashboard: HTTPS via Caddy, scrypt-hashed password, rate-limited login, strict CSP, zero external requests
  • Secrets only in the environment — never in config files or the repo
  • Tests run on synthetic data only; the repository has never contained a real heartbeat
  • Full-state backup and restore for moving to a new machine

Read the source — it's an evening, not a weekend.

The wristpull terminal UI: overview screen with device status, 7-day KPIs with sparklines and recent activities
Prefer a terminal? The TUI has ten screens, German and English — rendered here from synthetic test data.