bump-core-req
Updates the minimum core version requirement for a fleet plugin in all three canonical places: `required_core_version` and `requires["claude-code-hermit"]` in…
Composes and delivers the daily fitness brief — a forward-looking morning read (readiness + today's plan) or a backward-looking evening read (today's training, or an earned-rest note, + tomorrow's setup) — in the operator's configured voice. Invoke with
$ npx -y skills add gtapps/claude-code-hermit --skill fitness-brief --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/fitness-briefContext preview
The summary Claude sees to decide when to auto-load this skill.
Composes and delivers the daily fitness brief — a forward-looking morning read (readiness + today's plan) or a backward-looking evening read (today's training, or an earned-rest note, + tomorrow's setup) — in the operator's configured voice. Invoke with
name: fitness-brief description: Composes and delivers the daily fitness brief — a forward-looking morning read (readiness + today's plan) or a backward-looking evening read (today's training, or an earned-rest note, + tomorrow's setup) — in the operator's configured voice. Invoke with /claude-code-fitness-hermit:fitness-brief --morning|--evening|--slot <name>. Becomes the plugin's two daily beats — the morning Strava connectivity check and the evening activity sync, RPE binding, and Run deep-dive. allowed-tools: - Read - Write - Edit - Bash(bun *fitness-lab.ts*) - mcp__strava__check-strava-connection - mcp__strava__get-recent-activities
One skill, two lenses on the same athlete's training state. Composition is intent-driven, not scripted: gather a bounded digest, then write the brief toward the goal below in the operator's configured voice — there is no fixed section order, no hardcoded tone, and no mandatory rest-day copy.
operator's own conventions say otherwise.
Resolve `<slot>` from the flag before starting. Filenames below use that resolved value. Steps below say "Morning"/"Evening" as shorthand for forward-looking/backward-looking orientation — a custom `--slot` follows whichever branch matches its resolved orientation.
1. **Connectivity + sync mechanics.** These fold in what `strava-health-check` and `strava-sync` used to run on their own crons — this brief now owns that beat.
brief and skip the data-dependent parts below rather than fabricating figures.
against `state/strava-last-activity-id.txt` (treat missing as "none"), and for any new activity whose Strava `type` is `Run`, invoke `/claude-code-fitness-hermit:activity-deep-dive <id>` (cap 3 — log skipped IDs to SHELL.md Progress Log past the cap). Advance the cursor file to the highest new ID. Hold the newest new activity's id/name/sport for step 4 — do **not** write `state/strava-pending-rpe.json` here. That file's writer contract (see `docs/knowledge-schema.md` and `CLAUDE.md` § Memory Conventions) is write-only-after-confirmed-delivery, precisely so a failed or push-only send can't bind a future RPE reply to an activity the operator was never actually told about.
2. **Gather (bounded).** Raw Strava streams must never enter context — `fitness-lab.ts` reduces them first.
rolling per-week load digest (km, moving time, zone %, `tss_proxy`). Read `state/strava-weekly-baselines.json` if present for trend context.
only deep-dives Run activities), `bun ${CLAUDE_PLUGIN_ROOT}/scripts/fitness-lab.ts analyze <the non-Run activity's id from step 1>` for today's session — pass the id explicitly, not `latest`: `latest` resolves the globally most-recent Strava activity, which on a mixed-type day (a Run uploaded after the non-Run) would analyze the wrong session. If the new activity *was* a `Run`, step 1's `activity-deep-dive` call already ran this same analysis and wrote `compiled/activity-<id>-<date>.md` — read that artifact instead of re-running the analysis, which would redo the same Strava fetch and computation. Either way, also read whatever `state/activity-notes.json` already holds for it. No new activity is itself the input — there's nothing to analyze.
Handle the script's error contract as `activity-deep-dive` does: `{"error":"strava_auth",...}` or `{"error":"fetch",...}` (both exit 1) → relay the `message` to the operator and stop gathering further data; compose from whatever was already gathered.
3. **Compose.** You have the digest from steps 1–2, the operator's voice (`agent_name`, `voice`, `operator_profile`, `language` in `config.json` — the same voice every other channel message uses), and the goal below. Write toward the goal; there is no required template.
load/trend, anything worth flagging, a plan or nudge for today.
logged, the rest itself is the information — an earned-recovery day reads very differently from a third silent day in a row; use judgment, don't force a script. Set up tomorrow. If step 1 captured a new activity, invite an RPE reply.
`compiled/brief-evening-<date>.md` if continuity would genuinely add something — reading just that one file is optional judgment, not a required step. These briefs accumulate daily with no retention cap (per `docs/knowledge-schema.md`), so never glob-read the whole `brief-*.md` set.
4. **Deliver** per the Operator Notification protocol in CLAUDE.md (core resolves the channel and falls back to push / SHELL.md logging when no channel is reachable). Never gate delivery on `session_state` — routines can fire while the terminal is unmonitored. Push-fallback: a single line per § Operator Notification push format, leading with the thing most worth knowing.
a logged-only send): write `state/strava-pending-rpe.json` with the activity held from step 1:
{"activity_id": <id>, "name": "<name>", "sport": "<Run|Ride|WeightTraining|…>", "synced_atIf you know Claude Tag, the idea will feel familiar: hand Claude work through a channel, such as Discord, Telegram, or your custom integration, and get results back there.
Repo: gtapps/claude-code-hermit
Updates the minimum core version requirement for a fleet plugin in all three canonical places: `required_core_version` and `requires["claude-code-hermit"]` in…
Changelog and commit — lightweight motion for day-to-day plugin dev work in the monorepo. One commit per plugin scope; CHANGELOG and staging routed by detected…
Documentation-drift audit for the plugin monorepo. Audits either each scoped plugin's unreleased changelog claims or its latest shipped release from the…
Explain in plain language what a fix, feature, PR, or plan will actually change for downstream hermits and the operators chatting with them — a before/after…
Use this skill whenever the user wants to release, ship, prep, or cut versions for two or more plugins together on the current branch. Trigger on phrasings…
Daily release-pipeline digest with a change gate — reports which plugins are pending release, whether main's CI is green, which branches went stale, and GitHub…