Repository navigation
Releases
Infinitune 1.5.1: the radio opens over plain HTTP again
Note
🤖 Claude Opus 5.5 responding on behalf of beastyrabbit
The radio opens again when you reach Infinitune over plain HTTP, for example on its LAN address. Since 1.1.0, /autoplayer crashed in that setup before anything rendered. This release also stops two Node 26 startup warnings from being reported to GlitchTip as errors at every pod start.
1.5.0 over http:// |
1.5.1 over http:// |
|---|---|
![]() |
![]() |
Both captured with no backend running, which is why the yellow "Reconnecting to server..." bar shows. Technical note with setup and console output.
Fixed
/autoplayerover plain HTTP. Browsers only providecrypto.randomUUIDon HTTPS and localhost, and the radio listener ID depended on it, so the page failed withcrypto.randomUUID is not a function. The listener ID now falls back to a random v4 UUID built fromcrypto.getRandomValues, which works on any origin. HTTPS behaves as before.- No
localStoragewarning during server rendering. The player reads and writes its saved volume and mute setting only in the browser. Server rendering uses the defaults, so Node 26 no longer prints itslocalStorageExperimentalWarning. Your saved volume and mute still apply once the page loads. - No
module.register()deprecation at startup. Server telemetry no longer installs Sentry's ESM loader hooks. Infinitune doesn't use the automatic instrumentation they serve, so Node 26 stops printing DEP0205. Manual telemetry spans still work. - Node warnings stay out of GlitchTip. Captured console output that is a Node process warning (
(node:<pid>) …Warning: …) is dropped before sending, so the next deprecation doesn't open a new issue. Otherconsole.erroroutput and exceptions are still reported.
Also new since 1.4.3
1.5.0 was tagged and deployed without release notes. It added:
GET /api/version, which returns{ "release": "<version>" }withCache-Control: no-storeand nothing else.- Safer releases. A version tag now publishes an image only after main CI has passed for that exact commit. After publishing, the workflow waits until the homelab deployment reports the new version and its front page responds. See
docs/releasing.md. (#81)
Upgrading
No configuration, schema or data changes. Pull the new image or let Flux roll it out.
Infinitune 1.4.3: the privacy policy states the 25-month analytics retention
Note
🤖 Claude Opus 5.5 responding on behalf of beastyrabbit
The privacy policy now states the actual retention for usage analytics. Umami analytics data is deleted automatically after 25 months; before, the page said it was kept for up to 10 years.
Changed
- Umami retention on
/datenschutzand/privacy. Analytics data is deleted automatically after 25 months by a nightly deletion job on the homelab. Both languages also still state that no session recordings take place: replay and heatmaps are disabled for Infinitune. - GlitchTip unchanged. Error reports are still deleted after 90 days at the latest, matching the server's setting.
Full change: #80.
Infinitune 1.4.2: the app starts in the browser again
Note
🤖 Claude Opus 5.5 responding on behalf of beastyrabbit
Infinitune starts in the browser again. Since 1.3.0, every client JavaScript chunk was delivered 358 bytes short. Pages rendered but stayed unresponsive, and browser analytics never started.
Fixed
- Complete JavaScript chunks. The image build added GlitchTip debug IDs to the client files after the SSR server had already recorded their sizes, so the server kept sending the old, shorter lengths. The debug IDs are now added during the Vite build, before those sizes are recorded.
- A build guard against this. The Docker build now starts the built frontend and fails if any served JavaScript file differs from the file on disk or doesn't parse.
Verified on the live deployment: the app hydrates without page errors, Umami receives page views, and a browser error in GlitchTip shows its original source file and line through the uploaded source maps.
1.4.1 and earlier back to 1.3.0 contain the broken build; upgrade to this version. Full change: #79.
Infinitune 1.4.1: playlists with / or % in their key open again
Note
🤖 Claude Opus 5.5 responding on behalf of beastyrabbit
Playlists whose key contains / or %, such as summer/2026 or 100% chill, open again. In 1.4.0 the server answered those requests with 400, from the web app and from the infi CLI alike.
Fixed
- Encoded playlist keys work again. 1.4.0 added a path check because the legal pages were going to be reachable without signing in. They now stay behind the same sign-in as the rest of Infinitune, so the check had nothing left to protect and only broke URL-encoded keys. It is removed from the web server, the API and WebSocket connections; path and key handling match 1.3.0 again.
- Playlist keys follow the 1.3.0 rules again. 1.4.0 also refused new keys containing
/,\or%; that restriction is gone.
The Impressum, privacy policy and footer links from 1.4.0 are unchanged.
Full change: #78.
Infinitune 1.4.0: legal pages anyone can open
Note
🤖 Claude Opus 5.5 responding on behalf of beastyrabbit
Infinitune now has a German Impressum and Datenschutzerklärung, with English versions. Anyone can read them without signing in, and every page of the app links to them.
Legal pages anyone can open
- Impressum and privacy policy at
/impressumand/datenschutz, in English at/legal-noticeand/privacy. They are standalone pages: they load no app code, make no API calls and set no cookies, so they work even for visitors who can't sign in. Search engines are told not to index them. - Footer links ("Legal notice", "Privacy") on every app page, including error and not-found pages. The embedded mini player stays clean.
- The privacy policy describes what Infinitune actually does with data: sign-in through the homelab's SSO, stored playlists and songs, text generation with OpenAI, music generation on the operator's own hardware, the self-hosted Umami and GlitchTip, logs and browser storage. The full data-flow inventory is in
docs/legal/privacy-inventory.md.
Privacy and hardening
- Server logs now expire. Entries in the server's own log files are deleted no later than 14 days after they were written. Before this, every log file was kept forever.
- No session replay. The app no longer loads Umami's session recorder or heatmaps; only usage events and page views are counted.
- Unusual encoded paths are rejected. The web server and the API answer 400 to request paths with encoded
/,\,%or., backslashes or./..segments, and WebSocket upgrades on such paths are refused. This keeps the public legal pages from becoming a way around sign-in.
Upgrade notes
- Playlist keys containing
/,\or%, or equal to.or.., are now rejected when a playlist is created, because they could not be read back. Generated keys are unaffected.
Full change: #77.
Infinitune 1.3.0: usage analytics and error tracking
Note
🤖 Claude Opus 5.5 responding on behalf of beastyrabbit
Infinitune now reports how it is used to the homelab's own Umami and its errors to the homelab's own GlitchTip, on every part of the app: the browser, the generation pipeline, the SSR frontend and the infi CLI. Both are self-hosted in Germany and configured at runtime, and they stay off when unconfigured, in local development and in tests.
Warning
This release's Docker build served every client JavaScript chunk 358 bytes short, so the app rendered but never started in the browser. Use 1.4.2 or later. 1.4.0 and 1.4.1 share the problem.
New
- Usage analytics in Umami. Page views, including in-app navigation; Web Vitals; outbound links; and events for the main flows: playlists created, steered and closed; songs played, completed, skipped and rated; requests; room joins; settings changes; and playback or save failures. Properties pass through an allowlist: prompts become lengths, and no lyrics, identities, device names or share tokens are sent. There is no identify call.
- Generation pipeline events. The server reports when a song starts, completes or fails generation, with stage, provider, model and duration. These reports never block or fail a song.
- Error tracking in GlitchTip.
- Browser: uncaught errors, rejections,
console.errorand the root error boundary. The SDK loads lazily, outside the main bundle. - Hono server, generation worker, Nitro SSR frontend: all report their errors.
infiCLI and daemon: report errors when configured.- Pipeline failures: reported with the original exception and with stage, provider and model tags.
- Privacy: credentials, Pangolin identity headers, emails, tokens, query secrets and share links are scrubbed.
- Browser: uncaught errors, rejections,
- Readable stack traces. Each tagged release uploads hidden source maps to GlitchTip from CI. The maps are never served by the app.
Configuration
Both containers read UMAMI_URL, UMAMI_WEBSITE_ID, UMAMI_DOMAINS, GLITCHTIP_DSN, TELEMETRY_ENVIRONMENT and GLITCHTIP_TRACES_SAMPLE_RATE. The release value is built into the image. See docs/telemetry.md.
Full change: #76.
Infinitune 1.2.4: private CLI credentials and faster text cleanup
Note
🤖 GPT-6 responding on behalf of beastyrabbit
Infinitune 1.2.4 restricts saved CLI credentials to their owner and avoids slow text cleanup on malformed input.
Reviewed release build, shown in its empty radio state without a backend or AI calls:
Credential handling
CLI configuration and systemd user-service files now use 0600 permissions before device tokens are written. Existing configuration files become private on their next save; existing service files are restricted when the service is installed again. The non-secret executable wrapper remains readable and executable with mode 0755.
New playlist keys use rejection-sampled cryptographic randomness while retaining their existing alphabet and length. Existing playlist keys remain valid.
Text processing and worker maintenance
HTML cleanup, URL normalization and worker-admin authorization parsing avoid unnecessary regex backtracking. The currently unused fenced-response utility received the same cleanup. Tests cover malformed text and long inputs. Worker callbacks no longer wrap void-returning actor dispatch in promises; actor processing and playback contracts are unchanged. Song-batch query keys use an explicit locale comparator, and the CLI preload contract marks its intentionally unused input.
Upgrade and verification
No database migration or new configuration is required. Token values can still be visible in process arguments. Restricting a file does not revoke access through a descriptor another process already opened. Seven CLI executable-lookup findings remain open because the application cannot prove every user's PATH is trusted.
Lint, type checks, the production build and 681 offline tests passed. The release candidate received an independent review by Claude Opus 5.5 at high effort. PR CI, SonarQube and Codex code/security reviews passed. No live AI provider was used for verification.
Changes since v1.2.3: #58 and #59. The two credential-file fixes are separate from SonarQube issue counts; the one wrapper false-positive classification is not a code fix.
The post-merge main analysis confirms 26 code findings fixed, one false-positive classification and zero new findings. Open findings fell from 221 to 194: 7 vulnerabilities, 0 bugs and 187 code smells remain. The new-code gate is green; this does not mean the backlog is clear.
v1.2.3
Infinitune 1.2.3: crash leftovers of the silence trim are cleaned up
This release resolves the known issue listed for 1.2.2. A server crash during the silence trim could leave a hidden, full-size .trimmed-<timestamp>.mp3 copy of a song in its folder in the music library.
Song saving
- Each save now removes both kinds of leftovers that a crash can strand in the song folder once they are older than 18 minutes: the save's private
.audio-<uuid>.mp3and the trim's.trimmed-<timestamp>.mp3. This also catches leftovers from earlier versions, which used the same trim file name. - Only these exact generated names are removed. Other files in the music library, including hidden ones, are left alone.
A test covers aged leftovers of both kinds, fresh files from a live save, and a similarly named file the save did not create. The test fails on 1.2.2.
Upgrade notes
- No configuration or data changes. Leftovers are removed the next time a song is saved into the same folder. Folders that are never saved to again keep theirs.
Pull request: #57.
v1.2.2
Infinitune 1.2.2: cancelled saves no longer overwrite songs
This release fixes the known issue from 1.2.0 and 1.2.1. A song worker that was cancelled while saving could overwrite the audio a replacement worker had already saved for the same song.
Song saving
- The save now prepares the audio under a private name in the song folder. It moves the audio into place only after confirming that its worker is still active, and in the same step writes the lyrics, generation log, cover files and id link. A cancelled worker leaves the folder untouched, so the files and the database stay consistent.
- The silence trim stops each ffmpeg pass after 2 minutes. A hung ffmpeg can no longer stall a song, and a timed-out trim keeps the untrimmed audio, as any trim failure already did.
- If the server crashes during a save, the next save into the same folder removes the private audio file left behind once it is older than 18 minutes.
Tests cover each case against a temporary music folder: a worker cancelled during the trim, a normal save, a failed download, crash leftovers, and a timed-out trim. The tests for cancellation, crash leftovers and the trim timeout fail on 1.2.1.
Maintenance
- GitHub Actions are updated:
actions/checkoutv7, the Docker login, Buildx, metadata and build-push actions v4 to v7, and the SonarQube scan 8.2.2. This release's image is the first one built with them.
Upgrade notes
- No configuration or data changes. While a song is being saved, its folder briefly contains a hidden
.audio-<id>.mp3file.
Known issue
- A crash during the second ffmpeg pass of the silence trim can leave a hidden
.trimmed-*.mp3file in the song folder. Earlier versions behave the same way.
v1.2.1
Infinitune 1.2.1: keyboard-operable oneshot sliders on Node 26
The seek and volume bars on the oneshot and reimagine pages now work with the keyboard, touch, and screen readers, and Infinitune runs on Node 26.
Real sliders for oneshot playback
- The seek and volume bars were clickable areas: keyboard users could focus them but not move them, and screen readers announced them as buttons. Each bar is now a real slider with the same look.
- Arrow keys, Page Up/Down, and Home/End seek or change the volume. Touch dragging works, and screen readers hear values such as "0:19 of 0:40" and "60%".
- A click lands exactly where the bar was hit. Seeking is disabled until this song is the one playing, so clicking the bar no longer moves a different song.
Node 26
- The container image now runs on Node 26 (
node:26-slim), the newest release line, which becomes LTS on October 28, 2026. CI tests on Node 26 as well. - Node 25 and later no longer ship corepack. The image installs the pinned pnpm with npm, and CI uses
pnpm/action-setup.
Development and maintenance
pnpm devhydrates pages again. Since 1.2.0's dependency update, the app pinned an older TanStack Store than the router needs, and Vite's dev server served the router that older copy. Production builds were not affected.- Six unused player components, five icons that only they used, and the
@dnd-kitpackages are removed, about 3,600 lines in total. - The SonarQube scan skips Dependabot pull requests, which never receive the scanner token.
Upgrade notes
- The image base changes from
node:22-slimtonode:26-slim. The app still runs asnode(uid 1000), and data and configuration stay compatible with 1.2.0. - Self-hosted CI runners need
libatomic1for Node 26. The CI workflow installs it when it is missing. - The known issue from 1.2.0 remains: a worker cancelled during a slow storage save can still overwrite its replacement's audio file.
Pull request: #55.








