Transform raw Garmin Connect data into actionable lifestyle intelligence using a Council of Experts parallel LangGraph architecture and a Japandi minimalist dashboard.
Health Signal is a personal health optimization engine. It automates the extraction of complex wearable data and uses specialized AI agents to synthesize "Signal" from "Noise," providing you with a unified narrative and a daily Wellness Score.
The core of Health Signal is built on LangGraph, utilizing a parallel processing pattern after data ingestion. This allows specialized AI agents to analyze distinct verticals without biasing each other until the final synthesis.
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#a8c5b5', 'primaryTextColor': '#2d4a3e', 'primaryBorderColor': '#5a7a6b', 'lineColor': '#6b8f7a', 'secondaryColor': '#e8ebe6', 'tertiaryColor': '#d4dcd6' }}}%%
graph TD
A[START] --> B[data_ingest]
B --> C{Parallel Experts}
C --> D[agent_sleep]
C --> E[agent_performance]
C --> F[agent_stress]
D --> G[synthesizer]
E --> G
F --> G
G --> H[db_storage]
H --> I[END]
style A fill:#e8ebe6,stroke:#5a7a6b,stroke-width:1.5px
style I fill:#e8ebe6,stroke:#5a7a6b,stroke-width:1.5px
style B fill:#a8c5b5,stroke:#4a6b5a,stroke-width:1.5px
style C fill:#c9d9d0,stroke:#5a7a6b,stroke-width:1.5px
style D fill:#b8d4c8,stroke:#4a6b5a,stroke-width:1.5px
style E fill:#b8d4c8,stroke:#4a6b5a,stroke-width:1.5px
style F fill:#b8d4c8,stroke:#4a6b5a,stroke-width:1.5px
style G fill:#
- Ingestion Node: Authenticates via Garmin Connect and structures raw payloads. If Garmin credentials fail, the system gracefully falls back to mock data for local development.
- Expert Agents (Parallel):
- Sleep Expert: Analyzes recovery cycles, sleep score, and REM vs Deep sleep to identify deviations from your baseline.
- Performance Expert: Correlates load, active calories, and cardiovascular readiness to balance exertion and capacity.
- Stress Expert: Evaluates Body Battery depletion, HRV, and resting HR to differentiate eustress from distress.
- Synthesizer Node: Resolves conflicting advice to construct a unified narrative, prioritized insights, and a daily "Wellness Score" (0-100).
- Presentation Layer: A polished Next.js dashboard reflecting the Japandi design philosophy.
Health Signal is divided into a Python backend for data processing and a TypeScript frontend for visualization.
- Language: Python >= 3.12
- Environment:
uvpackage manager - AI Framework: LangGraph (
>=1.1.2), LangChain (>=1.2.18) with DeepSeek - Data Integration:
garminconnect(>=0.2.38) - Database: SQLite3
- Data Manipulation: Pandas (
>=2.3.3), Pydantic (>=2.12.5), Plotly (>=6.6.0)
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS 4.0
- Animations: Framer Motion
- Icons: Lucide React
- Database Access:
better-sqlite3
Follow these steps to set up both the backend data pipeline and the frontend web dashboard.
- Python 3.12+
- uv (for ultra-fast Python package management)
- Node.js 24+
- pnpm or
npm - DeepSeek API Key (for the AI analysis)
- Garmin Connect Account (Optional, falls back to mock data if omitted)
git clone https://github.com/your-username/health-signal.git
cd health-signalCreate a .env file in the root directory. You can use .env.example as a template:
cp .env.example .env| Variable | Description | Required |
|---|---|---|
DEEPSEEK_API_KEY |
Your API key for DeepSeek. | Yes |
GARMIN_EMAIL |
The email address for your Garmin Connect account. | No* |
GARMIN_PASSWORD |
The password for your Garmin Connect account. | No* |
*Note: If Garmin credentials are not provided or authentication fails, the application will automatically use mock data for safe, seamless local development.
Garmin Token Caching: On the first successful login, OAuth tokens are dumped into ~/.garminconnect to avoid repeatedly hitting Garmin with hardcoded credentials.
Navigate to the project root and install the Python dependencies using uv:
uv venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
uv pip install -e .Execute the LangGraph agent to fetch and analyze your recent Garmin health data. By default, it processes the last 7 days to capture retroactive changes.
python main.pyThis will run the Council of Experts and populate the src/health_data.db SQLite database with both raw JSON payloads and structured AI analysis.
Open a new terminal, navigate to the web/ directory, and start the Next.js development server:
cd web
npm install
npm run devOpen http://localhost:3000 in your browser to view your personalized dashboard.
A brief overview of the directory structure to help you navigate the codebase:
.
├── docs/ # Comprehensive "Deep Wiki" documentation
├── src/ # Python Backend (Logic & Utilities)
│ ├── graph/ # LangGraph Core
│ │ ├── nodes/ # Pipeline execution steps (Agents)
│ │ ├── main.py # Graph builder
│ │ └── state.py # Pydantic state definition
│ ├── utils/ # DB, Garmin, and LLM utilities
│ └── health_data.db # SQLite database (Read-only for frontend)
├── web/ # Next.js Dashboard (Japandi Minimal)
│ ├── src/app/ # Next.js App Router (Dashboard)
│ └── src/components/ # UI Components & Charts
├── main.py # Root entry point for the AI data pipeline
└── pyproject.toml # Python build configuration
For a deeper dive into specific components, refer to the documentation:
- The Mental Model: Vision, core logic, and design philosophy.
- System Topography: Detailed directory rules and schema.
- Logic Deep Dives: Detailed agent prompts, persistence strategies, and parallel processing logic.
- Developer Playbook: Environment setup and common workflows.
Health Signal uses a clean, single-table SQLite schema (daily_health) optimized for simple read queries from the Next.js frontend.
- Storage: We store both the curated AI analysis and the raw Garmin JSON payload in JSON blobs. This allows the AI model to re-process historical data without needing to re-fetch from the Garmin API if prompts are improved.
- Upsert Logic: The
datecolumn isUNIQUE. If the pipeline runs multiple times for the same day, we use an upsert strategy (ON CONFLICT(date) DO UPDATE) to regenerate the AI analysis and update the row. - Access: The frontend connects to the database in a purely Read-Only mode to prevent accidental corruption.
Contributions are welcome! Please see the Developer Playbook for detailed contribution guidelines, architectural rules, and coding standards.
This project is licensed under the MIT License.