Skip to content

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 28 Aug 12:10
· 158 commits to main since this release

Added

  • Workstr can now create or restore a device-managed Nostr sync account. New users can
    create an encrypted sync account from Settings, save the shown recovery key, and keep the
    key only in this browser profile for faster signing and backup checks. Existing Nostr
    users can still use a mobile signer or browser extension instead.

Fixed

  • Encrypted sync can recover when the relay's wrapped backup key was replaced after records already existed. A device that still has the older working key cached now republishes it when it sees that the newer relay key would orphan records it had already read, and sync errors no longer leave a stale progress bar stuck on the screen.

  • Mobile signer connection waits until Workstr is listening on the Nostr Connect relay, and recovers a stored reply if the phone backgrounds the app. This avoids the loop where Clave shows a successful Connect activity, but Workstr misses the answer and returns to Settings still signed out.

  • Backup no longer pauses for 45 seconds at a time on a remote signer. A signer's answer
    can go missing on its way back — it is published before the app is listening again, and
    the app then waits out its whole timeout before trying once more, even though the signer
    has already done the work. The app now notices much sooner and asks again, but only on
    signers that answer by themselves; where a signer puts the request in front of you, it
    still waits, because asking again there would mean approving the same thing twice.

  • Backup recovers in seconds on a desktop instead of looking broken. Two waits stacked
    up on the first sync after opening the app: what the app knows about how quickly your
    signer answers was thrown away with every page load, so the first request — the one whose
    answer goes missing most often, on a connection that has just been rebuilt — always waited
    the full timeout; and the retry afterwards then sat behind the same long backoff a dead
    relay gets. The app now remembers that your signer answers by itself, and reconnects a few
    seconds after one stops answering rather than half a minute later. While it does, the
    panel says it is reconnecting instead of telling you to go and open your signer app.

Changed

  • EMOM live sessions now use a compact workout cockpit. The active movement moves into
    the session header, the timer sits beside a balanced Now card, logging gets explicit
    Actual reps/load labels, and the pause/finish controls stay lighter at the bottom.

  • Live workout logging is now focused on the current set. Standard workout sessions use
    a compact exercise header, thumbnail-sized form image, current-set input card, lighter set
    plan, and a sticky Log set action before showing Next or Finish.

  • Recovery now reads like a readiness dashboard. The Recovery tab has shorter copy, a
    compact ready summary, a smaller body-map layout, Recently trained/Other muscles sections,
    Fresh labels for muscles not logged recently, and a shorter Build quick workout action.

  • Workout history cards now read like finished-session receipts. Collapsed history cards
    separate date/duration from set, exercise, and volume chips; expanded cards add a compact
    summary panel, numbered exercise rows, and a stronger repeat-workout action.

  • Workout program cards have a more polished training-app preview. The Programs intro is
    shorter, collapsed cards now show concise duration/format/focus metadata instead of long
    descriptions, expanded cards add a compact program preview/timeline, exercise rows are
    numbered, and Start workout is promoted to a full-width primary action.

  • Account setup now uses one focused login flow. The signed-out account chip and Settings
    account row open a tabbed Account modal with Log in as the default and Create account as
    the second tab, while Data & Sync points back to that single Account action instead of
    adding another sign-in button.

  • The header account control is now a compact Nostr identity chip. Signed-in users see
    their kind 0 profile avatar, nickname, and a small green status dot in the top-right
    instead of a heavier Account card.

  • Settings is now a compact control center. Account, Data & Sync, Training Preferences,
    Support Workstr, and Advanced are grouped in that order; encrypted relay behavior is
    described as sync/auto-sync, JSON export/import is presented as manual backup, support
    is compact by default, equipment lives behind a concise row, and diagnostics are tucked
    into Advanced.

  • The backup relay now accepts only the current record format. The previous format was
    accepted alongside it while the app was being rolled out, so the relay and the app did not
    have to change in the same instant. That window is closed.

  • Backup no longer interrupts a workout. Logging a set used to queue a backup a few
    seconds later, which on a remote signer meant your signer app waking up over and over
    while you were still training. A workout is now held on the device and copied to the
    relay once you finish it. Editing or deleting a finished workout still backs up straight
    away.

  • Backup starts fresh, and older history stays on the device. Workout history is now
    copied to the relay one workout at a time, from the day backup is switched on. Workouts
    logged before that are kept on this device and are included in JSON export, but they are
    not sent to the relay. Settings tells you how many of those you have.

  • Restoring is no longer slowed down by an index nobody read. Backup used to publish
    and re-publish a growing list of everything it had stored, which cost a signer round trip
    on every pass and was never used to restore anything. It has been removed.

  • Restoring a device now takes seconds instead of minutes. Your backup used to be
    encrypted and decrypted one record at a time by your signer app, so restoring a full
    history meant hundreds of round trips to it — and on a remote signer, minutes of waiting.
    Your account now has a single backup key, which your signer unlocks once. Everything
    after that is read and written on the device, and your signer is only asked to sign.

  • Workout history no longer tells the relay how often you train. Every workout used to
    be its own record with its own name on the relay, in the clear, so anyone reading it could
    count them. History now travels in batches: a year of training is around six records
    instead of two hundred, and the relay learns roughly how much you have stored rather than
    exactly how many times you trained.

  • Two devices can no longer lose each other's work. Body weight used to be copied as one
    whole record, so if two devices each logged a weigh-in before either had synced, one of
    them quietly won and the other entry was gone. Weigh-ins and workouts are now merged one
    at a time, and a deletion is carried explicitly rather than by falling silent.

  • Finished history is written once and left alone. Once a batch is full it is never
    rewritten, so editing an old workout no longer re-uploads the rest of that month, and a
    correction costs a single small upload however long your history is.

  • Backups take up far less room. Records are compressed before they are encrypted,
    which takes a typical workout from around 2,900 bytes to 440 on the relay. Compression is
    skipped where it would not help, such as on a deletion marker.

Fixed

  • A backup that was stuck now unsticks itself. A device left holding records queued by
    the previous version could not send them and reported "needs attention" on every attempt,
    with no way out. Those entries are now cleared once, automatically, the first time the
    new version syncs.
  • Importing a JSON archive now backs the workouts up. Workouts restored from an export
    file were treated as older history and quietly left out of backup, while the panel still
    reported everything up to date. An imported archive now joins backup like anything else,
    and the exporting device's pending queue is no longer replayed onto the importing one.

Changed

  • Connecting a signer now asks for exactly what Workstr needs, once. It names the two
    kinds of event the app ever signs — your encrypted backup records and the workout
    summaries you choose to share — instead of asking to sign anything at all in your name.
    Connecting by pasting a bunker:// link previously asked for no permissions whatsoever,
    which left some signer apps asking you to approve every single record; that link now
    requests the same permissions the QR code does. Existing connections are unaffected.

Fixed

  • The page jumped back to the top constantly. Expanding a workout in history, or a
    backup progress line ticking over while it worked, threw you back to the top of whatever
    you were reading — on every device. The app redraws the whole page on any change, which
    loses your place; it now keeps it. Moving to another view still starts at the top, which
    is where a new page should start.

  • Signing in on a second device restored your training but did not show it. The
    restore wrote everything to the device correctly, while the screen kept showing what it
    had read before the restore ran — so a laptop that had just pulled a whole history looked
    empty, and only reloading the page revealed it. The screen is now re-read as soon as a
    restore lands.

  • One press of Sync now backs up everything, instead of one record at a time. The
    connection to a remote signer can close between records, and backup treated that as the
    signer being away: it stopped, and you had to press Sync now again for the next record —
    eight presses for a month of training. It now reconnects and carries on, so a whole
    month goes up in one attempt. If the signer really is away it still stops promptly
    rather than working through the queue one timeout at a time.

  • Backup managed one record per attempt, then said your signer did not respond. The
    connection to a remote signer is allowed to close between requests, and reopening it
    raced the reply to the next one — so the first record of every attempt went through and
    the one after it timed out. The connection is now made ready before every request rather
    than only the first.

  • "Sync now" showed no count while a long backup was running. Progress was counted in
    months rather than in records sent, so a month that uploads as eight records showed
    nothing at all until the whole month finished — on exactly the months that take longest,
    which read as a hang. The count now moves with every record.

  • A big month of training could never finish backing up, resending the same records
    every time.
    A month is uploaded in several records, and the month only counted as done
    when all of them were in — so if a backup ran out of time or lost its connection partway,
    the next one started that month again from the beginning. On a month with a lot of
    training it never got to the end, and the same records went to your signer over and over.
    Records already safely on the relay are now skipped, so each attempt picks up where the
    last one stopped.

  • Backup could stop doing anything at all — no request reaching your signer, and Sync
    now doing nothing.
    Waiting for the connection to your signer to be ready was meant to
    stop replies being missed, but it waited for every relay it could reach your signer
    through, with nothing to end the wait if one of them stalled while connecting. On a
    phone that happens routinely, and then nothing was ever sent. It now goes ahead as soon
    as one relay is up, and never waits more than a few seconds regardless.

  • Backup could still fail to sign a month of training, on months made up of shorter
    workouts.
    The limit on how much training goes into one record was set from a month of
    long workouts, which never fills a record completely. A month of shorter, more frequent
    workouts packs one full — and those records came out just over what a signer will accept,
    so encrypting worked and signing failed. The limit is now worked out from the signer
    limit itself rather than set by hand, and checked against a record packed completely
    full.

  • Backup said your signer did not respond while the signer app showed it had already
    answered.
    The reply from a signer travels back over a relay connection that was still
    being opened when the request went out, so a signer quick enough to answer immediately —
    any signer you have already given permission to — answered before anything was listening,
    and the reply was lost. Every retry started a new connection and lost the reply the same
    way. The connection is now open before the first request is sent.

  • Backup stayed broken until you reloaded the app, once your signer had gone quiet
    once.
    A remote signer is reached over a connection your phone closes when it puts the
    app to sleep, and the app kept using that closed connection for the rest of the session
    — so every backup afterwards waited 45 seconds and gave up, even with the signer app
    wide open. It now drops a signer that stops answering and reconnects on the next
    attempt. Backup also no longer asks your signer to confirm which account you are: it
    already knows, and that request was both the slowest part of starting a backup and the
    first thing to fail. The message when a signer really is away now says so plainly
    instead of naming an internal call.

  • Backup failed with "your signer did not respond" and never got past the first few
    records.
    A month of training was packed into a record large enough that asking a
    remote signer app to sign it meant sending that signer a message twice the size again —
    bigger than any relay will carry — so the request never arrived and backup waited out
    its timeout. Months are now packed to a size a signer can handle, split across a few
    more records where needed. Anything already uploaded in the oversized shape is rewritten
    automatically the next time backup runs.

  • A deleted workout could come back on a restore. A training month heavy enough to be
    split across several relay records left the extra record behind when it later shrank,
    and a workout deleted from that month was still listed in it — so setting up a new
    device could bring the workout back. The leftover record is now cleared when the month
    no longer needs it, and a deletion always outranks an older record that still mentions
    the workout, whichever order they arrive in.

  • Opening the app no longer restores your whole history every time. Backup re-read and
    re-decrypted every record on the relay at every start, which meant one signer round trip
    per session just to conclude nothing had changed. It now remembers which records it has
    already read and asks the relay only for what is newer, so a routine start does no
    decryption at all and a restore only covers what actually changed on another device.

  • Backup could get stuck on "Syncing now…" and never recover. If a signer app stopped
    answering — backgrounded on a phone, or the connection dropped while switching apps to
    approve — backup waited on it forever: no error, no retry, and Sync now did nothing.
    Signer requests now time out, backup says your signer did not respond and to open it and
    tap Sync now, and it retries on its own. Nothing queued is lost while the signer is away.

  • A long first backup no longer looks like a hang. The status line now counts through
    what it is doing — restoring, preparing, or backing up, with a running total — instead of
    showing one unchanging "Syncing now…" for the whole run.

Added

  • Auto-backup. One switch in Settings → Backup copies your programs, workout history,
    body log and preferences to the Workstr relay, and keeps them there as you train.
    Everything is encrypted on your device to your own key before it leaves: the relay holds
    ciphertext it cannot open, and only your key can read it back. Sign in on another device
    with the same identity and your training is restored. Turning it on the first time backs
    up the history you already have, and picks up where it left off if that is interrupted.
    A status line says what is waiting to upload and when the last backup ran; Sync now is
    there when you want it, and a relay that cannot be reached retries on its own without
    ever interrupting a workout. Turning it off stops the copying and leaves both your device
    and the relay untouched. Backup needs an identity, so turning it on while signed out
    takes you through sign-in and comes back on by itself.

  • The app now updates itself. An installed PWA resumes its existing page instead of
    navigating, so a phone could keep running a build for days and never pick up a fix. The
    app now checks for a new version while it is open, and applies it the next time you
    leave the app, so you come back to the current build without ever seeing a reload. An
    update is never applied during a workout, with the session overlay open, or with a form
    open, and a short message says when one is waiting.

Changed

  • Shortened the History intro line. On a short phone screen it ran to seven lines and
    pushed the calendar almost entirely below the fold; the calendar now leads on every
    iPhone size, and fits above the fold outright from the iPhone 13 up.