Three fixes from a review of the previous commit.
Chromium's sandbox helper ships setuid, the way Arch's own electron and chromium packages ship theirs. Dropping --no-sandbox was right, but it left the app relying on unprivileged user namespaces alone: on linux-hardened, or anywhere else they are denied, Electron falls back to the helper and aborts because it is not root-owned 4755.
The AppImage's usr/ tree is now read before it is removed. Deleting it wholesale is correct for what upstream ships today, and the version bumps arrive unattended, so a release that starts putting something needed in there would have had it dropped on the way past without anyone seeing it. Anything that is not a known icon or a known compatibility library stops the build instead.
The upstream hook checks that the feed still names the asset the PKGBUILD builds. It hashes whatever the feed points at, so a rename — or an arm64 build reaching the Linux feed first — would have pinned that file's checksum to a URL nobody fetches, and the failure would have surfaced a build later as a checksum mismatch.
🤖 Generated by Opus 5 in Claude Code. Reviewed by Codex XHigh.
Co-Authored-By: Codex XHigh <codex@openai.com>
The AUR package installs the AppImage payload as it comes out of the image: AppRun, .DirIcon, the app's own desktop file and six compatibility libraries — libgconf, libappindicator, libindicator, libXss, libXtst, libnotify — bundled for distributions that do not ship them. Arch does, and nothing in the tree links the bundled copies anyway, so they were only along for the ride. The launcher's APPDIR, PATH, XDG_DATA_DIRS and GSETTINGS_SCHEMA_DIR exports existed to serve that layout, and CODEX_CLI_PATH is not a variable the app reads at all.
So the tree now goes to /usr/lib/t3code as a plain Electron install, next to how openai-codex-desktop ships. Cleaning that up meant rewriting most of package(), which is more than a patch should carry over an upstream we do not control, hence a local PKGBUILD and an .omarchy/upstream.sh that follows the electron-builder feed the app updates itself from.
Three things the AUR package lost that this keeps: the AppImage's own 16px-512px icons, rather than a separately downloaded 1024px PNG; upstream's desktop entry, which carries the t3code:// scheme handlers a hand-written one drops; and libnotify in depends, which Electron dlopens for notifications.
🤖 Generated by Opus 5 in Claude Code.
T3 Code is an open-source control plane for coding agents — Claude Code, Codex, OpenCode, Cursor and Grok driven from one desktop app, on the user's own subscriptions. Upstream ships a Linux x86_64 AppImage only, and the AUR's t3code-bin already tracks it, so this syncs from there in the fast ring.
One Omarchy patch: the AUR launcher runs Electron with --no-sandbox. Chromium falls back to a user-namespace sandbox when it finds no setuid helper, which is what happens on Arch, so the flag only turns the sandbox off. Verified both ways against the built package — sandboxed it reaches display setup, and only with namespaces restricted does it abort on the setuid helper.
🤖 Generated by Opus 5 in Claude Code.
A second review pass found the PKGBUILD rewriting could still go wrong in ways
the pattern matching did not anticipate: an array element carrying a ")" in a
comment left the tail of the old array behind, and jq's "$" also matches before
a trailing newline, so a pkgver of "1.0\n" passed validation and then broke sed
after the checksum arrays had already been written.
Rather than chase each shape, prove the result. Every edit now lands on a
scratch copy that is parsed with bash -n and read back to confirm it holds the
version and checksums we meant to write, and only then replaces the PKGBUILD in
a single rename. Corruption that slips past the matching fails loudly with the
original untouched instead of landing in a pull request.
The validation anchors are \A and \z accordingly, empty checksum lists are
rejected rather than written as '', and the hook picks the newest stanza with
vercmp so it agrees with the comparator the updater uses.
Also stop the launcher probing /.config when HOME and XDG_CONFIG_HOME are both
unset, and require a regular file, so a directory at that path is skipped
instead of crashing the app on startup.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
OpenAI ships the ChatGPT desktop app several times a week and the AUR
packaging trails it -- as of this commit by a full version, 26.803.81509
against 26.810.52044. Every sync we took from there was a sync we could have
taken from OpenAI directly.
So track OpenAI's own Debian repository instead. Its per-architecture package
index carries the version and SHA256 of every deb, which makes an update two
small HTTP requests rather than a 750 MB download, and the pool keeps old
versions, so the URLs pinned here stay resolvable after the next release.
Omarchy now maintains the package outright: the max-zstd patch is simply part
of the PKGBUILD, chatgpt-launcher.sh is ours, and the Arch REUSE files are
gone -- they annotated packaging paths (.SRCINFO, keys/**, .nvchecker.toml)
that do not exist here. The app's own license still ships; package() installs
upstream's copyright file.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Some vendors publish a release feed of their own that is faster and more
precise than anyone's packaging of it. A package opts in with an
.omarchy/upstream.sh hook that reports the newest release as JSON, and the
driver rewrites pkgver, the checksum arrays the hook names, and pkgrel.
Writes are guarded on both ends: every assignment the update will touch is
verified to exist before anything is written, so a hook naming an array the
PKGBUILD lacks fails with the file untouched rather than half rewritten; and
pkgver is held to pacman's character set, because it lands in a file makepkg
sources as shell.
Ordering is vercmp's, not sort -V's -- they disagree about whether 1.0a
precedes 1.0, and pacman is what decides if a published package is an upgrade.
That is also why the workflow runs in an Arch container rather than straight on
the runner.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Package the official Grok Bot Linux .deb (internal name: sand) for Arch.
Wraps /opt/Grok Bot/sand with a Wayland launcher and grok-bot desktop entry.
Linux has no latest feed; update-pkgver.sh resolves version+commit from the
darwin-arm64 sand feed and HEAD-checks the Linux deb before pinning.
Omarchy 4 generates most theme specs from default/themed/neovim.lua.tpl on
top of aether, pinned as `name = "aether", branch = "v3"`. lazy indexes
specs by url and lets an explicit name rename the merged plugin, so the
bare "bjarneo/aether.nvim" entry here built the cache into lazy/aether.nvim
while every aether-themed install renamed that same plugin to lazy/aether at
runtime -- a directory the package never shipped. Picking one of those themes
on a fresh install cloned aether over the network at first launch and left
the session on tokyonight until nvim was restarted. Six stock Omarchy 4
themes route through the template, plus last-horizon.
Naming the entry to match builds the cache into lazy/aether directly. There
is still only one clone: Omarchy 3.8's hackerman theme depends on the bare
"bjarneo/aether.nvim" url, which merges into the same plugin, so 3.8 keeps
resolving offline as before.
Also keep refs/remotes/origin/HEAD when slimming. It pins no objects, but
lazy.nvim resolves the default branch through it for plugins parked on a
detached HEAD by a version pin -- lazy.nvim, LazyVim and blink.cmp. Without
it get_branch() returns nil and every lockfile write asserts, so :Lazy
install/update/sync died with E5113 on a fresh install, taking out the usual
self-heal path too. Regression from 45ca871.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#6746 added the unit, the binary, the enable-user-units.sh entry, and a
migration, but not the install line here -- so omarchy-settings shipped
omarchy-crash-watch.service only into the default/ template tree and never
into the search path systemd actually reads.
install/user/first-run/enable-user-units.sh enables its six units in a single
`systemctl --user enable --now` call, so the missing unit failed the whole
call. omarchy-provision-first-run only marks first-run-user when every step
succeeds, which meant first-run never completed and replayed on every login,
re-firing the "Learn Keybindings" and "Update System" notifications. Because
enable is atomic, it also left the other five units disabled -- no bluetooth
agent, sleep lock, monitor recovery, migrate notifier, or fcitx5.
Migration 1786539345 falls back to writing the wants symlink by hand when
there is no live user manager, pointing at the /usr/lib path this omission
left empty, so existing installs got a dangling symlink too.
No new migration is needed: affected installs retry first-run on the next
login and succeed, and the dangling symlinks resolve as soon as the file
exists at that path.
test/shell.d/config-test.sh already asserts this install and fails without it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm1hEGtGRUrfqxMbTi1fWe