Commit Graph
623 Commits
Author SHA1 Message Date
Spencer Bull f99d33a8dd Merge pull request #9663 from spencerbull/fix/hermes-prompt-probe
Fix the Hermes CLI readiness probe, and tear the CLI down on uninstall
2026-09-02 15:21:45 -05:00
Spencer BullandClaude Opus 5 21470fd1ea Say how to finish a failed teardown, and record the probe's real history
A failed --remove told the user to run it again, but that advice could
never work: rm -f has usually taken the marked stub by the time the
failure is judged, and a rerun that finds nothing it owns succeeds
without touching the mise environment it was asked to finish removing.
Spell out the three commands that complete the job by hand instead.

Also correct the story the probe comment told: chat never lost
--oneshot in v0.20 -- no released Hermes defined it there. It lived at
the top level until v0.21 added chat's own, so the old probe was keyed
to a flag no release ever carried under chat, and every install read
as not ready. Recorded straight so a future hermes-desktop bump to
v0.21+, which would make the old probe pass on the desktop path alone,
cannot read as the fix.

Findings from omarchybot's review (Opus 5, with Codex at xhigh).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 09:40:44 -05:00
d3d23fddde Honor keepLoaded for services during plugin hot-reload (#9485)
* Honor keepLoaded for services during plugin hot-reload

Plugin reload destroyed every service, including omarchy.lock, which drops the ext-session-lock client while Hyprland still holds the lock and surfaces the crashed-lockscreen fallback.

* Prove keepLoaded service survival with a fixture service

A fresh lock service also reports an empty lastEventAt, so comparing it
across the rescan passed whether or not the instance survived. A fixture
keepLoaded service whose in-memory marker is set before the rescan and
read back after can only pass when the same instance is still mounted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Drop kept services whose plugin no longer declares a service

The _syncServices cleanup only asked whether the plugin was still
installed and enabled, so a kept service whose plugin dropped its
service kind or entry point kept running as a zombie until shell
restart. Apply the same eligibility checks used at creation, and hand
kept instances the refreshed manifest after a rescan.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Cover omarchy.media in keepLoaded expectations; note kept services reload on restart

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-02 12:33:44 +02:00
46cfc4ada5 Judge the CLI teardown by what is left, and match flags as definitions
Two review follow-ups. The probe counted any mention of --tui/--query in
the help as support -- Hermes already writes "With --tui:" into --dev's
description, so a release that dropped the option while keeping the
prose would still read as ready. A flag now counts only when followed by
a shape argparse prints after a definition: the usage bracket, the gap
before same-line help text, an uppercase metavar, or the line end. Not
probed by parsing a real invocation on purpose -- a release that ignores
unknown arguments would turn the probe into a live session.

And the teardown trusted its commands: a stub rm that failed aborted
Remove Hermes under set -e before any ~/.hermes handling, while mise
failures vanished into || true. --remove now attempts every step, then
judges by what is left -- the marked stub still present, or mise still
resolving the tool -- and Remove Hermes tolerates the failure until the
runtime is handled, then carries it in its exit code.

Findings from the same codex review at xhigh, verified and proven by
mutation before landing.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 01:01:13 -05:00
c462aad9ee Prove ownership before --remove touches mise
The teardown removed the Omarchy tool spec from mise unconditionally,
so removing Hermes Desktop could destroy a mise environment the user
had built against the same spec while sparing their wrapper -- the very
command the removal claims to preserve, broken behind its back. The
whole teardown now turns on the marked stub, as replacement already
does; the desktop takeover keeps its own bargain, where a second Hermes
goes whoever built it and the app still provides the command after.

Also close the probe over underscores -- _ continues a flag name just
as - does, so --tui_mode no longer answers for --tui -- and pin the
gaps review found in the tests: each flag must match on its own (either
grep could be deleted before without a failure), a foreign wrapper's
mise environment must survive --remove, and Remove Hermes must tear
down the CLI in the interrupted-install case, not only after the app's
runtime landed.

Findings from an independent codex review at xhigh, each verified
against the source and proven by mutation before landing.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-01 23:32:35 -05:00
Spencer BullandClaude 36d52254a7 Tear down the mise Hermes CLI on Remove Hermes
Remove Hermes dropped the desktop package and its ~/.hermes runtime but
never touched the mise CLI, on the assumption the install-time handoff
had already removed it. A CLI the app never superseded -- an interrupted
install, or the terminal CLI from before the app existed -- was left
stranded on PATH after uninstall.

Add a --remove mode to omarchy-install-hermes-cli that performs the same
teardown the desktop takeover already does (mise rm -g + mise uninstall,
and the marked stub), and call it from omarchy-remove-ai-hermes. The tool
spec and ownership marker stay defined in one place, so the takeover and
teardown paths cannot drift. Scoped to what Omarchy owns: a Hermes the
user installed themselves is left alone.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-01 22:51:03 -05:00
Ryan Hughes 7eca64e268 Merge pull request #8859 from tobi/feat/network-captive-portal
Show captive portal status and sign-in action in network panel
2026-09-01 23:39:43 -04:00
Spencer BullandClaude f7078b9136 Match Hermes flag probe at a boundary, cover the mise path
Review follow-up on the readiness probe. The two greps were fixed-string
substring matches, so a future release listing only --tui-theme or
--query-log while dropping the bare --tui/--query omarchy-agent passes
would read as ready -- the same false verdict inverted. Anchor both to a
flag boundary.

Add a regression case pinning that a substring-only help is rejected,
and one exercising --check through a mise-installed hermes in both
capability directions: the desktop and foreign cases only covered their
own wrappers, and the mise path is what a machine without the app runs.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-01 15:53:52 -05:00
Spencer Bull f08840d6cc Probe Hermes readiness by the flags omarchy-agent passes
Hermes v0.20 removed chat's --oneshot flag, which hermes_prompt_ready
used as its capability marker. A fully bootstrapped Hermes Desktop
install then read as not ready: --check failed forever, the default
agent flow looped back into the installer, and --now dead-ended with
"Launch Hermes Desktop once to finish installing it" on a machine
where it already had.

Probe for --tui and --query instead: the flags omarchy-agent actually
passes to seed an interactive session, rather than one that merely
shipped alongside them.
2026-09-01 14:25:37 -05:00
Spencer Bull b71dcad96e Merge pull request #7469 from omacom/hermes-agent
Add Hermes as a desktop app and a coding agent
2026-09-01 11:11:57 -05:00
Ryan HughesandClaude Fable 5 5c03dc8c09 Disable sshd entirely when no usable key is authorized
The old setup command enabled sshd before importing a key, so an aborted
run left a password-only server exposed. Skipping that machine kept the
hole Omarchy opened; close it instead by disabling sshd. Omarchy is a
desktop distro, so the console remains, and the warning explains how to
set up key-based access or deliberately re-enable password logins.

With the stakes flipped from skip to disable, "no usable key" must not
false-positive: follow an authorized_keys symlink to its key (dotfiles
setups have working key auth), and treat an unreadable file as
unverifiable rather than keyless.

Amends the unreleased 1788124236 migration in place; no released install
has run it, so every machine still gets the new behavior in one pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 18:45:05 -04:00
Ryan Hughes 3c2a24b248 Merge pull request #9255 from omacom/security/migrate-existing-sshd-hardening-v4-0-2
Harden existing key-based SSH setups
2026-08-30 18:38:00 -04:00
Ryan HughesandClaude Fable 5 986962bb64 Keep the sshd hardening migration from locking users out
Validate authorized_keys line by line with the question sshd actually
asks: ssh-keygen -lf on the whole file also fingerprints a private key
copied there by mistake, which sshd cannot use, so the migration would
have disabled the only working login path.

Tighten ~/.ssh and authorized_keys the way omarchy-setup-security-sshd
does, and back off from a group-writable home directory: StrictModes
makes sshd ignore the key either way, with the same lockout.

Complete with a notice instead of failing on conditions the migration
cannot repair (a broken or pre-Include sshd_config, an overriding admin
rule, a failed reload of a valid config), so those machines keep passwords
as they were without blocking every migration queued behind this one.
Only missing privileges stay pending, since a terminal rerun fixes that.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 18:36:26 -04:00
acrogenesis ca4f596a14 Harden existing key-based SSH setups 2026-08-30 18:07:59 -04:00
Ryan Hughes 243fe1c9d9 Shadow the git URL checker instead of thinning PATH
The missing-checker case dropped $ROOT/bin from PATH to make
omarchy-git-url-check unfindable, but installed machines carry the
packaged checker in /usr/bin, so it was always found and the test
failed on every 4.x machine. Shadow it with a stub that reports
command-not-found so the scenario holds regardless of the host.
2026-08-30 17:48:34 -04:00
Ryan Hughes bae189861f Copy the Windows VM helper before the test hides /home
The mount-boundary test tmpfs-mounts over /home before sourcing
$ROOT/bin/omarchy-windows-vm, so a checkout living under /home vanished
mid-test and set -e aborted with no output. Take a mount-safe copy of
the helper into the test tmpdir before the mounts land.
2026-08-30 17:48:34 -04:00
Ryan Hughes 71d7ac81ae Match sshd -T keywords case-insensitively when verifying hardening
OpenSSH 10.x prints configuration keywords in CamelCase in its sshd -T
dump, where 9.x printed them lowercase. The case-sensitive grep in
omarchy-setup-security-sshd therefore never matched on OpenSSH 10.x, so
the hardening drop-in was always judged ineffective and removed, leaving
password authentication enabled.
2026-08-30 15:03:06 -04:00
Ryan HughesandDavid Heinemeier Hansson df819a6f98 Close three paths from an unprivileged session to root
Apply the Omabot patch on Quattro, verify effective SSH hardening, prevent stored provisioning state from restoring the blanket input-group grant, and stop Omarchy from shipping asdcontrol authorization that belongs to the package.

Co-authored-by: David Heinemeier Hansson <david@hey.com>
2026-08-30 12:54:08 -04:00
Ryan Hughes 943d2fcbe9 Merge pull request #9002 from acrogenesis/remove-legacy-installer-privileged-files
Repair legacy paths and privileged files left by retired installers
2026-08-30 12:07:18 -04:00
Ryan Hughes 58c399de30 Revert "Drop unrelated privileged heredoc scanner"
This reverts commit 4c23077f80.
2026-08-30 11:54:31 -04:00
Ryan Hughes 15f26cbe1b Remove redundant migration command preflight 2026-08-30 11:49:54 -04:00
Ryan Hughes 4c23077f80 Drop unrelated privileged heredoc scanner 2026-08-30 11:49:50 -04:00
Ryan Hughes 40d0c9bbdf Require Quattro migrations to complete 2026-08-30 11:36:22 -04:00
Ryan Hughes 8add7b49de Repair legacy XCompose and vulnerable power paths 2026-08-30 11:36:22 -04:00
625c4a1603 Quote install-app and install-font names like install-and-launch (#7843)
* Quote install-app and install-font names like install-and-launch

* Quote the package list too, not just the display name

The display name was quoted but omarchy-pkg-add's own arguments were still interpolated into the bash -c string raw, so `omarchy install app Vim 'vim; id'` ran id. The list has to reach the helper as several words, so it cannot be quoted whole: it is split the way the unquoted expansion split it and each word is quoted on its own. Reading with -d '' keeps a newline-separated list intact instead of dropping every package after the first, which plain read -a would. install-font's package is singular and is quoted whole, and install-and-launch carried the same flaw.

Reported by acrogenesis in review of #7843.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Codex XHigh <noreply@openai.com>

* Test that install-font skips font-set when pkg-add fails

The hostile-package case was asserting the family still got set, which only held because the mock always exits 0. pacman would reject that name and the && chain would skip font-set.

* Keep the installers working when errexit is inherited

read -d '' always ends at EOF rather than on its delimiter, so it reports failure on every input. Under an inherited errexit the installers exited there and built no command at all.

Reported by Codex XHigh in review of #7843.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Codex XHigh <noreply@openai.com>

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Codex XHigh <noreply@openai.com>
2026-08-30 14:22:58 +02:00
David Heinemeier Hansson a041e9a7f3 Merge pull request #8611 from smfworks/feat/hermes-skill-symlinks
Link Omarchy agent skills into Hermes
2026-08-30 12:53:21 +02:00
David Heinemeier Hansson 2541eeee3d Merge quattro into hermes-agent
Catches the branch up on 94 commits so what lands here is reviewed against
current quattro, and so #8611 contributes its own five files rather than
dragging a partial catch-up in behind it.
2026-08-30 11:58:37 +02:00
e3b566bae8 Remove the last first-run sudoers grant the installer wrote
install/post-install/first-run-mode.sh shipped on quattro between 53e26115 and 75cb4f71, and its final body writes `Cmnd_Alias FIRST_RUN_CLEANUP = /usr/bin/rm -f /etc/sudoers.d/first-run, /bin/rm -f /etc/sudoers.d/first-run`. The predicate's case listed only the two `/bin/rm` spellings, so that line fell through to the user-spec test, failed it, and the whole file read as hand-written. The migration then left it alone and wrote its machine marker, which is permanent: on an offline install from that window the account keeps passwordless `/usr/bin/systemctl` for good, and nothing looks at the file again.

Adding the string is the whole fix. The test now carries all nine bodies the installer wrote across both locations rather than the eight from install/preflight.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Codex XHigh <codex@openai.com>
2026-08-30 09:06:22 +02:00
David Heinemeier HanssonandClaude Opus 5 96404be37b Catch a privileged heredoc redirected with >|
`>|` is a plain redirect with noclobber overridden, not a redirect followed by a pipe. command_destinations detached `>` from its target before looking at the bar, so the target read as `|` and the privileged path behind it was never examined: `cat <<EOF >| /etc/udev/rules.d/99-x.rules` with `$HOME` in the body produced no finding at all, while the same write through `>` produced one.

Normalizing `>|` to `>` alongside the existing `>>` handling closes it. The fixture fails without the normalization.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 08:58:12 +02:00
acrogenesis 8e41961c7d Close privileged cleanup review gaps 2026-08-29 23:55:42 -06:00
acrogenesis f91d2e5453 Restore strict migration ordering 2026-08-29 22:42:33 -06:00
acrogenesis 4d697a063c Harden privileged cleanup review fixes 2026-08-29 21:08:33 -06:00
acrogenesis 4996941513 Address privileged cleanup review findings 2026-08-29 20:03:46 -06:00
acrogenesis 7ed761fb31 Stop the heredoc check writing its own exemption
The failure advice printed a ready-to-paste annotation with the scan's
verdict already filled in, so the shortest way past the check was to copy
back what it had just concluded. That is worst exactly where the scan is
weakest: a path it cannot follow through a variable reads as an ordinary
value, and the annotation it offers for that case is paths=none.

Print the annotation with the path list left blank and say why the author
has to fill it in. The scan's own reading stays in the report above it, so
nothing diagnostic is lost.
2026-08-29 19:23:02 -06:00
acrogenesis 80e7c25b37 Fail the sudoers cleanup when it cannot elevate to look
Running the migration on a real machine with no cached sudo credentials
printed sudo's "a terminal is required to read the password" and still
exited 0. bin/omarchy-migrate writes the completion marker on a zero exit,
so the cleanup would have been recorded as done on every install that runs
migrations without a terminal, and never tried again.

Probe for elevation before the combined existence check and exit non-zero
when it fails, so the marker stays unwritten and the next run retries. The
probe is skipped when the directory is readable as-is, which is the case
when migrations run as root.
2026-08-29 19:23:02 -06:00
acrogenesis 394c1371c9 Model what each parser does with an empty and a dangling directive
Review of the previous commits turned up four places where the predicates
and their tests disagreed with the tools they are modelling, each checked
against udevadm verify, systemd-analyze verify and visudo -cf rather than
against reading of the sources.

An empty ExecStop= resets the list, so a unit an administrator neutralised
that way runs nothing at shutdown and is no longer ours to remove; the
predicate now tracks the last state instead of returning on the first home
path it sees. A file whose last line ends in a backslash still carries a
live directive for systemd, so the pending logical line is emitted at EOF;
udev ignores such a line and sudo rejects the file outright, so this costs
those two nothing. The scanner's taint pass now reads += appends, which its
own comment already promised: the value of an append is no use, but a name
that reaches a user root through one has to be judged on it.

Two regression guards passed against the implementations they were written
for. The udev continuation fixture put the whole RUN+= below the comment, so
it matched whether or not the pending half was carried across; the split now
falls inside the RUN+= value. The sudoers one kept its file on the strength
of a spec above the comment, so it could not fail either; the hand-written
spec now sits below. Both fail against a mutant that discards the pending
line. The comment above the second also claimed a continued comment stays a
comment, which visudo contradicts.
2026-08-29 19:23:02 -06:00
acrogenesis d593847728 Fail the suite on privileged writes through unquoted heredocs
An installer that writes a root-owned file through a heredoc with an
unquoted delimiter (<<EOF rather than <<'EOF') has the installing user's
shell expand the body first, so a user-controlled value is baked in as a
literal. Send that into /etc and root later reads or executes a path the
unprivileged user picked: a udev rule carrying
$HOME/.local/share/omarchy/bin/... resolves through a symlink that user
owns, so replacing the symlink gets their code run as root.

Add the static check. A heredoc is flagged when its delimiter is
unquoted, its body contains an install-time expansion (escaped \$VAR does
not count, since that is left for a root daemon to expand at runtime),
and its output reaches /etc, /usr, /opt, /srv, /boot or /var/lib via sudo
tee, sudo dd, a redirect, or an install/cp/mv of the generated scratch
file. Destinations written as variables are resolved from the file's own
assignments.

Sites that genuinely need install-time expansion declare it inline:

  # omarchy:heredoc-expands paths=none -- $servers is a validated IP list

paths= is machine-checked against the expansions the scanner finds to be
path-shaped, so this cannot become a rubber stamp: adding a $HOME/... to
an already-annotated heredoc makes the declaration false and trips the
check again. Path expansions anchored under a root-owned prefix, as in
"/etc/systemd/system/$unit", are correctly not path-shaped.

Annotate the sites the scan reports, each of which expands a scalar: DNS
addresses in omarchy-dns, a literal PAM line in
omarchy-setup-security-fingerprint, kernel cmdline parameters and
usernames in omarchy-upgrade-to-quattro. omarchy-provision-owner expanded
a unit name that was already a constant, so its delimiter is now quoted
and the name hardcoded; the generated unit file is byte-identical.
omarchy-windows-vm declares paths=storage,shared, the only site that
interpolates a user-chosen path.

Fixtures prove non-vacuity in both directions: the write routes other
than a pipe into sudo tee, the shapes that must stay quiet, udev rules
and a shutdown unit taken verbatim from this repository's history, and
the rubber-stamp case where a paths=none annotation on a baked $HOME path
still fails.
2026-08-29 19:23:02 -06:00
acrogenesis 96ed473ce1 Remove privileged files left behind by retired Omarchy installers
Three installers that no longer exist each left a root-owned file on
disk, and nothing in Omarchy has ever removed any of them.

/etc/sudoers.d/first-run granted the installing account passwordless
sudo for the rest of the first boot, unrestricted /usr/bin/systemctl
included from 2025-10-14 on. omarchy-first-run clears its first-run.mode
guard before eight set -e steps and only deletes the grant after them,
so any failure in between strands it with nothing left to retry.

/etc/sudoers.d/tsui named whatever $(which tsui) resolved to for the
installing user, normally a binary under their own home that the vendor
script had just written without sudo.

/etc/systemd/system/omarchy-plymouth-shutdown.service ran an ExecStop
under the installing user's home as uid 0 on every shutdown.

Each file is judged against what the installer that wrote it actually
produced. The first-run grant was rewritten eight times and only the
last four carry both Cmnd_Alias lines, so rather than key on those, every
active line must be one the installer emitted and one of them must be
its own self-cleanup. The shutdown unit is disabled but never stopped:
stopping it is what would run the ExecStop being taken away.

Generalize the migrations.md exception, which framed itself around pre-4
layout transitions and so did not cover installers retired on their own.
2026-08-29 19:22:44 -06:00
acrogenesis cd519283fe Remove Omarchy 3 power udev rules that run a command out of a user home
Omarchy 3 wrote 99-power-profile.rules and 99-wifi-powersave.rules with
an unquoted heredoc, baking the installing user's home into a rule udev
runs as root. That path resolves through ~/.local/share/omarchy, a
symlink the unprivileged user owns, so replacing it and provoking a
power_supply event runs their code as root. HEAD points the rules at
/usr/bin under new names, but the one-shot cleanup for the old
filenames was dropped, leaving the file on every install that came up
through the 3.x line.

Remove a legacy file only when an active RUN+= really does run that
filename's binary out of a home directory, so a rule of the same name a
user wrote themselves stays, comments and all.
2026-08-29 19:22:44 -06:00
Ryan Hughes 158e8cfb3a Merge pull request #8419 from AFOliveira/security/windows-vm-mount-boundary
[codex] Secure Windows VM host mounts
2026-08-29 19:31:39 -04:00
Ryan Hughes e229927671 Merge pull request #8934 from ErikMelton/security/plymouth-publication-race
Secure Plymouth and SDDM asset publication
2026-08-29 18:45:37 -04:00
Ryan Hughes 70e79c40ae Harden Plymouth and SDDM reset publication 2026-08-29 18:19:51 -04:00
Ryan Hughes c720f0b981 Merge pull request #8951 from omacom/cups-browsed-temporarily-removed
Temporarily remove automatic printer discovery
2026-08-29 15:38:23 -04:00
Michael Gannotti e482977f09 Add a Hermes skills migration test and list Antigravity in file-layout
The provision-user suite never ran the one-shot migration. Cover default-home
links, a pre-existing profile, idempotency, and a missing skill source.
Document ~/.gemini/config/skills and stop wrapping that bullet.
2026-08-29 15:31:29 -04:00
Ryan Hughes 2002fb35ed Test installed CUPS state directly 2026-08-29 15:27:16 -04:00
James (SMF Works) c64e03d9c5 Link Omarchy agent skills into Hermes skill directories
Hermes was missing from the provision-user symlink list that already
covers Claude, Codex, Pi, Antigravity, and ~/.agents. Add ~/.hermes/skills
plus existing ~/.hermes/profiles/*/skills. Migration for current installs.
2026-08-29 15:26:33 -04:00
David Heinemeier HanssonandClaude Opus 5 e47784be11 Name the dev-link authorization when it is the thing that failed
Validating /etc/omarchy.conf walks its parent chain to /, and that walk leaves
its own subject behind in the global failure_context. The comparison that
follows -- the one deciding whether the authorization actually names this
checkout -- sets no context of its own, so an unauthorized development tree
refused with:

  refusing to publish: directory / (must be root-owned and not group- or
  world-writable) failed validation

naming a directory that had just passed, and pointing the reader at a
filesystem problem that is not there. Seen on a worker VM running an
unauthorized checkout, where / is 0555 root-owned.

The hint line underneath was already right, which is what kept this from being
worse. Restore the context before the comparison so the first line agrees with
it, and assert both halves: that the refusal names the authorization, and that
it does not blame the root directory.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0115LngksSpXLD9NSXBEP3ki
2026-08-29 21:03:02 +02:00
Ryan Hughes 96d5682460 Fix cups-browsed removal migration 2026-08-29 14:58:33 -04:00
Ryan Hughes bb5b178e5f Remove unused cups-browsed install override 2026-08-29 14:24:05 -04:00
Erik Melton aac1b009e4 Cover non-regular Plymouth logo descriptors 2026-08-29 17:47:42 +02:00