feat(skills): add fitness-nutrition skill to optional-skills

Cherry-picked from PR #9177 by @haileymarshall.

Adds a fitness and nutrition skill for gym-goers and health-conscious users:
- Exercise search via wger API (690+ exercises, free, no auth)
- Nutrition lookup via USDA FoodData Central (380K+ foods, DEMO_KEY fallback)
- Offline body composition calculators (BMI, TDEE, 1RM, macros, body fat %)
- Pure stdlib Python, no pip dependencies

Changes from original PR:
- Moved from skills/ to optional-skills/health/ (correct location)
- Fixed BMR formula in FORMULAS.md (removed confusing -5+10, now just +5)
- Fixed author attribution to match PR submitter
- Marked USDA_API_KEY as optional (DEMO_KEY works without signup)

Also adds optional env var support to the skill readiness checker:
- New 'optional: true' field in required_environment_variables entries
- Optional vars are preserved in metadata but don't block skill readiness
- Optional vars skip the CLI capture prompt flow
- Skills with only optional missing vars show as 'available' not 'setup_needed'
This commit is contained in:
haileymarshall 2026-04-13 20:31:18 -07:00 committed by Teknium
parent 62fb6b2cd8
commit f0b353bade
5 changed files with 658 additions and 1 deletions

View file

@ -245,6 +245,9 @@ def _get_required_environment_variables(
if isinstance(required_for, str) and required_for.strip():
normalized["required_for"] = required_for.strip()
if entry.get("optional"):
normalized["optional"] = True
seen.add(env_name)
required.append(normalized)
@ -378,6 +381,8 @@ def _remaining_required_environment_names(
remaining = []
for entry in required_env_vars:
name = entry["name"]
if entry.get("optional"):
continue
if name in missing_names or not _is_env_var_persisted(name, env_snapshot):
remaining.append(name)
return remaining
@ -1042,7 +1047,8 @@ def skill_view(name: str, file_path: str = None, task_id: str = None) -> str:
missing_required_env_vars = [
e
for e in required_env_vars
if not _is_env_var_persisted(e["name"], env_snapshot)
if not e.get("optional")
and not _is_env_var_persisted(e["name"], env_snapshot)
]
capture_result = _capture_required_environment_variables(
skill_name,