still working on this · jun 2026 - present
Marathon Prep Bot
I wanted one place that could remember my training, put each workout in context, and help me tell whether I was actually improving. So I built it around my own workout history.
how it moves
From a workout to a useful week.
Today encrypts its private snapshot before upload. The public page gets a smaller version with the progress I actually want to share.
- 01 · recordprivate
Watch and heart-rate strap
Capture the workout and the full sensor stream.
- 02 · logprivate
Today on iPhone
Captures weight, exercises, sets, reps, and load without slowing down the workout.
- 03 · exportprivate
HealthFit
Moves each workout into a FIT file in iCloud.
- 04 · understandprivate
TypeScript pipeline
Decrypts Today, cleans HealthFit duplicates, and joins the two histories.
- 05 · planprivate
Private coach
Uses the full archive to shape and check the week.
- 06 · sharepublic
Fitness page
Publishes only the progress that is safe to show.
- workouts processed
- 1,300+
- running miles
- 250+
- history since
- 2022
what I wanted
Training apps can tell me how far I ran. I wanted something that remembered the bigger picture. It should know the difference between a hard run and a hot run, remember the last few months, and help me understand what to do next.
That mattered more once I signed up for my first marathon. A single workout can look good while the month around it tells a completely different story.
what I built
HealthFit exports workout files from my Apple Watch and Polar H10. A TypeScript pipeline cleans and deduplicates them, then works out heart-rate zones, TRIMP training load, aerobic decoupling, weekly volume, and long-run progression.
I also built an iPhone app called Today for the information a watch cannot capture well. It logs morning weight plus each lift's exercises, working sets, reps, and load. Today encrypts the full snapshot with AES-256-GCM before sending it through the website. The website stores an opaque payload, and only the private coach has the key that can open it. Separate read and write tokens limit what the phone and coach are allowed to do.
The coach joins both private histories when it helps write the next week. The public fitness page gets a much smaller version with the progress, recent workouts, strength trends, and plan. New files are picked up automatically, and a written plan has to contain seven valid days before it can be published.
what was difficult
The hard part was deciding what the numbers actually meant. The pipeline has to handle duplicate exports, edited workouts, missing recovery data, treadmill and outdoor runs, and weather that can make the same pace feel completely different.
Privacy was just as important. Raw files include workout timestamps and GPS coordinates. Notes can include health context. Those stay in the private archive. The site only gets the specific fields I chose to share, such as distance, time, heart rate, training load, working-set count, and broad muscle groups.
The phone is still the source of truth if the network disappears. It saves first, marks the snapshot as waiting, retries later, and never blocks a workout because the server is down. The sync uses a versioned contract so the Swift and TypeScript sides can change without quietly corrupting old data.
That is also why the main repository is private. A public code link is not worth turning years of health and location data into a public dataset.
what works now
The archive holds more than 1,300 workouts going back to 2022. A background sync can move a new HealthFit export all the way to the site, while the plan publisher checks the week and confirms that production received the same seven days.
Today now closes the loop in the other direction. A finished lift can check off the public plan within seconds, while the encrypted detail gives the coach strength freshness, muscle exposure, exercise history, and a body-weight trend before the next plan is written.
My favorite part is that the project grows with the training. Every run gives it more context, and every improvement to the system helps me understand the next run a little better.
try it yourself
The private repo stays private, but I made the parts anyone can use public. I pulled the coaching guide, setup questions, workout import, and analysis tools into a template with none of my data in it: marathon-coach-starter.
Open it in Claude Code and say "you're my running coach, onboard me," and it will ask what you're training for, what your goals are, whether you have any injuries, and what shoes you run in. Then it sets itself up and writes your first week. There is also a standalone prompt that works in any chatbot, so you do not need to know how to code.