Skip to content

v1.4.0

Latest

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 16 Oct 17:28
bfde1fe

Minor release. Big themes: LiftTrace on your watch, offline mode for gyms with no signal, coaching that asks first and talks back (with a conversation and set videos), layouts made for foldables and tablets, and an Android sync rebuilt so accounts, offline edits and deletes stay right. Plus a large security round.

Upgrade note. Update the Android app too: it carries a critical security fix, and coaching requests, the coach conversation and prescribed workouts that ask first need the 1.4.0 app (an older app shows none of them; answer on the web meanwhile). Coaching set up before this update stays as it is, with nothing to accept. Update checks are now off on a fresh install until you turn them on; existing installs keep checking, and UPDATE_CHECK=off keeps them off for good. If you sign in at a plain http:// address, INSECURE_COOKIES=1 now works from .env with the sample docker-compose.yml.

Added

  • LiftTrace on your wrist. A Wear OS app for watches running Wear OS 3 and up. It opens on the set in front of you, weight and reps already filled in, so logging one is a tap; edit sets, mark them done and add one from the watch. The session and rest timers are the same ones the phone keeps, the rest timer buzzes on your wrist, and a set logged on either shows on the other at once. Supersets alternate the way you train them, holds count down and log themselves, and what you lifted last time sits under the exercise name. Installed from GitHub, the watch app updates itself to the phone's release, on its charger. Wear OS
  • Offline mode (the same idea as nutritrace#211). In a gym with no signal the web app still opens, today's workout is there, and you keep logging: sets, notes, body stats, cardio, your own exercises, progress photos and settings. Changes go up on their own when the connection returns, merged set by set rather than one device overwriting the other, and the menu button shows an amber cloud while anything waits. What needs a connection (Trace, exercise videos, catalog imports, editing programs, admin) says so, and a change your server refuses is named in plain words and logged in Settings, Diagnostics. Train without a connection
  • Coaching asks first. A coach (a Trainer, or an admin) sends a request with an optional note, and nothing of yours is shared until you accept it on the new Coach tab in Programs. You have one coach at a time, and you can leave yours from their name on the Coach tab; the programs and prescriptions they gave you go with them. An admin's trainer picker, and choosing a coach when creating or inviting a member, send a request too.
  • A conversation between coach and client, beside the notes on workouts and exercises. Text and a photo per message, read receipts, unread counts, and deleting your own message. It opens offline, and a message written with no connection is sent once when it returns. Photos are served only to the two of you, and Trace never reads it.
  • A prescribed workout asks before it loads. On the Diary, a workout your coach prescribes shows Accept and Decline; once accepted, Load works as before. Your coach sees Waiting for an Answer, Accepted or Declined, and a declined workout is never reported as missed. Prescriptions from before this update count as accepted.
  • Film a set and have your coach review it (#57, requested by @backmind). Film a set in the app or pick a clip you have. Your coach pauses where the problem is and leaves a note stamped at that moment, so tapping "0:04" jumps straight there, and you can reply from the player. Only you and your own coach can open a clip; an admin is nobody's exception. Set videos
  • Coaching notifications, in Settings, Notifications, Coaching: New Message (with an optional email, at most one per conversation every 30 minutes), New Recommendation and Client's Answer. They say who, never what was written.
  • Preliminary foldable support. Half open like a book, Settings puts its section list on one side of the crease; dialogs, sheets, the rest timer and Trace stay off the fold; menus open on the roomier side. Programs and Exercises split into a list and a preview on an opened foldable or a tablet, and the Diary, Add Exercise and Progress Photos use the extra width. Diagnostics reports the hinge. The Diary, charts and photos still cross the fold.
  • Reading your training over a date range, for AI clients and scripts (#93, by @kgenerozov). New get_workouts and get_body_stats MCP reads answer a whole range at once, recent workouts, records and per-exercise progress take the same bounds, and the REST API has the same filters. MCP tools
  • Settings has a Support page, next to About: Ko-fi and GitHub Sponsors, plus free ways to help.

Changed

  • Update checks are off until you turn them on, and your server does the asking. Every browser and phone used to ask GitHub every 4 hours. Setup now asks, and a fresh install contacts nothing on its own. Reported on r/selfhosted.
  • Fonts are served by your own instance. The app loaded Inter and its icon font from Google on every page load, so Google saw the address of everyone who opened it. Reported on r/selfhosted.
  • Trace's model lists are current. Claude Haiku 5.5 and Gemini 3.8 Flash are the new defaults; Claude Sonnet 5.5 and Opus 5.5, GPT-6 Luna, GPT-5.6 Sol and Gemini 3.1 Flash Lite are added; Gemini 3.1 Pro is listed as the preview it is; Gemini 2.5 leaves the list (open to existing Google users only). A model you already chose keeps working, and shut-down Gemini models switch to the default.
  • "Client" is the word for the person a coach coaches (it was "member" or "coachee"), and a program your coach assigned opens read-only: follow it, and your coach changes it. The Android app without a server says Coaching Needs a Server instead of showing empty lists.
  • Trace's attach button offers Camera or Gallery on phones, the same as the other Trace apps.
  • The in-app updater reuses an update it already downloaded, so coming back to Updates goes straight to Install. Older downloads are cleared.
  • A program's preview can open a workout directly, with the same actions as the program's own page.
  • Importing workouts from other apps is no longer marked Experimental.

Fixed

  • The Android app's sync is rebuilt (#139, reported by @surfingbytes). Programs, exercises, workouts and body stats deleted on the web leave the phone, and starter programs you deleted stay gone. Signing in as another account keeps each account's data, settings and offline changes apart. An offline edit no longer overwrites a newer one made elsewhere, or stops later changes from arriving, and a change the server refuses is named instead of dropped. What only the phone has is never overwritten by a sync, Upload sends each workout as its own session (body stats and cardio included), Disconnect and Replace with Server ask before dropping anything unsent, and a sync with nothing new no longer reloads the page every few seconds.
  • Several workouts on one day stay apart (#142, reported by @surfingbytes). The Android app no longer jumps back to the day's first workout while you log a later one. Trace, Copy From Yesterday and a workout logged offline or before the first sync go into the workout you mean, and saving no longer puts back a name, notes or finished mark changed on another device.
  • Pictures and videos uploaded to an exercise show in the Android app (#141, reported by @rgpag1), connected or local, and on the web under a subpath. Behind a login proxy (basic auth, Authelia, VoidAuth) they are no longer kept broken for offline use.
  • The installed app works when LiftTrace is served from a subpath (#129, by @kgenerozov). With BASE_URL set, every visit after the first sent requests to the site root.
  • The Android app's local mode can import the exercise library from Settings (#133, reported by @daniel-bernardino747), instead of only in the setup wizard.
  • Statistics counts the right days. The heatmap no longer marks a day you didn't train (#124) and the date picker's dots follow the month (#125), both reported by @Scorch-Light. Clearing a workout clears the day (#120, by @backmind), a cardio-only day counts toward your streak (#115, by @benniemosher), the current streak and cardio weeks hold around midnight and west of UTC, and the Last Workout card and Recent Workouts appear.
  • The Body Measurements chart puts each reading on its own day (#131, reported by @Scorch-Light).
  • The body map counts each exercise's own muscles (#110, reported by @kavemang). Nine of wger's Latin muscle names were not recognized, so lunges read as a generic leg day.
  • Search ignores accents, in the library, the exercise picker, Statistics, Settings search, Trace, the MCP tools and imports: "elevacion" finds "Elevación lateral".
  • SSO is sturdier. An email that already has an account no longer creates a second one when the provider doesn't mark it verified (Authentik's default); Authelia 4.39 and later works out of the box; the callback works at the address older docs gave; OIDC_ENABLE_EMAIL_PASSWORD_LOGIN works for providers added in Settings; and sign-in finishes on older Android WebViews.
  • Signing in at a plain http:// address says what's wrong instead of looping back to the login page, and links to the fix.
  • Trace works with more providers. OpenAI-compatible endpoints that stream unless told not to (nutritrace#258), that check every field, or that have no tool support (nutritrace#259) all work, thanks @jsapede for the reports. A Base URL with /api (#118, reported by @kgenerozov), with or without /v1, and servers that need no key all work; no answer says what to check. Trace opens on your newest messages and handles dates at UTC+13 and +14.
  • The Diary does what you tapped. The week strip and Recent load the day (#111, by @benniemosher), moving an exercise keeps its superset together, a coach's note stays on its exercise after a reorder, the Load Type chooser opens next to its exercise (#116, reported by @kgenerozov), and the Trace button no longer covers sheets and dialogs.
  • The Diary compares an exercise with your previous session, not the one you're logging. Once a set was ticked, the Last line showed your own sets from today, its change compared today with itself, and loading a workout copied today's sets. It now uses the last day before the one you're on, like the watch and the PR badges.
  • The Diary's buttons stay where you can reach them. On phones the Coach Feedback button sat under the top-bar buttons, so tapping it opened More; in a desktop window under about 1420px wide the Overview column covered the right side of your sets; and Add in the page header did nothing after the round + button had been dragged.
  • Importing a FitNotes export works in kilos and with day-first dates, and the language picker shows the language the app is actually in. Both reported on r/selfhosted.
  • The bottom nav's active tab follows your accent color (#114, by @benniemosher).
  • Saving your Profile no longer depends on the browser's storage, and first-run setup keeps your name and email (found with nutritrace#269, thanks @jsapede).
  • Reminders set between midnight and 1 AM fire.
  • A file of the wrong type, or over the size limit, is turned away with a clear message, and the web's "A New Version Is Available" banner means what it says and Reload works.

Translations

  • Simplified Chinese is in the language picker, translated by tinyarrow on Weblate. A phone set to Simplified Chinese opens the app in it.
  • Spanish updated by Hernan Lopez on Weblate.

Security

  • Programs and their workouts stay with the account that made them. Any signed-in account could open, rename or delete someone else's program and its workouts, and a logged workout could point at another account's program; every phone also received every account's program workouts.
  • Coaching data reaches only an active coach the client accepted. A coach received every unpaired member's account record, and an admin saw every coach's activity and a client's workouts and set videos without coaching them.
  • The Android app no longer answers as the previous account after switching. A leftover sign-in cookie took priority over the app's own session; the server now reads the app's session first and the app clears the cookie on an account change. SSO on Android also no longer passes the session token through the lifttrace:// link.
  • The radio and music server proxies pass only audio and music data, and require signing in. A station link to a web page ran that page as LiftTrace, station redirects could reach inside your network, and the music proxy passed any path through. Push notifications and the NutriTrace link never reach cloud-metadata addresses.
  • Password reset, invite and coach emails link to PUBLIC_URL (or an address an admin uses), never the request's host, and everything an email shows is escaped.
  • Uploaded files get unguessable names.
  • Dependency updates: @capacitor/android, @capacitor/ios and @capacitor/core 8.5.3 close GHSA-rvm3-566m-v7fv (critical; the Android app was exposed through links in Trace replies, so update it). proxy-addr 2.0.8 closes GHSA-jqcg-44mw-7w3h (critical; not exposed, trust proxy is unset). @modelcontextprotocol/sdk 1.32.1 closes GHSA-6qxp-vccf-f47h (high; not exposed, LiftTrace runs no MCP client). brace-expansion 5.0.12 (GHSA-q2hr-2g5m-vwhr, high) and source-map-js 1.2.2 (GHSA-68fv-2mgg-jv7q, high) are build tooling only. nodemailer 10.0.12 closes GHSA-prgh-xp8r-p3m5 and GHSA-v53p-9fqp-m79j (high: slow parsing of crafted addresses; the addresses LiftTrace sends to come from signed-in accounts) and three moderate ones (GHSA-6vj9-mwq6-2f5v, GHSA-8vvx-rff5-p5rq, GHSA-g57g-f23g-4646). undici 6.29.0 closes GHSA-rfgv-xxqx-mfg5 (high) and GHSA-3wwx-pv8p-q78v (moderate), both WebSocket-only; LiftTrace opens no WebSocket. Moderate: fast-uri 3.1.8 (GHSA-hrr3-gc8f-f4qj), ip-address 10.7.2 (GHSA-j6r3-76f7-8jcv), multer 2.4.0 (GHSA-3pph-fpjx-jg34) and markdown-it 15.0.2 (GHSA-253c-mchw-3w2r; not exposed, Trace renders with links off).
  • npm audit reports 0 vulnerabilities for the app and the server.

LiftTrace is free and always will be. Support on Ko-fi goes toward a Mac and an iPhone so my apps can come to Apple devices, and GitHub Sponsors helps with the monthly costs.