Daily checkin
Skill kaustin923/agent-fitness-coach/.claude/skills/daily-checkin
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.From its SKILL.md
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.
SKILL.md
11.8 KB, ~2.8k tokens by cl100k_base, 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."
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.