# Package Choices & Rationale

## Fitbit SDK

| Package | Version | Why |
|---------|---------|-----|
| `@fitbit/sdk` | `7.2.0-pre.0` | Includes `rhea` (Sense 2) and `hera` (Versa 4) build targets. Stable 6.1.0 doesn't have them. |
| `@fitbit/sdk-cli` | `^1.7.3` | Required for `fitbit-build`, `fitbit-install` commands. |
| `fitbit-sdk-build-targets` | GitHub:cmengler | Unofficial drop-in that adds target definitions for SDK 6.x/7.x. Used as fallback if pre-release SDK doesn't build. |
| `typescript` | `~5.4.0` | Fitbit SDK toolchain uses its own bundled TS, but we need this for editor/CI linting. |

## Backend (Pipo)

| Package | Version | Why |
|---------|---------|-----|
| `fastify` | `^5.x` | Low overhead, TypeScript-native, async/await, JSON schema validation. Already in Pipo ecosystem. |
| `@fastify/cors` | latest | Companion `fetch()` from phone needs CORS headers. |
| `hevy-api-client` | N/A (internal) | Existing Hevy API wrapper in Pipo skills; reuse for `POST /v1/workouts` and `GET /v1/routines`. |

## Device App (no npm deps — Fitbit SDK bundles)

| Concern | Choice | Why |
|---------|--------|-----|
| State management | Plain FSM (`state-model.ts`) | 8 states, no complex derived state. Redux/MobX is overkill. |
| UI rendering | Fitbit SVG GUI (`index.gui`) + imperative JS | Fitbit's native rendering model. No DOM, no React. |
| Messaging | `peerSocket` (messaging API) | Built-in watch ↔ companion bridge. |
| Persistence | `fs` API (Fitbit) | Read/write JSON session files on device. |
| Timers | `setInterval` / `setTimeout` | Built-in; sufficient for 1-second rest countdown. |
| Haptics | `vibration` API | Built-in vibration motor control. |
| Heart rate | `HeartRateSensor` API | Optional: display HR during workout (read-only). |

## Deliberate Omissions

| What | Why Skip |
|------|----------|
| React/Preact UI | Fitbit Studio is dead; SVG GUI + imperative JS is simpler and official. |
| Redux/MobX | Overkill for 8-state FSM with ~15 fields. |
| WebSockets (watch side) | Fitbit companion `fetch()` only; no WebSocket support in companion. Backend uses long-poll or SSE. |
| SQLite/local DB on watch | `fs` + JSON is simpler; <100KB session data. |
| OAuth/PKCE on watch | Hevy API key auth happens in backend only; watch never sees credentials. |
