返回 Skill 列表
extension
分类: AI Agent 能力无需 API Key

fitness-tracker

记录和分析锻炼。当用户想要(1)通过对话记录在健身房的锻炼,(2)将锻炼的Markdown文件解析为CSV,(3)使用DuckDB查询锻炼历史,或(4)跟踪健身进度时使用。触发词包括“log workout”、“record workout”、“track workout”、“add exercises”、“what did I lift”等。

person作者: jakexiaohubgithub

Fitness Tracker

Log workouts via conversation and save to github and analyze workout data with DuckDB.

Chat Mode - Logging Workouts

Use this conversational flow when the user wants to record a workout:

Step 1: Date

Ask for the workout date or default to today. Format: YYYY-MM-DD

Step 2: Muscle Group

Ask what they're working. Categories from reference/exercises.md:

  • Chest, Back, Shoulders, Legs
  • Arms - Biceps, Arms - Triceps
  • Core, Compound, Cardio

Step 3: Exercise Selection

Show exercises from that category. Let user pick or type their own.

Step 4: Sets Entry

User enters sets naturally:

  • "135 for 10, 10" → - 135 - 10, 10
  • "185 - 8, 8, 8" → - 185 - 8, 8, 8
  • "10, 10, 10" (bodyweight) → - 10, 10, 10
  • "30 minutes" (cardio) → - 30m
  • Add "warmup" or other notes as // comment

Step 5: More Exercises?

Ask if they want to add another exercise. Repeat steps 2-4 as needed.

Step 6: Save

Save the workout to GitHub (or Obsidian as fallback):

  • File: YYYY-MM-DD.md (one file per day, e.g., 2026-01-02.md)
  • If file exists, append new exercises (multiple workouts per day are supported)
  • Push to GitHub using scripts/github_sync.py

Example Conversation

User: Log my workout
Claude: What date? (default: today, 2026-01-02)
User: Today
Claude: What are you working? (Chest, Back, Shoulders, Legs, Arms, Core, Cardio)
User: Chest
Claude: Chest exercises: Bench Press, Incline Bench Press, Dumbbell Press, Cable Flyes, Push-ups, Dips...
User: Bench
Claude: Enter your sets (e.g., "135 - 10, 10" or "185 for 8, 8, 8"):
User: 135 for 10, 10 warmup, then 185 - 8, 8, 8
Claude: Got it:
  Bench Press
  - 135 - 10, 10 // warmup
  - 185 - 8, 8, 8

  Another exercise?
User: Cable flyes, 30 - 12, 12, 12
Claude: Added. Another exercise?
User: Done
Claude: Saved to 2026-01-02.md

Workout File Format

Files are named YYYY-MM-DD.md (one file per day). Multiple workouts in a day append to the same file.

Example: 2026-01-02.md

Bench
- 135 - 10, 10 // warmup
- 185 - 8, 8, 8

Situps
- 10, 10, 10

Treadmill
- 30m

Format Rules

  • Filename: YYYY-MM-DD.md (date is in the filename)
  • Exercise name: Plain text on its own line
  • Weighted sets: - weight - reps, reps, reps (e.g., - 185 - 8, 8, 8)
  • Bodyweight sets: - reps, reps, reps (e.g., - 10, 10, 10)
  • Duration: - 30m or - 1h30m
  • Notes: // comment at end of line

Configuration

Edit scripts/config.json to configure GitHub (default) or Obsidian storage:

{
  "github_repo": "username/repo-name",
  "github_token": "github_pat_xxxxx",
  "github_branch": "main",
  "github_workout_dir": "workouts",
  "obsidian_workout_dir": "/path/to/obsidian/vault/Fitness"
}

GitHub Configuration (Default)

  • github_repo: Your repository in username/repo-name format
  • github_token: Personal Access Token with repo scope. Create at: https://github.com/settings/tokens
  • github_branch: Target branch (default: main)
  • github_workout_dir: Directory in repo for workout files (default: workouts)

Obsidian Configuration (Fallback)

  • obsidian_workout_dir: Local path to Obsidian vault directory (used if GitHub not configured)

Writing Workout Files

When saving workouts in chat mode:

GitHub Workflow

Important: Must cd into the scripts directory so github_sync.py can find config.json.

Step 1: Fetch existing file from GitHub (if any)

cd /mnt/skills/user/fitness-tracker/scripts
uv run github_sync.py --fetch workouts/2026-01-02.md > /tmp/2026-01-02.md

If the file doesn't exist yet, create it empty.

Step 2: Append exercises to the local file

cat >> /tmp/2026-01-02.md << 'EOF'

Pull-ups
- 10, 10, 10
EOF

Step 3: Push back to GitHub

cd /mnt/skills/user/fitness-tracker/scripts
uv run github_sync.py \
  --file /tmp/2026-01-02.md \
  --dest workouts/2026-01-02.md \
  -m "Add workout for 2026-01-02"

Step 4: Update CSV

Fetch existing CSV, parse the new workout, and update:

cd /mnt/skills/user/fitness-tracker/scripts
uv run github_sync.py --fetch workouts/workouts.csv > /tmp/workouts.csv
uv run parse_workout.py /tmp/2026-01-02.md -o /tmp/workouts.csv --append
uv run github_sync.py \
  --file /tmp/workouts.csv \
  --dest workouts/workouts.csv \
  -m "Update workout data"

The --append flag replaces rows for the parsed date(s) while keeping other dates intact.

Obsidian (Fallback)

If GitHub is not configured (github_repo is empty):

  1. Use obsidian_workout_dir from config
  2. Target file: {obsidian_workout_dir}/YYYY-MM-DD.md
  3. Use Obsidian MCP tools or write directly to filesystem

Parse Mode - Analyzing Workouts

# Parse all daily workout files in a directory
uv run scripts/parse_workout.py /path/to/workouts/ -o workouts.csv

# Parse a single day and update existing CSV (replaces that date's rows)
uv run scripts/parse_workout.py /tmp/2026-01-02.md -o workouts.csv --append

# Parse and run a query
uv run scripts/parse_workout.py /path/to/workouts/ --query "SELECT * FROM workouts"

The parser matches files named YYYY-MM-DD.md and extracts the date from the filename.

Exercise Validation

The parser checks exercise names against reference/exercises.md and suggests corrections for typos:

Unrecognized exercises:
  'Bech Press' - did you mean 'Bench Press'?
  'Squatts' - did you mean 'Squats'?

Add new exercises to reference/exercises.md to expand the known list.

Output CSV Schema

| Column | Type | Description | |--------|------|-------------| | date | DATE | Workout date (YYYY-MM-DD) | | exercise | VARCHAR | Exercise name | | set_num | INTEGER | Set number within exercise | | weight | DECIMAL | Weight used (empty for bodyweight) | | reps | INTEGER | Rep count (empty for duration exercises) | | duration_min | INTEGER | Duration in minutes (for timed exercises) | | notes | VARCHAR | Comments from // note |

Example Queries

-- Total volume per exercise
SELECT exercise, SUM(weight * reps) as volume
FROM workouts GROUP BY exercise ORDER BY volume DESC;

-- Bench press max weight over time
SELECT date, MAX(weight) as max_weight
FROM workouts WHERE exercise = 'Bench' GROUP BY date;

-- Weekly workout frequency
SELECT DATE_TRUNC('week', date) as week, COUNT(DISTINCT date) as days
FROM workouts GROUP BY 1 ORDER BY 1;

-- Exercises by total sets
SELECT exercise, COUNT(*) as total_sets
FROM workouts GROUP BY exercise ORDER BY total_sets DESC;