Facilitates real-time tracking and automated data delivery from Garmin devices. Use this skill when the user needs to access live location, activity data, or...
编程
garmin-nutrition
试用Low-friction food tracking - a pattern cache of the user's usual meals, a local-first journal, and Garmin Connect Nutrition as a sync target. Log "my usual salad, double oil" in one message. Logged meals are uploaded to the user's Garmin Connect account (Garmin cloud) unless `--no-garmin`; the skill can also read and delete entries in the user's Garmin food log. Requires Garmin Connect+ for the Garmin sink.
它能做什么
Low-friction food tracking - a pattern cache of the user's usual meals, a local-first journal, and Garmin Connect Nutrition as a sync target. Log "my usual salad, double oil" in one message. Logged meals are uploaded to the user's Garmin Connect account (Garmin cloud) unless `--no-garmin`; the skill can also read and delete entries in the user's Garmin food log. Requires Garmin Connect+ for the Garmin sink.
技能文档
Garmin Nutrition
Track what the user eats with minimal friction. The core idea: people eat a limited repertoire. Cache it once, then a short message ("ate my usual salad, double oil") is enough to log a meal with real numbers.
All data is local-first: the journal is the source of truth, Garmin Connect is a sink. The Garmin sink needs a Connect+ subscription; the cache and journal work without it (use --no-garmin).
The one rule that matters
Ask zero or one question per food event, never more. Prefer a stated assumption over a question. Log with --confidence low rather than interrogate. The user correcting you afterwards is cheaper than friction before logging.
- One cached match for "чипсы" → use it silently, mention the assumption in your reply.
- Several matches → one short question: "какие — лейз (пачка 45 г) или начос?"
- No pattern and no data ("тарелка картошки с мясом") → estimate standard portions, log adhoc with low confidence, state assumptions in one line. Do NOT ask for grams.
Storage
- Config:
~/.config/nutrition/config.json—{"data_dir": "...", "day_cutoff": "04:00"}(both optional) - Data:
$NUTRITION_DATA_DIR, else configdata_dir, else~/.local/share/nutrition/patterns.json— the food cachejournal/YYYY-MM-DD.json+ rendered.md— the log
day_cutoff: food logged before this hour belongs to the previous day (late-night eating). Default00:00(calendar days).
The pattern cache
Two kinds of entries:
Dish — ingredients with amounts and per-100g macros; totals are always computed, never stored. Supports deltas at log time.
Product — a packaged item photographed once: per-100g from the label plus named portion sizes.
uv run {baseDir}/scripts/garmin_nutrition.py pattern list
uv run {baseDir}/scripts/garmin_nutrition.py pattern show
uv run {baseDir}/scripts/garmin_nutrition.py pattern add --json ''
uv run {baseDir}/scripts/garmin_nutrition.py pattern set --json '' # full replace
uv run {baseDir}/scripts/garmin_nutrition.py pattern rm
Dish entry:
{"type": "dish", "aliases": ["салат"],
"ingredients": [
{"name": "помидоры", "qty": 150, "unit": "g",
"per100g": {"kcal": 18, "p": 0.9, "f": 0.2, "c": 3.9},
"source": "generic", "confidence": "medium"},
{"name": "масло", "qty": 3, "unit": "spray", "g_per_unit": 1.66,
"per100g": {"kcal": 900, "p": 0, "f": 100, "c": 0}}
],
"notes": "frying oil would get counting: 0.5"}
Non-gram units (spray, piece, …) need g_per_unit. counting (default 1.0) is the absorbed fraction — e.g. 0.5 for frying oil that stays in the pan.
Product entry:
{"type": "product", "aliases": ["lays"],
"per100g": {"kcal": 536, "p": 6.6, "f": 34, "c": 51},
"portions": {"пачка": 45, "маленькая": 25}, "default_portion": "пачка",
"source": "label photo 2026-08-22"}
When the user photographs a label, read per-100g values and package size from it and pattern add a product. That is the whole point of the photo — one shot, cached forever.
Growing the cache
- Same uncached dish logged for the second or third time (check recent journal days): offer once to save it as a pattern with the user's typical amounts.
- The user corrects your numbers ("в твороге не столько белка"): ask whether to update the pattern, then
pattern set. Never update baselines silently. - Label values the user confirmed beat generic database values; record
sourceandconfidenceper ingredient.
Logging
Everything goes through log. Dry-run by default; --yes writes journal + Garmin.
# dish by name/alias, with deltas translated from the user's words
uv run {baseDir}/scripts/garmin_nutrition.py log салат --mult масло=2 --meal dinner --yes
# "порция побольше, где-то полторы" → --portion 1.5
# "без сыра" → --without сыр
# "помидоров сегодня 200 г" → --set помидоры=200g
# "добавил фету грамм 30" → --add фета=30g (cached product)
# --add фета=30g@264,18,21,0 (with per-100g macros)
# product: named portion or grams
uv run {baseDir}/scripts/garmin_nutrition.py log лейз --qty пачка --meal snack --yes
# no pattern: agent's estimate, stated assumptions, low confidence
uv run {baseDir}/scripts/garmin_nutrition.py log adhoc --name "картошка с мясом" \
--kcal 700 --p 35 --f 30 --c 60 --confidence low --meal dinner --yes
# correction: replaces an earlier event AND deletes its Garmin entry
uv run {baseDir}/scripts/garmin_nutrition.py log салат --set авокадо=150g \
--supersede food-002 --meal dinner --yes
# day summary from the journal (no network)
uv run {baseDir}/scripts/garmin_nutrition.py day [--date YYYY-MM-DD]
Before --yes, show the user one compact line: name, kcal, macros, meal. Corrections use --supersede, not delete+re-add: it keeps history and cleans Garmin automatically.
Direct Garmin commands
status (subscription, goals, meal slots), show (Garmin's own log for a day), delete (by --name or --log-id, dry-run without --yes). Reads are safe to run without asking.
Garmin API notes
Private, undocumented endpoints; verified August 2026. Add = PUT /nutrition-service/food/logs/quickAdd. Delete = DELETE /nutrition-service/food/logs/{date} with {"logIds": [...]} (date in path, ids in body — an id in the path 404s). quickAdd with action: "DELETE" returns 200 and does nothing; never use it. There is no update. After every write the script re-reads the log to confirm; unknown_after_push in the output means check before retrying, a retry can duplicate.
Related
- garmin-pulse — syncs the full daily health picture (sleep, HR, HRV, body battery, training status, activities, and nutrition totals) into markdown files. Use it for reading health history; use this skill to log food.
相关技能
Fetch health and fitness data from Garmin Connect -- 40+ metrics including sleep, HRV, stress, body battery, SpO2, VO2 Max, training status, and activities. Stores data locally as JSON and SQLite.
Plan daily meals and workouts from a user's age and health profile with customizable ingredients, then schedule localized plans via OpenClaw automations.
Sync health and analyze supported cycling data sources
拍照、文字或拍营养标签都能记录一餐,输出区间形式的热量与宏量营养素估算,并带安全护栏。
More granular and few more features than the original one that is based on and seems to be abandoned. I will be fine to merge with original one but I have got not reply for MRs.