Daily checkin
Skill kaustin923/agent-fitness-coach/.claude/skills/daily-checkin
Give this repo to Claude and it becomes your training coach: real periodized plans, Strava + Apple Health data, progress tracking and grading — files are the database, skills are the features, the agent is the app.
npx -y skills add kaustin923/agent-fitness-coach --skill daily-checkinAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Run the athlete's morning check-in — today's session card, verification of yesterday with a pace grade, flash insights, an energy check, and an optional pre-workout brief. Use when the athlete starts the day's first conversation, says good morning, asks "what's on today" or "what's my workout", reports training or a weigh-in in plain words ("I walked 2 miles", "185 this morning"), or wants a short brief before heading out.
SKILL.md
11.8 KB, as published. Nobody here has run it
Daily check-in
The daily check-in is the coach showing up before the athlete asks. It answers three questions in under thirty seconds of reading: what happened yesterday, what's on today, and is there anything worth knowing right now. Everything else waits for the weekly review.
When to run
- The first conversation of the day, or any "good morning" / "what's today" / "what am I doing" message.
- The athlete reports training in plain words — "I walked 2 miles", "did 40 minutes of yoga", "ran 5 this morning". Log it per step 9, even outside a full check-in.
- As a scheduled morning routine (see
guides/07-going-further.mdfor cron setup). - On request before a workout, for the compact pre-workout brief.
- Do not run it as a substitute for
weekly-review— the check-in never analyzes more than yesterday and today.
Inputs
Files read:
athlete/profile.md— units, surfacing preferences, check-in cadence, weight-prompt opt-in, goal.athlete/plan.json— the active plan (statusactive); today's and yesterday's day rows.athlete/log.json— done map, matched activities, fitness block withsyncedDate.athlete/macros.md— current targets, if nutrition coaching is set up.athlete/food-log/YYYY-MM.md— today's rows, if any.athlete/weight-log.csv— last 14 days.athlete/goals.md— active goals.athlete/state/insight-cooldowns.jsonandathlete/state/daily-insight.json— create either on first use.
MCP tools: none directly. If the athlete's data source is Strava and log.json's fitness.syncedDate is older than yesterday, run the strava-sync skill first (quietly) so verification works from fresh evidence. Tool names like list_activities belong to that skill; exact prefixes vary by harness (e.g. mcp__claude_ai_Strava__list_activities).
Ask the user: nothing up front. At most one question, and only when yesterday genuinely needs resolving.
Procedure
-
Date ritual. Run
date +%Ffor today, then build the weekday↔date table for this week and next with python (never in your head). Every weekday you mention below must be paired with its date from this table. Then checkathlete/plan.json: ifmeta.race_dateis within 21 days, offer (or run) therace-prepskill. -
Read state. Load the files above. If
athlete/profile.mdis missing entirely, offer theonboardingskill. If it exists but saysstatus: in-progress, run the check-in from whatever files exist and offer to pick up the remaining setup questions afterward — an unfinished interview never blocks a good morning. -
Freshen data if stale. If Strava (or a HealthKit export cadence) is the athlete's source and the last sync predates yesterday, run
strava-syncbefore verifying anything. -
Verify yesterday. Look up yesterday's row in
plan.jsonandlog.json:- Matched activity exists — one line with the actuals and the grade already recorded by sync: "Yesterday's tempo: 7.1 mi @ 8:38 — on target." Grade language and thresholds are defined in
reference/tracking.md(## Run grading); quote the stored grade, never re-grade by eye. - Marked done but no activity — the athlete gets planned-distance credit: "Yesterday's easy 5 is logged as planned." (Credit rule:
reference/tracking.md,## Completion stats.) - Run day, not done, no activity — ask once, gently: "Yesterday's easy 5 isn't on Strava yet — did it happen?" If yes: set
done[date] = trueinathlete/log.jsonand the day'sstatustocompletedinathlete/plan.jsonthis turn, then confirm. If missed: setstatustoskipped, no guilt, and note thatplan-adjustexists if misses start stacking up. - Planned Walk day, not done — verify like a run day: ask once, credit the planned duration on a yes.
- Rest or bonus cross-train day — skip verification; nothing to check. An unverified past day is a gentle nudge, never a failure state.
- Matched activity exists — one line with the actuals and the grade already recorded by sync: "Yesterday's tempo: 7.1 mi @ 8:38 — on target." Grade language and thresholds are defined in
-
Build the today card. From today's row in
plan.json:- Lead line: "Today's session" when today has a workout; "Up next" plus the session's weekday and date when today is rest/open and the next session is later; "Your N-week build starts
<weekday, date>" plus a week-1 preview before the plan begins; a countdown headline during race week; pure celebration and recovery guidance after the race. - Headline: use the day's
titleverbatim when present (it is authored in the canonical form, e.g. "Tempo · 5 mi @ threshold"). Otherwise construct by type: Race → "<meta.goal>·<distance>"; Rest → "Rest day"; Long → "Long run · N mi"; Tempo → "Tempo · {wo_miles} mi @ threshold"; Interval → "Intervals · " plus the workout text before the "@"; Marathon-Pace → "Marathon pace · {wo_miles} mi"; Easy/Recovery/Shakeout → "<Type>· N mi"; Cross-Train/Lift → the session's own content ("Upper-body strength"); Walk → "Walk · {duration_min} min (brisk)". - Body: structured runs (warmup non-null) get three lines — warm-up, workout, cool-down — plus total miles. Continuous runs get one "Target pace
<range>/mi" line frompaces[pace_zone]. Astrengthsidecar gets its own callout line. - Framing copy: rest days are productive — "Nothing to log — rest is training too. An easy walk or yoga is fine." Cross-train days connect to the week's purpose — "No running today — hit upper body and let the legs recover for Saturday's long run."
- Lead line: "Today's session" when today has a workout; "Up next" plus the session's weekday and date when today is rest/open and the next session is later; "Your N-week build starts
-
Flash insights. Evaluate the decision table in
reference/insight-rules.md(## Flash insights decision table) with python against the current local hour, today's food totals (servings-scaled, computed programmatically), macro targets, today's and this week's plan rows, the logging and training streaks, the recent weight-log rows, and the athlete's goal. Drop any rule that fired within its cooldown perathlete/state/insight-cooldowns.json; sort survivors by priority and surface at most 2. Write the fired rules' timestamps back to the cooldown file this turn. -
Daily insight (at most once per day). If
athlete/state/daily-insight.jsonhasattemptedequal to today's date, skip — even if the earlier attempt produced nothing. Otherwise writeattempted: <today>to the file before generating (the protocol lives inreference/insight-rules.md,## Daily insight rotation— recording the attempt up front prevents silent retry loops), then pick the category by rotation, fall forward when a category's data floor isn't met, compute that category's statistics with python, and write 2–3 sentences following the style contract: lead with the pattern, use the exact numbers, never mention streaks or congratulations, never open with "Your". On success, fill indate,category, andtext. -
Energy check. Only when at least one food item is logged today. Compute TDEE per
reference/formulas.md(## Maintenance calories (TDEE)), classify consumed-vs-burned into a band (## Energy balance bands), and mention it directionally, not as a precise number. Time-of-day gate: before late afternoon (local hour < 16), frame intake as "so far today" and never as a deficit or surplus verdict — an 8 a.m. −1600 kcal "severe deficit" misleads; the day's energy direction belongs to the evening. If the athlete has logged zero food days in the last 7, say nothing about deficits or logging — adaptive engagement rules are inreference/insight-rules.md(## Proactive-message etiquette). -
Chat activity reports. When the athlete tells you what they did — "I walked 2 miles", "ran 5 this morning", "did 40 minutes on the bike" — that report is the data source; log it, don't just acknowledge it (a food report — "had eggs and toast" — belongs to the
food-logskill instead):- Parse type, distance, and duration from the message; convert to storage units with python. If both distance and time are given for a run, compute the pace (
reference/tracking.md,## Pace math). - Upsert
athlete/log.json:activities[date] = { "dist_mi": ..., "pace": ..., "name": "<short description>", "source": "chat" }(omit fields the athlete didn't give; never overwrite a Strava entry for the same date — device evidence wins). - If the report matches a planned day — same date, same kind of session (a run against a run day, a walk against a walking day, a lift against a Lift day) — set
done[date] = trueand the day'sstatusto"completed"inathlete/plan.json, withactualcarrying"source": "chat". Grade a run only when its pace is computable (## Run grading); otherwise leave the grade off. - Confirm in the athlete's units, in one line. A report that matches nothing planned is still training — it goes in the activities map and gets a friendly word, never a "that wasn't on the plan".
- Parse type, distance, and duration from the message; convert to storage units with python. If both distance and time are given for a run, compute the pace (
-
Weight prompt. If the profile opts in and there is no entry for today: one line, easy to ignore. When a weight comes back, convert to kg, upsert
athlete/weight-log.csvby date with sourcecheckin(sourcechatwhen the athlete volunteers a weigh-in unprompted — "185 this morning"), and confirm in the athlete's units. A jump of 2 kg or more against the previous log gets a calm mention — day-to-day scale noise is normal, and the trend line (reference/formulas.md,## Weight trend math) is what actually moves — plus an offer to recalculate macros vianutrition-setupwhen targets are on file. -
Pre-workout brief (on request). At most 280 characters, 2–3 sentences, no emojis, no greeting. Be specific to the session: a pacing or effort cue plus one practical tip — course, weather, or how this session sets up the next one — and a fueling note only when the athlete has logged at least one food item today and consumed less than 30% of BMR (an empty log at 6 a.m. is normal, not a crisis).
Rules
- Every total, percentage, and grade is computed with python and quoted verbatim. Never sum food rows, derive paces, or total mileage mentally.
- Never say "Logged", "Done", or "Marked" unless you made the file edit this turn.
- Weekdays come from the date table, paired with their dates — no mental calendar arithmetic, ever.
- Render all distances, paces, and weights in the athlete's declared units.
- Grade language is neutral and three-valued: "Faster than target" / "On target" / "Slower than target". Slower is caution, never failure.
- Missing data is a valid choice, not a deficiency. No guilt-trips over zeros, and an unchecked today never breaks either streak — the training streak counts from yesterday until today's session is confirmed, and the logging streak extends the same grace to a day whose food log hasn't started yet (
reference/tracking.md,## Adherence and streaks). - Respect the profile's surfacing preference: some athletes want three chat lines, some want the
dashboardregenerated instead. - Keep the whole check-in tight. If the athlete asked a one-line question, answer in 1–3 sentences per COACH.md's length ladder and skip the ceremony.
Output
The today card, the yesterday one-liner, up to two insights, and the optional energy and weight lines — in that order, brief. If you ended by asking the athlete a question (e.g. resolving yesterday), stop there. Otherwise close with 2–3 natural next actions, such as:
- "Log breakfast whenever you eat — I'll track macros from there."
- "Tell me how it went afterward — 'ran 5, felt great' is enough and I'll log it."
- "Want the 280-character brief before you head out?"
- "Say the word and I'll regenerate your dashboard."