.claude/skills/training-plan/SKILL.md
Persist a confirmed weekly training plan (one row per session with target HR range and pace range) and measure adherence against actual activities. Use when the user says "my plan this week", "what's on today", "save this plan", "how am I doing vs plan", "plan adherence", "did I complete this week", or any equivalent in Spanish.
npx skillsauth add AlvaroLaraFF/strava-coach training-planInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Stores the agreed plan in the planned_sessions SQLite table and
cross-references it with activities to compute execution. Every session
row must carry an HR range (bpm) and a pace range (min/km) — this is a
hard rule from project memory: no plan is ever presented or persisted
without both axes.
Phases used throughout: correction | base | quality | taper | freeform.
python3 -c "
import sys
sys.path.insert(0, '.')
from strava.db import load_token
from strava.client import get_default_db_path
t = load_token(get_default_db_path())
print('OK' if t else 'NO_TOKEN')
"
If NO_TOKEN, run the strava-setup skill first.
Add a single session:
python3 .claude/skills/training-plan/scripts/training_plan.py add \
--date 2026-04-15 --sport Run --session-type tempo --phase correction \
--duration 45 --distance 8 --hr-min 155 --hr-max 170 \
--pace-fast 5.00 --pace-slow 5.20 --description "15min tempo + recovery"
Bulk-insert a whole week from stdin JSON (this is the main entry point after the user confirms a weekly plan in conversation):
cat <<'JSON' | python3 .claude/skills/training-plan/scripts/training_plan.py \
add-bulk --replace-range 2026-04-13 2026-04-19
[
{"plan_date":"2026-04-14","sport_type":"Run","session_type":"easy",
"phase":"correction","duration_min":40,"distance_km":7,
"hr_min_bpm":135,"hr_max_bpm":150,
"pace_fast_min_km":5.45,"pace_slow_min_km":6.15,
"description":"easy zone-2 shakeout"}
]
JSON
--replace-range START END deletes any existing planned sessions in the
closed interval before inserting, so re-confirming a modified week is a
single call. Omit it when adding a fresh plan.
List sessions in a window (defaults to the current ISO week) and auto-match past-dated rows with real activities:
python3 .claude/skills/training-plan/scripts/training_plan.py list \
--start 2026-04-13 --end 2026-04-19
Review adherence in a window (same matcher plus aggregates):
python3 .claude/skills/training-plan/scripts/training_plan.py review \
--start 2026-04-06 --end 2026-04-12
Update or delete a single session:
python3 .claude/skills/training-plan/scripts/training_plan.py update --id 12 --duration 50
python3 .claude/skills/training-plan/scripts/training_plan.py delete --id 12
Every session passed to add or add-bulk must carry:
plan_date (YYYY-MM-DD)sport_type (Run, Ride, Swim, WeightTraining, Rest, ...)session_type (easy, tempo, interval, long, fartlek,
recovery, race, strength, rest)hr_min_bpm and hr_max_bpm (both integers, min < max)pace_fast_min_km and pace_slow_min_km (decimal min/km, fast < slow)Rest/strength sessions may pass zeros or sentinel values — the validator still requires the keys to be present. If the user has no reference pace yet for a given intensity, pass a wide provisional range, never omit one of the two axes.
Day | Sport | Type | Phase | Duration | Distance | HR | Pace | Description
(Spanish labels in the chat are fine; the JSON payload is English).add-bulk. Do NOT ask for
permission — the feedback_plan_persistence memory already authorises
persistence of confirmed plans.add-bulk with
--replace-range <monday> <sunday> and the updated JSON.project memory entry
(e.g. "week 2026-W16 plan confirmed, focus on correction phase — first
week adding a tempo session"). Never dump numbers into memory.list outputRender as a table: Date | Sport | Type | Phase | Duration | Distance | HR range | Pace range | Status. For past-dated rows already matched,
append a second small table with deltas:
duration_delta_min, hr_avg_vs_range, pace_avg_vs_range.
review outputHeadline line first: Adherence: X/Y sessions (Z%). Then a breakdown
per phase and per session_type with completion count and average
deltas. Close with one qualitative sentence — is the user executing the
plan as agreed, or drifting?
| Error contains | Action |
|---|---|
| No token / NO_TOKEN | Invoke strava-setup, retry |
| No activities / Sync first | Invoke strava-sync --level summary, retry |
| anything else | Surface |
Only chain ONCE.
Write a qualitative memory entry about what the adherence data says — never numbers. Examples:
review: "User completed the first correction week fully; HR
ranges were inside target on all easy runs. Pattern holds."add-bulk: "Week 2026-W16 confirmed; first week with a tempo
session — watch for HR drift."Only write if the observation is NEW or CHANGED since the last entry.
data-ai
Show a weekly training log: activities grouped by ISO week and sport, with totals for distance, time and elevation. Use when the user asks "what did I do this week", "weekly summary", "training log".
tools
Cross-reference recent runs/rides with historical weather (temperature, humidity, wind) from Open-Meteo to find correlations with performance. Use when the user asks "do I run worse in the heat", "weather impact", "temperature vs pace".
testing
Show how the user's training time and volume distribute across run, ride and swim, and flag underweighted disciplines. Use when the user asks "am I balanced", "discipline balance", "which sport am I neglecting".
data-ai
Compute a combined CTL/ATL/TSB across run, ride and swim for triathletes. Use when the user asks "my combined load", "triathlon training load", "total TSS across sports".