3 Commits

Author SHA1 Message Date
Chris Farhood 700cad57ef fix(athlete): drop athlete-tag filter, harden write guardrail, guard empty echo
- get_athlete_summary no longer offers a tags filter: the endpoint's tags param
  filters ATHLETES (coach-facing), not activities, so it produced falsely-empty
  or wrongly-unfiltered summaries (confirmed against the OpenAPI description).
- update_sport_settings: an answered elicitation is now authoritative — accept
  without the confirm tick is a refusal that stops WITHOUT emitting the
  confirm=true fallback instructions (an agentic client could use them to bypass
  the refusal), and an explicit confirm param cannot override it. The elicit
  except no longer swallows failures silently (logged), and an empty-body PUT
  echo renders the merged record instead of an empty settings block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGzHtDvJur9U7ysgRKRUTN
2026-07-20 16:27:52 -04:00
Chris Farhood 9a66183d39 feat(writes): add update_wellness_bulk and update_sport_settings
update_wellness_bulk writes many days in one PUT to /wellness-bulk; the
snake_case->camelCase mapping is extracted into a shared _wellness_payload helper
so single and bulk can't drift, and the whole batch is rejected if any date is
invalid (no partial writes).

update_sport_settings changes FTP/LTHR/pace/zones with a dual guardrail: a warning
docstring, a native ctx.elicit() confirmation on capable clients, and a hard
confirm=True fallback that refuses the write (returning the old->new diff) on
clients without elicitation. It read-modify-writes the full record and passes the
spec-required recalcHrZones query param. Widened the HTTP client's data type to
accept the bulk array.

Implements #5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGzHtDvJur9U7ysgRKRUTN
2026-07-20 15:54:10 -04:00
Chris Farhood 28119f1761 feat(athlete): add profile, sport-settings, and summary read tools
Closes the biggest coaching-context gap: expose the athlete's identity/physiology
(get_athlete_profile), per-sport FTP/zones/thresholds (get_sport_settings, with an
optional sport filter and the settings id needed for future writes), and a
training-load summary over a range (get_athlete_summary). New tools/athlete.py plus
formatters in utils/formatting.py; registered in server.py and tools/__init__.py.

Implements #2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGzHtDvJur9U7ysgRKRUTN
2026-07-20 15:44:05 -04:00