<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Libre WebUI Changelog</title>
    <link>https://librewebui.org/changelog/</link>
    <description>Track every update, feature, and fix for Libre WebUI, the open-source self-hosted AI workspace.</description>
    <language>en</language>
    <lastBuildDate>Fri, 04 Sep 2026 12:47:09 GMT</lastBuildDate>
    <atom:link href="https://librewebui.org/changelog.xml" rel="self" type="application/rss+xml"/>
    <image>
      <url>https://librewebui.org/logo.svg</url>
      <title>Libre WebUI Changelog</title>
      <link>https://librewebui.org/changelog/</link>
    </image>
    
    <item>
      <title>v0.33.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.33.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.33.0</guid>
      <pubDate>Fri, 04 Sep 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[The sky comes indoors: a fourth theme follows the sun where you are, with a
live sky behind an interface that steps back while you write. Administration
moves into Settings, and the demo lands in the new theme.

### ✨ New Features

- **Celestial theme.** A fourth theme that follows the sun: the palette and a
  live sky shift minute by minute, with sunrise and sunset moving through the
  year. The sun or moon crosses on its arc (the moon shows its real phase),
  clouds drift at different depths, stars come out after dusk with the odd
  meteor, a horizon glow spreads under a low sun, and an aurora ribbons across
  the night while a reply streams. The scene parallaxes with the pointer and
  tilts as you scroll the conversation; at night a lamp follows the pointer
  over the words and brightens with each keystroke. While you type, the
  sidebar and tab strip step back so the words sit in the landscape. The
  theme toggle cycles through it, administrators can make it the instance
  default, the sign-in page renders the sky, and choosing Celestial plays the
  last six hours into the present.
- **Time of day scrubber.** Settings > Appearance previews any minute of the
  day with today's sunrise and sunset shown; **Follow the clock** returns to
  real time.
- **Your actual sky, and your weather, on your terms.** Share a location
  (browser prompt or typed coordinates) and sunrise, sunset, and solar noon
  are solved for that spot. Coordinates are rounded to about a kilometre,
  kept only in that browser, and never join the synced preference, so the
  server never learns them. With a location, an opt-in **Match the weather**
  switch fetches current conditions from Open-Meteo straight into the
  browser: cloud cover greys the sky and dims the sun and stars, rain and
  snow fall, fog washes the horizon, storms flash, and wind drives the
  clouds. Everything above respects reduced-motion settings.
- **User Management lives in Settings.** Administrators find it under a new
  **Administration** group in the Settings panel, with every access toggle,
  policy, group, audit log, and the user list. The old `/users` link, the
  avatar-menu shortcut, and the pending-approval badge still work: they open
  that tab. Translated into all 25 languages.
- **The demo lands in Celestial.** demo.librewebui.org opens in the new
  theme before the app even paints.

### 🔧 Improvements

- The celestial sky stays off the main thread: clouds drift and the sun and
  moon glide on the compositor, stars twinkle on their own layers, and colours
  ease briefly after each tick. Idle cost is about 2% of a core with no
  layout work, and the heap stays flat across theme switches and long idles.
- Muted text keeps its contrast over the sky, the frame (sidebar and tab
  strip) is one continuous surface exactly as in the flat themes, the user's
  bubbles are dark glass at night, and the composer is glass at all hours.
- The README hero shows the celestial dusk with a Three.js artifact.

### 🐛 Bug Fixes

- Imagine: gallery images no longer break after a filter change or a
  strict-mode remount. Each card's blob URL was revoked while the image still
  pointed at it; the revoke is now deferred and cancelled when the card comes
  straight back.
- Visiting Settings in a flat theme no longer mounts an invisible celestial
  sky behind the interface.

### 🔒 Security

- The compressed static-asset middleware resolves every requested file
  inside the dist root and rejects anything that normalizes elsewhere,
  closing a CodeQL path-injection finding; traversal attempts are tested.

### 📚 Documentation

- Pro tips describe the celestial theme, the scrubber, location, and
  weather; every page that pointed at the User Management page now points at
  Settings > User Management.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.32.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.32.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.32.0</guid>
      <pubDate>Thu, 03 Sep 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[A quieter, faster release: administrators pick the theme the whole instance
starts from, the theme toggle reaches Pure Black, long conversations stop
stuttering while a reply streams, and the app arrives lighter and faster
from a plain Docker install.

### ✨ New Features

- **Instance default theme.** A new **Default theme** card on the Users page
  lets administrators choose Light, Dark, or Pure Black for the whole
  install. It paints the sign-in page before anyone signs in, seeds every new
  account, and applies in any browser that has not picked a theme of its own;
  a personal choice made in Settings always wins. The default is cached
  locally, so a returning visitor gets it before the first paint instead of a
  dark flash. Translated into all 25 languages.
- **Three-way theme toggle.** The sun/moon button on the sign-in page and in
  the sidebar, `Cmd/Ctrl + D`, and the command palette now cycle Light, Dark,
  and Pure Black, and the icon shows where the next press goes.

### 🔧 Improvements

- **Long chats stay smooth while a reply streams.** Streamed text used to
  re-render every message in the conversation on every animation frame, and
  none of the message components were memoized, so each finished message
  re-parsed its markdown sixty times a second. Messages, branches, and the
  content renderers are memoized, each message reads only the store slices
  it needs, streaming state reaches only the streaming turn, and off-screen
  turns skip layout and paint. Main-thread script time during one streamed
  reply in a 250-message chat drops from 3.1 s to 0.9 s.
- **A lighter first paint.** Vite 8's Rolldown had folded React itself into
  the markdown chunk, so every page, including sign-in, preloaded a third of
  a megabyte of markdown machinery. Explicit chunk groups put React back in
  its own vendor chunk and the release-notes modal loads on demand; the
  initial payload drops from 367 KB to 269 KB gzipped.
- **Math and raw HTML load on demand.** The KaTeX pipeline and rehype-raw's
  HTML parser are now lazy modules that a message loads only when it
  contains a `$` delimiter or raw HTML is allowed (notes). The shared
  markdown chunk shrinks from 88 KB to 47 KB gzipped.
- **Compressed, cacheable assets from the built-in server.** Hashed bundles
  under `/js/` and `/assets/` are brotli- or gzip-compressed once per process
  and served with a one-year `immutable` cache lifetime, while `index.html`
  and the service worker are `no-cache` so a new release is picked up on the
  next load. Self-hosters without a compressing reverse proxy no longer
  download raw bytes on every visit, and the service worker now caches the
  `/js/` chunks it had been skipping.
- **Cleaner production build.** The frontend targets ES2022, so noVNC's
  top-level `await` is emitted as-is without a build warning.

### 🐛 Bug Fixes

- The tool picker in the composer stays inside the chat pane: it is capped to
  the space above its button, its option list scrolls, and the enable toggle
  and approval hint stay pinned. It previously ran off the top of the screen
  under the tab bar with a long tool list.
- Artifact and Work preview sandboxes no longer emit a Content Security
  Policy source browsers reject (`http://[::1]:*` has no valid CSP form),
  which had logged an error on every render in development.
- The three-replica team platform drill no longer fails when the gateway's
  round-robin cursor resets between issuing and consuming a WebSocket ticket.

### 🔒 Security

- Dependency audit: `qs` 6.16.0 (array-limit bypass via bracket-key comma
  parsing) and `@humanfs/node` 0.16.8 (recursive copy following symlinks),
  plus the earlier `postcss-selector-parser` bump.
- Ollama endpoint normalization uses a linear trailing-slash walk with URL
  length caps instead of a regular expression CodeQL flagged as polynomial.

### 📚 Documentation

- Pro tips describe the instance default theme and the three-way toggle;
  the Docker guide notes that the server already compresses and caches the
  built frontend so a reverse proxy need not.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.31.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.31.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.31.0</guid>
      <pubDate>Tue, 01 Sep 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Getting started stops assuming Ollama, and staying current stops hurting:
a first-run screen connects whatever you already use — a local runtime, your
own OpenAI-compatible server, or a cloud key — while stale browser shells
heal themselves after updates, years-old databases upgrade instead of being
refused, and Libre WebUI lands on Debian, Ubuntu, Arch, and the Omarchy
desktop.

### ✨ New Features

- **Connect your models at first run.** Setup ends with a new step (also
  replacing the dead-end "ollama pull" card on an empty chat): an Ollama
  card with live detection, a local-server card whose presets — llama.cpp,
  vLLM, llama-swap, LM Studio, mlx-lm — share one flow with a server-side
  **Test connection** probe that lists the discovered models before
  enabling the provider, and a cloud card (OpenAI, Anthropic, Groq,
  OpenRouter, Gemini, Mistral) that takes an API key and connects.
  Skipping is a respected answer; non-admins are pointed to their
  administrator. Translated into all 25 languages.
- **Ollama is a setting, not an assumption.** Administrators can disable
  the Ollama provider entirely from the access page — no more health
  probes, reconnect polling, or "Ollama is not available" toasts on
  plugin-only installs — and point the endpoint at any Ollama-compatible
  gateway, local or remote. Disabling from the first-run screen is one
  click; everything re-enables just as easily.
- **Native Linux packages.** Every release now builds Debian/Ubuntu
  packages (amd64 and arm64) with a hardened systemd service and a
  dedicated system user, plus an Arch Linux PKGBUILD, from the new
  `linux-packages` repository — each package install-tested against the
  live health endpoint before publishing.
- **Omarchy bar plugin.** Libre WebUI ships a verified plugin on the
  Omarchy marketplace: server status, health, and latency in the bar, with
  one-click launch as a web-app window. Documented on the docs site.

### 🔧 Improvements

- **Follow-up messages just run.** Sending the next instruction to a Work
  task no longer demands stopping a preview the agent left running — the
  preview stops gracefully and the run starts, the same way the agent
  manages it mid-run.
- **A file manager in the Work computer.** Thunar sits in the sandbox dock
  between the browser and the terminal.
- **Development networking.** API and WebSocket traffic use Vite's
  same-origin proxy in development, so `npm run dev:host` works from
  another device without exposing the backend port; production origin
  policy stays strict.

### 🐛 Bug Fixes

- **Updates can no longer strand a stale browser shell.** The service
  worker cache is keyed to each release and clients recover automatically
  when a cached page requests a chunk a newer deployment removed —
  previously that failed dynamic import silently blanked part of the page.
- **Old databases upgrade again.** Ledger-less SQLite databases from
  releases that predate the `system_settings` and `personas` tables were
  refused at startup as incompatible; the bootstrap now recognizes them as
  upgradable history, creates the missing tables, and adopts the migration
  ledger — proven by a regression test that walks a pre-`system_settings`
  database end to end.
- **Unanswered takeover requests keep the screen alive.** Asking to take
  over no longer races the sandbox teardown: the screen session holds
  through the request plus a fifteen-minute grace window, so a late click
  lands on the blocked page instead of a fresh start screen.

### 🔒 Security

- The Omarchy plugin's health probe is byte-capped at the producer
  (`--max-filesize` plus a hard pipeline ceiling) with the URL passed as a
  positional argument — reviewed and verified by the marketplace's
  security process.

### 📦 Dependencies

- Routine minor and patch bumps across 15 packages, including axios,
  TanStack Query, and the AWS SDK; plotly.js moves to 4.0 for artifact
  charts.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.30.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.30.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.30.0</guid>
      <pubDate>Sat, 29 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Hired agents become governable and connected: approve their risky actions
before they run, let them delegate work to each other with @-mentions, fire
routines from external systems through webhooks, and hand agents the same
MCP and OpenAPI tool servers chat already uses — all without giving up
per-agent sandboxes.

### ✨ New Features

- **Approve actions before they run (Auto Review).** When a Work policy
  requires review — or an agent's new Auto Review switch is on — the run
  pauses before `run_command`, `computer_act`, `delete_file`, `move_file`,
  or a delegation and shows a decision card in the conversation: **Allow
  once**, **Always allow**, or **Deny**. Always-allow persists a scoped
  rule (the command's program for shell commands, the one target for
  delegation), listed and removable in the Agent tab; denial reaches the
  model as an answer, never a silent skip; an unanswered request expires
  after five minutes and the run hands off as **Needs input**. Pending
  approvals notify (in-app and push) and every decision lands in the
  security audit log. Ships with schema migrations (SQLite v28 /
  PostgreSQL v27).
- **Agents delegate to each other.** Type `@` in the Work composer to
  mention another hired agent, and agents carry a peer roster with a new
  `message_agent` tool. Delegation is asynchronous message-passing between
  separate sandboxes: the target runs in its own task (its conversation
  shows **Delegated by** the sender) and its report is delivered back into
  the delegating conversation — mid-run if the delegator is still working,
  as a waiting message if it is idle. Delegated runs cannot delegate
  further, busy targets refuse honestly, and a report never auto-starts a
  run, so agents cannot ping-pong each other.
- **Webhook triggers for automations.** An external system — CI, a cron
  service, home automation — can now fire an automation with a POST and a
  per-automation secret. The secret is generated in the edit dialog, shown
  exactly once, stored only as a hash, compared in constant time, and
  rotatable; a paused automation refuses external fires. Webhook fires use
  the same manual-run path as Run now, so history, settling, and
  notifications behave identically. Ships with a schema migration (SQLite
  v29 / PostgreSQL v28).
- **Connected tools for Work agents.** Agents can call the MCP and OpenAPI
  tool servers configured under Settings → Tools, through the same
  hardened backend gateway as chat (SSRF-guarded egress, per-user
  credentials, size and time caps) — never from inside the sandbox.
  Offline tasks offer none, servers missing a personal credential are
  filtered out at offer time instead of failing mid-run, persona
  tool-server bindings scope what a hired agent sees, and tools the server
  classifies as side-effecting pause behind Auto Review while read-only
  tools run free.

### 🔧 Improvements

- Finished Work runs show a **run summary**: rounds, tool calls,
  screenshots, safety fences, verification verdicts, and recovery nudges,
  plus why a run handed off early — live, after reconnects, and on
  persisted handoff messages.
- The chat composer's dictation now runs on the same engine as the Work
  composer, keeping the transcription-source picker (browser speech or a
  named provider model) while removing a duplicated recorder
  implementation.

### 🐛 Bug Fixes

- Migrating a SQLite deployment to PostgreSQL no longer silently drops the
  Work policy columns for the Work Computer and screen-takeover settings —
  or any of the newer policy and task fields — during import.

### 🌍 Translations

- 35 new interface messages across all 25 shipped languages for action
  approvals, Auto Review rules, agent mentions and delegation labels, run
  summaries, and webhook management.

### 📚 Documentation

- The Workspaces guide covers action approvals, delegation between agents,
  and connected tool servers, with the API table brought current; the
  Automations guide documents webhook triggers with a copy-paste example;
  the chat tools guide notes the shared Work boundary; the notifications
  reference lists the approval notification type.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.29.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.29.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.29.0</guid>
      <pubDate>Fri, 28 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Personas can now become persistent Work agents: hire one into a pinned sidebar
identity, revisit its screen and taught skills, schedule routines inside its
existing workspace, and receive notifications when it finishes or needs
attention. Model curation gains persistent stars, while Work gets dictation,
direct file shortcuts, and a calmer, more reliable computer sandbox.

### ✨ New Features

- **Hire personas as named Work agents.** Choose a persona when creating a Work
  task and it becomes a persistent agent with that persona's name, avatar, and
  instructions. Agents stay pinned above one-off tasks, show concise status and
  unread activity, and remain available in the compact sidebar.
- **A home for every agent.** The new Agent tab combines identity, a live
  view-only screen thumbnail, scheduled routines, and taught skills. Routines
  run inside the agent's existing conversation and workspace instead of
  creating a fresh task, while completion, attention, and takeover
  notifications link directly back to the agent. Ships with schema migrations
  (SQLite v25–v27 / PostgreSQL v24–v26).
- **Star important models.** Administrators can star models in the shared
  catalog, placing favorites first in both the catalog and default-model
  picker. Several stars follow most-recently-starred order, and removing one
  restores its manual or provider position.
- **Dictate Work instructions and open results directly.** The Work composer
  now accepts browser speech recognition or configured speech-to-text, and
  files created or moved by an agent appear as clickable chips that open
  directly in the workspace editor.
- **A living Work Computer start page.** The sandbox desktop gains an offline,
  time-aware Sunset Valley scene and built-in, checksum-verified blocking for
  ads, trackers, and cookie-consent banners.

### 🔧 Improvements

- Persona identity now carries through model selectors, header chips, and
  assistant replies in both Chat and Work, with consistent avatar presentation.
- Settings → Model is now **Defaults**, separating model defaults and catalog
  curation from the **Models** manager. The existing bulk Ollama updater now
  lives with the installed-model controls, reports per-model progress, and
  refreshes the list when it completes.
- The persona editor now uses one clear Save action, stays open after the server
  confirms a create or update, and shows an accessible saved state.
- Tool-server save and refresh failures now show the backend's specific reason
  instead of a generic error.
- Recommended starter models and hardware guidance now reflect the Gemma 4 and
  Qwen 3.8 lineups rather than the older 2024 suggestions.

### 🐛 Bug Fixes

- Persona-backed replies resolve the persona's display name instead of exposing
  its raw identifier in model-trigger UI.
- Work Computer runs no longer fail when a provider rejects screenshots: the
  run switches to text-only observations, records the degradation, and
  continues.
- The animated start scene renders as time-keyed stills so it remains
  responsive under the GPU-less SwiftShader sandbox, with improved
  initialization and the existing PNG fallback retained.
- Containerized backends now reach Docker-published Work preview, screen, and
  audio ports through the configured host address, including working Docker
  Desktop defaults.
- Work Computer audio now loads its processor from a same-origin asset, fixing
  playback under the production Content Security Policy.
- The cross-replica replay drill now seeds current event timestamps so retention
  cannot remove fixtures during its assertion.

### 🌍 Translations

- Added 89 localized interface messages across all 25 shipped languages for
  agents, routines, model starring, Work file links, startup and OAuth errors,
  chat actions, uploads, settings, model operations, and portable archive
  import/export.
- Previously hardcoded toast messages now use the translation catalog, and
  portable archive parse failures expose stable error codes for localized
  validation.

### 🔒 Security & Dependencies

- Container builds now refresh the runner stage without reusing stale
  OS-package layers, ensuring current Alpine and OpenSSL fixes reach security
  scans and published images.
- Refreshed AWS SDK, UUID, Framer Motion, i18next, Lucide, Mermaid, React
  i18next, Vite, and PostgreSQL type dependencies.
- Work Computer browser extensions are version-pinned and checksum-verified
  during image construction.

### 📚 Documentation

- Expanded the Work, Automations, and Notifications guides for hired agents,
  task-bound routines, unread state, Work notifications, content blocking,
  screenshot degradation, and Docker-published port routing.
- Updated model-management guidance for stars, the Defaults/Models split, bulk
  updates, and the current recommended model lineup.
- Refreshed the Work Computer screenshot and corrected documentation media
  metadata and demo links.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.28.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.28.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.28.0</guid>
      <pubDate>Sun, 23 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Every Work task can now have a real computer. The Work Computer gives each sandbox a watchable virtual desktop with a browser: see the agent work live, hear its audio, take over the mouse for sign-ins, and teach it tasks by demonstrating them once on screen. Underneath, the agent's actions are verified rather than assumed — typing asserts its target field, batches stop when the screen changes under them, and outcomes are checked against declared expectations.

### ✨ New Features

- **The Work Computer.** A policy switch gives tasks a virtual desktop (window manager, dock, and Chromium on a 1280×800 display) with a live Screen tab: VNC over WebSocket behind one-use task-bound tickets, up to four concurrent viewers, and a browser profile that survives restarts. Administrators enable it with one click; the GUI sandbox image is now published ready to pull, and deployments behind a build-denying Docker proxy install it with pull + tag. Ships with schema migrations (SQLite v22–v24 / PostgreSQL v21–v23).
- **The agent drives it — with receipts.** New `computer_observe` and `computer_act` tools give the model eyes and hands, and every action earns evidence: observations carry the active window, page URL, focused element, and a screenshot hash; typing can assert its target field and fails closed when focus drifted; batches fence themselves when a window, title, or context changes mid-batch; clicks report whether pixels near them changed; `scroll_until` scrolls toward target text and reports whether it became visible; batches declare expected outcomes the runtime verifies with an adaptive deadline; and repeated no-effect actions end the run asking for help instead of burning its budget.
- **Take over the screen.** A cooperative, TTL-bounded control lease hands you the mouse and keyboard through a dual-password VNC session — watchers stay input-inert, credentials go from your keyboard to the page and never through the model, and the agent's own `request_takeover` posts a banner and waits. Policies decide whether takeover is allowed at all.
- **Teach it by demonstration.** Record a task once on the real screen: the demonstration compiles deterministically into a natural-language playbook — click targets named by an element anchor probe, secret-looking input redacted, and an allowed scope derived from the sites the demonstration actually visited. Playbooks save as ordinary skills, load into computer-enabled runs automatically, and collect a worked/failed track record from one-click reviews on finished runs.
- **Hear the computer.** Live audio passthrough from the sandbox over a second authenticated bridge — same tickets, same access re-checks as the screen.
- **Message the agent mid-run.** Send a note while a run is executing; the agent picks it up at its next step without stopping.
- **Automations can run Work tasks.** A scheduled automation can now target a Work policy and deliver its run as a Work task instead of a chat.
- **A replay benchmark for computer use.** `npm run bench:work-computer` drives the real GUI image through adversarial browser fixtures and scores the runtime guards — the regression baseline for future loop changes.

### 🔧 Improvements

- The agent's desktop is presentable: a branded start page in the product's own visual language, themed search, a dock with running apps and a clock, and wallpaper support.
- Loop telemetry: per-tool durations, rounds on every call, and a run-end summary of screenshots, fences, verdicts, and recovery nudges.
- The Work workspace pane gained the Screen view alongside Files, Activity, Changes, Terminal, and Preview.

### 🐛 Bug Fixes

- Containerized backends on Docker Desktop reach published Work ports through a dedicated dial address (`WORK_DOCKER_PUBLISHED_HOST`), fixing screens and previews on Windows and macOS container installs.
- Watching a screen no longer conflicts with the run that owns it in team deployments — and a run ending no longer stops a screen someone is watching.
- GUI containers no longer churn on every workspace refresh, and screen connections survive helper calls.
- Passkey sign-in accepts RS256 credentials, and the sign-in button hides when no accounts exist.
- The one-click Work Computer setup works in containerized installs and converges on an existing image behind filtered Docker proxies.
- Security hardening from two CodeQL passes, plus a migration-checksum false positive silenced without weakening the check.

### 📚 Documentation

- A complete Work Computer guide: screen, takeover, teach mode, audio, per-policy gating, and the agent's verified-action loop — with an embedded demo video of a real, unedited agent run.
- README, documentation landing page, environment reference, and the comparison page brought current with the release.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.27.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.27.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.27.0</guid>
      <pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Signing in gets serious — two-factor with recovery codes, passkeys, and a live password meter. The app now installs to your phone with real push notifications, knowledge ingests scans and audio, backups prove they restore on a schedule, artifacts get a proper split-screen panel, and the desktop app gets its real name.

### ✨ New Features

- **Two-factor and passkeys.** TOTP two-factor with one-time recovery codes, passkey (WebAuthn) sign-in, a per-role step-up policy administrators can require, and admin reset of a locked-out user's factors. Ships with a schema migration (SQLite v21 / PostgreSQL v20).
- **Install it like an app.** Libre WebUI is now an installable PWA with an offline shell, and notifications can reach your device through web push — riding the same durable notification inbox introduced in 0.26.
- **Knowledge reads scans and audio.** Images and scanned PDFs are OCR'd through the vision model, and uploaded audio is transcribed through speech-to-text, so screenshots, paper scans, and recordings become searchable, citable documents.
- **Backups that prove they restore.** Scheduled recovery drills restore a real backup into an isolated area on a cadence you set, verify the result, and measure actual RTO and RPO — so restore confidence is measured, not assumed.
- **A split-screen artifact panel.** On desktop, artifacts open beside the conversation instead of covering it, with a pin toggle that keeps the panel open while you chat, optional auto-open when a new artifact is generated, and compact chrome.
- **Pure-black AMOLED theme.** A true-black appearance mode alongside light and dark, with redesigned circular accent swatches.
- **Night-owl code theme.** Code blocks share one night-owl palette with line numbers across chat, thinking, and Work, rendered in a self-hosted JetBrains Mono — no external font requests.
- **Live password strength meter.** Setup, signup, and user management show strength and policy feedback as you type.

### 🔧 Improvements

- **The desktop app is now Libre WebUI Desktop.** Renamed from "Libre WebUI Frontend" across installers and Homebrew: the old cask tokens migrate automatically on upgrade, installer assets use the new name from this release on, and existing installs keep their data and sessions through the rename.
- Your chosen accent color now carries through approval cards, Work panes, the git panel, and the terminal instead of falling back to the default coral.

### 🐛 Bug Fixes

- Tool egress timeout and size caps are clamped defensively, so a malformed valve value can no longer disable the limits.
- Artifact previews stay inside the sandboxed panel; the open-in-new-window escape hatch was removed.
- Split-view polish: the artifact panel stacks below modals, inline previews collapse while the panel is open, and the composer stays compact beside it.
- The compact sidebar rail no longer renders unreadable session chips.

### 📚 Documentation

- Completed the 0.26 guide set, including new observability and notes guides, a refreshed documentation landing page, and updates across Kubernetes, SSO, web search, and monitoring docs.
- Added a factual, sourced product comparison page.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.26.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.26.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.26.0</guid>
      <pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Models that use tools under your approval, retrieval that cites its sources, channels and sharing for teams, hands-free voice conversations, image editing — and the cost controls, evaluations, observability, and high-availability certification to run all of it in production. Everything built since 0.25.0 lands here at once.

### ✨ New Features

#### Agents and tools

- **Models use tools, with your approval.** A chat can now run multiple tool rounds inside a single reply: the model calls a tool, reads the result, and continues — through Ollama and every OpenAI-style provider. Each call is shown as it happens, and side-effecting tools wait for your explicit approval before they run.
- **Bring your own tools.** Register any OpenAPI service or MCP server as a tool source; its operations become tools the model can call, with per-user credentials and an egress guard between the model and your network. A safe public demo preset is included to try the flow end to end.
- **Prompts, Skills, and Tools workspaces.** Saved prompts open from a slash menu in the composer; skills are folders of instructions and companion files the model can load on demand — write your own, or import from remote skill stores. All three live in the settings panel with starter templates, beside the model manager.
- **Knowledge tools with citations.** The model can list and read your documents mid-conversation, and its answers cite the exact source passages they came from.

#### Knowledge and chat

- **Richer document ingestion.** Word, PowerPoint, and Excel files extract with page, slide, and sheet provenance — with no new native dependencies — and re-uploading an unchanged file is detected instead of re-indexed.
- **Hybrid retrieval.** Keyword ranking (BM25) fuses with vector similarity, so exact identifiers and rare terms are found even when embeddings miss them. Because content stays encrypted at rest, ranking happens in memory over decrypted candidates the requester is allowed to see — there is deliberately no plaintext index on disk.
- **Answers cite their sources.** RAG replies carry source citations down to the page or slide, and a chat can attach a document in full-context mode when you want the model to read the whole thing.
- **Notes grow up.** Revision history with restore, file attachments, pinning, per-user sharing (view or edit), Markdown export, and an AI edit sidebar that previews every proposal as a diff — applying snapshots the previous version first, so any AI edit can be undone. The preview also renders inline SVG and basic HTML, sanitized.
- **Queue prompts while a reply streams.** Follow-up messages wait in an editable queue and send one at a time when the model finishes.
- **Ask several models at once.** A comparison fan-out sends the same message to additional models and labels each reply, so you can judge them side by side in the conversation.
- **Fork a whole chat.** Duplicate a conversation with its full history and provenance recorded, and take the copy in a different direction.
- **Search everything from the palette.** Cmd-K now searches across your chats, notes, and documents — scoped to what you can access, without a plaintext index.
- **An OpenAI-compatible API.** `/v1/chat/completions` and friends work with scoped API tokens, so existing OpenAI-style clients and SDKs can point at your instance for stateless inference.

#### Team collaboration

- **Channels.** Public, private, and direct-message channels with threads, reactions, and file attachments — and @model mentions that bring an AI reply into the conversation under the asking member's identity. Delivery rides the same durable event ledger as everything else; the database rows are the truth.
- **Share nearly anything.** Grant-based sharing for chats, personas, prompts, skills, and knowledge collections, per user, with view or edit roles. Shared knowledge answers retrieval queries for grantees immediately, and revocation is just as immediate.
- **A notification inbox.** Durable in-app notifications with live delivery, plus signed outgoing webhooks so other systems can react to events — envelopes are redacted and retried sensibly.
- **Calendars for more than one person.** Share a calendar with view or write access, color-code several of them, import and export ICS, and get single-fire reminders per occurrence. The model gains calendar tools, so an automation or chat can read and write events.

#### Voice and media

- **Hands-free voice mode.** A turn-based voice conversation: speak, the model answers aloud, and the turn returns to you — with an on-screen overlay showing exactly what state the exchange is in.
- **Voice governance.** Administrators set access modes for speech-to-text, text-to-speech, voice mode, and voice cloning independently. Saved voices carry a consent lifecycle — consent is recorded, revocable (the receipt is kept), and every transfer of voice data to a provider is receipted.
- **Edit images, not just generate them.** Inpaint with a mask, edit with an instruction, or composite multiple images — through the same approval and gallery flow as generation.
- **The gallery cleans up after itself.** An optional retention sweep removes old generated media, and long-running media jobs notify you when they finish.

#### Running it in production

- **Costs and budgets.** Versioned per-model tariffs price real usage, a cost analytics view breaks spending down, and hard budgets stop generation when a period's limit is reached — with alert notifications on the way there.
- **An evaluation platform.** Thumbs feedback on replies, blind arena battles between models with an Elo leaderboard computed from votes, and repeatable evaluation runs over saved sets — all admin-managed.
- **Observability you can plug in.** Structured JSON logs with request correlation ids and secret redaction, and an opt-in OpenTelemetry export speaking OTLP/HTTP with zero new dependencies — spans cover HTTP requests and durable jobs.
- **Certified high availability.** The Helm chart supports referencing an existing Secret instead of inlining credentials, ships optional NetworkPolicies for app and workers, and the three-replica failover drill that gates releases is now documented as the HA certification.

### 🔧 Improvements

- The Prompts, Skills, Tools, and Model Manager surfaces live inside the settings panel, reachable from the command palette.
- Every document picker shares one upload accept contract, so the accepted file types are identical everywhere and pinned by test.
- The frontend clears every react-hooks lint warning — imperative engines (like the voice controller) now live outside components by design.
- Schema migrations (SQLite v16–v20, PostgreSQL v15–v19) create the agents, notes, team, and media/enterprise tables; applied automatically on upgrade.

### 🐛 Bug Fixes

- **Lexical retrieval stops admitting junk.** A candidate must fully contain every part of at least one query word — compound identifiers no longer let two shared fragments smuggle an irrelevant chunk through rank fusion.
- **The v18 migration applies cleanly on upgraded databases.** A preflight check misread an index on a pre-existing table as missing schema and blocked the team migration.
- **Composer menus tell the truth.** Slash and skill menus work on the welcome screen, stay live while typing, and the tool picker reflects what is actually enabled.

### 🌍 Translations

- All new interface text across the agent, knowledge, team, voice, media, and operations surfaces — roughly 350 new keys — is translated in all 25 languages.

### 📚 Documentation

- New guides for tools and the tool gateway, skills, prompts, sharing, channels, notifications, team calendars, voice governance, image editing, costs and budgets, evaluations, observability, and the high-availability certification — plus worked examples for every tool, and honest boundary pages for what each system deliberately does not do yet.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.25.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.25.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.25.0</guid>
      <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[A calendar, and automations that use it: recurring events on a month or week grid, and scheduled AI tasks whose runs land in your chat list as ordinary conversations. Around them, web search that plans its queries before running them, a rebuilt command palette, and a round of persona and interface fixes.

### ✨ New Features

- **A personal calendar.** Month and week views with one-off and recurring events — hourly through yearly. A recurring event is stored once and expanded server-side, so editing it updates every future occurrence. Titles and notes are encrypted at rest with the same envelope used for chats and notes.
- **Automations: scheduled AI tasks.** An automation runs your instructions on up to five triggers and delivers each run as a normal chat session — a daily digest or a weekly review lands in your chat list, ready to be opened and continued like any other conversation. Runs go through the same durable generation pipeline as every chat — provider routing, persona defaults, and web search when it is enabled — with pause and resume, run-now, starter templates, optional in-app notifications when a run finishes, and a run history that tells failures apart from runs that stalled. The scheduler ticks once a minute behind a coordination lease, so exactly one replica advances schedules and each occurrence fires at most once; a server that was down fires the missed occurrence once when it returns. Automations project their upcoming occurrences and finished runs onto the calendar, and both pages appear in Explore on the home screen.
- **Web search plans its queries.** A chat message is rarely a good search query, so the session's own model first turns it into a few keyword queries, plus an optional freshness window and engine category. Every failure along the way degrades to the plain raw-message search this replaces, never below it. The results-per-search ceiling rises to 100.
- **A larger command palette.** Cmd-K opens centered, with fuzzy matching and the matched characters highlighted.
- **Pinnable admin shortcuts.** Administrators can pin admin pages into the sidebar footer for one-click access.
- **The About screen checks for updates.** It compares the running version against the latest published release and says which of the two is ahead, and gains links to reopen the release notes and to star the project.
- **Small comforts.** The settings modal is larger, and a new chat shows a spinner in the sidebar while its title is being written.

### 🔧 Improvements

- The sidebar and top bar share one continuous surface, text fields no longer draw a double frame when focused, the chat composer's icons align left like the new-chat composer's, and Work task rows use the same actions menu and hover preview as chats.
- A routing error now renders the branded error screen instead of a blank page.
- New schema migration on both backends (SQLite v15, PostgreSQL v14) creates the calendar and automations tables; applied automatically on upgrade.

### 🐛 Bug Fixes

- **Editing a message now rewrites the conversation on the server.** Edit-and-resend sent its truncation through a metadata update that silently ignores messages, so the server kept the entire replaced tail and the edit existed only in the browser. A dedicated truncate operation removes the cut messages for real, cancels any generation still writing into them, and keeps the prefix from the server's own copy so a stale client can never erase a newer reply.
- **Personas answer with the model they are built on.** A persona backed by a provider plugin now routes to that provider, its model default resolves to the persona's backing model, provider models are selectable as persona backends in the first place, and the home screen's continue list shows persona names.
- **A failed regenerate cleans up after itself.** The failed attempt is removed and the conversation resyncs with the server instead of drifting out of step.
- **A stray `h` no longer opens settings.** Single-letter navigation shortcuts require their modifier; the shortcuts help opens with `?`.

### 🌍 Translations

- All new interface text — the calendar, automations, the palette, the About screen, and the admin pins — is translated in all 25 languages.

### 📚 Documentation

- New guides for the calendar and automations, and the quick start, pro tips, and keyboard shortcuts pages catch up with the palette, the admin pins, and the current shortcut set.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.24.1</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.24.1</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.24.1</guid>
      <pubDate>Tue, 18 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[A correctness pass over the three systems 0.24.0 introduced. Compaction, the context meter, and the thinking levels now share one definition of what a conversation's context is — and each of them answers to the person using it: compaction can be refused or undone per conversation, the meter counts exactly what the next request sends, and a thinking setting never reaches a model that cannot honor it.

### ✨ New Features

- **A compaction can be refused, and undone.** Every summary now records exactly which messages it replaced, and an undo on the summary card restores them and removes the summary — chained compactions walk back one at a time. The chat controls panel can switch compaction off for a single conversation while the server-wide policy stays on.
- **The application knows which provider models reason.** Model discovery keeps reasoning support beside each model's context window: the listing's own answer where one exists, a maintained name-family table where it does not. The thinking control is hidden for models known not to reason, and the setting is stripped before a request reaches one — the provider-side twin of the local capability gate. Unknown models stay offered, exactly as before.
- **The meter measures the real window.** With compaction on, the "recent messages kept" count is now also the rolling window a conversation sends, so raising it genuinely widens what the model sees — and a narrow context-policy endpoint lets the meter mirror that number instead of assuming the default.

### 🔧 Improvements

- **The context meter counts the prompt that is actually sent.** It mirrors the server's message selection, so compacted history, abandoned branches, and turns outside the rolling window cost nothing — the ring no longer drifted upward without bound or rose after the very compaction that had just shrunk the prompt. The count anchors to the provider's last measured reply plus an estimate of what followed, instead of flipping between measured and estimated on every turn.
- **Token estimates price text and images honestly.** CJK characters count at roughly a token each rather than a quarter — a Japanese conversation no longer reads as a fraction of its real size — and images carry a flat per-image cost instead of counting as zero, identically on the server and in the meter. The compaction transcript notes attached images so a summary cannot silently erase that they existed.
- **The summary reads as what it is.** The compaction summary renders as a conversation-summary card at the point in the chat where the history was folded, and the summarized messages render dimmed: still readable, no longer sent. The card is not editable — its earlier edit path overwrote the global system prompt — and compacted turns no longer offer branch selection that would silently resurrect a message the summary already covers.
- **The summarizer behaves like part of the product.** Its transcript is bounded so it fits its own context window, template placeholders substitute literally, the conversation is framed as data rather than instructions, the session's provider binding travels with the call, pressing Stop reaches it, and its configuration is read from a short-lived cache instead of the database on every reply. The compaction configuration endpoint is admin-only in both directions, and a retried background generation reuses the first attempt's compaction instead of paying for another summarizer round trip.
- **Anthropic requests respect each model's output ceiling.** A thinking budget or an oversized token cap can no longer push `max_tokens` past what the model accepts; documented family ceilings bound both, and unknown families stay unclamped so a wrong guess can never truncate real replies. An explicit answer cap now shrinks the thinking budget into it rather than being silently raised.
- **Reasoning renders wherever it was paid for.** The Responses API asks for a reasoning summary so thinking is shown rather than only billed, Gemini requests thought summaries and routes them as reasoning with an output ceiling that holds the budget plus the answer, and Anthropic replies keep their thinking on the non-streaming path too.

### 🐛 Bug Fixes

- **Replaced summaries stayed in every prompt forever.** Deactivated system messages were still selected into the model context, so each compaction left one more stale summary riding along; they are now filtered exactly like deactivated conversation turns.
- **Persona conversations lost the summary entirely.** The persona prompt replaced all stored system messages, compaction summary included — pure context loss. The summary now survives beside the persona prompt, and the writers that update the leading system message can no longer overwrite a summary that happens to sit first.
- **The keep-recent boundary kept fewer messages than configured.** It extended forward to the next user turn and could summarize everything except the message just typed; it now extends backwards, so at least the configured count always survives, still starting on a user turn.
- **A conversation on an unresolved model read as full.** While the model list loaded — and for every agent conversation — the meter borrowed the 2,048-token application default and rendered a full amber ring; an unknown window now shows a dashed ring instead of a wrong one. Over budget shows red past the amber warning instead of being rounded down to exactly full, the ring is a real meter to screen readers, and token counts format in the reader's locale with bidi isolation.
- **Gemini thinking could consume the entire reply.** The thinking budget counted against an output ceiling that had not grown to hold it, so low effort on default settings returned empty replies at the token limit.
- **Reset to defaults now clears a saved thinking level** instead of leaving it behind while every other option reset.
- **A named thinking level no longer errors on models without named levels.** It degrades to plain "on", so a conversation that moves between models keeps working.
- **The thinking control tells the truth everywhere.** The composer button reflects the pinned or global default a conversation inherits, the chat controls panel shows the conversation's own choice with the inherited value named inside "Default", saving the panel no longer drops sibling session settings such as attached knowledge collections, and capability lookups stop firing for provider, persona, and still-loading models.
- **The compaction settings toggle no longer lies.** A rejected or invalid save leaves it in the server's state instead of visually flipped, and a failed configuration load says so instead of leaving the controls silently dead.

### 🌍 Translations

- All new interface text — the summary card, the restore action, and the per-conversation compaction control — is translated in all 25 languages.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.24.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.24.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.24.0</guid>
      <pubDate>Tue, 18 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Control over how models answer, and a clearer view of what they are working with: a thinking level per chat, a context meter in the composer, an administrator model catalog, and long conversations that compact themselves.

### ✨ New Features

- **Set how hard a model thinks.** A control in the composer opens the reasoning levels (off, on, low, medium, high) for the chat you are in, on the new chat screen as well, and the same setting lives in the chat controls panel and in Settings → Generation as a default for new replies. One value travels with the chat and is translated at each provider boundary: Ollama takes it in the request body, OpenAI-style providers take a reasoning effort, the Responses API takes its own field, and Anthropic and Gemini take a token budget with room reserved for the answer. Nothing is sent when the setting is unset, so a model you never configure behaves exactly as before, and a model Ollama reports as unable to reason is never asked to. (#205, Zack Young)
- **See how full the context window is.** A ring beside the model name fills as the conversation grows; hovering it reports how full, the tokens used, and the window they run against. The count is what the provider measured for the last reply where it reported one, and an estimate at four characters per token before that, marked as an estimate. A window capped below what the model was trained for says so, which is what explains a 32k reading on a model trained for 262k.
- **Context windows for provider models.** Model discovery now keeps the context window a provider publishes with its listing, reading whichever field that provider uses, so the meter has something to measure against on hosted models and not only on Ollama. Catalogs stored before this release are refreshed once instead of waiting out their refresh interval.
- **Administrator model catalog.** Settings → Models gains a searchable catalog where administrators choose which models everyone sees, the order they appear in, and the name and picture each one carries. Hiding a model applies immediately, dragging shows where it will land, and a default model can be set for the deployment.
- **Long conversations compact themselves.** Past a token threshold, older turns are replaced by a summary that carries the goals, decisions, facts, and open questions forward, keeping a long chat inside the model's window instead of failing at it. Administrators control the threshold, the model that writes the summary, and the prompt.
- **Code blocks read like code while they stream.** Line numbers and syntax highlighting now apply to a reply as it arrives, rather than only once it has finished.
- **Model names and pictures in the chat.** The picker and each assistant message show the model's configured name and picture. A reply that is still streaming has no model stamped on it yet, so it shows the chat's own model rather than the generic word Assistant.

### 🔧 Improvements

- Titles and follow-up suggestions never spend a reasoning pass, whatever the chat is set to.
- The About screen names the mirror correctly as Forgejo and links to project sponsorship.
- The Vite configuration reads its own directory through `import.meta`, so builds no longer warn about an unsupported configuration feature.
- All new interface text is translated in all 25 languages.

### 🐛 Bug Fixes

- **Reasoning models can name a chat.** A model that thinks before answering spent its whole allowance on reasoning and returned empty content, so the chat fell back to a message preview for its title. Local models are asked not to reason for this, and providers that cannot be told that are given room to think and still answer.
- **A long reply no longer fails its durable job and regenerates.** Progress events carried the whole accumulated reply, so a long answer hit the durable event size ceiling and the interface responded by generating the same reply again. Completion events are bounded and oversized deltas are split across ordered events.
- **Token counts and timings appear for provider-backed replies.** Streams never asked for usage, so nothing was reported, and the timings llama.cpp returns beside the counts were dropped on the way through.
- **Work rounds that only reason keep their context and finish.** A round that produced reasoning and no visible text lost that context instead of completing with it.
- **The workspace file list retries quietly while a sandbox is preparing.** It used to report a failure for a sandbox that was simply not ready yet.
- Three interface render fixes: mount-time loaders no longer force a second synchronous render, a streaming code block no longer rebuilds and resets its scroll mid-stream, and the durable reload effect no longer misses a dependency.

### 🔒 Security & Dependencies

- Dependencies refreshed across the workspace: `@kubernetes/client-node` 2.0 (a major upgrade, with the Work Kubernetes driver verified against it), `framer-motion` 13.1, `katex` 0.18.4, `papaparse` 5.6, `zustand` 5.0.15, `tsx`, and `eslint-plugin-react-refresh`, along with AWS SDK and TypeScript ESLint updates resolved in the lockfile.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.23.1</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.23.1</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.23.1</guid>
      <pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Same-day fixes for 0.23.0, all found and verified on a live team deployment. Recommended for everyone, especially Work users.

### 🐛 Bug Fixes

- **The first message on a new Work task no longer fails with "This Work task is active on another replica."** Creating a task races the interface's file browser against the run itself: the file helper briefly holds the task's runtime lease while it prepares the sandbox, and the run used to give up instantly when it lost that race — killing the user's first prompt. The run now waits out transient lease holders (up to `WORK_RUN_LEASE_WAIT_MS`, default 60 seconds) before reporting a genuine replica conflict.
- **Tab menus draw above page headers.** The tab bar's right-click menu and the new-tab menu could render underneath the Work header and banners; both now render at the top of the page's stacking order.
- **A WebSocket hiccup during sign-in can no longer break app loading.** Signing in could kill a racing WebSocket connection attempt mid-handshake, and the resulting error aborted the entire post-login initialization — models and chats then failed to load. Superseded connection attempts are no longer treated as failures, sign-in re-dials atomically, and data loading proceeds even when the socket needs its own reconnect cycle.
- **Work previews can capture the mouse.** Previewed games and 3D scenes may now request pointer lock; it still requires a click and the preview keeps its isolated, opaque origin.
- **Chat reconnects no longer compete with sign-in traffic for one rate limit.** WebSocket tickets have their own rate bucket, and the general authentication bucket — which now also serves the session and API-key management screens — has room for real interactive use. Login and signup keep their strict limits.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.23.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.23.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.23.0</guid>
      <pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[The trust release. Accounts get real sessions you can revoke, scoped API keys, administrator-managed groups, a sharing-grant foundation, sign-in with any OpenID Connect provider, and a security audit log — all working identically on SQLite and PostgreSQL deployments. Also fixes two Work bugs, including one that could take the whole server down.

### ✨ New Features

- **Sessions you can see and sign out.** Every sign-in now creates a server-side session bound into its token. Settings → Sessions lists each device with its sign-in method and activity; revoking one (or "Sign out other sessions") invalidates that token immediately on every replica and closes its live chat and terminal connections. Logout now really signs the token out instead of only clearing the browser.
- **Scoped API keys.** Settings → API keys mints personal tokens for scripts and integrations. Each key carries an explicit scope list (chat, models, documents, notes, personas, media, work, admin), is shown once and stored only as a hash, supports expiry, tracks last use, is rate-limited per key, and can be revoked at any time. A notes-only key cannot touch chats or administration, and session management is never reachable with a key.
- **Groups.** Administrators can create groups and manage memberships from the User Management page. Membership is evaluated live, so removing someone revokes group-granted access immediately. A new "effective access" view answers "why can this account access this?" — role, groups, feature access, and every grant that reaches the user.
- **Resource sharing grants (foundation).** One private-by-default grant model for chats, notes, documents, knowledge collections, folders, and personas: owners can grant read, write, or admin access to a user or a group through the new access API, and group-shared retrieval is plumbed all the way into vector search. Every access decision now flows through a single authorization service — the global admin role deliberately grants no access to other people's content. Sharing UI arrives in a later release; the machinery and API ship now.
- **Sign in with any OpenID Connect provider.** Keycloak, Authentik, Authelia, Okta, Entra ID, Google Workspace, and friends — configured with three environment variables. The flow uses PKCE, CSRF state, and a nonce verified inside the signature-checked ID token; identities link on the stable subject claim, so a renamed provider account keeps its Libre account. Optional policies: allowed email domains, admin-role mapping from a group claim, and per-login group membership sync.
- **Security audit log.** Sign-ins and failures, logouts, session and key revocations, and user, group, and grant changes are recorded in an append-only log that is separate from usage analytics. Details are redacted before storage — secrets and prompt content can never enter the log — and group/grant changes commit in the same database transaction as their audit event, so a change cannot exist without its trail. Administrators query it from the User Management page; retention defaults to 180 days.

### 🔧 Improvements

- Work, model download, web search, and agent access checks now flow through the same central authorization service as resource grants, with unchanged semantics.
- New schema migration on both backends (SQLite v14, PostgreSQL v13) creates the seven trust-foundation tables; applied automatically on upgrade.
- All new interface text is translated in all 25 languages.

### 🐛 Bug Fixes

- **A long Work response no longer crashes the server.** Work streamed each progress event with the full accumulated reply attached, so once a response passed 64 KiB the durable event log rejected the payload — and the unhandled rejection killed the process. Durable copies of delta events now carry only the delta, oversized payloads are bounded instead of rejected, and a durable append failure can never take a running task down — live viewers keep receiving events either way.
- **Work's Files pane works during runs on team deployments.** While the external worker was executing a task, the app replica could not acquire the task's runtime lease and answered file browsing with "This Work task is active on another replica." File helpers now attach to the running sandbox when the lease holder is the deployment's own worker.

### 📚 Documentation

- Authentication, single sign-on, and environment variable docs cover sessions, API keys, groups, grants, the audit log, and the full OIDC configuration reference.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.22.1</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.22.1</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.22.1</guid>
      <pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[A same-day repair release for 0.22.0. If 0.22.0 refused to start after an upgrade with "Invalid platform storage encryption configuration", or the interface came up empty after signing in, this release fixes both — no manual steps needed.

### 🐛 Bug Fixes

- **Signing in no longer requires a page refresh.** On deployments with authentication, the app initialized once before login, marked itself done, and never loaded models, sessions, or plugins after the login landed — leaving an empty interface until a manual reload. Initialization now runs again the moment authentication completes.
- **Providers that start late appear without a reload.** If Ollama or the backend was still starting when the page loaded, the model list stayed empty forever. The app now quietly re-checks until a provider shows up, and re-checks a previously offline Ollama when the window regains focus — without polling forever on deliberately plugin-only setups.
- **Upgrades no longer fail on legacy key file permissions.** Installations whose `.encryption_key` was created by an older release carried default file permissions, and 0.22.0's hardened startup refused them outright — every such npx, npm, source, and Docker upgrade crashed on boot. Startup now tightens the key file to owner-only permissions in place when it is a regular, single-link file owned by the server user; symlinks, multi-link files, and files owned by someone else still fail closed. Startup errors also name the actual problem now instead of a generic line.
- **Brand-new provider models work as soon as the provider ships them.** Chatting with a model a provider had just released could fail with a generic error: the model picker shows the provider's live catalog, but the request resolved against the stored one. A missed lookup now refreshes a due catalog once before rejecting, which also covers team deployments where the external worker only sees the stored catalog.
- **Failed generations keep their real reason.** A crashed chat generation logged nothing anywhere — the durable job record kept only a sanitized summary. The worker now logs the underlying error before sanitizing, so a dead-lettered generation can actually be diagnosed.

### 🔧 Improvements

- **The jobs API is rate limited.** The durable jobs endpoints gained the same per-user shared rate limit as every other API surface.
- **Plugin upload cleanup hardened.** Temporary-file deletion now rebuilds its target from a validated relative path — the canonical containment pattern — instead of checking and deleting the incoming path.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.22.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.22.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.22.0</guid>
      <pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[The largest release so far. Libre WebUI now scales past a single machine: a new team profile runs on PostgreSQL, Redis, and S3-compatible storage with external workers, while the solo SQLite setup stays the default and works exactly as before. Around it: speech input, voice cloning, a redesigned interface, real data portability, and integrated backup tooling. The local database schema migrates automatically on first start — back up your data directory before upgrading, as always.

### ✨ New Features

- **Team deployments.** A shared `team` profile brings PostgreSQL persistence, S3-compatible encrypted blob storage, PGVector document search, Redis coordination, and external durable job workers — with a ready-made Docker Compose stack and a Helm worker deployment. A packaged CLI migrates an existing SQLite database to PostgreSQL. Solo stays local-first on SQLite with an embedded worker; startup refuses mixed or half-configured profiles instead of silently splitting state. See the [Platform Foundation guide](https://docs.librewebui.org/PLATFORM_FOUNDATION).
- **Durable chat and media generation.** Generations now run as durable jobs with a replayable event stream: workers run concurrently, responses are recorded as they stream, Stop actually cancels the upstream provider request instead of letting it burn tokens, and accepted media jobs recover after a crash instead of vanishing. Old streams are pruned on a retention schedule.
- **Speech to text.** A microphone button in Chat transcribes voice into the composer. The browser's own speech recognition is used by default when available; otherwise recordings go to a configured provider with a speech-to-text capability, with explicit disclosure of where the audio is sent.
- **Voice cloning and natural speech playback.** LongCat AudioDiT joins as a local text-to-speech provider (a ready-to-run example server is included) with consent-based voice cloning: a reference recording plus its exact transcript, entered in Imagine → Audio. Cloned voices can be saved as encrypted, owner-bound profiles and reused for Speech playback anywhere. Playback itself got natural: phrase-aware batches generate through a look-ahead window and play in order, so speech starts before the full reply is finished.
- **Data portability.** Settings → Data Management exports a versioned per-user archive of your data and imports it into any Libre WebUI installation. Exports are verifiable and restorable — not a dump that only looks complete — and deleting a user account now sweeps every store the account touched.
- **Backup and recovery tooling.** A read-only recovery inventory reports what state exists and what would block a snapshot, and packaged maintenance commands produce signed, verifiable backups and restore them — for solo and team deployments alike. See [Recovery Readiness](https://docs.librewebui.org/RECOVERY_READINESS).

### 🔧 Improvements

- **Interface redesign.** The sidebar collapses to an icon rail with elevated New Chat and Work actions, Settings moved into a redesigned window with a searchable navigation rail, and both Chat and Work got a floating two-row composer. The whole app sits on a refreshed neutral palette with layered surfaces and an adaptive accent.
- **Security hardening.** Real-time connections authenticate with short-lived one-use tickets instead of query-string tokens, AES-GCM decryption enforces explicit authentication-tag lengths, the runtime Docker image no longer carries build-only npm tooling, replicas share coordinated rate limits, and a new Security workflow gates every push with static analysis.
- **Health probes.** Dependency-aware liveness and readiness endpoints report the actual state of the database, storage, and coordination backends, so orchestrators restart the right thing.
- **Capability contracts.** Every provider capability is now inventoried in a generated, test-enforced contract: schema, handler, client, UI action, documentation, and tests must agree before a capability counts as shipped.
- **Private deployments upgrade deliberately.** The app container is excluded from unattended replacement; upgrades are digest-pinned and manual, taken from a verified recovery point.
- **Notes are readable first.** Existing notes open in a read-only preview instead of the editor, and Markdown tables render as real tables across notes and chat instead of raw pipe-delimited text.
- **Helm grew up with the platform.** The chart validates its values against a published schema, deploys the external durable worker for team mode, and supports suspending a deployment by scaling it to zero.
- **TypeScript 7.** The whole project moved to the new toolchain.

### 🐛 Bug Fixes

- **Discovered OpenAI-compatible models failed at request time.** Model discovery accepted API roots while Chat sent them as complete operation URLs, so every discovered model 404ed unhelpfully. Standard roots are now composed with the correct path, custom operation URLs stay exact, and explicit plugin targets skip Ollama metadata probes.
- **Settings survived malformed provider data.** Image model and configuration discovery is awaited before responses serialize, and malformed model or plugin payloads are treated as empty collections instead of breaking the Settings page.
- **Speech playback no longer stalls on autoplay policies.** Audio output is unlocked before synthesis starts, so the first spoken reply plays instead of waiting for another click.

### 📚 Documentation

- **Six new guides**: [Platform Foundation](https://docs.librewebui.org/PLATFORM_FOUNDATION), [Data Portability](https://docs.librewebui.org/DATA_PORTABILITY), [Speech to Text](https://docs.librewebui.org/SPEECH_TO_TEXT), [Recovery Readiness](https://docs.librewebui.org/RECOVERY_READINESS), [LongCat AudioDiT](https://docs.librewebui.org/LONGCAT_AUDIODIT), and the generated [Capability Contracts](https://docs.librewebui.org/CAPABILITY_CONTRACTS) inventory.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.21.3</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.21.3</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.21.3</guid>
      <pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Documents attached to chats are finally manageable: see what is in a conversation's context, remove what should not be there, and delete collections with real feedback. Model pulls also stop pretending to succeed when they failed, and reasoning models no longer leak their deliberation into chat titles.

### ✨ New Features

- **Chat context documents are now visible and removable.** The docs chip above the message box opens a panel listing every document in the conversation's context — the chat's own uploads plus standing documents that join every chat — each with its size, scope, and a remove control. Settings → Documents gained the same power: an always-visible document library with per-document delete and collection assignment. All new interface strings ship in all 25 languages.

### 🔧 Improvements

- **Collection management got honest feedback.** Deleting a collection now uses an in-app confirmation instead of the browser dialog, which some environments silently suppress, and create, delete, and assignment failures surface as toasts instead of doing nothing. The assignment dropdown also reflects a document's saved collection now — the list API previously omitted it.
- **Complete social preview metadata.** The app shell now ships full Open Graph and social card tags, so shared links to a deployed instance preview richly everywhere.

### 🐛 Bug Fixes

- **Failed model pulls no longer report success.** Ollama reports pull failures as an error line inside a successful-looking stream, and the backend treated any stream end as completion — so a typo'd model name showed "pulled successfully" while installing nothing. Pull errors now surface with Ollama's real reason, and an interrupted download is reported as interrupted instead of complete.
- **Chat titles no longer leak model thinking.** Reasoning models could turn every session title into "The user wants a very short, ..." — their deliberation instead of a title. The title prompt now forbids thinking out loud, and the sanitizer strips tagged think blocks and rejects reasoning-shaped output, falling back to the message preview.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.21.2</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.21.2</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.21.2</guid>
      <pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[The important fix: Work tasks on Ollama models broke with a 400 on every message after the first one that used tools; 0.21.2 repairs that, so upgrade if you use Work with local models. Alongside it, the Git tab in Work grew into a real diff manager, and this is the first Libre WebUI release carrying code from outside contributors.

### ✨ New Features

- **An IDE-grade diff manager in Work's Git tab.** Opening the tab now shows every changed file as a rendered diff: line numbers, per-file and total +/− counts, colored status letters, a filename filter, and dividers for skipped unchanged regions. Folded context in the turn diff expands in place, and untracked files display as fully added instead of hiding until staged.

### 🔧 Improvements

- **The desktop app moved to its own repository.** This repo no longer carries the Electron shell, its build tooling, or 149 packages of its dependency tree. Releases here dispatch the [desktop repository](https://github.com/libre-webui/libre-webui-desktop), which builds the installers and uploads them onto the same GitHub release, so download links and the Homebrew cask are unchanged.
- **End-to-end tests for pinned folders and chat drag-and-drop.** Sidebar foldering now has real browser coverage, including drag-and-drop moves. (#194, Rohit Babu)

### 🐛 Bug Fixes

- **Work with Ollama failed with a 400 on the second message.** Replaying the first turn's tool calls sent their arguments as JSON strings, the shape every OpenAI-compatible provider expects, but Ollama's native API requires objects and rejected the request. The Ollama transport now converts arguments at the protocol boundary. Streamed error responses are also read and parsed now, so an Ollama failure surfaces its real reason instead of "Request failed with status code 400".
- **Chat toasts now speak your language.** A batch of hardcoded English toast messages went through translations instead. (#192, Rohit Babu)
- **The app shell's social metadata caught up with the product.** Stale page description replaced and Open Graph tags added, so links to a deployed instance preview correctly.

### 📚 Documentation

- **Reverse-proxy WebSocket guidance.** Why chat streams fail behind nginx or Caddy and the exact upgrade, origin, and timeout settings that fix it, verified against the source. (#195, ColumbusLabs)
- **The desktop app guide is now user-facing.** Install per platform, approve the ad-hoc-signed macOS build, and connect to a local or remote server; build-from-source instructions left with the code.

### 🙏 Acknowledgements

First release with outside contributions. Thank you [Rohit Babu](https://github.com/BabuBahir) for the toast i18n fix and the Playwright e2e suite, and [ColumbusLabs](https://github.com/ColumbusLabs) for the reverse-proxy WebSocket documentation. Both are in [CONTRIBUTORS.md](CONTRIBUTORS.md) now.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.21.1</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.21.1</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.21.1</guid>
      <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[A small patch that matters if you start Libre WebUI with `npx`: deep links no longer fail, so the app actually loads past the home screen. Upgrading is safe in place; nothing else changed behavior.

### 🔧 Improvements

- **A one-time note on first start.** The very first backend boot prints a single line asking for a GitHub star if the project is useful. It never repeats (the flag persists in the local database), and nothing is transmitted anywhere.

### 🐛 Bug Fixes

- **`npx libre-webui` returned 500 on every page except the home screen.** npx runs the package from `~/.npm/_npx`, and the SPA fallback passed an absolute path containing that dot-directory to `sendFile`, which rejects dot-segments by design. Deep links — including the automatic redirect to `/login` — failed on every npx install. The fallback now resolves `index.html` against the frontend root, and a packaging test boots the packed tarball from a dot-directory and asserts deep links serve the app. Global (`npm i -g`), Docker, and desktop installs were never affected.
- **Search URL normalization no longer uses a backtracking regex.** The admin-supplied SearXNG URL had its trailing slashes stripped with an end-anchored regex that backtracks polynomially on a long run of slashes (flagged by CodeQL); it is now a simple character scan.

### 📚 Documentation

- **CONTRIBUTING.md.** Setup, project layout, PR expectations (25-locale key parity, license headers), and where to start — paired with a first set of `good first issue` tickets.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.21.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.21.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.21.0</guid>
      <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Libre WebUI 0.21.0 adds self-hosted web search, repairs document retrieval (RAG) so every document in scope is actually used, and puts each dual-use capability behind an explicit administrator access control. Chat picks up long-requested quality of life: pinned chats, drag-and-drop foldering, message avatars, and a sources panel that shows exactly what fed each reply.

Upgrading notes: database migrations (the `pinned` session column and the new settings) run automatically at startup, and every new capability ships off or admins-only. Two defaults changed deliberately: **the Agents section (Libre Claw and agent CLI models) is now disabled until an administrator enables it** in User Management — or pins it with `AGENT_CLI_MODELS_ENABLED=true`, which is now tri-state (unset defers to the toggle) — and **the private deployment stack now requires `SEARXNG_SECRET` in `.env`** for its bundled search service.

### ✨ New Features

- **Self-hosted web search through SearXNG.** Administrators configure the engine in Settings > Search (URL, enable, live connection test, results per search 1-10, safe search). Chat gains a composer globe: results are injected as context before generation, so every model benefits — including small local models without tool calling — and replies show numbered source chips. Work tasks with network access gain a `web_search` tool whose result count is capped by the admin ceiling. The private deploy stack bundles an internal-only SearXNG service, and `SEARXNG_URL` pre-fills the endpoint.
- **Sources and documents panel.** Conversations show their evidence: every web source the replies drew on and every document retrieval used, plus the documents attached to the chat. A flat right rail on wide screens, a bottom sheet behind a compact trigger on smaller ones; per-message source chips persist across reloads.
- **Pinned chats and a session context menu.** Every sidebar chat gets a "..." menu — open in new tab, rename, pin, move to folder, archive, delete. Pinned chats sit in a Pinned group at the top and survive reloads.
- **Drag and drop chats into folders.** Drag a chat onto a folder header to file it, or onto a date-group label to take it back out.
- **Message avatars in Chat.** Assistant replies carry the Libre mark (or the persona's avatar); user messages show the account avatar — matching the Work conversation.
- **Welcome-screen parity.** The first-message composer gains the web search toggle and document attach (PDF/TXT/MD), so search and retrieval work from the very first message of a new chat.
- **Access controls for model downloads, web search, and agents.** User Management gains three cards beside Work access: Model downloads (open Ollama pulls and the Hugging Face browser to all users; administrators always can), Web search (same shape), and Agents (enable the Agents section, off by default). Each is a persisted mode enforced server-side on every request path and failing closed to admins-only.

### 🔧 Improvements

- Work policy editing rejects garbage numeric input instead of silently clearing limits, stores CPU limits normalized, anchors policy image references to a registry charset so nothing flag-shaped can reach the container runtime, bounds memory (6m-1024g) and workspace (up to 16Ti) magnitudes, and no longer rounds sub-minute idle timeouts in the edit form.
- Work access changes reach live sessions without a re-login: the interface re-checks on window focus and when a Work call is rejected.
- The System page Work panel shows its error with a retry instead of disappearing, reports zero terminal sessions as 0, and open clients converge after an idle-stopped preview.
- The Work task-actions menu renders above the workspace panes instead of hiding behind them.
- The Work policy picker refreshes when returning to the landing view and clears stale selections.
- Cleared every React set-state-in-effect lint warning; `npm run lint` is silent again.

### 🐛 Bug Fixes

- **Document retrieval (RAG) repaired across all chat paths.** The chat WebSocket path now honors attached knowledge collections exactly like the REST API; user-scoped uploads join every chat's searchable scope; documents whose chunks were never embedded surface through keyword scoring instead of staying permanently invisible (the "only my first document is used" failure); and keyword search takes over when nothing clears the similarity threshold.
- **Work agents keep their tool history across runs.** Chat-completions providers now persist tool calls for cross-run replay, so a follow-up run sees what was already built instead of re-reading every file; reasoning-only rounds are nudged back to work instead of silently ending the run; and the empty-response placeholder no longer re-enters model context.
- Added 68 translation keys that the interface referenced but no locale defined — command palette, tab strip, Work Git panel, model selector states, and the host workspace form — with real translations in all 25 languages.

### 🔒 Security & Dependencies

- The bundled SearXNG service is internal-only (never published to the host), runs with dropped capabilities and no-new-privileges, and search queries execute server-side with bounded result text and http(s)-only result URLs.
- Individual model pulls moved from hard-coded admin-only to a fail-closed persisted mode; every other model lifecycle operation remains strictly admin-only.

### 📚 Documentation

- New Web Search guide: setup with the bundled stack or any SearXNG instance, privacy and scope notes, troubleshooting.
- Agent CLI documentation updated for the disabled-by-default toggle and the tri-state `AGENT_CLI_MODELS_ENABLED`.
- Private deployment guide covers the SearXNG service and `SEARXNG_SECRET`; the environment reference gains `SEARXNG_URL`.]]></description>
      <category>Release</category>
    </item>
    <item>
      <title>v0.20.0</title>
      <link>https://github.com/libre-webui/libre-webui/releases/tag/v0.20.0</link>
      <guid isPermaLink="true">https://github.com/libre-webui/libre-webui/releases/tag/v0.20.0</guid>
      <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[Libre WebUI 0.20.0 introduces a major expansion of the Work sandbox system, headlined by an experimental Kubernetes runtime backend, named runtime policies, and idle-stop for unwatched sandboxes. This release also strengthens deployment security with Docker socket proxy isolation, adds an admin overview panel for monitoring all sandboxes, and allows per-user access control behind an admin setting.

Upgrading is safe in place: database migrations (the `work_policies` table, the `policy_id` task column, and the access-mode setting) run automatically at startup, every new capability is off or admins-only by default, and the per-task policy fingerprint is byte-compatible with the previous global fingerprint, so existing sandboxes are not recreated by the upgrade.

### ✨ New Features

- **Named runtime policies.** Admins can define named presets (image, memory/CPU/PID limits, workspace size, idle timeout, network default) from the User Management page and users pick one at task creation on the Work landing page. Policies are managed through `GET/POST/PUT/DELETE /api/work/policies` (reads open to Work users for the picker, mutations admin-only). Empty policy fields inherit the global runtime config, and the hardening profile (non-root, read-only rootfs, dropped capabilities, network isolation) is deliberately not a policy field, so a policy can never weaken the sandbox. Deleting a policy clears task references so those tasks fall back to global defaults on next recreation, and the per-task fingerprint means changing a policy recreates exactly the sandboxes running under it.
- **Idle-stop for unwatched sandboxes.** A new `WORK_RUNTIME_IDLE_TIMEOUT_MS` setting (default 0, off; also settable per policy) stops a running sandbox after a period of inactivity. Activity is a finished command, a terminal session ending, or an authorized request through the signed preview proxy. The sweep skips busy tasks (active command, attached terminal, running operation) while refreshing their clock, starts a first-seen sandbox's clock at the sighting, and stops idle previews through the real preview-stop path so admission leases release and task state updates. The workspace persists, so an idled preview simply restarts on next use. The private deployment stack now defaults this to 30 minutes.
- **Admin overview of every sandbox.** The System page gains a Work panel backed by `GET /api/work/admin/overview`: task inventory with owners across all users, live runtime state from one labeled listing, terminal session counts, preview state, admission headroom, pending recovery cleanups, orphaned containers, and the access mode, refreshing every 30 seconds. The endpoint is registered before the fail-closed gate so it stays readable exactly when administrators need it most, and per-task state degrades to "unknown" instead of failing when the runtime is unreachable.
- **Per-user access control.** Work remains admins-only by default, but a new persisted access mode (User Management page, `GET/PUT /api/work/access`) lets administrators open Work to all active users. Every check reads current database state, so mode flips or demotions take effect immediately across routes, terminal WebSockets, and in-flight runtime mutations. Host-folder workspaces remain admin-only in every mode because they bind-mount server paths.
- **Kubernetes runtime backend (experimental).** Setting `WORK_RUNTIME_BACKEND=kubernetes` runs Work sandboxes as Pods in a namespace with PVC-backed workspaces (a real per-task disk quota), on-demand Pods with the full hardening profile, exec transport for files/commands/git, and label-driven startup reconciliation. No Docker daemon or socket is involved. Configured through `WORK_K8S_NAMESPACE`, `WORK_K8S_STORAGE_CLASS`, `WORK_K8S_WORKSPACE_SIZE`, `WORK_K8S_POD_READY_TIMEOUT_MS`, and `WORK_K8S_POD_GONE_TIMEOUT_MS`; verified end to end on a kind cluster in CI under the exact namespace-scoped RBAC the Helm chart grants.
- **Terminal and preview on Kubernetes.** Interactive terminals ride the exec subresource as a TTY WebSocket with resize support. Preview targets the sandbox Pod IP, with the driver reporting a full endpoint (host + port) and the signed preview proxy accepting a per-task upstream host.
- **Work sandboxes via Helm.** The Helm chart supports `work.enabled=true` to switch the backend to the Kubernetes runtime, creating the sandbox namespace, a namespace-scoped Role/RoleBinding, and NetworkPolicies (default-deny, ingress from the backend on the preview port, egress for networked sandboxes minus private and cloud-metadata ranges).
- **Socket-isolated deployment.** Work no longer requires the raw Docker socket in the app container. Terminal and diagnostics speak the Engine API over a plain-HTTP `tcp:// DOCKER_HOST`, allowing a filtered socket proxy to hold the socket. Ships `docker-compose.socket-proxy.yml` with only the API sections Work uses enabled.
- **Startup container reconciliation.** Startup recovery now asks Docker once which managed containers exist and acts only on those: running containers of known tasks are stopped, exited ones are left alone, and labeled containers whose task row is gone are force-removed. Boot cost follows what is actually running instead of the task count.
- **Wider Turnstile, login footer links, npx @latest.** The verification widget takes the width of its block instead of a fixed 300px card. The login page's left panel links the website, docs, and kroonen.ai. Install commands now say `npx libre-webui@latest` so a cached older version is never started.

### 🔧 Improvements

- **Runtime driver seam for pluggable backends.** Docker CLI calls, Engine API terminal transport, and resource ownership verification move behind a `WorkRuntimeDriver` interface with `DockerWorkRuntimeDriver` as the default implementation. The runtime service retains all policy decisions (admission, leases, lifecycle locks, recovery bookkeeping, budgets) with zero behavior change.

### 🐛 Bug Fixes

- **Runtime driver split follow-ups.** Armed the Kubernetes exec timeout before WebSocket connects, gave the Kubernetes exec failure path its own `WORK_COMMAND_FAILED` code, retry the empty-inventory startup sweep for a bounded window (5 min) for late-starting socket proxies, report orphaned workspace PVCs during reconciliation, clear the preview proxy's per-task upstream host on stop/removal, accept Docker's two-letter memory suffixes in Kubernetes quantity translation, and block 100.64.0.0/10 by default in sandbox egress policy.
- **Over-long proxy bridge name.** The custom bridge name `lwui-dockerproxy` exceeded Linux's 15-character interface name limit, causing `docker compose up` to fail. The name was cosmetic and is now auto-assigned by Docker.
- **E2e probe output retrieval.** `kubectl run --rm -i` could miss the output of fast wget commands. The probe now creates the pod, polls for a terminal phase, reads `kubectl logs`, then deletes — deterministic on any runner.

### 🔒 Security & Dependencies

- Remediated npm security advisories for nanoid.
- Added `@kubernetes/client-node` for the Kubernetes runtime backend; it is loaded lazily so Docker-backed deployments never pay for it at startup.
- Sandbox egress NetworkPolicies now also block `100.64.0.0/10` by default, covering managed clusters that use the CGNAT range for pod and service networks.

### 📚 Documentation

- Documented the idle-stop default for the private stack.
- Added socket-proxy Work override guidance for the private deployment stack, including a new `docker-compose.work-proxy.yml` overlay that puts a filtered socket proxy on an internal-only network.
- Added a planning document for the Kubernetes runtime driver.]]></description>
      <category>Release</category>
    </item>
  </channel>
</rss>