Skip to content

Releases: ryanbr/noop

NOOP 8.5.0

Choose a tag to compare

@github-actions github-actions released this 09 Jul 04:53
3a17263

NOOP v8.5.0

A data-and-polish release: a new native raw-SpO₂ readout, unit/display fixes that make skin temperature and Effort honour your settings, the return of the live workout card, steadier battery behaviour, and a lighter, faster app. Update from the Releases page, AltStore, or brew upgrade.

Added

  • Raw SpO₂ on the Health screen (WHOOP 4.0, #93). The strap only streams the raw red/IR PPG optical channels — the calibrated blood-oxygen % is a WHOOP cloud computation NOOP can't reproduce. Rather than fake a number, NOOP now surfaces the nightly raw red/IR ADC means as an honest, explicitly uncalibrated "Raw SpO₂" reading. Both platforms.
  • Fitness Age shows a countdown while it builds (#81). Instead of an empty gauge, Fitness Age now says how many more nights of wear it needs before it can score you.

Fixed

  • Skin temperature respects the Fahrenheit setting (#101). The Deep Timeline hard-coded skin temp to °C — the line, axis, stats and readout ignored your unit preference. They now convert to °F when you've chosen it. Both platforms.
  • The Today "Effort" ring follows your Effort scale (#45). The hero gauge ignored the 0–100 vs WHOOP 0–21 setting and always showed 0–100. It now shows the scale you picked, with one decimal on the compressed 0–21 axis (matching WHOOP and the rest of the app).
  • The "workout in progress" card is back on Home (#105). The Liquid Home rewrite dropped the live indicator that appears while a manual workout is running. It's restored, auto-appears/clears with the workout, and taps through to the live view.
  • Apple Health steps import into your daily totals (#89). Imported steps were written everywhere except the daily-metric row the step display actually reads, so they never showed. Fixed on both platforms.
  • Clearer "Overnight only" HRV wording (#92). The setting now spells out that continuous background HRV capture (including daytime naps) is paused outside your quiet-hours window, and points you at the "Take an HRV reading" button on the Live screen for an on-demand daytime reading. Both platforms.
  • Low-battery alert no longer re-fires while charging (#80). Plugging in no longer re-triggers the low-battery notification.
  • Battery estimate fixes (#99). A low-state-of-charge cap and a corrected slope window keep the battery estimate honest near empty.
  • Home-screen widget shows current battery (#114). The widget could display a stale value; it now refreshes to the latest reading.
  • Smaller display fixes. The Motion metric is now labelled "g" (#102); skin-temp banding no longer misreads an absolute reading (#111); the steps empty-state reads correctly on WHOOP 5.0/MG (#107); Today hero labels no longer wrap (#78); and the Settings Appearance card has its row dividers back (#79).

Performance

  • Export imports can't balloon memory (#70, #125). The WHOOP and wearable-export importers were bounded per-entry but not on the sum of what they held in RAM. A large or crafted export could accumulate unbounded data before parsing; a per-import total-byte budget now caps peak memory, and a truncated import says so rather than silently dropping data. Both platforms.
  • Snappier Sleep screen (#128). The sleep-consistency chart rebuilt its per-night bed/wake fold on every frame; it's now memoized, so scrolling reuses it.
  • Fewer per-render allocations on Today (#129). Date formatters that were allocated on every ~1 Hz redraw are hoisted to shared, cached instances.

Diagnostics & honesty

  • Oura ring: the log now says WHY a time anchor was rejected (#91). When an Oura ring's UTC anchor won't land (so sleep/daily can't be timed), the strap log now names the reason — an implausible timestamp — instead of failing silently.
  • Test Centre no longer cries "missing sleep" when sleep was computed (#127). The Sleep & Rest capture check keyed only on a deep gate trace that legitimately doesn't re-emit when a night was already scored; it now also accepts the per-day computed-sleep line as proof, so a valid capture reads complete. Both platforms.

Notes

  • Raw SpO₂ is a raw sensor reading (unit "ADC"), not a calibrated blood-oxygen percentage — an accurate % needs WHOOP's proprietary calibration curve, which no independent app has. The calibrated % still comes through a WHOOP or Apple Health import.

What's Changed

  • Battery estimate: scale the sanity cap to current SoC — fixes "9% = 3 days" (#99) in #118
  • Widget: keep the Home-screen widget fresh (publish on background + live battery/connection) (#114) in #117
  • Steps: make the no-motion empty state WHOOP 5/MG-aware (#107) in #116
  • Skin temp: fix Fahrenheit (deviation must not get the +32 offset) (#111) in #115
  • Fix battery estimate anchoring on a stale, multi-cycle-old peak (#99) in #109
  • Fix unlabeled Motion readout in Deep Timeline (#102) in #108
  • Raw SpO2 on Health: WHOOP 4.0 raw PPG ADC — iOS/macOS + Android (#93) in #119
  • Settings: add missing row dividers in the Appearance card (#79) in #83
  • Battery alert: stop re-firing the low-battery notification while charging (#80) in #82
  • Fitness Age: "N more nights" countdown while it's building (iOS + Android) in #81
  • fix(issue #92): clarify overnight-only HRV setting and manual HRV reading in #95
  • iOS/macOS: clarify overnight-only HRV setting copy (#92) in #120
  • Today/Deep Timeline: respect °F + Effort scale on the hero, with one-decimal Effort (#45, #101) in #121
  • Android Deep Timeline: respect °F for skin temp (#101) in #122
  • Oura: log WHY a UTC anchor was rejected — iOS + Android (#91) in #123
  • Apple Health import: write steps to DailyMetric — iOS + Android (#89) in #124
  • Android import: bound peak RAM with a per-import total-byte budget (#70 parity) in #125
  • perf: bound import RAM with a per-import total-byte budget in #70
  • Today (liquid): restore the 'workout in progress' card (#105) in #126
  • Perf: hoist per-render DateFormatters to static in #129
  • Sleep: memoize SleepConsistencyCard per-night fold (perf) in #128
  • Test Centre: capture check accepts computed-sleep evidence (#127) in #130
  • Today hero: keep ring labels/pills on one line (oversized card, #74) in #78
  • Release v8.5.0: changelog + version bump in #131

Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.5.0.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.5.0.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.5.0.ipa (AltStore / Sideloadly)

NOOP 8.4.0

Choose a tag to compare

@github-actions github-actions released this 08 Jul 06:49

NOOP v8.4.0

A broad tune-up: platform fixes (Intel Macs, iOS sideloading), a picker-free backup option, meaningfully faster sleep/recovery analysis, and better honesty around strap-clock and alarm problems. Update from the Releases page, AltStore, or brew upgrade.

Added

  • Backup & Sync: "Use NOOP's own folder" (iOS, #52). Some iOS 26 builds won't let the system folder picker select a folder at all. NOOP now offers a picker-free option that backs up inside its own folder — browsable in the Files app under On My iPhone → NOOP → Backups, or dragged into iCloud Drive to read on a Mac. The picker path is also instrumented so a debug export shows exactly where it fails.
  • Oura ring live heart rate in the Live console (#56, #59). A connected Oura ring's live stream is recognised as a trusted source and shown in the console — on both iOS/macOS and Android.

Fixed

  • Intel Macs: native again (#51, #58). The macOS app is now built as a universal binary (x86_64 + arm64), fixing an arm64-only regression that left Intel Macs running under translation (or not at all).
  • iOS sideloading: "integrity could not be verified" (#53). The prebuilt IPA is now a Release build, which re-signs and installs cleanly via AltStore / Sideloadly — the debug artefacts in the old build were what modern iOS rejected.
  • Oversized Settings screen (#43). The Sex selector could force the whole Settings column past the screen edge — most visibly in German or at larger text sizes. It's now a compact menu that fits any label length.
  • Restore no longer risks your newest history (#57). After restoring a backup, a sync could run into the just-closed database and discard freshly-offloaded records, and an empty offload could advance past history that never got stored. NOOP now blocks that path and prompts a clean restart. Both platforms.
  • Smart-alarm phone backup follows the alarm (#34). The backup notification was gated behind the unrelated wrist-alerts switch, so people who set a smart alarm without enabling wrist alerts got no backup at all. It's now tied to the alarm itself.

Performance

  • Faster sleep & recovery analysis (#68). The nightly re-score read each session's motion/sleep-state one database row at a time; those are now single batched queries (N+1 → one), cutting the round-trips on the score-of-record path. Output is identical and equivalence-tested.
  • Live decode does the work once (#47). Each live WHOOP 4.0 frame is now parsed a single time instead of two or three, and the offload gesture path skips the full decode of frames it doesn't need.
  • Lighter app art (#46, #48). Scene backdrops re-encoded to HEIC/WebP for a smaller download and quicker screen loads.

Diagnostics & honesty

  • Strap log shows where offloaded sleep actually landed (#67). A strap whose clock has reset banks last night with a wrong date, so the night lands off the recent timeline and reads as "missed sleep." The log now records where the rows landed and whether the stale-clock correction could engage — turning a silent misdating into a one-glance diagnosis.
  • On-device warning when a strap refuses the alarm (#34). When a strap keeps reporting back a different alarm time than NOOP sends (a reset/corrupted alarm register), the Alarms screen now says so and points to a strap reset — instead of the alarm silently never firing.

Notes

  • The strap firmware alarm and the iOS phone backup are still best-effort: a sideloaded build can't sound a guaranteed loud wake, so keep your phone's built-in Clock alarm as your real backup.
  • Dead links to the retired upstream repository were cleaned up across the docs (#60, #61).

What's Changed

  • Android: recognize the Oura ring's live stream as trusted in the Live console (#56 parity) in #59
  • Fix/oura live console trusted stream in #56
  • CI: build the macOS app as a universal binary (x86_64 + arm64) (#51) in #58
  • docs: repoint dead NoopApp/noop links to ryanbr/noop (curated from #54) in #60
  • docs: fix two remaining dead NoopApp/noop links (#60 follow-up) in #61
  • Restore: don't sync into a closed DB, and never ack past un-stored history (#57) in #62
  • perf: decode each live WHOOP4 frame once, not 2–3× (#47) in #63
  • perf: skip full decode of non-EVENT frames on the offload gesture path (#47 follow-up) in #64
  • resources: re-encode day-cycle scene backdrops as HEIC (−2.8 MB, ~85%) in #46
  • resources: re-encode Android day-cycle scenes as WebP (−1.4 MB, ~86%) in #48
  • iOS: build the sideload IPA in Release, not Debug (#53) in #65
  • Strap log: surface WHERE offloaded rows landed + WHY (stale-RTC "missed sleep", #67) in #69
  • Strap log: soften stale-RTC diag wording ("no clock correlation at decode") — #67 follow-up in #71
  • iOS Backup & Sync: "use NOOP's own folder" fallback + folder-picker instrumentation (#52) in #66
  • perf: batch the per-session motion/sleep-state reads (N+1 → one query) in #68
  • Settings: Sex picker → .menu, fixes oversized Settings screen (#43) in #72
  • Smart alarm: instrument + warn when the strap keeps refusing the alarm (#34) in #75
  • Smart alarm: phone backup follows the alarm, not the wrist-alerts master (#34) in #73

Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.4.0.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.4.0.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.4.0.ipa (AltStore / Sideloadly)

NOOP Staging — base 8.4.0 · 2026-07-08 · bf1c683

Choose a tag to compare

@github-actions github-actions released this 08 Jul 23:23
bf1c683

Rolling latest testing build — refreshed in place, so this tag is always the newest. NOOP main + ryanbr's open PRs + vetted community PRs, built with the NOOP Staging identity (installs beside the official app, separate data). Filenames carry the base app version (v8.4.0).

  • Android (release)NOOP-android-v8.4.0.apk — optimized, non-debuggable build; installs beside the official app. com.noop.whoop.staging.
  • Android (debug)NOOP-android-debug-v8.4.0.apk — debuggable build. com.noop.whoop.debug.
  • macOSNOOP-macos-v8.4.0.zip — unzip, then right-click → Open (unsigned; Gatekeeper warns once).
  • iOSNOOP-ios-unsigned-v8.4.0.ipa — sideload via AltStore / Sideloadly (re-signs on-device); embedded watch app stripped.

Base app version 8.4.0 · built 2026-07-08 · bf1c683.

NOOP 8.3.4

Choose a tag to compare

@github-actions github-actions released this 07 Jul 14:42

NOOP v8.3.4

A focused fix for a confusing sync message. Update from the Releases page, AltStore, or brew upgrade.

Fixed

  • No more false "charge to 100%" alarm right after a successful sync (#42). When NOOP auto-continues an offload to drain the last of your strap's banked history, the final (empty) pass could print the alarming "strap has no banked history — fully charge it and reconnect" line and count it as an empty sync — even though the same sync had just banked hundreds of records. NOOP now recognises that tail as "caught up" and keeps the real charge-to-100% guidance for straps that genuinely aren't banking. Both platforms.

What's Changed

  • Backfill: stop the false "no banked history" alarm on an auto-continue's empty tail (#42) in #44

Full Changelog: v8.3.3...v8.3.4


Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.3.4.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.3.4.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.3.4.ipa (AltStore / Sideloadly)

NOOP 8.3.3

Choose a tag to compare

@github-actions github-actions released this 07 Jul 13:52

NOOP v8.3.3

A recovery-and-polish release: the macOS app finds your existing data again after an upgrade, French is now complete, the sleep-stage graphic renders properly on fragmented nights, and a "didn't buzz" alarm report is finally diagnosable. Update from the Releases page, AltStore, or brew upgrade.

Fixed

  • macOS: data lost after upgrading is recovered (#39). The Mac app started reading a different on-disk location than earlier versions, so an upgrade opened an empty database. Nothing was ever deleted — your store was still on disk, just not where the app looked. On first launch the app now finds your existing database and copies it in (a copy, never a move, and only when its own store is empty), so your history reappears.
  • Sleep-stage graphic no longer collapses into a row of circles (#36). On a night with many short on-device stage segments, the stage strip overflowed the card and clipped into a disconnected row of dots. It now scales to fit and draws as a continuous bar across the whole night.
  • Honest strap-alarm status (#34). The alarm log no longer claims "armed" when the strap is disconnected — it says "queued, will send on next connect" until the command actually goes out.

Localization

  • French is complete. The String Catalog carried only a partial French locale; every string is now translated (matching German and Spanish). More of the Today screen — the hero labels, recovery vitals, key-metric tiles, readiness wording and greeting — is now translatable too.

Under the hood

  • Alarm diagnostics in the shared log. A "didn't buzz" report is now decidable at a glance: the debug export carries an Alarm block — the time we sent vs. what the strap reports back (flagging a mismatch), whether the strap was connected when we armed, last-fired, the model + 5/MG experimental gate, and a reset/stale-clock warning.

What's Changed

  • macOS: import the official app's store into the fork build (#39) in #40
  • Sleep: stop the stage strip clipping into a row of circles (#36) in #38
  • Debug export: Alarm block + honest "armed" log (#34) in #37
  • i18n: localize Today strings + complete the French catalog (#35) in #41

Full Changelog: v8.3.2...v8.3.3


Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.3.3.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.3.3.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.3.3.ipa (AltStore / Sideloadly)

NOOP 8.3.2

Choose a tag to compare

@github-actions github-actions released this 07 Jul 11:24

NOOP v8.3.2

A workouts fix-up: imported files and re-paired straps now show their sessions, and shared strap logs carry more of what's needed to solve a report. Update from the Releases page, AltStore, or brew upgrade.

Fixed

  • Imported activity files now appear in Workouts (#29). A FIT / GPX / TCX import reported success and was counted in Data Sources, but never showed in the Workouts list — the load path didn't read the imported-file source. It does now, with the "File import" badge.
  • Workouts show after re-adding / pairing a strap (#28). Workouts banked under your canonical history became invisible once a strap was re-paired, because the Workouts screen queried only the new strap's id. It now reads across both — the same union every other screen already uses — so nothing disappears on a re-pair.

Under the hood

  • More useful bug reports. The strap log you share now includes a workout + daily-data source breakdown (which id/source each metric lives under, vs. what the screen shows) and an on-device data-volume line, so a "present in Data Sources but missing from the screen" report is diagnosable at a glance.

What's Changed

  • Release notes: drop the author-handle credit from the auto breakdown in #25
  • iOS: ship production bundle ID (fixes #26 AltStore install) in #27
  • Android: read Workouts across the my-whoop union (fixes #28) in #30
  • Workouts: show imported activity files (FIT/GPX/TCX) — fixes #29 in #31
  • Debug export: add a Workouts-by-source breakdown in #32
  • docs: v8.3.2 release notes + What's New in #33

Full Changelog: v8.3.1...v8.3.2


Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.3.2.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.3.2.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.3.2.ipa (AltStore / Sideloadly)

NOOP 8.3.1

Choose a tag to compare

@github-actions github-actions released this 07 Jul 09:23

NOOP v8.3.1

A fixes-and-polish release: the backup-restore failure is fixed, the Today screen gains two appearance controls, and shared strap logs carry more of what's needed to solve a report. Update from the Releases page, AltStore, or brew upgrade.

Fixed

  • Restoring a backup works again (#18). Importing a .noopbak could fail with "This backup file is damaged … unable to open database file" — even for a perfectly good backup — because the safety check opened it the wrong way. NOOP now reads the backup correctly during that check, so restores go through, while still refusing a genuinely damaged file. (iOS / macOS; Android was already handling this.)

Appearance

  • Card transparency. Settings → Appearance has a new slider that fades every card — Heart Rate, Key Metrics, Recovery Vitals, the score hero, and the rest — from solid to see-through, saved and previewed live as you drag. Android and iOS.
  • Sky behind cards. A new opt-in toggle extends the day-cycle sky behind the whole Today screen (not just the top band), so lowering Card transparency reveals it under every card. Off by default; needs the day-cycle background on.
  • On iOS, the Day-cycle background setting now also applies to the redesigned Today — turning it off gives the plain dark canvas, matching Android.

Diagnostics

  • Richer strap logs for bug reports. The strap log you share now also carries your strap & data state (model, firmware, last sync, days of history, most recent sleep / recovery) and the REM + skin-temp analysis funnels for the latest night — so a "0% REM" or "won't sync" report arrives with the detail needed to diagnose it. It self-reports when it can't compute a value, and never adds anything personal the log didn't already contain.

Under the hood

  • AltStore updates itself. Each release now updates the AltStore / SideStore source automatically, so sideload users are offered new versions without a manual step.

What's Changed

  • Backup & Sync: configurable daily backup time (default 1am) in #13
  • Card transparency: user-configurable opacity for all home cards in #14
  • Settings: "Sky behind cards" — day-cycle sky behind the whole Today scroll (opt-in) in #15
  • iOS: "Sky behind cards" parity — day-cycle sky behind the whole Today scroll (opt-in) in #16
  • iOS: liquid Today honours the Day-cycle background toggle (closes #16 parity gap) in #17
  • Release workflow: auto-update the AltStore source manifest in #23
  • iOS: fix restore of WAL-header backups (SQLITE_CANTOPEN) — #18 in #22
  • Debug export: strap & data state + analytics-funnel diagnostics in #20
  • iOS: debug export parity — strap & data state + analytics-funnel diagnostics in #21
  • docs: v8.3.1 release notes + What's New in #24

Full Changelog: v8.3.0...v8.3.1


Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.3.1.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.3.1.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.3.1.ipa (AltStore / Sideloadly)

NOOP 8.3.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 05:00

NOOP v8.3.0

A tidy-up release: automatic backups got real controls, a few things that no longer belong were removed, and the project now builds and releases itself. Update from the Releases page, AltStore, or brew upgrade.

Backups

  • Choose how many to keep. Automatic backups has a new "Keep last snapshots" control — pick how many daily copies to keep (default a week), and older ones are pruned oldest-first. Available on Android and iOS.
  • Runs at a set time. The daily auto-backup is anchored to run around 1 am (best-effort), so you get a fresh dated snapshot overnight without opening the app.
  • Easier to find. Settings → Backup & restore now has an "Automatic backups" entry that takes you straight to the folder picker and toggle.

Removed

  • Donations and the "Support NOOP" section are gone — the Today nudge card, the Support screen, and the surrounding copy, on every platform.
  • The dead noop.fans mirror link is removed (the site closed). The in-app "Project home" link and the docs point at the project's GitHub.

Under the hood

  • The project builds and releases itself. On-demand testing builds across Android + macOS + iOS, and a proper Release build that bumps the version and publishes a real release — installed beside the official app so it never clashes.
  • Release notes and "What's New" write themselves from a single per-version source, with an automatic list of everything that changed since the last release.
  • A sweep of code cleanups (deprecated icons, redundant code, name shadows) — no behaviour change.

(Note: the reliability, Bluetooth, and HRV fixes credited to community contributors shipped in v8.2.2.)


Downloads — NOOP Staging identity, installs beside the official app (separate data):

  • AndroidNOOP-android-v8.3.0.apk (com.noop.whoop.staging)
  • macOSNOOP-macos-v8.3.0.zip (unzip, then right-click → Open)
  • iOSNOOP-ios-unsigned-v8.3.0.ipa (AltStore / Sideloadly)

NOOP Staging — base 7.3.1 · 2026-06-27 · 14c5642

Choose a tag to compare

@ryanbr ryanbr released this 27 Jun 11:45

NOOP Staging testing build — base 7.3.1 · 2026-06-27 · 14c5642

Resynced onto upstream v7.3.1. Most of the earlier fork-only PRs are now in upstream (the maintainer reimplemented them in v7.3.0/7.3.1), so this build is now just upstream v7.3.1 + the one still-open fork PR:

  • #791 Backup & Sync (folder, Phase 1) — the only feature not yet upstream.

Everything else (steps calibration status, skin-temp funnel, backfill log, sleep awake-gap, corrupt-RTC detect, bond-loop pause, breathe-cancel, French, etc.) now comes from upstream v7.3.1.

Signed with the fixed fork key, versionCode 245 — upgrades in place over the previous fork build (no uninstall needed if you're already on the signed 7.3.0 build).

Unsigned/sideloadable; installs beside official NOOP ("NOOP Staging" identity).
Artifacts: app-full-debug.apk (Android) · NOOP-macos.zip (macOS) · NOOP-ios-unsigned.ipa (iOS, AltStore/Sideloadly).

Pinned snapshot; rolling testing-latest tracks newest.