Repository navigation
Conversation
Start a workout from the Activity tab, record the strap's live heart rate on the phone, and keep a complete record through disconnects and a killed app. - Recording: WorkoutSession streams live HR in the background during a workout, writes it to Room every 10 s, and resumes a workout left recording when the process restarts. New tables app_workout and app_workout_hr (DB v8), kept apart from the strap's own workouts. - Gap filling: after each history sync, whole minutes the phone missed are filled from the strap's per-second HR, else its minute records (WorkoutRecorder, WorkoutGapFill). - Screens in the glow language, following the Workout Mode canvas: start card with the most-used sports, ready screen, live screen in the zone's colour with hold-to-end, capsule and tinted tab bar while minimized, and a summary with heart rate coloured by zone. - Notification: an Android 16 Live Update with a zone bar, Pause/Resume and End; the foreground service stays up for the whole workout. - Zones take the canvas palette and names app-wide; phone workouts join the workout lists and the CSV export. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ching End well (2) - "Looks like you've stopped": after 8 min near resting heart rate and no steps, following an active spell, the strap buzzes and the live screen and notification offer "End at 18:50" or "Keep going". A dropped strap never triggers it; "Keep going" waits for a new active spell. Toggle on the ready screen. - Car detection without location or Google services: a car stereo or hands-free kit connecting over Bluetooth asks at once. - Early ends and trims are non-destructive (recordedEnd, shownStart), with undo; the summary says what the app did. Trim the start and end on the heart-rate chart. - Summary compares with your last 5 similar workouts of the same sport, and marks "your usual" on each zone bar. Missed sessions (3) - Awake stretches of 10+ min at 40 %+ of heart-rate reserve that aren't a workout become a card on Today and Activity: Save as workout (choose the sport) or Not a workout (remembered for that range). - "Add a workout you didn't record": pick the range on the day's heart rate. Both are built from the strap's stored minutes. Entry points (4) - Start card rebuilt from the app's stat tiles; a Start workout row on Today; a Quick Settings tile; Start run / Start strength launcher shortcuts. All open the ready screen. Coaching (5) - Targets on the ready screen (a zone, a zone range, a time); Start takes the target's colour. The strap buzzes on leaving and re-entering the target (held 15 s, cues 40 s apart), at halfway and at the goal, each with its own pattern; never while a call rings or DND silences everything. Also: DB v10 (app_workout_dismissed, app_workout_route, GPS and target columns), CSV export of the new tables, MapLibre added for milestone 6, and a debug-only strap simulator (simulate_hr) for testing on the emulator. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GPS and maps (6)
- GPS for outdoor sports through Android's own location service (no Google
services), off by default; asked for only when turned on. The route is
used live for distance, pace and the map, then discarded unless "Keep
route on this phone" is on. Without location, distance comes from the
strap's steps (≈).
- Live screen pages Heart · Map · Splits: MapLibre with OpenFreeMap's dark
tiles (no key), the route in zone colours, GPS accuracy, "route only" (no
tiles), and per-km splits with pace and heart rate.
- Summary: distance, the kept route on a map, Export GPX with the first and
last 300 m left out; phone workouts go to Health Connect as exercise
sessions (GPS distance with them).
- The foreground service adds the location type for a GPS workout.
Strength (7)
- Sets against an optional target, "Start set" / "Set done"; rest ends at
its time (+30 s to extend) or sooner once heart rate holds below a chosen
level, and the strap buzzes. Lock-screen notification with the rest
counting down. Sets on the summary.
Strap-side sessions (8, experimental, off by default)
- SportModule 0x0019 codec (version, config, state, keep-alive, pushes)
with byte tests from the teardown's examples; docs/protocol/04.
- When on (debug: --ez strap_sessions true): START/PAUSE/RESUME/STOP follow
the phone workout, START again after a reconnect, and the strap's "heart
rate back to normal" asks whether to end. A strap workout synced for the
same time shows on the phone summary ("From the strap"). Unverified on
hardware.
DB v11 (app_workout_set; rest and sets target). README: Network use
(OpenFreeMap tiles) and Location permission.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Lap button left of Pause on the live screen (as on the design) and a Lap
action in the notification; a short buzz confirms. Laps are stored as
marks on the workout (DB v12) and listed on the summary with time,
distance (GPS) and average heart rate.
- Start-card tiles wrap long sport names ("Strength training").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto-start: while idle, live heart rate is sampled for 30 s every 3 minutes, and streams on while it's up or the feet are busy. Once an effort has lasted 10 minutes (the missed-workout rule, on live readings) the strap buzzes and "Looks like a workout" offers to record it from where it began, with the readings since; walk, run or free training from the cadence. On by default, with a switch under Start a workout. Notifications: - Everyday: Recovery and Charge as the title, problems first (Retry, low battery, sync progress), last sync as the time, Start workout and Sync now; a quiet mode on the You tab. - Workout: zone colour (the whole card where Live Updates can't show, as on Samsung), target progress, distance and pace, a disconnected state, and a two-step End. - A "saved" summary after a workout, with Undo when it ended on its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the zone colour The zone stays on the bar and in the text; the line says "Waiting for heart rate" before the first reading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A lighter grey while paused or disconnected; the logo's red stays the accent where the notification isn't colorized. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each other CPU type carried its own ~13 MB copy of the map engine. Release APK 55.6 MB -> 18.4 MB; debug 100 MB -> 62 MB. The emulator on Apple silicon is arm64 too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rimmer - Pause, Lap and End are flat like Start and Done (white Pause, dark Lap and End with a red stop and hold ring); the live card keeps the glow. - The zone bar's marker is the Recovery/Charge gauge dot in the zone colour, bright up to it and faint after, in the app and the notification. - Trim is a video trimmer (Snapchat, Polarsteps): one rounded frame whose thick sides are the handles, over the workout as zone-coloured dot columns; what's left out fades back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Avg | time | Max (or distance and pace/avg), labels under the numbers with thin rules between (WHOOP, Oura on Mobbin); the row centred between the card and the buttons, which sit a little higher. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It squeezes on each beat (lub, then a smaller dub) and relaxes, staying as dark throughout; each beat also nudges and squashes it a new way, so the colour surges past a different side. The old beat faded the core 20%, which read as a glitchy flash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Android raises a foreground service's MIN channel to LOW, so Quiet never hid the status-bar icon. Since Android 14 the notification can be swiped away with the service still running; it now stays away until a workout starts or a new problem (connection failed, low battery) needs it. Debug: the strap simulator takes simulate_battery. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GlowSwitch is white with a black knob when on and dim grey when off, like the workout buttons; the Material switches (alarms, phone alerts, firmware server) use it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…live pages Route.clean starts the route at the first of five agreeing fixes within 20 m, so a cold start's far-off fix doesn't count, and distance, pace, splits and the map line follow Route.track, which takes a fix only once it's further than both fixes' error from the last. Standing at home now stays at 0 m. The live map centres on the latest fix before there's a line, Heart, Map and Splits swipe as well as tap, and the MapLibre logo is gone (the attribution button stays). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The live screen no longer scrolls: Map and Splits take the heart card's height (splits scroll inside their panel), so swiping never moves the stats or controls. The map fills its page; the note about map tiles moves to the GPS switch on the ready screen. After a Lap press, "Lap 3 · 1:24" shows the lap under way under the moving time, and the phone gives a short haptic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Minimizing the live screen shrinks it, corners rounding, into the capsule above the tab bar (and back on a tap), over 550 ms, keeping the live screen composed through the move so it isn't rebuilt as it starts. On Today, Start workout is a white pill under the Workouts header, above the day's workouts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Running, it shows the sport and clock with a live dot and opens the live screen; paused, "Resume walk · 12:34" resumes at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 2×2 grid becomes a white "Start walk" pill for your usual sport (like Today's) with the next sports and All sports as chips under it. "Notice workouts" is renamed Auto-detect workouts, the term other apps use, and its line says the strap buzzes and asks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uto-detect line The strap files movement it logged on its own as sport 223, "Activity"; it counted toward your most-used sports and took a chip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…off foot Start a workout on Activity is four alike round buttons (most used first, then All sports) sharing the width. The ready screen opens as a circle from where it was tapped and shrinks back into it; a workout starting replaces it at once. Distance from steps is only for sports done on foot (runs, walks, hikes); cycling, swimming and the rest show average and max heart rate instead, and the GPS switch says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thirteen sports that were another one under a second name, and the strap's generic Activity, are kept for naming recorded workouts but no longer offered. The rest sit in seven sections (Running & walking, Gym, Cycling, Water, Mind & body, Racket & ball, Outdoors) as a four-wide grid of the same round buttons as Start a workout, each sport with its own Phosphor icon; the current one is ringed. Search filters within the sections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…shorter lists The ready screen slides in and out like every other screen, and minimizing the live workout slides it down and fades while its capsule rises, both at the app's 240 ms. A workout with under a minute of moving time is deleted as it ends, with a toast. Today lists the day's last three workouts; Activity's list is four rows tall, scrolls inside its panel with a bar in the margin, and keeps its scroll from moving the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orchid Recovery was grey whenever OpenStrap's score was missing, so it read as "no data" through the learning nights and even with the strap's estimate on the card. Learning is now a muted teal, and the strap's estimate picks the card colour like a real score. Healthspan's lavender sat next to Sleep's blue; orchid keeps it clearly apart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The card shows an age ("34 · 3 years younger"), not a span of healthy
years, and the inputs are habits, not blood markers. It's also WHOOP's
feature name. Only user-facing text changes; code names stay Healthspan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On, the switch in a glow card is a deeper shade of the card's colour with a white knob, so it belongs to the card. Switches in lists and sheets stay monochrome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a foldable half-open during a live workout, the standing half shows the workout's heart card as big as it fits and the flat half keeps the figures and the Lap, Pause and End controls. Flat on a table that's top and bottom; stood up like a book, left and right. A minimized workout leaves the tabletop heart card as it was. The controls row is capped at a thumb's reach and centred, so on a wide screen Lap and End stay beside Pause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phone-started workouts, built to the spec OpenStrap Workouts: Feature Spec and its Workout Mode canvas, in the app's glow design language. All eight milestones from the spec's build order are here, one commit each (2–5 and 6–8 grouped).
What's in it
--ez strap_sessions true); merges the strap's own record into the phone summaryTesting
--es simulate_hr 140x120,75x600) andgeo fix:Needs the phone and strap
13 00timingKnown gaps
🤖 Generated with Claude Code