Files
bikeslop/CLAUDE.md
T
2026-07-27 10:05:29 -04:00

34 lines
2.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
uv run uvicorn app:app --reload # start dev server at http://localhost:8000
LLAMACPP_BASE_URL=http://host:port/v1 uv run uvicorn app:app --reload # point at a specific LLM
uv sync # install/sync dependencies
uv add <package> # add a new dependency
```
## Architecture
Two-file app: a FastAPI backend (`app.py`) and a single-page frontend (`static/index.html`).
**`app.py`** parses all GPX files in `garmin_gpx_exports/` at startup into an in-memory dict (`_rides`), keyed by filename stem. Stats (haversine distance, elevation gain/loss, HR zones) are computed once at load time. Three API routes:
- `GET /api/rides` — summary list (no track points)
- `GET /api/rides/{id}/points` — full lat/lon/ele/hr array
- `POST /api/rides/{id}/insights` — streams AI response via OpenAI SDK
**AI integration** uses the OpenAI Python SDK pointed at a local LLM endpoint (`LLAMACPP_BASE_URL` env var, defaults to `http://localhost:8080/v1`). The model name is auto-discovered from `GET /v1/models` at startup (falls back to `"local-model"`). The model is a reasoning model (GLM-4.7-Flash alias) that streams output into `reasoning_content` rather than the standard `content` field — the chunk reader handles both.
**`static/index.html`** is a self-contained SPA (no build step). Leaflet.js draws the route as per-segment polylines colored by HR intensity. Chart.js renders elevation and HR profiles against cumulative distance. AI insights stream via `fetch` + `ReadableStream`.
**`main.py`** is a separate Garmin Connect download script (not part of the web app).
## GPX data notes
- Garmin extension namespace for HR: `http://www.garmin.com/xmlschemas/TrackPointExtension/v1` (`ns3:hr`)
- One file (`2026-06-21_18-17-11_Indoor Cycling_*`) has an empty `<trkseg/>``has_gps: false` in the API, frontend shows no map/charts for it
- HR zone boundaries: Z1 <120, Z2 120140, Z3 140160, Z4 160180, Z5 >180 bpm