nutrition-mcp/.beads/issues.jsonl
2026-08-22 23:59:54 +01:00

9 lines
14 KiB
JSON

{"_type":"issue","id":"hm-zy2.1","title":"Fix health-sync.js — wrong HealthUnit method names and Scriptable/Scripting app confusion","description":"The health-sync.js script doesn't work. Root causes identified:\n\n1. HealthUnit.gram(HealthMetricPrefix.kilo) is wrong — the API uses HealthUnit.gramUnit(HealthMetricPrefix.kilo) for prefixed units, or HealthUnit.gram() for base unit. There is no gram(prefix) overload.\n\n2. HealthUnit.millimeterOfMercury() is not exposed in the Scripting app HealthUnit API. Use HealthUnit.fromString('mmHg') instead.\n\n3. Scriptable vs Scripting app confusion. The script header says 'Scriptable' but the API (Health global, HealthUnit class, queryQuantitySamples) matches the Scripting app (scriptingapp.github.io). Scriptable uses a different pattern (new Health(), setTypeIdentifier, setUnit, quantitySamples). The script must target whichever app is actually installed.\n\n4. The script needs to be tested on-device after fixing.\n\nAcceptance: Script runs without errors in Scripting app, successfully POSTs health samples to /ingest, and server returns 201 with ingested count.","notes":"v11 working end-to-end. Script successfully reads HealthKit and POSTs to /ingest.\nConfirmed: blood_pressure (147/98 from Omron) and steps (24501 from Apple Health) ingested.\nKey fixes through iterations v1-v11:\n1. Scriptable API → Scripting app API (fetch, Notification.schedule, import from 'scripting')\n2. Top-level await → async main() + .then(Script.exit)\n3. HealthUnitPrefix not available → HealthUnit.fromString('kg')\n4. allowInsecureRequest: true for HTTP\n5. timeout on fetch to prevent hanging\n6. @ts-nocheck to suppress type checker errors\n7. Notification imported from 'scripting' (not global)\n\nScript deployed at http://chronos:9432/scriptable/health-sync.js (serves health-sync.tsx as inline text).\nUser has Scripting Pro (required for Health API access).\nAutomation not yet set up — user needs to create iOS Shortcut with scripting://run/Health%20Sync URL.\n\nScript name in Scripting app: 'Health Sync' (user should verify exact name).","status":"closed","priority":0,"issue_type":"bug","assignee":"Anthony Merlo","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:54Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T22:53:38Z","started_at":"2026-08-22T21:34:26Z","closed_at":"2026-08-22T21:35:47Z","close_reason":"Fixed 3 API bugs in health-sync.js. Server side verified working. Needs on-device test to fully confirm.","dependencies":[{"issue_id":"hm-zy2.1","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:31:53Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":0,"dependent_count":4,"comment_count":0}
{"_type":"issue","id":"hm-zy2","title":"Transform nutrition-mcp into health-mcp with Apple Health integration","description":"Expand nutrition-mcp into a broader health-mcp server. Fix the broken Apple Health sync script, expand metric coverage, add server-side health tools, and rename the project. The existing /ingest endpoint and vitals table are already generic enough to accept any health metric.","notes":"EPIC STATUS — Aug 22 2026:\n\nDONE:\n- hm-zy2.1 ✅ CLOSED — health-sync.tsx v11 working end-to-end. iPhone reads HealthKit (blood pressure, steps) and POSTs to /ingest on chronos:9432. Data confirmed in vitals table via recent_vitals MCP tool.\n\nNEXT UP (all unblocked):\n- hm-zy2.2 — backfill mode (query last 90 days, chunk into batches)\n- hm-zy2.3 — expand metrics (BMI, body fat, HRV, distance, energy, exercise time, etc.)\n- hm-zy2.4 — sleep tracking (needs Health.queryCategorySamples, not quantity)\n- hm-zy2.5 — new MCP tools (health_summary, vitals_trend, log_vital)\n\nNOT STARTED:\n- hm-zy2.6 — health_goals table + tools\n- hm-zy2.7 — workouts table + tools\n- hm-zy2.8 — rename project (do LAST, depends on .5 .6 .7)\n\nKEY CONTEXT FOR NEXT SESSION:\n- Scripting app (NOT Scriptable) — completely different API. Skill 'scripting-app-health-sync' saved with all pitfalls.\n- Script is at scripts/health-sync.tsx, served at /scriptable/health-sync.js on chronos\n- Server deployed on chronos via systemd (nutrition-mcp.service), built with cargo on chronos directly (cross-compile from macOS doesn't work — ring crate needs Linux toolchain)\n- Deploy flow: git push → ssh chronos → git pull → cargo build --release → systemctl --user restart nutrition-mcp\n- User has Scripting Pro (required for Health API)\n- Automation: user needs to set up iOS Shortcut with scripting://run/Health%20Sync URL (not done yet)\n- Working script version: v11","status":"open","priority":1,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:35Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T22:53:45Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"hm-zy2.5","title":"Add new MCP tools: health_summary, vitals_trend, log_vital","description":"Add new MCP tools to tools.rs:\n\n1. health_summary — daily/weekly health dashboard combining vitals + activity + sleep in one call. Returns latest values + daily sums.\n\n2. vitals_trend — time-series trend for a specific metric over N days. Returns min/max/avg + data points. Useful for 'weight over 30 days' or 'resting HR trend'.\n\n3. log_vital — manually log a vital (e.g. blood pressure from a non-connected cuff). Inserts into vitals table directly.\n\nFollow existing patterns in tools.rs (#[tool], schemars::JsonSchema for params, match existing error handling style).\n\nAcceptance: cargo build --release \u0026\u0026 cargo test pass. Tools appear in tools/list. Each tool returns correct data from vitals table.","status":"open","priority":2,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:58Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:31:58Z","dependencies":[{"issue_id":"hm-zy2.5","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:31:57Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.5","depends_on_id":"hm-zy2.1","type":"blocks","created_at":"2026-08-22T22:32:09Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"hm-zy2.4","title":"Add sleep tracking support (category type) to health-sync script","description":"Sleep data is a HealthKit category type, not a quantity type. Health.queryQuantitySamples() won't work. Need to use Health.queryCategorySamples() for sleepAnalysis.\n\nGroup samples by sleep stage (asleepCore, asleepDeep, asleepREM, asleepUnspecified, awake, inBed) and sum durations per stage.\nStore one vitals row per night: type='sleep', value={inBed: secs, asleepCore: secs, asleepDeep: secs, ...}.\n\nNeed to verify Scripting app supports queryCategorySamples() — check docs at scriptingapp.github.io.\n\nAcceptance: Sleep data is read, grouped by stage, and POSTed as a single JSON object per night.","status":"open","priority":2,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:57Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:31:57Z","dependencies":[{"issue_id":"hm-zy2.4","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:31:56Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.4","depends_on_id":"hm-zy2.1","type":"blocks","created_at":"2026-08-22T22:32:08Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"hm-zy2.3","title":"Expand health-sync script to cover more HealthKit metrics","description":"Add the following HealthKit types to health-sync.js:\n\nBody: bodyMassIndex (latest), bodyFatPercentage (latest)\nCardiovascular: heartRateVariabilitySDNN (latest), walkingHeartRateAverage (latest)\nActivity: distanceWalkingRunning (daily sum), distanceCycling (daily sum), flightsClimbed (daily sum), activeEnergyBurned (daily sum), appleExerciseTime (daily sum), appleStandTime (daily sum)\n\nNo server changes needed — vitals table accepts any type string and value as JSON. Just add readLatest()/readTodaySum() calls and push to samples array.\n\nAcceptance: All listed metrics are read and POSTed. Missing metrics (no data) are silently skipped, not errored.","status":"open","priority":2,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:56Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:31:56Z","dependencies":[{"issue_id":"hm-zy2.3","depends_on_id":"hm-zy2.1","type":"blocks","created_at":"2026-08-22T22:32:07Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.3","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:31:55Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"hm-zy2.2","title":"Add historical backfill mode to health-sync script","description":"Current script only grabs the latest sample per metric. Add a backfill mode that queries all samples from a date range (e.g. last 90 days), chunks them into batches of ~500, and POSTs each batch to /ingest.\n\nFor daily-sum types (steps, energy, distance), iterate day-by-day, summing each day's samples into one row with timestamp_utc=YYYY-MM-DD.\n\nIdempotency is handled by UNIQUE(type, timestamp_utc) + ON CONFLICT DO UPDATE — re-running backfill is safe.\n\nAcceptance: Running backfill for last 30 days populates vitals table with historical data. Re-running produces same row count (upserts).","status":"open","priority":2,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:55Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:31:55Z","dependencies":[{"issue_id":"hm-zy2.2","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:31:54Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.2","depends_on_id":"hm-zy2.1","type":"blocks","created_at":"2026-08-22T22:32:07Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"hm-zy2.7","title":"Add workouts table and workout-related MCP tools","description":"Add a structured workouts table:\nCREATE TABLE workouts (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp_utc TEXT NOT NULL, workout_type TEXT NOT NULL, duration_sec INTEGER, total_energy_kcal REAL, total_distance_m REAL, source TEXT, metadata TEXT, UNIQUE(timestamp_utc, workout_type, source));\n\nAdd MCP tools: log_workout (manual entry), workout_history (query by type/date range).\n\nAlso add workout ingestion to /ingest — if sample type is 'workout', insert into workouts table instead of vitals.\n\nAcceptance: cargo build --release \u0026\u0026 cargo test pass. Workouts are queryable via MCP tools. /ingest routes workout samples correctly.","status":"open","priority":3,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:32:00Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:32:00Z","dependencies":[{"issue_id":"hm-zy2.7","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:32:00Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"hm-zy2.6","title":"Add health_goals table and get/set health goals MCP tools","description":"Add a health_goals table (like daily_goal but for health metrics):\nCREATE TABLE health_goals (id INTEGER PRIMARY KEY, goals TEXT NOT NULL DEFAULT '{}');\n\nGoals JSON: {steps: 10000, sleep_hours: 8, weight_kg: 80, resting_hr: 60, blood_pressure_systolic: 120, ...}\n\nAdd two MCP tools: get_health_goals, set_health_goals — following the same pattern as get_goals/set_goals.\n\nAcceptance: cargo build --release \u0026\u0026 cargo test pass. Goals persist in SQLite. Tools round-trip correctly.","status":"open","priority":3,"issue_type":"feature","owner":"atradeus@pm.me","created_at":"2026-08-22T21:31:59Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:31:59Z","dependencies":[{"issue_id":"hm-zy2.6","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:31:58Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"hm-zy2.8","title":"Rename project: nutrition-mcp → health-mcp","description":"Rename the project:\n- Cargo.toml: name, binary name, description\n- Env var prefixes: NUTRITION_MCP_* → HEALTH_MCP_* (with backwards compat alias)\n- Update AGENTS.md, CLAUDE.md module map and references\n- Update config.rs struct/docs\n- Update scripts/health-sync.js server URL comments\n- Update Hermes config.yaml mcp_servers:nutrition → mcp_servers:health\n\nDo this LAST, after all other issues are complete, to minimize disruption during development.\n\nAcceptance: cargo build --release \u0026\u0026 cargo test pass with new names. Old env vars still work via backwards-compat. Hermes MCP config updated.","status":"open","priority":4,"issue_type":"task","owner":"atradeus@pm.me","created_at":"2026-08-22T21:32:01Z","created_by":"Anthony Merlo","updated_at":"2026-08-22T21:32:01Z","dependencies":[{"issue_id":"hm-zy2.8","depends_on_id":"hm-zy2.5","type":"blocks","created_at":"2026-08-22T22:32:09Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.8","depends_on_id":"hm-zy2.7","type":"blocks","created_at":"2026-08-22T22:32:10Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.8","depends_on_id":"hm-zy2","type":"parent-child","created_at":"2026-08-22T22:32:01Z","created_by":"Anthony Merlo","metadata":"{}"},{"issue_id":"hm-zy2.8","depends_on_id":"hm-zy2.6","type":"blocks","created_at":"2026-08-22T22:32:10Z","created_by":"Anthony Merlo","metadata":"{}"}],"dependency_count":3,"dependent_count":0,"comment_count":0}