User setup recreates installer-seeded files, so presenting a full rerun as a refresh or an after-login recovery step implies that it safely preserves an existing account. Remove that advice from first-boot provisioning and both user-setup entry points. Setup failures still report the log path, and provisioning behaviour is unchanged.
Co-authored-by: Omarchybot <317366263+omarchybot@users.noreply.github.com>
Co-authored-by: GPT-6 <noreply@openai.com>
* Apply the system keyboard layout to the SDDM greeter
* Extract shared assert_resolved_input helper
* Make the missing vconsole.conf tests actually open nothing
The stub only returned nil for an unset OMARCHY_VCONSOLE, but bash passes it
through as "", so both fallback cases were reading an empty temp file instead
of exercising the failed open.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Keep the Wi-Fi icon steady on OWE transition-mode networks
An OWE transition-mode network pairs an open SSID with a hidden "_owetm_"
twin on the same BSSID. Between scans NetworkManager reports the in-use
access point under the hidden SSID and drops the active profile from the
device's AvailableConnections, which is the only place Quickshell builds
known networks from. No listed network is then connected, so the bar fell
back to the disconnected icon until the next scan brought the open SSID
back, flickering on and off while the link stayed up.
Fall back to the Wi-Fi device's own connected state when no listed network
is connected, and read the in-use access point's strength from nmcli
(without a rescan) while the connected network has none of its own.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Discard stale in-use AP reads and key Wi-Fi checks on the device
Bump a generation whenever the cached in-use access point strength stops
describing the link (leaving Wi-Fi or a device change), and drop any nmcli
read started before it, re-reading immediately instead of a full interval
later.
Key Wi-Fi connectivity checks on the device rather than the SSID, so the
listed network coming and going with each scan on an OWE transition-mode
network no longer schedules a check. A real network switch still passes
through "disconnected".
Add a QML fixture that runs the panel against a mocked device through the
scan churn, a mid-read disconnect, and a final disconnect.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Pin root= before the packages that can drop it
limine-entry-tool falls back to /proc/cmdline for root= only while nothing
appends to KERNEL_CMDLINE. Installing omarchy-settings lands a drop-in that
appends with +=, switching that fallback off, and a kernel bump in the same
transaction then bakes a UKI with no root= at all. preserve_kernel_cmdline_root
repaired that afterwards, so a completed upgrade booted — but the machine was
unbootable for the seconds in between, and an upgrade interrupted there left it
in an emergency shell.
Pinning cannot wait until after the packages land, and the old guard could not
be moved earlier as it was: it asked the tool for its effective cmdline, which
still resolves root= through the fallback right up until the drop-in arrives,
so it reported healthy on exactly the machines about to break. Ask the config
layers whether root= is stated explicitly instead, for the default profile
alone, and pin before the package transaction. Verification stays after it,
since that is what rebuilds the UKIs.
The pin no longer gates on limine-mkinitcpio being present, since it now runs
before the transaction that can install it, and a machine still missing it is
exactly one that needs pinning first.
Verified in a VM upgrading a 3.8.0 install, sampling the UKI every 2s across the
upgrade: a legacy install without the pin lost root= for ~10s, and booting that
state landed in "Failed to mount '' on real root". With this change the same
upgrade never loses it, and an install that already pins root= is untouched.
Closes#6894
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Merge the limine config layers when checking for a root= pin, and re-pin after the transaction
The pin check returned on any line that mentioned root= under KERNEL_CMDLINE[default]. limine-entry-tool merges its layers in order, /usr/share drop-ins, /etc/limine-entry-tool.conf, /etc drop-ins, then /etc/default/limine, where = replaces and += appends, so a later layer's = could remove a pin the check still counted, and a quote before root= let systemd.setenv="root=..." read as one. Both skip the pin, which is the direction that bricks the next boot. The check now merges the layers the same way, strips only the outer double quotes the tool strips, drops quoted values the kernel does not split, and looks for root= as a parameter of its own. It was checked against limine-entry-tool --get-cmdline on a worker for every fixture in the test.
Installing limine-mkinitcpio-hook runs limine-install, so a machine with no /boot/limine.conf when the pin runs ahead of the transaction can have one after it, and verification only warned about the UKI it found without root=. Verification now runs the pin for any machine the first call skipped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex Medium <noreply@openai.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: omarchybot <omarchybot@users.noreply.github.com>
Co-authored-by: Codex Medium <noreply@openai.com>
* Read Codex app-server replies from the raw fd (#13703)
* Resolve Codex through mise which instead of running the lazy launcher (#13109)
* Skip the Codex app-server probe when there are no credentials (#13106)
Adapted: credentials are checked in the home being probed rather than in
the CODEX_HOME environment variable, since each registered account is
probed in its own home, so a signed-out secondary account isn't hidden
behind the primary's login. A home without credentials reports "Waiting
for auth" like any other signed-out home. The credentials store setting is
read with tomllib, so a single-quoted value counts too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show the Codex CLI's own error when its app-server dies (#8977)
Detect an app-server that exits or stops answering, and report the end of
its stderr instead of a bare RPC method name. Rebased onto the raw-fd
reply reader; the switch from "-a on-request" to "-a never" is left out,
keeping the current approval flags.
* Count pi sessions when HOME is a git checkout (#13209)
* Count only OpenAI-backed native sessions as Codex usage (#12032)
* Deduplicate Pi usage across forked sessions (#8602)
* Skip unchanged native Codex token snapshots (#10531)
* Count omp and pi profile sessions in the agent usage collectors (#9546)
`omp --profile=<name>` (and pi's equivalent) relocates the whole agent
tree under <base>/profiles/<name>/. The Claude and Codex collectors only
ever scanned <base>/agent/sessions, so a subscription driven entirely
through a profile was invisible to the agents panel: no tokens by day, no
tokens by model, no prompt or session counts.
Discover the profile roots alongside the default one. Sessions are keyed
by file path, so a profile adds sessions instead of double-counting the
default root, and a missing or unreadable profiles directory leaves the
existing behavior untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014zFbJcDEEpV5BAmsH6kAB3
* Skip unrelated Codex session lines before JSON parsing (#12803)
Adapted: session_meta lines also pass the pre-filter, since the provider
filter from #12032 reads them to skip rollouts served by a non-OpenAI
provider.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Read only the Codex session files that changed since the last scan (#12595)
Native Codex rollouts keep per-file totals between runs, replayed while a
file's mtime and size are unchanged. Rebased onto the session_meta
provider filter, snapshot dedup, and line pre-filter, which now live in
the per-file reader. pi and omp sessions are left out of the per-file
cache: a forked pi session repeats its parent's messages, so they are
deduplicated across the whole tree on every scan.
* Count streamed Claude messages by their highest-output usage line (#10606)
Claude Code writes a streamed assistant response as several transcript
lines that share one message id, one per content block. Each line
carries a usage object. The first line's output_tokens is a placeholder,
often 1, and the last line has the real count. Input and cache fields
usually match across the lines.
The scanner dedupes by message id and keeps the first line it sees, so
it under-counts output tokens. On a machine with 2,577 transcripts it
reported 39.0M output tokens against 60.1M used, a 35% shortfall. Input
and both cache fields differed by under 0.01%.
Keep the line with the highest output count, with the last one scanned
winning a tie. The whole line is kept because a response can fall back
to another model mid-stream. Those lines are separate snapshots with
different cache figures and a different model, and taking a maximum per
field across them over-counts cache tokens and credits the wrong model.
The zero-usage check now runs before dedup, so a zero-usage first line
no longer claims a message id and hides a later line with real usage.
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: GPT-6 Astra <noreply@openai.com>
* Index Claude transcripts so the agents refresh reads only what was appended (#8313)
omarchy-agent-usage-claude re-parsed every line of every transcript under
~/.claude/projects on each refresh: no mtime cutoff, no memory of the last
pass. The agents widget is on by default and ticks every 15 minutes, so the
cost grew for the life of the machine. After one month here that was 803
files, 640 MB, 127k lines and 57k JSON parses per tick, about 1 core-second,
pushed through the page cache every quarter hour forever.
Keep a per-file index next to the scan cache: the unique usage records
already parsed out of each transcript and the byte offset they end at. A
file whose size and mtime match is not opened; a file that grew is read
from the stored offset; a file that shrank or was rewritten is read from
the start. --force drops the index and rescans from scratch.
The summary is built from the indexed records in the same directory order
the walk always used. That matters: when a resumed session carries earlier
messages, the same message id appears in two files with different usage,
and the first file visited wins. 91 ids differed on this machine; sorting
the walk moved one model's output total by 25k tokens. Output is now
byte-identical to the previous scan on a frozen copy of the corpus, cold,
warm, and after an append.
Warm refresh: 1.0 s -> 0.10 s of CPU, of which the scan itself is 70 ms;
the index for this corpus is 2.9 MB.
Adapted:
- Rebased onto #10606: the highest-output rule for streamed messages now
lives where the index parses records, and decides between files too.
- The index records the timezone it was written in, and a change rereads
every transcript, since its records hold local days.
- A file only counts as appended to when its inode and the hash of what
was already read still match, so a transcript replaced by a larger one,
or rewritten in place, is read from the start.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Label a Claude Team seat by its subscription, not its rate-limit tier (#11109)
The collector built the plan label from the OAuth rateLimitTier first, so a
Team premium seat, which runs on default_claude_max_5x, showed in the agents
panel as "Max 5x". Lead with subscriptionType and keep the multiplier as its
qualifier: Max still reads "Max 5x", a Team seat reads "Team 5x".
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Label the Claude plan from the profile the CLI refreshes (#7225)
Adapted: the profile is found the same way current_account_id() finds it,
now shared as profile_path(): ~/.claude.json for the default home, the
home's own .claude.json otherwise. The original fell back to ~/.claude.json
for any home without CLAUDE_CONFIG_DIR set, so a secondary account read the
primary's tier. The profile's tier also keeps the subscription in the label,
so a Team seat stays "Team" (#11109).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Call a lapsed Claude access token paused, not signed out (#8093)
* Refresh Claude usage after the clock moves backwards (#9956)
* Bound unreadable Claude transcript warnings (#12414)
* Count Claude usage from opencode v2 sessions (#13894)
* Reload agent usage records when an inotify watch fails to rearm (#10067)
* Reload agent usage records after each update run instead of on a timer
Rather than #10067's two-minute timer per record, reload every record when
the omarchy-agent-usage-update process exits, the moment its files can have
been replaced. A reload that finds a file unchanged keeps its record, so the
panel isn't stirred up by identical data. The grep test now runs the QML
functions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show the agent status when the trouble line has no help text (#8497)
* Clear stale agent login guidance after a successful probe (#8892)
* Clear the Grok login hint after a successful probe
#8892 cleared the default login hint after a successful probe in the
Claude and Codex collectors; Grok's collector had the same stale hint.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Read Fireworks credentials from pi's auth.json (#7455)
The Fireworks collector skipped pi, Omarchy's default agent, when
walking its credential ladder, so a machine signed in to Fireworks only
through pi (/login fireworks) never showed the tab. Insert the key pi
stores in $PI_CODING_AGENT_DIR/auth.json (default ~/.pi/agent) between
the firectl auth.ini and the opencode fallback.
pi keys can be literals, $ENV_VAR/${ENV_VAR} references, or !command
shell lookups. The collector resolves the first two; command lookups
stay pi-only and are skipped rather than sent to the API verbatim.
* Call a lapsed Grok access token paused, not signed out
Grok's access token lives six hours and Grok mints a new one from its
refresh token whenever it starts, so a lapsed one is routine. Reporting
it as an expired sign-in made the panel offer Sign-in required several
times a day, sending people through grok login for nothing. With a
refresh token present it now reads as paused, like Claude's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep showing Grok's last limits while it sits idle
While Grok hasn't run, nothing on the machine has spent its allowance,
so with a refresh token on hand the last numbers still stand: they show
as current rather than dimmed under a status line. A weekly window that
reset in the meantime starts over at 0%, a whole number of weeks on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Ask for a Grok sign-in once its refresh token is past 30 days
A refresh token older than Grok's 30-day sign-in can't renew anything,
so the panel offers Sign-in required again instead of showing the last
limits as current. With nothing cached yet it says to start Grok, rather
than showing an empty section without a word.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Check both ends of what the Claude index read before resuming a transcript
A transcript rewritten in place could grow and change only after its
first kilobytes, and the index took it for an append. It now compares
the last kilobytes before the resume point too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Simplify the agent usage collectors
- Codex: pass the forced-scan choice down instead of a module global, make
the per-file reader's cache arguments required, shrink the cache record
check, and drop guards for shapes that can't occur: an empty launcher
path, realpath raising, mise itself being a lazy launcher, multi-line
`mise which` output, and probing without a temp file for stderr.
- Claude: decide an append by the digest of both ends of what was read
alone; the inode and mtime checks it made redundant are gone.
- Snapshot: the device id falls back to the hostname, which always exists.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Share fixture setup in the agent usage scanner tests
Every fixture home lives under one scratch directory with a single cleanup
trap, instead of a trap rewritten with a longer list for each new home, and
the Codex test builds its signed-in homes with one helper.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Treat a replaced Claude transcript as new even when its ends match
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Probe Codex without its error text when there's no temporary space
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: tossbaws <17258053+tossbaws@users.noreply.github.com>
Co-authored-by: surim0n <suritech@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: anonwurcod <anonwurcod@proton.me>
Co-authored-by: Kevin Rajan <7121943+kvnloo@users.noreply.github.com>
Co-authored-by: Nate Ashby <nate.ashby11@gmail.com>
Co-authored-by: Aris Gysel <aris.gysel@me.com>
Co-authored-by: Brams <76213579+Brams-s@users.noreply.github.com>
Co-authored-by: This_Is_NPC <gabrielfollone27@gmail.com>
Co-authored-by: sanjyay <102979855+sanjyay@users.noreply.github.com>
Co-authored-by: PapistProtocol <12738904+PapistProtocol@users.noreply.github.com>
Co-authored-by: steez <stevedimakos97@gmail.com>
Co-authored-by: GPT-6 Astra <noreply@openai.com>
Co-authored-by: Ryan Yogan <ryanyogan@gmail.com>
Co-authored-by: Oli Denton <41393837+omdenton@users.noreply.github.com>
Co-authored-by: Igor Kramar <i@ikramar.ru>
Co-authored-by: Martin Eidensten <martin@meibe.se>
Co-authored-by: Romain Perron <rdj.perron@gmail.com>
Co-authored-by: Omarchy Contributor <contributor@users.noreply.github.com>
Co-authored-by: manuaudio <manu@arimaka.com>
Co-authored-by: Tyler South <tsouth2@gmail.com>
Co-authored-by: whathek <Hek846@users.noreply.github.com>
Co-authored-by: Ty Richards <me@tyrichards.com>
* Let the agents in the panel be put in any order
Drag an agent by its mark to move its section; the header it will land
on lights up, and the move happens on release. Each agent's header is
now a keyboard stop with its own highlight, and Ctrl+Up/Down moves the
agent the cursor is in. The order is kept in agents/order.json beside
the usage records. The key catcher turns Ctrl+Up/Down into a reorder
only for panels that opt in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Light only an agent's mark when the cursor or a drag is on it
The mark is the handle the agent moves by, so the keyboard cursor and
the drop spot while dragging box it alone rather than the header line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep a lit agent mark's box from being clipped at the panel's edge
The box overhangs the content's left edge, which the scrolling area
clipped. The scrolling area now reaches a little into the panel's
padding with the content shifted back, so nothing moves and the box
draws whole.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reuse a Grok session scan only on the day it was made
A limits-only refresh just after midnight reused a scan from the evening
before, which counted yesterday's sessions as today's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep Ctrl+Up/Down from moving an agent when the cursor is outside one
The hero's buttons and the starter tiles carry indices too, and the
lookup read them as accounts, so with several accounts Ctrl+Up/Down on
one of them moved an unrelated agent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Report a failed mise update even after the Grok upkeep runs
The Grok block ran after `mise up` and its last command set the script's
status, so a failed tool update could read as a success to callers that
warn about it. The update's own status is now the script's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Unpack a Grok update into ~/.grok whatever GROK_HOME says
The upkeep replaces ~/.grok's link, but the npm launcher unpacks into
GROK_HOME when it's set, so with a custom home the link never came back
at the new release and the old one was restored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Hold off reordering agents while an account name is being edited
Ctrl+Up/Down reached the key catcher during an inline rename, and moving
the agent rebuilt its section, dropping the unfinished name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Install Grok through mise's first-party package
The npm launcher keeps an old ~/.grok/bin binary because mise skips its
postinstall. Use mise's grok tool, and drop the npm tool so its shim
does not stay ahead of the stub.
* Drop the npm Grok workarounds now that mise installs Grok itself
With Grok installed through mise's first-party package, the CLI is the
binary mise manages, so the update upkeep that repointed ~/.grok/bin and
the shared bin directory for added Grok accounts have nothing left to do.
omarchy-update-mise is back to running mise up and nothing else, and
adding a first Grok account installs the same package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Count Grok's tokens and prompts from its usage ledger
Each Grok session keeps a usage.json, the ledger `grok usage` prints, with
every finished turn's end time and tokens by model. The collector now
reads it for tokens today, by day for the last week, and by model, with
cached input kept apart, and counts today's prompts by the turns that
ended today. Found in #12352's research.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Count cache writes in Grok's daily token totals
Grok's totalTokens leaves cache writes out while the per-model buckets
count them, so a turn with cache writes added less to its day than to
its model. The day's total is now the sum of those same buckets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Remove the npm launcher's old Grok binaries when moving to mise's Grok
Omarchy's npm wrapper ran the binary the launcher unpacked into
~/.grok/bin, where x.ai's installer also puts a copy with a PATH entry
ahead of mise. Once the wrapper is replaced, a binary left there would
keep shadowing the mise tool, so the migration removes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Jesse Miller <jmiller@jmiller.com>
* Let Grok updates through mise take effect
Grok's npm launcher runs ~/.grok/bin/grok whenever it exists, and the
install script that repoints it at a new release doesn't run under mise,
so every machine kept running the release it first unpacked. Updating
mise tools now drops a link to an older release and the old binary, and
lets the launcher unpack the installed one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep several Grok accounts, the way Claude and Codex do
Grok honors GROK_HOME, so an added Grok account gets its own home holding
only its login and settings cache, with the CLI binary, sessions, skills,
plugins, memory, and config linked back to ~/.grok. The account commands,
the add flow (a second account signs in through a private window), the
launcher, and a grok shell function all take it like the others, and its
identity and plan come from the files Grok writes at login.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show Grok's plan and credits in the agents panel
A grok collector reads each account's plan from the settings Grok caches
and its credits from the endpoint behind Grok's own /usage view, so Grok
gets a section, per-account limits, and autoswitch like Claude and Codex.
A signed-in agent with a plan now shows before its first numbers, so a
lapsed sign-in has somewhere to say so. Grok's mark joins the assets, and
with every agent able to take another account the add screen no longer
needs to dim one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Document Grok accounts and limits alongside Claude and Codex
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Read Grok's credits the way xAI actually answers
The answer nests under config, names a weekly period with its end, and
as protobuf JSON leaves the usage percentage out while it's zero. The
collector now reads that shape, so a fresh week shows as 0% until it
resets rather than as nothing known.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Count Grok's prompts and sessions from its session summaries
Grok keeps a summary beside each session with when it was last active
and how many prompts it had, so its section and the hero's summary get
today's prompts and sessions and its active days. It records no token
counts there, so none are claimed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Give each Grok limits cache write its own temporary file
Two overlapping collector runs wrote the same cache through one .tmp
path, so one rename could leave the other's failing and its record not
updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Read a single Grok account from GROK_HOME when it's set
The launcher and the CLI honor GROK_HOME, but the collector always read
~/.grok, so a Grok signed in only in a custom home showed nothing. With
one account, the collector now reads the home the CLI would; with
several registered, the primary stays ~/.grok.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop guesses the real Grok credits answer made unnecessary
The collector carried fallbacks for fields and shapes guessed from the
binary before xAI's actual answer was seen, a numeric timestamp branch
nothing writes, the panel's default for prompt stats, and guards that an
empty sign-in already covers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep the working Grok release until its update is in place
The update dropped the link and older binaries before the new release was
unpacked and ignored a failed unpack, which could leave every Grok
account without a CLI. The old release now stays until the new one is
linked, and its link comes back if it never is.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Count only Grok sessions for today, not prompts
A session's summary holds all its prompts and only when it was last
active, so a resumed session put its whole history on today. Today now
counts the sessions active in it; prompts stay an all-time total.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reuse the Grok session scan on a limits-only refresh
Opening the panel and near-limit checks only need fresh limits, so they
reuse a scan up to 15 minutes old, as the Codex collector does; --force
still rescans.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Plan multiple Claude and Codex accounts with manual or automatic switching
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep several Claude and Codex accounts and start new sessions as the active one
Each added account gets its own home holding only its login, with history,
settings and skills linked back to ~/.claude or ~/.codex so --continue works
across a switch. Accounts are added through the CLI's own login, and cx, cy,
plain claude/codex and omarchy-agent all start as the active account unless
CLAUDE_CONFIG_DIR or CODEX_HOME is already set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Report limits for every Claude and Codex account in the usage records
Each registered account is probed with its own sign-in and cached on its own,
and a parked account whose sign-in lapsed keeps its last-known numbers marked
stale. The record's top-level limits keep describing the active account.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Switch accounts automatically near a limit, or notify with a one-click switch
After each usage update, an active account at or over its provider's
threshold (95% by default) moves new sessions to the account with the most
headroom in auto mode, or offers that switch as a notification in manual mode.
It never flaps back to an account that just reset, and says once when every
account is over.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show every subscription account's limits in the agents panel
With several Claude or Codex accounts, the limits become one card per account
with the active one badged. Pick a card with its number and press Enter (or
click Use) to move new sessions to it, press a to add an account, and m to
toggle automatic switching. Limits refresh every minute while an active
account is above 80%.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add Setup > Agent Accounts to list, switch and add Claude and Codex accounts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Document switching between several Claude and Codex subscriptions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Count a rested parked account as available, and pin Main to its own home
A parked Claude account whose windows all reset now reads as 0% instead of
unknown, so switching can pick it. Main's Codex limits come from ~/.codex even
when CODEX_HOME is set, and duplicate logins are checked against who each home
is signed in as now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Key limits caches by subscription and report when an account truly frees up
An added account's limits cache follows its account id, so a new account
reusing a removed one's label never inherits its allowance. The all-accounts
notice now names when an account's blocking windows have all reset, not the
earliest reset of any window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep account ids clear of routing keywords and refresh the panel after removal
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Share Codex plugins and hooks across accounts, and key Claude caches by current sign-in
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop the key hint from the Add account button
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Sign new agent accounts in through a private browser window
The main browser is almost certainly signed in to the account you already
have, and the login would silently reuse it. Both CLIs open their login page
through $BROWSER, so it now points at omarchy-launch-browser --private.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let agent account commands default to your default agent's provider
With Claude or Codex as the default agent, the provider can be left out:
omarchy agent account use work, and primary names the primary account.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop the primary alias, which shadowed an account named Primary
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Replace the auto switch button with a small Notify / Autoswitch toggle
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add accounts from a small + beside the switch toggle
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix the punctuation of the switch toggle's README line
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop the border around the add account +
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Rename Claude and Codex accounts without moving their homes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Lay out agent accounts on accent rails instead of boxed cards
The active account gets an accent rail and the others a quiet one, each
window is a single compact line, and the switch toggle, add, and Use are text.
Clicking an account's name renames it in place. A window without a reset time
no longer leaves an empty line, and last-known numbers are only red when the
sign-in needs attention.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Read Codex limits without waiting on account/read
Codex 0.158's app-server can leave account/read unanswered, and asking it
first lost the limits whenever it did, leaving the agents panel showing
"Codex limits unavailable". The limits name the plan themselves, so they're
asked first and account/read is only a short fallback when they don't.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Switch agent providers from their marks in the panel header
The row of provider buttons gives way to a small mark per provider in the
hero's corner, the selected one at full strength, with the add account +
beside them in place of the + by the switch toggle and the full-width Add
account button.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep the agents panel's scrollbar off its contents
The panel's content narrows to leave the scrollbar its own strip whenever it
scrolls, and the add account + leads the provider marks instead of sitting at
the very edge.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add Claude, Codex, or Grok subscriptions from one Add Account menu
The first account for a provider installs its CLI if needed and signs in to
the CLI's own home through the normal browser; only additional accounts get a
home of their own and a private window. Grok signs in its first account.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reveal Autoswitch beside Use instead of a Notify / Autoswitch row
The panel's + now opens the Add Account menu for any provider.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Split agent accounts with plain separators instead of rails
ACTIVE already marks the account new sessions use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Only call Claude limits stale once they're old, and poll near a limit less
Anthropic rate-limits its usage endpoint, and polling two accounts every
minute near a limit got every re-check refused, so both accounts read
"Last known" with numbers a minute old. A refused check of numbers under
15 minutes old now counts as current, older ones say how old they are,
and near-limit polling is every three minutes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show every agent's limits on one page under an Agents hero
The panel stops switching between one provider at a time and lists every
agent and account with its limits, dropping the tokens-by-day and by-model
charts. The hero carries the agents robot and rotates through what the token
counts add up to: tokens this week and today, the most used model, the
busiest day, and today's prompts and sessions. Middle-clicking the bar icon
refreshes, since there's no provider left to advance to.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Report Codex's free rate-limit resets in its usage record
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Give the agents panel more room, and show Codex's free resets
Limit lines are a notch larger with more space between them, each account's
limits sit a clear step below its name, and sections breathe. Codex has one
limit on Pro, so its section now also says how many free full resets are
waiting and when the next one lapses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Mark Claude's Fable limit on the Weekly meter instead of its own row
A model-scoped allowance on the same clock as a base window is drawn as a
tick on that window's meter and named in the row's tooltip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let omarchy-default-agent set the default without launching it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let the agents panel drive adding an account without a terminal
--check says whether adding one now would be each provider's first sign-in
or an additional account, and --events reports progress as tagged lines
alongside the CLI's own output, notifies with the result, and cleans up the
login and its scratch home when cancelled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add subscriptions and pick the default agent right in the agents panel
The + is a proper accent button, and it swaps the list for a picker of
Claude, Codex, and Grok that signs in without a terminal: name a further
account, then follow the sign-in with its status, Grok's confirmation code, a
field for Claude's pasted code, and a link to reopen the page. A dropdown at
the bottom sets the default agent without launching it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Draw the Fable tick in its meter's own color
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Revert "Let omarchy-default-agent set the default without launching it"
This reverts commit da96261f7d26bb76774cbdc1cb9e0abde92bb841.
* Make the first agent signed in the default when none is picked
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep the agents panel in the bar, with setup, starters, and adding in it
A machine with no agent opens the panel on setting one up. Once set up, the
list ends with starter prompts for a new theme, plugin, or app, and a quiet
Add a subscription. The panel no longer sets the default agent, and the hero
drops its add button.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Offer the starter prompts as tiles, and adding as a row beneath them
Theme, Plugin, and App each get a tile with its glyph, and Add a
subscription a matching row with the + in a tinted square. The panel is
allowed to grow tall enough to show it all without scrolling.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Put the tinted add button in the agents panel's hero corner
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show when a limit resets in small type under its meter
The percentage keeps the right edge to itself, so the meter runs longer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Revert "Show when a limit resets in small type under its meter"
This reverts commit 108d9de59da1af12cddbf232b0b5333ad8994c64.
* Put each account's plan beside its name, and its email in a tooltip
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Stack each limit's percentage over its time left, so the meter runs longer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show only each limit's time left, with the exact percentage on hover
The meter already says how full a window is. Dropping the percentage beside
it leaves one calm figure per row, and the row's tooltip carries the number.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Sign an existing account in again with omarchy-agent-account-add --reauth
It signs in where the account already lives: the CLI's own home (:primary)
through the normal browser, an added one through a private window. The usage
records now say which account is the primary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Offer Sign-in required in the agents panel instead of how old the numbers are
A lapsed sign-in shows as a link that signs that account in again right in
the panel. The "as of" and "last known" notes are gone; trouble that isn't
about signing in still shows as text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep the separator dot out of the Sign-in required link
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop the Setup > Agent Accounts menu and the stale plan
The agents panel now lists, switches, and adds accounts, so the menu's
duplicate of it goes, and the plan written before the design settled no
longer describes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Install the compiler and Qt pieces for building Omarchy-style apps
base-devel plus qt6-base, qt6-declarative, qt6-multimedia, and qt6-wayland,
which is what Hype, Monologue, and Omacut build with through qmake6 and make.
Qt was only there as a dependency of those apps, and the compiler not at all.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add an omarchy-app agent skill for building apps the Omarchy way
It teaches how Hype, Monologue, and Omacut are built: C++ and Qt Quick in
one flat project, qmake6 and make into a single binary, a theme that follows
Omarchy's accent live, portal dialogs, keyboard-first conventions, Qt Test
offscreen, and a PKGBUILD that puts the app in the launcher, with starter
files that build and pass their tests as written. The agents panel's App
starter uses it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Link the omarchy-app skill on existing installs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let Cancel stop a waiting login, and list a lone account's limits
Bash holds a trap until the foreground command finishes, so a login waiting
on the browser outlived Cancel. It now runs behind an interruptible wait.
With one account the usage record keeps its limits at the top level, which
omarchy agent account list now reads for the primary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Re-read identity even when signed out, and count Grok as set up
A home whose login is gone no longer keeps the identity the registry saved,
so it reads as signed out and can be added again. The agents panel leaves its
setup screen once any agent is signed in, not only once one has usage to
show, since Grok has no usage collector.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Save each account's current identity before collecting usage
A home signed in to someone else since it was added kept the old email in
the registry, which the usage records name accounts by. The usage update now
refreshes the registry from each home first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Offer Claude's paste field from the start, and keep providers with accounts
Claude's login prompts for a pasted code without a newline, so the panel's
line reader never saw it; the field is simply there for Claude sign-ins. A
provider with accounts stays listed even when the active one's limits are
unavailable, so its other accounts can still be switched to.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Never autoswitch to a signed-out account, and report Codex's missing sign-in
An account nobody is signed in to is left out of switching, however much
room its cached numbers show. Codex answers a home without a login with an
error, which now reads as Waiting for auth, so the panel offers Sign-in
required for Codex accounts too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Link shared files before they exist, and only call every account over when it is
A shared file the primary home didn't have yet was left unlinked, so an
added account made its own copy and the two diverged for good; it's linked
up front now, and written in the primary home by whichever account writes it
first. The all-accounts-over notice waits until every account's limits are
actually known.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Make the agent starter tiles compact and call the section Make something cool
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Hold the agents hero line until its next fade
Every usage record that landed rebuilt the summary phrases, and the hero
indexed that live list, so opening the panel could swap the line several
times between fades. It now keeps what it shows until the timed swap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Start the default agent from the agents panel hero
A console button beside the add button runs the same launcher as the
right click: the default agent, or the picker when none is set. It hides
while adding a subscription, where the add button becomes the way back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Put the add button before the agent launcher in the hero corner
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bring keyboard navigation back to the agents panel
The one-page redesign dropped left and right with the per-agent pages,
leaving the arrows only to scroll. They now walk everything that does
something, row by row: the hero's add and launch buttons, each
switchable account, and the starter tiles. Enter acts on the cursor,
the cursor scrolls into view, and hovering moves the same cursor so only
one thing is lit. Number keys still jump to an account.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let adding an account take over the agents hero
While adding, the hero's line reads "Add an account" in place of the
rotating summary, and the X in its corner is the only way back, so the
add view drops its own title and Back link. Each agent to add is just its
mark and name; one that can't be added is dimmed and says why on hover.
The arrows walk that list too, and Enter picks one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show the agents to add as large marks, three across
Each agent is a large mark over its name with no box around it, in one
row the arrows move along. The chosen one turns accent and grows a touch.
The reason an agent can't be added is shortened to fit inside the panel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Move between Autoswitch and Use on an account with the arrows
An account that isn't active is now two stops, Autoswitch then Use, so
left and right move between them and Enter acts on the one that's lit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Land on Use when moving up or down onto an account
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Hide Use on an autoswitching account until you're on its line
With Autoswitch on, the line shows only Autoswitch. Use appears when the
line is hovered anywhere or the keyboard is on it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Start adding an account with the first agent focused
Opening the add screen puts the keyboard cursor on the first agent, so
Enter picks it straight away. A focused agent lights up even before the
check says whether it can be added.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop the Sign in link under the account name field
Enter in the field already starts the sign-in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Key the primary Claude account's limits cache by its subscription
The primary home always used claude-limits.json, so signing it in to
another subscription could carry the old one's numbers over when the
first probe failed, and autoswitch would act on them. Once the home says
who it's signed in as, its cache is keyed by that like every other
account's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Leave Qt Multimedia out of the base packages again
Quattro dropped it once the shell no longer needed it, and the app skill
already has an app that plays audio or video add it and list it in its
own depends. The compiler and the rest of Qt stay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Render the agents panel's dynamic text as plain text
Sign-in status, help text, and provider names come from outside the
shell, so none of them should be read as markup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep an account's plan and trouble clear of its Use and Autoswitch links
The details beside an account's name grew to their full width, so a long
plan or warning could run under the links on the right. They now shorten
with an ellipsis instead, and Sign-in required keeps its whole width.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let primary name the first account, as the manual says
`omarchy agent account rename primary Hey` was documented but failed,
since the primary account's id is main and lookups took exact ids only.
primary now reaches the account marked primary, whatever it's been
renamed to, and no new account can take primary as its id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Install everything an Omarchy app needs by default
The app skill builds with Qt Multimedia, SVG icons, and ffmpeg as well as
the compiler and the rest of Qt, so qt6-multimedia, qt6-svg, and ffmpeg
join the base packages and the migration. The shell still plays no video
through Qt Multimedia, which is what its test now checks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Dim agent limits kept from an earlier check, with their age on hover
When a Claude probe fails, the last numbers carry on and looked just like
fresh ones. Those meters now dim, and their tooltip says how old they
are. The record carries limitsStale and limitsFetchedAt for this.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Give the app skill templates for every file its build needs
The templates named src/backend.{h,cpp} and a test file without showing
them, so each app had to invent its own. They're now templated, with a
starter icon, a note that LICENSE and the icon must exist for package(),
and qt6-wayland in the PKGBUILD's depends. Scaffolded from the templates
alone, the app builds and its tests pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Start the agents panel cursor over when the agent list comes or goes
Right after the shell starts, the panel can briefly look like a first
setup and focus the first agent to add. When the records land the rows
change under the cursor, which then lit an account nobody had picked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop dead hover and limit checks from the agents panel
The tiles and hero buttons fell back on their own hover when there were
no keyboard rows, but the hero always has one, so hover only ever moves
the cursor. Stale meters only exist when there are limits, so neither
the panel nor the record needs to check for some.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Drop the a hotkey for adding an agent subscription
The + in the hero is the way in, by mouse or by arrowing to it. The
plugin README also catches up with the panel: the launcher, dimmed stale
limits, the new add screen, and the arrows walking a cursor rather than
scrolling.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* List a command family that sits under a flags-only command
`omarchy agent account` reached omarchy-agent, which takes only flags,
and failed on the word instead of listing the account commands. When the
command matched so far takes only flags and the next word names visible
commands, the router now lists them. `omarchy update aur` likewise lists
the update aur commands rather than running a full update.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refuse to remove an agent account a running session uses
Removing an account deleted its home at once, pulling the login out from
under any session started in it, though running sessions are never meant
to be touched. It now says to quit that session first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Prefer an account checked just now when switching near a limit
Autoswitch weighed numbers kept from an earlier check like fresh ones.
A parked account's sign-in lapses within hours, so a stale one stays a
candidate, but an account checked just now wins over it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Leave a user's own omarchy-app skill in place when linking ours
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reach Sign-in required with the keyboard in the agents panel
Both the link on a lapsed account and the one on a single-account agent
are now stops in the cursor's walk, and Enter signs in again. A picked
link scrolls into view.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bring the manual's agent accounts paragraph up to date
Near-limit checks run every three minutes, not every minute, and
Autoswitch now appears on hovering an account's line and takes Use's
place while it's on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep the agents panel cursor on things you can act on
The active account was a stop with nothing to do, so the cursor seemed to
vanish there. It now only stops on it to sign in again. The hero's
buttons also show the cursor plainly, with an accent border and a deeper
tint instead of a shade's difference.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Never leave an added agent account's login outside the registry
Registering moved the login into its home before carrying settings over
and saving the registry, so a failure in either stranded a home holding
a sign-in that the account commands couldn't see. Settings are now
carried while the login is still pending, and a failed save moves the
home back there for the add command to clean up.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Put room before freshness when picking an account to switch to
Preferring accounts checked just now outright could pick a fresh one at
94% over a stale one at 10%. An account within 15 points of the
threshold now counts as near its limit however fresh, so accounts with
room come first and freshness only decides among them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Check agent limits more often relative to the switch threshold
Faster checks started at a fixed 80%, so a threshold set lower could be
crossed and wait out the 15-minute interval. They now start 15 points
below the threshold, which is still 80% at the default 95%.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
No suite failed with the strip restored, so nothing kept the 4.0.3 regression from coming back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bar widget instances are not handed sourceDir (ModuleSlot.injectProps sets only bar, moduleName and settings), and a plugin could reach its directory through Qt.resolvedUrl, so the comment's rationale was wrong on both counts. Two lines carry what the code cannot say.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex 0.158's app-server can leave account/read unanswered, and asking it
first lost the limits whenever it did, leaving the agents panel showing
"Codex limits unavailable". The limits name the plan themselves, so they're
asked first and account/read is only a short fallback when they don't.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
fzf's completion.bash rewraps the completions of ~76 commands on every
interactive shell start, costing ~25ms once bash-completion is loaded. Keep
only the key bindings (Ctrl-R, Ctrl-T, Alt-C); **<Tab> fuzzy completion goes.
`starship init bash` only prints a line that runs starship again with
--print-full-init, so call that directly and start the binary once.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The fake nodes carried only id and name, so a projection that handed back the node passed every assertion. Giving one an object-valued audio property, as a live PwNode has, makes the deep comparison catch it.
Co-Authored-By: Codex Medium <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A machine without a GPU, like most VMs, renders through llvmpipe on the
CPU, where every animated frame and every translucent window costs. In a
VM, opening and closing a terminal took ~5s of CPU; a panel ~3.4s.
omarchy toggle animations (also under Toggle > Animations) places a Hyprland
flag that turns off animations, blur and shadows and makes windows opaque.
The shell follows Hyprland's animations:enabled, rereading it on every
config reload: its one-shot animations run for Style.duration(ms), which
is then 0, and its spinners, pulses and title marquee hold still. A new
install in a VM starts with the flag in place.
Measured in the ISO test VM (llvmpipe), CPU per interaction:
terminal open+close 5000ms -> 481ms, workspace switch 1670ms -> 409ms,
audio panel 3446ms -> 796ms, volume OSD 2324ms -> 584ms, menu 2028ms ->
1241ms.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Hand browser and web app launches to the running browser directly
With a Chromium-based browser already running, each launch started a second
browser process only to pass its command line over the profile's singleton
socket and exit, ~165ms before the running browser even heard of it.
omarchy-cmd-browser-handoff sends that message itself with socat and waits
for the ACK, so a web app opens in ~210ms instead of ~430ms.
It hands off only what it can do exactly as the browser would: the packaged
browser binary rather than a wrapper, a flags file holding nothing beyond the
process flags Omarchy ships, no other data directory, and a socket we own.
Anything else, or no answer, launches the browser as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Hand Brave Origin launches to the running browser too
/usr/bin/brave-origin is the package's own launcher, reading
brave-origin-flags.conf, with the profile in BraveSoftware/Brave-Origin.
A web app now opens in ~158ms instead of ~345ms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Collapse identical notifications from the same sender into one toast
A web app open in several tabs fires one notification per tab for a single
reminder, stacking identical toasts. A new notification matching an on-screen
toast's app, summary, and body now replaces it like a replaces_id update.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Only collapse live duplicates that share image and click target
Screen recording toasts share text but preview and open different files, and
replayed history rows share images with entries still in history.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Compare a notification's current content when collapsing duplicates
A replaces_id update can land while the insert is deferred, so the initial
snapshot may no longer describe what the notification says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
To open a new terminal in the focused terminal's directory, the launcher
asked Hyprland for the active window with hyprctl, ~10ms on every
SUPER+RETURN. The binding now reads the pid from hl.get_active_window() and
passes it as --pid. Without one, from the menu or a shell, the launcher asks
Hyprland as before.
The bind is now a Lua function, which Hyprland reports only as __lua, so
o.bind_commands records the command it stands for and the keybindings menu
still launches a terminal when the entry is picked.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Read the default browser from mimeapps.list when launching
omarchy-launch-browser and omarchy-launch-webapp asked xdg-settings for the
default browser on every launch, ~72ms through several POSIX shell scripts.
The new omarchy-cmd-default-browser reads the http handler from the
config-dir mimeapps.list files the way xdg-mime does, desktop-specific list
first, taking the first listed entry whose command is installed, in ~10ms.
With nothing set there it falls back to xdg-settings as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Let the first copy of a browser entry decide whether it is installed
A user-local entry whose browser is gone could be rescued by a system copy
of the same ID, which the launchers never read. xdg-mime judges the first
copy found, as the launchers use it, so do the same.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Add SSH Agent as an optional service install
Enables gcr-ssh-agent (already shipped via the gnome-keyring dependency)
so passphrase-protected SSH keys work from any context: the agent prompts
graphically on first use, with opt-in passphrase storage in the keyring.
Adds install/remove commands and Install > Service / Remove > Service
menu entries.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BReZWvvLsDRUaqgjiRzvZ5
* Clear the agent's SSH_AUTH_SOCK when removing the SSH agent service
The socket's ExecStartPost exports SSH_AUTH_SOCK into the user manager with set-environment, which disabling the socket does not undo, so apps launched after removal still pointed at a stopped agent. The environment.d file also has to be deleted before disable reloads the manager, or the generator re-exports it. Only an SSH_AUTH_SOCK pointing at gcr is cleared, so another agent's stays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Move SSH Agent setup to Setup > Security
Turning on an SSH agent is security configuration of the machine rather than installing software, so it sits with SSHD and the other Setup > Security entries. It hides once enabled, as Sudoless Docker does, and Remove > Service > SSH Agent turns it back off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
The wizard writes its config while prompts remain, so the watcher starts probing a gateway that is not up yet; each probe hangs until its 10 second timeout, and OpenClaw's CLI, killed by it, takes the terminal it inherited on stdin out of raw mode on the way out. The wizard does not set raw mode again, so from then on its prompts echo keys instead of reading them: the first letter typed at the channel search landed and the next one was printed below the prompt. The probes now read from /dev/null. This is the change reverted earlier on a test that only ever saw probes that exited on their own, never one the timeout killed.
Installing a service enables and starts it, so moving an old-package gateway or node host the user had stopped or disabled turned it back on. What was running and enabled is read before the move and put back after it.
Co-Authored-By: Codex XHigh <noreply@openai.com>
A service counted as the runtime's, or as a half-moved old one on /usr/bin/node, whenever it ran anything under ~/.openclaw, so a script of the user's in that directory could be stopped and rewritten, and seeding could go ahead beside it. The runtime is now OpenClaw's own script as upstream's installer lays it out, under ~/.openclaw/tools/*/lib/node_modules/openclaw, and both checks use that one definition.
Co-Authored-By: Codex XHigh <noreply@openai.com>
Judging a moved service by whether its program sat under ~/.openclaw missed a retry after a half-finished move, whose unit already ran the runtime's script on /usr/bin/node and so was never selected again; misread a symlinked home against the resolved Node it pins; and would have moved a gateway the user runs on Bun. A service now needs moving while it runs the old package's script, or the runtime's script on /usr/bin/node, the Node the old package pulled in; any other runtime is left alone.
Co-Authored-By: Codex XHigh <noreply@openai.com>
Since 2026.9.6 upstream's installer keeps the Node a gateway service already ran when it rewrites the unit, so moving a gateway the old package installed left it running the runtime's code on /usr/bin/node, from the nodejs package the old openclaw package pulled in and the seed no longer depends on. A moved service now counts as moved only once its program is under ~/.openclaw, and the reinstall pins the runtime's Node with --runtime-path, which gives the same unit a fresh install gets.
Hype joins Omacut, Monologue, Omacalc and Omawrite as an Omacom app in
the base install and the preinstall set, so Remove and Install
Preinstalls cover it too. A migration installs it on existing machines,
unless their owner has removed the preinstalls, and the GUIs chapter of
the manual introduces it.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Flip Elsewhen between Fahrenheit and Celsius with Shift+T
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Flip Elsewhen's temperature units with Alt+T instead of Shift+T
PanelKeyCatcher's textKey now carries the held modifiers, which is how the
panel tells Alt+T from T. Existing handlers take only the text and are
unaffected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A row lit itself by lifting its own time-of-day fill, so a picked night row
could read darker than the daytime rows around it. The picked city now takes
midday's lifted fill, the brightest, whatever its time of day; hover still
lifts each row from its own.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Monologue is Omarchy's own webcam recorder: pick a camera and microphone
once, press Space to record, and stop straight into a built-in editor
to split, trim and remove clips before saving an MP4.
Ship it in the base packages alongside Omacut, include it in the
preinstall restore/remove lists, and describe it in the manual. A
migration installs it on existing machines unless the user removed the
preinstalls.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Flip Elsewhen between 24-hour and AM/PM time with t
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Line up Elsewhen's weather in one column
The temperature and weather icon sat against each row's time, which is
narrower for "4:06" than "10:06", and shared the name's slack. The time
column now takes the widest time's width in every row, and a spacer holds
the weather against it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Navigate Elsewhen from the keyboard and summon it with Super+Ctrl+Alt+E
Up and down walk home and the cities, lighting the picked row and turning
the globe to it. Left and right move the clocks an hour, held until Escape
or close. Escape now clears a shifted time before leaving the globe.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reach Add a city from the keyboard and shift time past a day
Down past the last city selects Add a city, where Return or Space opens the
search. The arrow keys no longer stop at twelve hours, and shifts past a day
read in days.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Delete the picked Elsewhen city from the keyboard
Delete (or x) removes the picked city and moves the cursor to the one that
takes its place. The picked row shows its × so the target is plain. Delete
now reaches every panel's deleteRequested, as it already does in the
clipboard and the menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Center bar glyphs on the open-panel underline
The 16px icon canvas in the 27px slot was snapped from 5.5 to 6, and the
glyph's fractional centering correction was snapped too, so glyphs sat up to
0.9px right of the underline, which centers on the slot. Both are now placed
exactly, and the geometry test measures against the slot to within 0.05px.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Answer the Elsewhen panel over the shell's IPC socket
The Elsewhen panel arrived with a plain IpcHandler, so omarchy-shell
reached it only through the slower qs ipc fallback, and the test that
every first-party handler registers as ShellIpc failed on quattro.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Remove the IPC socket of each shell a test starts
The runtime smoke and screenshot sanity tests start the real shell from a
temporary copy and kill it, which leaves its IPC socket behind in
XDG_RUNTIME_DIR. A session that runs the suite a few times collected
dozens of them.
base-test.sh gains shell_ipc_socket, which derives a shell's socket as
omarchy-shell does, and both tests remove theirs in cleanup. The socket
test derives its fixture's socket through it too, so the helper cannot
drift from omarchy-shell.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Every plugin change handed the panel Instantiator a fresh array, which
rebuilds every panel. The panels were rebuilt four times in the first
700ms of startup, each rebuild starting a new asynchronous load of every
keepLoaded panel while the last was still in flight. Under load two OSDs
could run at once, each registering the osd IPC handler: the runtime
smoke test's intermittent "another handler is registered for target
osd".
The entries now live in a ListModel synced in place. A panel whose
plugin still loads the same way keeps its loader, so startup adds each
panel once, and a full plugin reload still clears the model to rebuild
from fresh code.
Under a six-core busy load the smoke test hit the duplicate in 1 of 5
runs on quattro and in none of 10 with this change.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A city on this machine's zone becomes homeCity, the zone's own city clears
it, and a city on another zone leaves it alone. Ported from omacom/elsewhen#5.
Co-authored-by: Shawn Yeager <shawn@shawnyeager.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Move Elsewhen into Omarchy as omarchy.elsewhen
The world clock ships in the shell tree instead of its own package. A
migration renames existing bar entries with their settings and removes
the retired package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Remove Elsewhen's shelved Earth row, overlap band and sky tint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Tidy Elsewhen's models, data helper and docs, and drop currency
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Restructure Elsewhen's panel and globe on the shared shell components
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Show Elsewhen's bar globe upright
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Use the shared city search for Elsewhen's globe jump bar
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep legacy Elsewhen entries single and retry offline geocodes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fetch Elsewhen's weather with curl instead of a Python helper
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>