Skip to content

Releases: TraceApps/lifttrace

v1.3.0-dev03

v1.3.0-dev03 Pre-release
Pre-release

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 07 Sep 22:32

Third dev pre-release toward v1.3.0. High-priority fix, grab this over dev02 if you use the Android app.

Fixed

  • Editing a set (weight, reps, or the completed checkbox) could revert a moment later, sometimes on every edit, especially under a slow or unstable connection. Root cause was a too-frequent background refresh serving a stale on-device cache over an edit that had already saved. See the CHANGELOG for the full technical breakdown.

If you hit the reverting-edits issue on dev02 or earlier, this is the fix, please try it and let me know how it holds up.

v1.3.0-dev02

v1.3.0-dev02 Pre-release
Pre-release

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 07 Sep 14:14

Second dev pre-release toward v1.3.0. Grab this instead of v1.3.0-dev01 if you want the latest fixes, including two real data-integrity bugs.

Changed

  • Statistics desktop rails now flow through i18n (#83).

Fixed

  • Settings API Tokens intro guide-link text now flows through i18n (#84).
  • Settings API Tokens expiry showed "just now" for its entire lifetime instead of counting down.
  • Android sync crashed on pull after the #76 multi-session migration, plus a quieter cross-session tombstone leak (#82, diagnosed by @kgenerozov).
  • Legacy (pre-uuid) program-day exercises duplicated on edit, and deletes never worked in templates at all (#85, reported by @iparout).
  • Diary: starting a new workout right after Clear/Delete could flash then silently revert to the old session (#86, reported by @bauerbyter).

Security

  • Swept open Dependabot alerts, including a browserslist advisory disclosed today. Already resolved on this branch, no change needed.

Full details in the CHANGELOG.

v1.3.0-dev01

v1.3.0-dev01 Pre-release
Pre-release

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 05 Sep 20:24

First dev pre-release toward v1.3.0. Grab this instead of dev-latest if you want to pin a specific build for bug reports.

Added

  • Multiple independent workout sessions per day (#76, requested by @yoyo-san). Log a stretching routine and a lifting session on the same date as two fully independent workouts, switchable via a session tab strip. Also fixes a real data-loss bug: loading a second template over a completed workout used to silently delete the first one with no confirmation.
  • Exercise browser display density toggle (#74, requested by @josefelixh). Compact/comfortable view switch on the Exercises tab (desktop widths), next to the category filter chips.
  • MCP server for external AI clients (#78, requested by @bursaar). Speaks the Model Context Protocol at /api/mcp, off by default. See the MCP setup guide.
  • Statistics: overlay a second body measurement on the Body Weight chart.

Fixed

  • Settings → Statistics "Lock Y-Axis to Zero" label rendering in English in every translated locale.
  • Reordering exercises silently reverting after the debounced save landed.
  • Superset weight/reps inputs collapsing to 0px wide on phone (#75, diagnosed by @backmind).
  • Body Stats widget/sheet showing "not logged" for records that exist on the server (#80, diagnosed by @josefelixh).

Full details in the CHANGELOG.

Security

  • Bumped fast-uri, @xmldom/xmldom, and browserslist (root) plus qs (server) for open Dependabot alerts, via a non-forcing npm audit fix within already-permitted lockfile ranges. npm audit reports 0 vulnerabilities on both root and server. (GitHub's Dependabot alert count on the repo still reflects main, which gets this fix on the next main release.)

v1.2.0

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 27 Aug 21:53
2601b5c

First minor release since v1.1.2. Bumped from the 1.1.3 patch line because the desktop wide-layout pass across the main routes is a much larger surface than a patch is meant to carry.

Highlights

  • Desktop wide-layout pass across Diary, Statistics, Programs, Radio, Exercises, Settings, and ExercisePicker. Mobile layouts unchanged.
  • Spanish + Italian translations, exposed in Settings → Language & Region.
  • Trace chat renders markdown.
  • Per-entry uuid + tombstone merge for the workout log — two devices editing the same day (or one device coming back online) merge per-exercise and per-set instead of one payload wholesale replacing the other.
  • Server forward-proxy support via HTTP_PROXY / HTTPS_PROXY / NO_PROXY env vars.
  • In-app updates got much bigger — PWA service-worker prompt, tab-focus re-check, configurable cadence, red dot on Settings nav.
  • User-management data-integrity fixes — single-user data adoption for cardio + custom exercises, startup adoption for stranded rows on upgrade, disable/re-enable is a lossless round trip, delete-user now clears the cardio log.
  • X-Forwarded-Proto honored for reset/invite links + email origin behind TLS-terminating reverse proxies.
  • Android release builds trust user-installed CAs for self-hosters on a private-CA cert.
  • Wave of small polish and i18n conversions from community PRs (thanks @backmind and @clifmo).

Full details in CHANGELOG.md.

Upgrading

Docker: pull :latest (or :v1.2.0) from GHCR (ghcr.io/traceapps/lifttrace) or Docker Hub (traceapps/lifttrace).

Android APK is attached to this release; the in-app updater will surface it on the next check.

Nothing config-breaking.

v1.2.0-dev01

v1.2.0-dev01 Pre-release
Pre-release

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 26 Aug 00:29

First dev pre-release of the 1.2.0 minor. Bumped from the 1.1.3 patch line because the desktop wide-layout pass across Diary, Statistics, Programs, Radio, Exercises, and ExercisePicker is a much larger surface than a patch should carry. Also picks up Spanish + Italian translations, in-app updates, server forward-proxy support, several user-management data-integrity fixes, an Android duplicate-workout fix, and small polish from community PRs.

Added

  • Desktop wide-layout pass across the main routes at min-width: 1280px (Diary, Statistics, Programs library + detail, Radio, Exercises; ExercisePicker as a wide modal). Mobile layouts unchanged.
  • Spanish + Italian translations, exposed in Settings → Language & Region.
  • In-app updates: SW-driven banner + OS notification for PWA, GitHub-release watcher for Android, configurable cadence in Settings, red dot on the Settings nav while pending.
  • Forward-proxy support via HTTP_PROXY / HTTPS_PROXY / NO_PROXY env vars.

Fixed

  • Data-integrity fixes around enabling / disabling user management (single-user data adoption, disable-preserves-data, delete-user clean-up, cardio-log + workout-tombstone reparenting), all in one transaction.
  • Android: template loads no longer wipe the local workout row and cause the next re-add to duplicate. Server GETs filter soft-deleted workouts; PUT resurrects the row.
  • Password-reset / invite / test-email links honor X-Forwarded-Proto behind TLS-terminating reverse proxies. Ported from CookTrace PR #42, thanks @clifmo.
  • Android release builds trust user-installed CAs (self-hosters with private-CA certs) (#58, reported by @orpetor).
  • Settings rail highlight pill no longer disappears when jumping into the Administration group (#68, diagnosed by @backmind).
  • Diagnostics panel em-dash mojibake (#60, thanks @backmind).
  • Double-v version prefix in Settings → About + desktop sidebar (#61, thanks @backmind).

Changed

  • Settings → Units renamed to Settings → Language & Region with a globe icon (#62, thanks @backmind).
  • Radio / NutriTrace Federation / Diagnostics / About / Workout / Users settings sections now flow through i18n; a handful of already-translated keys start doing work (#66, #67, thanks @backmind).

Security

  • No new dependencies affect the security surface. npm audit reports 0 vulnerabilities and there are no open Dependabot alerts.

Full changelog: CHANGELOG.md

v1.1.3-dev01

v1.1.3-dev01 Pre-release
Pre-release

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 16 Aug 11:25

First dev pre-release of the 1.1.3 patch. Workout persistence fix (foreground no longer bloats programs with duplicate sets), Trace chat markdown rendering, catalog re-import history preservation, and clear-chat confirmation.

Added

  • Trace chat renders markdown properly (#52, thanks @backmind). Lists, bold, tables, and code blocks in the coach's replies now render instead of showing raw asterisks and pipes. Assistant bubbles only; user messages stay plain text. Renderer loads lazily on first Trace open, so users who never open Trace pay no bundle cost.

Fixed

  • Every foreground of the app no longer adds a full extra layer of sets to your program's exercises. A combination of debounced save + lifecycle handlers (visibilitychange / App.pause / pagehide) was re-firing the same save entry with freshly regenerated set uuids each time; the server-side per-uuid merge treated the fresh uuids as new sets and appended them onto the existing ones. Set counts now stay stable across foreground/background cycles.

    Existing workouts already inflated by this bug stay inflated. The fix stops the leak but doesn't clean up prior damage. Recover by opening the affected day, tapping Clear on the workout, and re-loading the template. Reload resurrects cleanly since uuids stay stable across the save now.

  • Exercise catalog clear + re-import no longer silently unlinks workout history (#49, diagnosed by @backmind). Both clear paths (built-in sources and imported catalogs) previously did a hard DELETE, so the re-import minted new autoincrement ids while every exercise_id in workout_log / workout_templates / coach_prescriptions JSON blobs still pointed at the deleted rows. Muscle Balance then bucketed every affected set as "other" and per-exercise Progress returned empty. Clearing now soft-deletes via the existing deleted_at column; the next matching re-import resurrects the row in place instead of minting a new one, preserving the id so historical references stay valid.

  • Clearing the Trace chat now asks for confirmation (#50, thanks @backmind). A single tap on the header button previously wiped the entire conversation with no way back. Also fixes a z-index bug where the confirm dialog opened behind the Trace panel and looked like nothing happened.

  • Statistics summary cards and plate calculator no longer show units in capitals (#48, thanks @backmind). Follow-up to #42 now that the strings sit in i18n keys. Reads MAX kg / TOTAL min / TARGET WEIGHT (kg) instead of MAX KG / TOTAL MIN / TARGET WEIGHT (KG). kg is kilograms; KG is not a unit.

Security

  • No new dependencies. npm audit reports 0 vulnerabilities.

services:
  lifttrace:
    image: ghcr.io/traceapps/lifttrace:dev
    # ...

v1.1.2

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 11 Aug 11:14
599028f

Patch release. Ten user-visible bug fixes and the latest AI model presets. Community reports + fixes from @backmind on most of these.

Added

  • Latest AI models in the picker. Claude Opus 5 and Claude Fable 5 join the existing Claude Opus 4.8; Sonnet 5 relabeled. Google Gemini 3.x and OpenAI GPT-5.6 added as presets. Existing saved selections keep working.

Fixed

  • The Login and Profile pages no longer render raw i18n keys as UI copy (#33). en.json declared the login and profile top-level sections twice; JSON.parse silently keeps only the last (biometric-only) block, dropping 21 login keys and 34 profile keys at runtime. Both sections now hold every key in one block. Also renamed two Settings sidebar titleKeys that pointed at non-existent keys and were rendering raw: AI Assistant now resolves via settings.trace.section and Backup & Restore via settings.backup.section. Diagnosed by @backmind.
  • Re-importing an exercise catalog no longer duplicates every row (#34). Every seeder used INSERT OR IGNORE against a table with no UNIQUE constraint, so importing free-db (873 rows), Wger, or ExerciseDB a second time silently doubled the whole library. A one-time boot migration merges duplicates (picks the lowest-id row as survivor, folds non-null user edits from duplicates onto it, rewrites exercise_id references inside the JSON blobs in workout_log / workout_templates / coach_prescriptions so past workouts + templates + coach prescriptions keep pointing at the right exercise, then deletes the duplicates), free-db now populates external_id, and a partial UNIQUE index locks in the fix. Full-backup restore force-runs the dedupe pass so a backup taken during the bug can't resurrect duplicates. Diagnosed by @backmind.
  • The All range on Statistics no longer hides body measurements taken before your first workout (#36). The body-weight chart bounded its query by the earliest workout date, but weigh-ins are independent of whether you trained that day. The All range now starts from the same 2000-01-01 floor the code already falls back to when there are no workouts.
  • Logging a cardio session with a distance or a heart rate no longer fails (#41). Both fields are <input type="number">, so the bound value became a number once you typed in them and null once you cleared them; the save path called .trim() on them as if they were still the empty string the form starts with, and threw. Both fields now test for emptiness rather than assuming a string.
  • Quick-log cardio templates now show up (#43). GET /api/cardio/templates was registered below GET /api/cardio/:date, and Express matches in registration order, so the request was answered by the date handler with templates read as a date. Feature has now worked since it was added. Pinning two sessions of the same activity also no longer gives you two identical chips.
  • Pre-caching exercise media for offline use no longer fails with "Exercise not found" (#44). GET /api/exercises/media-urls was registered below GET /api/exercises/:id and hit the id handler. Moved above.
  • Confirmation dialogs with two long button labels no longer overflow the dialog card (#39). .btn carries white-space: nowrap, so a flex item can never shrink below its one-line text width. Action row now wraps.
  • The body stats sheet no longer shows its units in capitals (#42). Field labels are uppercased by CSS, which took the unit along with the name and produced WEIGHT (KG), WAIST (CM). Unit symbols are case-sensitive: kg is kilograms, KG is not a unit. The symbol now opts out of the transform.
  • Weight placeholders in the workout editor and the plate calculator now follow the kg/lb setting. Both hard-coded pound examples (e.g. 135, e.g. 225) regardless of preference.
  • The rest field in the workout editor now reads REST (s) instead of REST (S). S is siemens; seconds is s.
  • Pull-to-refresh no longer fires mid-page on editor screens. The gesture gated on window.scrollY, but editor pages use their own scroll container. It now walks to the nearest actually-scrolling ancestor and gates on that.

services:
  lifttrace:
    image: ghcr.io/traceapps/lifttrace:latest
    #

v1.1.1

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 08 Aug 03:53
a2257fa

Patch release. ntfy push-notification titles with non-ASCII characters no longer arrive mangled; Docker images now mirror to Docker Hub alongside GHCR; two open Dependabot alerts closed.

Changed

  • Docker images now mirror to Docker Hub alongside GHCR. Pull from traceapps/lifttrace:1.1.1 on Docker Hub (hub.docker.com/r/traceapps/lifttrace) or ghcr.io/traceapps/lifttrace:1.1.1 on GHCR (the existing primary). Both registries are kept in lockstep. Publish list also trimmed to just :latest and :dev (dropped noisy :main and per-commit :sha-* tags — semver-tagged pulls like :1.1.1 / :1.1 / :1 are unaffected).

Fixed

  • Push notification titles with non-ASCII characters no longer arrive mangled. The ntfy Title header carries HTTP header bytes only, so a workout name with an em-dash, accented character, or emoji (e.g. "Push — Chest Day") was being dropped or corrupted by the receiving client. Titles are now RFC 2047-encoded (=?UTF-8?B?…?=) when they contain any non-ASCII byte, so the notification shade renders them correctly on every ntfy client.

Security


services:
  lifttrace:
    image: ghcr.io/traceapps/lifttrace:1.1.1
    #

v1.1.0

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 03 Aug 21:50
d7f8204

First minor release. User-facing polish: cardio session logging, library-level exercise load-type, in-app self-updater, full internationalization foundation, sync UX overhaul.

⚠ Upgrade requires re-signing in (Android)

The Android app-identifier change (app.lifttrace.local, see the CHANGELOG "Changed" section) orphans the WebView's cached auth cookie. Server-connected Android users will need to re-enter their server URL and sign back in once after upgrading. Standalone Android users lose theme / accent / display prefs but keep all workout, program, and exercise data (that lives in local SQLite, unaffected). PWA and browser users are not affected.

Added

  • Cardio session logging (#23). Opt-in via Settings → Workout → Track Cardio (off by default so pure lifters aren't cluttered). Log a session with activity, duration, optional distance / avg HR / notes; a new Cardio metric on Statistics tracks weekly minutes with an optional target line. All cardio is excluded from volume, PRs, and rest-timer firing so it never corrupts the lifting side. Manual entry only by design; device sync (Fitbit / Garmin / Health Connect) lives in NutriTrace via federation and is not planned for LiftTrace.
  • Pin cardio sessions as quick-log templates. Tap the pin on any cardio session to save it as a one-tap template; pinned templates render as chips at the top of the Cardio card so the next "same-as-yesterday" run / bike / row is a single tap instead of re-filling the form. Templates carry activity, duration, distance, HR, and notes forward. Matches NutriTrace's Activities quick-log flow.
  • Library-level load_type on exercises (#24). New Load type field in the Exercise Editor (Unset / Bilateral / Per side / Alternating) so the setting travels with the exercise instead of being buried per-workout-instance. Batch-imported catalogs (Strong / Hevy / FitNotes / Jefit CSV) can now be fixed up per-exercise once instead of having to re-select per session. Statistics, muscle-group volume, per-exercise progress, share cards, and CSV export all resolve through a new four-tier chain: per-instance override → library value → per-user Diary preference → 'bilateral'. Historical volume numbers for imported unilateral / alternating exercises will change on first render; that's the fix.
  • In-app updates. New Settings → Updates panel checks GitHub Releases for a newer version and, on Android, downloads the signed APK and hands off to the system installer via FileProvider. One primary button drives the whole flow (Check Now → Download & Install → Downloading X%). Skip This Version link when an update's available. Collapsible "What's new" panel renders the release notes inline. Silent shade notification when the OS notification permission is granted; top-of-app banner as fallback. Opt-in Stable or Dev channels.
  • Pull-to-refresh sync (Android). In native server mode, swipe down from the top of any page to trigger a manual sync. Matches NutriTrace's behavior for family consistency.
  • Smart connection banner. When sync fails, the banner explains what actually went wrong (no network vs cellular-only vs server unreachable vs HTTP error) with a Retry button, instead of a generic "sync error". Structured classification via describeConnectionIssue mirrors NT.
  • Cloud icon in hamburger menu goes red on server disconnect. Previously never lit up; now driven by a real reachability probe + browser online/offline events + server-side classifier, matching NT's behavior.
  • Optional email on the "Create Admin Account" form. Shows up only when SMTP is configured via environment variables. Stored on the admin's user record for password-reset and invite emails later.
  • Accent-tinted browser chrome. The browser tab bar / address strip picks up your current accent color via <meta name="theme-color">. Favicon stays the branded LiftTrace mark.

Changed

  • Full i18n retrofit across the app. Every hardcoded UI string extracted into src/i18n/en.json and read via svelte-i18n. Covers Settings (all sections), Diary + WorkoutEditor + WorkoutSummary + SupersetCard + ExerciseCard + SmartLog, Coaching + Programs + ProgramDetail + TemplateSpecRow, Exercises + ExerciseDetail + ExerciseEditor + ExerciseInfo, Statistics charts + MuscleRecovery, Radio (station library + dialogs), Profile, Login, NativeSetup, Trace AI, and shared UI (TimePicker). ~500 new keys, Weblate-ready. Chicago-style title case for labels/buttons/headings, sentence case for body prose / errors / placeholders / toasts.
  • Bitwarden / password managers now show a real app identifier instead of "localhost" (Android). LiftTrace identifies itself as app.lifttrace.local, which reads clearly in autofill dialogs and in your saved-credentials list.
  • SMTP "Username" field relabeled to "Email or Username". Most SMTP providers want the full email as the username; label change removes the guesswork.

Fixed

  • Server-connection banner no longer covers the phone's notification bar. The red "server unreachable" banner used to sit edge-to-edge at viewport top:0, which on Android meant it slid up over the status bar / clock / hamburger. Now floats as a rounded card below the status bar and the app's compact header, matching NutriTrace.
  • Exercise picker sheet on Statistics rendered off-screen for some browsers (#25). The Statistics → Exercise Progress picker had its own inline bottom-sheet CSS that had drifted from the shared Sheet component the rest of the app uses; on Vivaldi's persistent-web-app mode the divergent viewport-height + safe-area math pushed the sheet body below the visible area. Consolidated onto the shared Sheet.
  • App icon no longer shows a white halo. Icon PNGs had ~15px of solid white padding baked into their corners. Corners now clear cleanly. Icon URLs cache-busted with the app version so shipped icon fixes take effect without users needing to clear their browser cache.
  • Create Admin form layout aligned with NT/CT (parity with NT #122). Two-column layout replaces the prior stacked single-column layout.

Security


services:
  lifttrace:
    image: ghcr.io/traceapps/lifttrace:1.1.0
    #

v1.1.0-dev09

v1.1.0-dev09 Pre-release
Pre-release

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 31 Jul 22:12

Heads-up before installing: this build fixes the in-app Updates panel's Server section, which was reporting the wrong running-server version and mixing Stable / Dev channel results. Redeploy your server (docker compose pull && docker compose up -d) so the Updates page's Server section renders correctly.

Fixed

  • Server-status endpoint reported wrong running version on Docker images built before this release. The runtime was reading server/package.json (stale at 1.0.2 on LT) instead of the client's root package.json where the real dev version lives. Dockerfile now copies the root package.json into the runtime image so version-source.js resolves to the correct current version. Server-side server/package.json also bumped to 1.1.0-dev09 for local-development consistency.

  • Server-status dev-channel filter dropped every versioned dev release. Server-side regex required a dot before the number (-dev.N) but the actual dev tags have no dot (-devNN). Both formats now accepted, matching the client-side regex.