CLI for parsing and searching Apple Fitness+ workouts.
Fast, deterministic, and ideal for scripts, notebooks, or a personal training database.
.dtable→workouts.json+summary.jsonin one step- Search like the original script (
filter_workouts.py), but as a CLI - JSON output for automations and skills
- Validation for stable public schemas
brew install voydz/tap/fithitOr install from source with uv:
git clone https://github.com/voydz/fithit.git
cd fithit
uv sync
uv run fithit --helpmake setup
uv run fithit --helpDefault path:
$XDG_DATA_HOME/fithit/workouts.json(falls back to the standard XDG data dir)
Override:
FITHIT_DB_PATH=/path/to/workouts.json
fithit parse <dtable>: extractscontent.jsonfrom the.dtable(ZIP) and writesworkouts.json+summary.jsonfithit search ...: filters workouts 1:1 like the original scriptfilter_workouts.pyfithit info: live stats fromworkouts.jsonfithit validate: schema checks for stable public fieldsfithit fetch: downloadsworkouts.jsonvia URL (e.g. SeaTable External Link)
uv run fithit --help
uv run fithit search --category Yoga --duration "20 min" --random --limit 3
uv run fithit search --categories "Yoga,Core,Mindful Cooldown" --equipment-free
uv run fithit search --trainer "Dustin" --body-focus "Total Body"
uv run fithit search --max-duration 20 --category HIIT
uv run fithit search --search "hip opener" --format json
uv run fithit parse /path/to/Weekly\ Workouts.dtable
uv run fithit parse --output /tmp/workouts.json /path/to/Weekly\ Workouts.dtable
uv run fithit fetch
uv run fithit fetch --url "https://cloud.seatable.io/dtable/external-links/..." --output /tmp/workouts.json
uv run fithit info
uv run fithit info --format json
uv run fithit validate
uv run fithit validate --format jsonmake testThe tap repo is voydz/homebrew-tap, and the formula lives at Formula/fithit.rb.
Before publishing, update homepage, url, and sha256.
The Fitness Coach skill should only call the binary:
fithit info(DB present?)fithit search ... --format json
Minimal, stable public schema:
- Required fields:
category,duration,trainer(strings, not empty) - At least one of:
nameordescription(string)
Optional fields (string or list of strings, depending on field):
equipment,body_focus,flow_style,dumbbells,muscle_groups,move_types,strikesdate,episode,music,link,playlist,detailed_moves,notes,formatworkout_details,resistance_band,theme,topic,workout_typeprenatal(boolean)