Omarchy, Plasma, GNOME and macOS all publish colours the user picked on purpose, so the dashboard offers the desktop as a theme of its own and repaints every window when it changes, and the admin dashboards it embeds stop wearing their own greys inside lerd's frame. The Debug window learned logs, exceptions and the messages a site sends that are not mail, each declared in the store against the package that owns it. Worktrees pick their own database from their migrations, and the store learned to change shape without breaking a binary already installed.
A desktop already says which colours its user wants, so the dashboard reads them rather than asking. The desktop appears in the theme picker as one entry named after what it is wearing, taking the place of the built-in theme that imitated it, and every open window repaints when the desktop changes. A theme chosen on purpose is never overridden. #1864 #1924 #1940 #2042
A banner suggests the desktop's theme to an install that never chose one, and the answer, use it or keep, is kept in the config, so the desktop app and every browser agree and nobody is asked twice.
pgAdmin, Kafbat UI and RedisInsight are asked for their own dark design and then have their greys laid over lerd's. phpMyAdmin, Mongo Express and RabbitMQ have none, so their stylesheets are turned around. Mailpit wears the accent through Bootstrap's own variables, and each one is handed the dashboard's language.
Breeze draws a focused window's header in its own tone, so next to every other KDE window the dashboard looked unfocused. The rail and headers lift to the scheme's header colour while the window has focus and drop back when it moves away.
lerd dashboard, the launcher and the tray open it as a Chromium --app window when the desktop app is not installed, and on Hyprland and Plasma an open window is focused rather than a second one opened.
The bar already shows lerd's state through the Lerd Glance plugin, so a fresh install on Omarchy turns the tray off and adds the plugin. lerd uninstall takes it off the bar again.
A fresh install opens on a card whose steps tick themselves off from state the dashboard already reads: a first site, a running service, notifications, the desktop's theme, starting with the dashboard and idle-suspend. It hands its slot back when the last one ticks.
Dialogs take focus, keep Tab inside and hand it back on close, a Skip to content button is the first stop, toggles are switches that say whether they are on, detail tabs move with the arrow keys, and every view has a heading and a title naming what is open. Secondary text and the accent as link text reach WCAG AA on every theme, derived per theme rather than hand tuned. The same pass moved the status banner into the header as a pill, gave each worktree tab its git state the way a shell prompt shows it #1949, offers to initialise git on a site that has no repository #1988, and lets the System page register lerd with AI assistants from a switch #2016.
The Debug window's wire format has carried log, exception and message kinds since it was built, with nothing ever emitting them. Each now has a source declared in the store against the composer package that owns it, so the Go side knows no framework by name and a new reporter is a YAML file away.
ray() without Ray #1887Inside a container ray() reaches no desktop app, so the value was simply lost. The payload is taken on its way out and shown as the dump it wraps, labelled by the kind of call.
Records come from Monolog with level, channel and context, grouped by the request that wrote them, and are taken where they are written, so a line the app's handlers drop still shows.
Symfony Notifier covers Twilio, Vonage and Slack with one declaration, and Laravel notifications are reported on every channel but mail. Clicking a notification opens the lens it is about rather than whichever one the tab last showed.
The SpamAssassin backend is a store preset Mailpit finds on its own, and the templates a request rendered travel on the message as X-Lerd-View. Mailpit's page offers the preset until it is installed or dismissed.
The App logs tab opens on the newest entries and fetches older ones as you scroll up, keeping your place, so a log of hundreds of megabytes no longer takes the browser tab down.
A worktree's database used to be a question that a script or an assistant could not answer. A framework can now name its migrations folder, and a worktree set up with nobody to ask, from the MCP tool, a script or lerd worktree setup, compares it with the parent checkout and decides, then says which and why. At a terminal and in the dashboard the question is still yours. #1969
The file is gitignored, so a worktree had none while its env pointed at the same relative path. The parent's file and its write-ahead log are copied in before dependencies install.
The MCP server points worktree work at its tool rather than plain git, and add finishes setup the way the dashboard does: assets built, database wired, the definition's commands run.
A worktree created with plain git worktree add is finished by lerd worktree setup run inside it, and the flag that isolates its database stays in the untracked .lerd.local.yaml rather than the committed config (#1968).
lerd worktree add ../app-same same Database: share, since the migrations match the parent checkout's. lerd worktree add ../app-extra extra Database: clone-main, since this branch adds migrations the parent checkout lacks (1), so it gets a copy of the parent's database to run them on. lerd worktree add ../app-fewer fewer Database: empty, since the parent checkout has migrations this branch lacks (1), so its database is ahead of this code.
Definitions reach every install within a day with no version gate, so the store may only grow. This cycle gave it a way to change shape anyway: a tree per definition schema, read newest first by the binaries that understand it, and left alone by those that do not.
This binary asks for its own schema's tree first and falls back to the path every older binary reads, so a definition can be introduced to new binaries only, the way SpamAssassin was.
A restart policy systemd cannot parse is silently dropped, and a schedule it cannot parse stops the timer loading. Both are checked before the unit is written, naming the value and asking for an update.
A package names the services it points at, so a Drupal site requiring search_api_solr gets Solr ticked at setup and suggested on its Overview, with the reason. A dismissal stays with that site.
A definition declares its installer with the file it writes, so a scaffolded Drupal site is offered its site install at setup, ticked while that file is missing and gone once it exists.
A worker that needs a service, a Redis queue say, used to fail setup with a hint to start it by hand. Setup starts it first, and asks only when there is a terminal to ask on.
An admin tool can front several engines now, which is how Adminer serves MySQL, MariaDB and PostgreSQL from one preset. The RustFS console opens already logged in, on the bucket you clicked, and logs in again once its session runs out rather than leaving you at its login form.
The rest of the cycle widened what a project can be and what it can run on, each one declared in the store or detected from the project rather than taught to the binary by name.
macOS remembers a folder grant against the signature of the binary that asked, and fnm ships unsigned, so a project under Documents was asked for again after every version bump. mise is notarized, so the grant holds. Versions pinned in mise.toml and .tool-versions are read too.
unixODBC with ext-odbc and pdo_odbc ships in the images, and lerd php:odbc add registers a licensed vendor driver, checking from inside the image that it will load and naming the cause when it will not.
Mark a workspace private and, while the mode is on, its sites leave every snapshot the dashboard and the TUI receive. On Wayland it follows screen shares through PipeWire on its own. It draws nothing until enabled.
A declared service carries an X that takes it out and points the env back at the example values, and the removal is remembered so the next lerd env does not wire it back.
The fixed list covers bugs that shipped in 1.35.0 or earlier. Regressions introduced and fixed inside this cycle never reached anyone, so they are left out. The release closed on scripted passes of the test plan across the distro guests and a Mac, and the ones that cost a new user the most all sat on a first run: the first link, the first start, the first download.
lerd link reported done before the site was served #1989Linking reloads nginx and returns, and the previous generation of workers goes on serving while it drains, so the request made straight after linking answered Site Not Found. Every site change now waits for the old workers to retire, the way a domain change already did.
A database initialises its data directory on the very first start, and an interrupted one left a half written directory that every later start read as an existing database. A first start that does not finish now moves its directory aside, so the next one initialises cleanly.
The first start of a built-in service pulled its image silently, which on a slow line looks exactly like a hang. It names the image and its size first, on the CLI, the dashboard and over MCP, and fails cleanly offline.
The guard that moves a service off a contested port trusted a port already in the config, so the service failed at the bind and sat in a restart loop, which then read as the port's owner. It probes the port it would actually publish now and moves it the way it always moved a busy default.
lerd stripe:listen restart looped #2060The Stripe CLI release of September 29 started refusing a bare listen, and lerd ran the unpinned latest image, so every listener on every install went into a restart loop overnight.
The dump carried GTID state and the server's own schema, which 9.7 refuses on the way back in, so a restore reported success over an empty database.
The rewrite missed URLs escaped inside JSON and passed Secure cookies over plain http, so a shared site rendered and then fell apart at its first client-side link or login.
A network created before the host had a route left every container offline until it was rebuilt by hand. lerd notices and rebuilds the container network itself.
lerd composer pointed composer at its own home, so the auth.json a private repository needs was not where it looked.
Install restored service units from every site's .lerd.yaml, so a service removed on purpose was back after the next start. A removal is remembered now.