Skip to content

Sync upstream quattro through #18544 - #130

Merged
mark-groves merged 100 commits into
quattrofrom
cursor/upstream-changes-pr-e655
Nov 12, 2026
Merged

mark-groves merged 100 commits into
quattrofrom
cursor/upstream-changes-pr-e655

Conversation

@cursor

@cursor cursor Bot commented Nov 11, 2026

Copy link
Copy Markdown

What changes

Upstream quattro moved past omacom#18378 (f428bb4fe), which is what #129 merged. Ninety-nine commits replayed onto current quattro, through e6554e02d (Acer Aspire 16 AI speakers, omacom#18544). No merge commits. One follow-up commit repairs the agents-panel replay. Fork delta vs e6554e02d is the same 256 paths as quattro vs f428bb4fe. On the 194 paths upstream did not touch, the added and removed lines are unchanged. Face, Grok Bot, Cursor, linux / linux-headers, and the dropped translation-sync workflow stay.

Three conflicts. The dock pin keeps Files and takes Chrome. The theme setup drops Yaru and keeps the Chrome and Chromium first-run preferences. The agents panel keeps the fork's hidden-provider list (a paused collector with nothing to show stays off the page, and a unified pool is not drawn twice) and takes the tailnet controls. A replay of that panel had left a second share action, which would not parse, and had treated a tailnet model's error as a local log link. The follow-up commit removes the extra action and limits the log link to this machine.

Verification

  • Cherry-pick of the 99 non-merge commits from 56a103fef through e6554e02d applied onto quattro c08496a20. git diff --name-only of HEAD vs upstream e6554e02d is the same 256 paths as quattro vs f428bb4fe. On the 194 paths upstream did not touch, the added and removed line counts match. The other 62 paths are the fork delta merged with upstream. A three-way merge of those 62 against f428bb4fe matches HEAD except the agents panel, whose four conflicts are the hidden-provider list versus the tailnet controls, resolved as above. linux and linux-headers are still in the other-packages list. Face, Grok Bot, and Cursor are still in the menu. The translation-sync workflow is still absent. All 203 i18n JSON catalogs parse.
  • bash test/shell.d/agents-panel-test.sh passed (95), including sharing, SSH-before-share, hidden ids in the saved order, and local-model progress.
  • bash test/shell.d/default-agent-test.sh passed (48), including --prefer-local opening the running local model and the usual agent otherwise.
  • bash test/shell.d/default-apps-test.sh passed (20), including an editor choice reaching every app, GLib's reading of mimeapps.list, and new installs opening text files in the default editor.
  • bash test/shell.d/menu-test.sh passed (110), including the Omarchy-font glyphs the menu draws.
  • Could not boot a Surface Laptop 8, a Surface Pro 11, an HP OmniBook X 14, or an Acer Aspire 16 AI, and this checkout has no Omarchy session, so the panel, Chrome, Files, and the new hardware were not checked on a machine. No other sync was open.

Screenshots

No visible change: this checkout has no Omarchy session, so nothing was drawn here. Chrome as the default browser, the tailnet models in the agents panel, the Agent menu, and Adwaita icons are visible on a machine; the tests above cover the behavior that can run here.

Open in Web View Automation 

dhh and others added 30 commits November 11, 2026 23:03
Chrome ignores --load-extension, so Copy URL, Download Video and WhatsApp
Slim never loaded there. Ship them as CRXs that Chrome's policy installs
from a local updates.xml, under Chrome-only keys so Chromium keeps the ids
its shortcuts are bound to. Machines that already have Chrome get the
policy through a migration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Skip the first-run dialog with --no-first-run, seed Chrome's initial
preferences as Chromium's are, and turn off metrics reporting, the ad
privacy prompts and promotional tabs by policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chrome replaces Chromium in the base packages, link handling, the dock and
the web app fallback, and installs from OPR rather than the AUR. Chromium
becomes an optional browser in Install and Remove. Existing installs keep
the browser they have.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mark Groves <mark-groves@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mark Groves <mark-groves@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mark Groves <mark-groves@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mark Groves <mark-groves@users.noreply.github.com>
While a model on another machine of the tailnet runs, its line now reads
MoE or Dense, its decode and prefill TPS there and its context, from the
survey, in place of a memory meter for a machine the user doesn't run.
Loading and stopping still show their progress bar.

Share only shows on a local model once it's running, and stays on a
shared one so sharing can always stop. It reads Shared while shared, and
Pair, Share and Shared are drawn in the icons' color, not dim or accent.

The survey's architecture comes from omarchy-local-ai's listing
(worktree-tailnet-sharing, "Publish each shared model's architecture").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CY6YBpPZd18VT3hSmgLTRC
A recording with a muted or wrong input looks the same as a good one until it is played back. While recording, a glow behind the ring now follows the microphone the recorder takes in, found through the recorder's own capture stream, so a still ring while talking means the take hears nothing.
Setup > Defaults > Agent becomes Setup > Agent > Harness, and Setup > Agent >
AGENTS.md opens ~/.agents/AGENTS.md after linking it into every harness that
keeps its own global instructions file (omarchy agent instructions). Picking
a default agent and provisioning a user link it too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent sits under Apps with Make something (theme, plugin, app), Harness and
AGENTS.md. The starter prompts move into omarchy-agent-make, shared by the
menu and the agents panel's tiles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mark Groves <mark-groves@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A blank ~/.agents/AGENTS.md gets one comment saying what it's for, and still
counts as blank so an existing harness file is adopted over it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An instructions link into a dotfiles checkout was replaced without being
imported or backed up. It now counts as the file it points at: the shared
file when there is none yet, and kept as .bak when it differs. A dangling
link is left alone.

Added Grok accounts never saw the shared rules. AGENTS.md joins Grok's
shared files, a migration links it into existing account homes, and Claude,
Codex and Grok are linked in their primary homes rather than whichever
account the environment selects.

A backup notice that can't be shown no longer aborts the run or keeps the
editor from opening, and each backup is printed too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stable image CI boots has libarchive 3.8.10, whose streaming zip reader
fails on the CRX payloads with "bsdtar: (null)". Read from the file, bsdtar
finds the zip through its central directory and skips the CRX header on its
own, so the header arithmetic goes too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Installs that kept Chromium and set Firefox or Zen as their default had web
apps fall back to Chrome, which they don't have. Try Chrome, then Chromium.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hosts in Chrome's profile are copies of the old templates, so they
rejected the CRXs' ids. The migration that installs the policy now
rewrites them too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
User defaults ship in config/, which omarchy-settings copies into
/etc/skel, rather than being copied in by the user install. Chrome's file
is a copy of Chromium's, and the test keeps the two from drifting apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Snapdragon video setup and the feature helper stopped at the first
flags file they couldn't write, so a read-only Chromium file left Chrome
without its settings. Both now try each file and fail at the end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
omarchy-provision-user calls xdg-user-dirs-update, and the acceptance
test reads the folders with xdg-user-dir. Nautilus brought the package
along through xdg-user-dirs-gtk. Since omacom#18378 replaced it with Files, no
package installs it, so every fresh install stops at "Finalizing boot
and user" with exit status 127.

Name it in the base packages. Dropping Nautilus with pacman -Rns took it
off existing machines too, so a migration installs it there.
* Add Surface Laptop 8 board setup

On the Surface Laptop 8 (13.8-inch, Snapdragon X2 Elite), load the panel,
keyboard and USB4 mux drivers before disk unlock, with the GPU and DSP
firmware they request there, and install surface-laptop-8-support. Since
linux-omarchy 7.3-5 the USB4 host router drivers are thunderbolt_qcom, which
the panel waits for; thunderbolt stays listed for 7.3-4.

Then copy the USB4 router firmware out of the Windows USB4 driver so docks
work. The router driver requests it once, at probe in the initramfs;
thunderbolt_qcom declares it, so mkinitcpio adds it. Without Windows on the
disk it is not found and USB4 stays off. Other Snapdragon laptops are left
alone.

* Test the Surface Laptop 8 setup's behaviour, not its lines

Drop the checks that grep all.sh and the package list for the lines this
setup adds, and the list of modules the initramfs names. Leave one DSP image
missing from the firmware fixture so the test checks that missing firmware is
skipped, as its message says.

* Match the Surface Laptop 8 by its agreed board name

Qualcomm's v2 device tree names the board microsoft,surface-laptop-8-13p8,
and linux-omarchy now uses that name.

* Put the Surface Laptop 8's DSP firmware from its new folder in the image

From linux-omarchy 7.3-17 the device tree loads the ADSP and CDSP images from
qcom/glymur/microsoft/mahua, where microsoft-surface-laptop-8-firmware installs
them.

* Install the Surface Laptop 8's support package by its new name

* Set up the 15-inch Surface Laptop 8 too
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Installs that kept the legacy Super + Ctrl + X dictation toggle get it
switched to o.rebind, so their binding keeps the key instead of firing
alongside the panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One hl.unbind before the first personal binding keeps every personal
action, matches quote, case and spacing variants, and follows a symlinked
bindings.lua. Registers the panel as a shell shortcut so a press needs no
process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
o.unbind_default drops an Omarchy default once per config load, so the
migration can put it ahead of each active personal binding without one
removing another. Commented-out calls no longer count, and a binding in a
false condition no longer leaves a later one sharing the key with the panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
omarchybot and others added 28 commits November 11, 2026 23:07
* Install pipewire-jack and gst-plugin-pipewire on ARM

* Read explicit JACK packages without a pipe in the ARM migration

pacman -Qqe | grep -q under the runner's pipefail let grep exit at the first match while pacman was still writing; pacman's SIGPIPE failed the pipeline, the negation turned that into "no explicit JACK", and the swap removed a jack2 the owner had installed on purpose. Capturing the list first removes the race, and a failed query now stops the migration instead of permitting the swap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep jack2 when jack2-dbus or pipewire-jack-client needs it

jack2-dbus depends on jack2 by name, so swapping jack2 out from under it fails the transaction ("removing jack2 breaks dependency 'jack2' required by jack2-dbus"), the migration exits non-zero, and every later migration stays blocked. pipewire-jack-client conflicts with pipewire-jack and runs PipeWire as a client of jack2, so --ask=4 would remove that arrangement along with jack2. Either one installed, explicitly or as a dependency, means something still needs jack2, so the swap is skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex Medium <noreply@openai.com>

* Keep an installed JACK server out of the ARM reinstall

pipewire-jack is now an aarch64 default, and the migration deliberately leaves jack or jack2 in place where the owner chose it or something still needs it. omarchy-reinstall-pkgs asks pacman for every default with --noconfirm, which answers the conflict with either server with no and fails the whole transaction, so on those machines the reinstall could not run at all. Leave pipewire-jack out of the reinstall wherever jack or jack2 is installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex Medium <noreply@openai.com>

* Keep the reinstall's JACK guard true to --ask 4

quattro now runs the default-set install with --ask 4, which answers pacman's conflict question with yes: a kept jack or jack2 would be removed for pipewire-jack rather than failing the transaction. The guard still leaves pipewire-jack out; its comment and the test's expected command line now say what quattro does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop the migration's test file

quattro's AGENTS.md now says no test for a migration (omacom#16302): it runs once and is frozen once it ships. The migration's cases were exercised against real pacman on a worker instead; the reinstall guard, which is lasting logic in bin/, keeps its test in platform-packages-test.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: LN Bodicherla <119286838+ln-bodicherla@users.noreply.github.com>
Co-authored-by: Omarchybot <317366263+omarchybot@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Codex Medium <noreply@openai.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
A tailnet model its host stops is no longer listed, so its error line can't
show, and one in the add menu that isn't running is loading, not stopped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generation speed with prefill in parentheses, in place of a separate
prefill segment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A running tailnet model shows just its speed and context; an offered one
its memory, context and speed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
omarchy-local-ai registers its models for pi and OpenCode under
omarchy-local, renamed from llamacpp, so local prompts keep counting.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Show the disk unlock prompt on the HP OmniBook X 14

* Ask for a reboot only when the OmniBook X 14 migration rebuilds the boot image
* Use play, pause and the Tailscale mark for network model actions

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

* Scroll network model action buttons into view when the cursor lands on them

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

---------

Co-authored-by: Claude Fable 5.2 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Install Spotify as a web app on every platform

The native client was x86-only, so ARM already got the web player. Use
the web app everywhere for new installs. Existing native installs keep
working: omarchy-launch-spotify still prefers /usr/bin/spotify when present.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Ship Spotify as a default web app like YouTube

Spotify is now a preinstalled web app launcher with a bundled icon, and
Super+Shift+M opens it directly. The install-on-demand script, the
launcher wrapper, and Install > Service > Spotify are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Focus an open Spotify window from Super+Shift+M

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Name the Spotify binding so it focuses an open player

Uses the webapp table form like WhatsApp and Google Maps. The keybinding
label moves from Music to Spotify across the catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Leave translations to the i18n sync workflow

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep the native Spotify client on Super+Shift+M where installed

omarchy-launch-spotify now launches or focuses /usr/bin/spotify when present
and the web app otherwise, so the binding and its label stay unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…al (omacom#18515)

* Open Qwen Code on local models, and count them and paired ones as local

omarchy agent --local and the panel's local launches open Qwen Code on
the model when it's the default, with the endpoint and model as flags
and the key read from its file inside the terminal, never on a command
line. An omarchy-local-ai without Qwen Code's overlay leaves it to pi.

Qwen Code's transcripts don't say where a reply went, so a model Omarchy
launched it on counts as local, here or on a paired machine, unless the
user's own route sends it elsewhere. pi and OpenCode's omarchy-local-<host>
providers count as local too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Read a paired machine's pi and opencode replies past the prefilters

Both readers skipped files and rows naming no exact local provider id
before the classifier saw them, so omarchy-local-<host> usage alone
never counted. Their filters now take the prefix too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#18508)

omarchy-update-keyring fetched Arch Linux ARM's build key from
keyserver.ubuntu.com when an aarch64 machine lacked archlinuxarm-keyring.
It runs under set -e as a step of omarchy update, so a failed fetch
stops the update, and on 11 November 2026 Canonical's keyserver went
down. keys.openpgp.org does not carry that key.

The key now ships with Omarchy in default/pacman/keys/, taken from Arch
Linux ARM's own archlinuxarm-keyring source. It is the only key there,
it never expires, and it is added with pacman-key --add and the pinned
fingerprint signed.

Omarchy's own packaging key came from keys.openpgp.org. It now comes
from Omarchy's Web Key Directory for pkgs@omarchy.org, so it carries the
current subkeys, and only the pinned fingerprint is added.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The fixed 1100x760 was taller than small laptop screens, pushing the
preview under the bar and off the bottom. Folio now sizes the window to
fit the screen, and Hyprland centers floating windows without a rule.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
omarchy-settings installs applications/icons/Spotify.png as /usr/share/icons/hicolor/*/apps/spotify.png, which the native spotify package already owns, so pacman refuses the update on any machine with native Spotify installed. Name it omarchy-spotify, as Discord's is omarchy-discord.

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Add Netflix as a default web app on new installs

The launcher ships in applications/, which seeds /etc/skel, so it reaches new users only. No migration, so existing installs are left alone. The icon is Netflix's red N symbol rather than the wordmark, which is unreadable at launcher sizes. Like YouTube, it drops the chromium-based-browser tag so the player can float.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep refreshes and the 3.x upgrade from adding Netflix to existing homes

omarchy-refresh-applications copies every shipped launcher, and it runs for existing users from the quattro upgrade and from migration 1786183928, so leaving out a migration was not enough. Netflix now reaches a home only through /etc/skel; a refresh updates a Netflix launcher that is already there and never creates one, and the upgrade's own copy skips it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex Medium <noreply@openai.com>

* Let Restore Preinstalls bring Netflix back

Restoring is the user asking for the default set, so it passes --restore and the refresh copies every launcher, Netflix included, rather than only updating what is there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex Medium <noreply@openai.com>

* Put the Netflix N on a black rounded square

The bare N is a tall, narrow mark that looks lost beside the wider web app icons, so it now sits on black the way Netflix's own app tile does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Let refreshes add Netflix like any other shipped launcher

Refreshing applications and restoring preinstalls are fine places for Netflix to arrive, so the gating in omarchy-refresh-applications, omarchy-install-preinstalls and the quattro upgrade goes back to how it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Codex Medium <noreply@openai.com>
…ree (omacom#18276)

The LCD model shares the OLED model's DMI name and systemd hardware IDs,
so it was set up on the OLED tree: its LG panel ignores the DP AUX
brightness the Samsung OLED driver sends, and six of its ten cores got
no cpufreq policy. Match any Surface Pro 11 and pin
x1p64100-microsoft-denali when the SoC is the X1P-64-100 (socinfo ID
615), load the eDP panel and PWM backlight drivers early for the disk
unlock prompt, and move existing LCD installs over.

Needs linux-omarchy-aarch64 with the LCD tree's PWM backlight and 10
CPUs, and microsoft-surface-pro-11-support and -sensors matching
microsoft,denali (omacom/omarchy-pkgs).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Birk Skyum <birk.skyum@pm.me>
…8544)

Install acer-aspire-16-ai-audio, the laptop's sound card topology, on the A16-11M at setup and by migration. The card itself and its UCM profile come from omacom/omarchy-pkgs#2565.
The agents panel replay left a duplicated share action, which would not
parse, and treated a tailnet model's error as a local log link. Hidden
providers still stay off the page, and a stopped tailnet model keeps its
logs on its host.

Co-authored-by: Mark Groves <mark-groves@users.noreply.github.com>
@mark-groves
mark-groves merged commit 5a00ceb into quattro Nov 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants