plugins/claude-code-fitness-hermit/skills/capture-activity-rpe/SKILL.md
Captures RPE (1-10) and subjective notes when the operator replies to a strava-sync notification on any configured channel. Triggers on inbound channel messages matching RPE grammar while state/strava-pending-rpe.json has a sync from the last 24h. Channel-agnostic.
npx skillsauth add gtapps/claude-code-hermit capture-activity-rpeInstall 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.
Records the operator's perceived effort and subjective notes for the most recent synced activity.
Self-triggers on RPE-shaped replies while state/strava-pending-rpe.json is fresh. The skill's description is intentionally narrower than claude-code-hermit:channel-responder's so the harness picks it for these specific messages; any non-matching message exits silently and the normal channel-responder flow proceeds. Re-checks allowed_users itself.
Read .claude-code-hermit/state/strava-pending-rpe.json. If the file is absent: exit silently. If synced_at is more than 24 hours ago: run rm .claude-code-hermit/state/strava-pending-rpe.json and exit silently (reply window closed).
Authorization. Read .claude-code-hermit/config.json → channels.<channel>.allowed_users for the inbound channel (extract the channel name from the inbound message metadata):
allowed_users exists and the sender's platform user ID is not in it: exit silently. No response, no log, no state write.allowed_users is absent: accept (backwards-compatible).allowed_users is []: reject all — exit silently.Parse the inbound message body (case-insensitive, leading/trailing whitespace stripped):
^(?:RPE\s*:?\s*)?(\d{1,2})(?:\s*/\s*10)?(?:[\s,:]+(.+))?$
This matches: 7, 7/10, RPE 7, RPE: 7, RPE:7, 7 heavy legs, RPE 7, heavy legs, RPE: 7 heavy legs.
rpe (group 1) and notes (group 2). If group 2 is absent or an empty string after trim, treat notes as null.rpe is an integer from 1 to 10 inclusive.yes/no/y/n cannot match \d{1,2} so they are naturally excluded; the micro-approval branch in channel-responder handles them.)Read .claude-code-hermit/state/activity-notes.json, or use {} if absent. Set the entry for <pending.activity_id> (overwrite if it already exists, silently), then write the file back:
{
"<pending.activity_id>": {
"rpe": <int>,
"notes": <string|null>,
"recorded_at": "<ISO 8601 with offset>"
}
}
The notes field is always present: null when no notes were captured, never missing.
Run rm .claude-code-hermit/state/strava-pending-rpe.json so the same sync cannot bind twice.
Reply via the channel's reply tool with {chat_id, text}. allowed-tools only lists Discord (mcp__plugin_discord_discord__reply); on non-Discord channels this step will fail with a permission error, but the RPE is already persisted in step 4. Extend allowed-tools when adding Telegram or iMessage.
Got it — RPE <rpe>/10 saved for <pending.name>.
Refresh the deep-dive. If pending.sport is Run, re-invoke /claude-code-fitness-hermit:activity-deep-dive <pending.activity_id>. The strava-sync routine generated this activity's deep-dive before any RPE existed, so re-running now folds the RPE in — the skill reads state/activity-notes.json at its step 3b and overwrites compiled/activity-<id>-*.md. For non-Run sports the routine writes no deep-dive, so skip.
tools
Presence history & tracker-health report — current home/away state, reliability, recent arrival/departure transitions, and activity patterns for person/device_tracker entities. Use when the operator asks about presence history or when a presence-dependent automation (locks, alarm, vacuum, climate) misbehaves.
development
Evening house brief — end-of-day security check, device status, and energy snapshot. Runs as a daily routine at 22:30 or on demand.
tools
Browse and explain the hermit's Home Assistant automations — list by topic, filter by keyword with plain-language YAML explanations, or sort by last-fired. Read-only. Use when the operator asks "what automations do I have / what does this one do / which haven't fired."
tools
On-demand HA-voice brainstorm — reads entity inventory, automation/script listings, and operator intent to surface at most 2 capability-gap ideas, each gated by proposal-triage before becoming a PROP. Invoke when the operator asks "what automations am I missing?", "any coverage gaps?", or "brainstorm improvements". Never runs autonomously.