Commit Graph
78 Commits
Author SHA1 Message Date
ZacharyZhang-NY 83d158ad07 List the China mirrors first when the machine's region is China 2026-10-05 23:13:20 -04:00
David Heinemeier HanssonandClaude Opus 5.5 c05d90196f Switch between several Claude and Codex subscriptions, and build apps the Omarchy way (#13770)
* 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>
2026-10-01 13:36:22 +02:00
Spencer Bull 5345673988 Add OpenClaw to Install > AI as a web app on its own gateway
OpenClaw's desktop experience on Linux is its Control UI, served by the
gateway the openclaw package runs, so the Install > AI entry installs
the package and a web app launcher that routes through the new
omarchy-launch-openclaw: first launch hands off to OpenClaw's own
onboarding wizard, later launches start the gateway when needed and open
the dashboard's single-use browser handoff URL as an app window.
Remove > AI tears the gateway service down through OpenClaw's own
gateway uninstall (falling back to systemctl by hand), aborts rather
than dropping the package under a gateway that will not stop, and keeps
the user's agent in ~/.openclaw.

OpenClaw also joins Setup > Defaults > Agent through the same
agent_installer seam Hermes carries: its CLI is the pacman package
rather than a mise tool, so omarchy-install-openclaw-cli answers
--check/--now with pacman, and omarchy-agent runs `openclaw chat`,
seeding prompts through --message.

The menu mark is a new U+E90C glyph traced from the package's lobster
favicon; E90B stays free for the Perplexity mark still in flight on its
own branch.
The launcher recovers the gateway through `openclaw gateway install --force`
(unit not enabled: missing, or an install that died after writing it) or
`openclaw gateway start` (enabled but stopped), never `openclaw dashboard
--yes`: as of OpenClaw 2026.9.1 that defers to "the owning supervisor" in
both cases, and once the gateway is up it copies a one-time browser pairing
URL into the clipboard. The dashboard probe is bounded so an app-grid launch
cannot hang without a terminal to interrupt it. Removal treats only
systemd's own "inactive"/"failed" as a stopped gateway, so an unreachable
user manager aborts instead of dropping the package under a live process.
All of it verified against a real 2026.9.1 install.
Removal also takes down the node-host unit if OpenClaw ever installed one, and
asks (default no, only on a terminal) whether ~/.openclaw should go too, with
its size: the chats and credentials live there next to hundreds of megabytes
of plugin runtimes and cache OpenClaw downloads for itself.
Onboarding goes through omarchy-openclaw-onboard rather than bare `openclaw
onboard`: as of 2026.9.1 the bare command is the guided flow, which ends by
running a foreground gateway and handing off to a browser tab without
returning, so the install script never reached the app launch and no service
was installed. The helper runs the classic wizard (--flow quickstart
--install-daemon --skip-ui) as a background job that keeps the terminal as its
stdin, so its prompts render and take input as upstream draws them, and stops
it once the gateway answers: upstream leaves the wizard running after its
outro (only the TUI branch exits, and the model sign-in holds a socket open).
Every quickstart prompt precedes the service install, so that point is safe.
A gateway that never comes up after this run applies setup ends the wait as a
failure instead
of hanging, an already-running OpenClaw is left alone rather than mistaken for
this run's success, a gateway answering on the port is only this run's once its
process is the unit's own MainPID (an orphan from an
earlier run) is not mistaken for the service this run installs, and a signal at
the helper takes the wizard down with it.
2026-09-05 09:18:27 -05:00
OmarchybotandCodex XHigh ea6ee9440a Add omarchy-crash-mute to mute and unmute one program
The mute was reachable only as `omarchy-toggle crash-ignore/<program>`, which asks whoever runs it to know the flag layout, to reduce a binary's path to the name the watcher keys on, and to have read the rule that a name climbing out of that directory writes an unrelated toggle. All of that was carried in the skill's prose, which is the wrong place for a rule that has to hold: prose is advice, and the thing being advised about is a name the crashed program chose.

So it is a command now. `omarchy crash mute hyprland` silences that program, `off` lifts it, `toggle` flips it, and no argument lists what is muted. It takes the binary's path as readily as the name and reduces it the way the watcher does, so the `Executable:` line from `coredumpctl` can be handed straight to it; it refuses what is not one component of a name, so it cannot be talked into writing outside its own directory whatever it is given; and it re-reads the flag afterwards and reports what is now true rather than what was asked for. The listing counts only regular files, because that is all the watcher honours -- anything else in there would read as muted while the crashes kept arriving. A leading `--` is consumed so a program named `-h`, which the router would otherwise answer with its own help, can still be muted.

The watcher gained an unrelated fix that this uncovered. Its fields are read with `IFS=$'\t'`, and tab is IFS whitespace, so an empty field collapsed into the next delimiter and shifted every field after it along one: a crash whose comm was empty had a path read as its pid and was discarded as somebody else's. A process can set its comm to nothing, so that was reachable. Empty fields now arrive as a dash like missing ones, and a dash joins the empty and dot cases that fall back to `unknown`.

Co-Authored-By: Codex XHigh <noreply@openai.com>
2026-08-27 11:26:28 +02:00
4baae6bf2a Draw text as ASCII art in the Omarchy logo font (#8037)
* Add omarchy-ascii for drawing text in the logo font

Renders text as ASCII art in Delta Corps Priest 1, the FIGlet font the Omarchy wordmark itself is drawn in, so branding art can be words rather than a picture. The font is embedded in the script and the layout is done in awk, so the command adds nothing to the default package set.

The layout runs on one-byte stand-ins for the five block characters the font draws with. Column arithmetic over the characters themselves counts bytes in one locale and characters in another, and the stand-ins keep length() and substr() counting columns either way.

Delta Corps Priest 1 carries letters and spaces only, and every mirror of it ships the same file with the digit and punctuation glyphs empty. Anything else is dropped and named on stderr, and text with nothing drawable at all exits 1 rather than printing silence.

🤖 Generated by Opus 5 in Claude Code.

* Correct what the renderer did with input it could not draw

The route never ran on piped text. The metadata declared `<text...>` as required, so `omarchy ascii` with nothing on the command line resolved to the router's help while `omarchy-ascii` run directly worked, which is why the tests missed it: they all called the binary. The argument is optional now, and a test goes through the route.

Text reached awk as a command-line variable, where awk reads backslash escapes of its own, so `omarchy ascii 'A\nB'` drew two blocks instead of naming the backslash as a character the font lacks. A text longer than the argument list could not be passed at all. It arrives as awk's input now, with the font on a descriptor of its own.

A line with nothing drawable printed nothing at all, so a blank line between two words closed the gap up rather than keeping it. Every line draws its block now, blank ones included, which is what figlet does with a newline.

Placing a glyph scanned and copied the whole width of the art so far, costing the square of the line's length: four thousand characters took forty-six seconds. A row is now held without its trailing blanks, counted separately instead, so a glyph costs its own width and those four thousand characters take a tenth of a second.

A skipped control character was named on stderr by writing it out, which sends it to the terminal as a control character; those are named by code now. An unknown option was drawn as art rather than refused, so a mistyped `--width 40` quietly rendered the word "width".

figlet.c trims the column of blanks that every row of an `M` shares when it is the first glyph on a line, and figlet.js keeps it. asciiart.eu runs figlet.js, so the rendering follows figlet.js and a test pins that `M`, because the wordmark alone does not catch the difference and the next reader would have no way to tell the choice from an oversight.

🤖 Generated by Opus 5 in Claude Code. Reviewed by Codex XHigh.

Co-Authored-By: Codex XHigh <codex@openai.com>

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Codex XHigh <codex@openai.com>
2026-08-24 17:58:52 +02:00
David Heinemeier HanssonandClaude Fable 5 93372d5fad Drop the tz and style command group descriptions
Neither group has any commands behind it, so both only ever printed
"Unknown Omarchy command" when browsed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 17:04:28 +02:00
9672d852f0 fix --help being skipped for bin routes that only partially resolve to a file (#6788)
* fix `--help` being skipped for bin routes that only partially resolve to a file

* Add regression tests for --help on partially resolved routes

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

* Stop help-flag scanning at -- and match --json as an exact token

A `--` marks the rest of the args as belonging to the command itself, so
neither --help nor --json past it should be treated as router flags. The
--json check also matched substrings of flattened args, so a --json inside
one quoted argument switched --help output to JSON.

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

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 09:53:31 +02:00
David Heinemeier HanssonandClaude Fable 5 2521b11fdd Add a disk speed test under a new Trigger > Tests menu (#6607)
* Extract the speed test gauge cluster into a shared SpeedTestOverlay

The dial cluster -- scrim, ignition sweep, self-ranging dials, run-again
button -- moves from the network speed test panel into qs.Ui with the
labels, unit, title, scale stops, and layer namespace as parameters, so
other measurements can wear the same cluster. The network panel keeps
its process handling and becomes a thin dressing of the overlay.

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

* Add a disk speed test and move speed tests under Trigger > Tests

omarchy-disk-speedtest streams live write and read MB/s once a second by
sampling the backing block device's kernel I/O counters while dd workers
generate the traffic, the same way the network test samples the
interface counters. The stress data is an incompressible urandom chunk
staged in RAM, written with fdatasync per pass and fadvise drop-behind:
O_DIRECT silently falls back to the page cache on btrfs, and zeros never
reach a compressed filesystem at all. Scratch files are created
exclusively per invocation and removed even when a dismissal interrupts
the run mid-phase.

The omarchy.disk-speedtest panel dresses the shared SpeedTestOverlay
with write and read dials in MB/s, titled with the hardware model of
the disk under test.

The menu grows a Trigger > Tests submenu holding the new Disk Speed
Test and the Network Speed Test, which moves there from Setup > Network.

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

* Make the disk speed test reproducible, direct, and read-first

Successive runs could swing 40% because the settled figure was just the
last one-second sample of a single buffered dd stream, taken while btrfs
copy-on-write churned the extent allocator on every rewrite pass and the
fadvise cache-eviction dance stayed advisory.

The test files are now marked NOCOW, which is what makes O_DIRECT truly
direct on btrfs -- with checksums on it silently falls back to the page
cache -- and lets every rewrite land in place. Four parallel workers per
phase give the device a queue depth it can stretch out on, and the
figure the dial settles on is the steady-state average over the whole
phase with the first warm-up second excluded, not whatever rate the
final second happened to catch. Together this tightens successive runs
from +/-40% to a few percent of each other, at the device's actual
spec throughput.

The read phase now runs first, staged against freshly written files,
with the read dial on the left. Workers also only loop while the main
script lives, so a dismissal that loses the kill race can no longer
leave an orphan hammering the disk forever, and any worker dying before
the deadline fails the run instead of passing off partial figures.

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

* Drop the menu aliases from the speed test entries

Aliases are reserved for established alternate names users already
type, kept for compatibility -- not something new entries pick up by
default. Note that in the menu definition header and AGENTS.md so the
next entry doesn't repeat it.

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

* Group dial readouts with thousands separators

A gen5 disk reads five digits; 11,450 scans, 11450 doesn't. Uses the
locale's grouping separator.

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

* Trim redundant overlay props and unused imports from the speed test panels

The network panel restated the overlay's default unit and scale stops,
and both panels carried imports and an omarchyPath property nothing
uses.

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

* Publish the specific speed test error whichever handler fires last

Process exit and stderr stream-finished have no guaranteed order, so a
failure that beat the collector showed the generic message forever even
when the command emitted an actionable one; the collector now replaces
it once the text lands. Also stop clearing the error on every stdout
line: only a new run should do that, or buffered output delivered after
a failed exit erases the failure message.

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

* Arm the disk speed test cleanup before any scratch file exists

A preflight failure -- tmpfs target, missing device statistics, not
enough free space -- exited between mktemp and the trap, leaking the
scratch files. Cleanup also now unlinks before stopping the workers and
sweeps once more after, so even a cleanup cut short by an impatient
SIGKILL leaves no names behind and a final worker pass cannot recreate
one.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 23:04:42 +02:00
David Heinemeier HanssonandClaude Fable 5 bb8d2f2cb3 Split agent usage into data files and rename the plugin to omarchy.agents (#6603)
* Add agent usage collectors that write display-ready data files

One omarchy-agent-usage-scan-<agent> collector per AI coding agent prints a
complete display-ready usage record — identity, tier, status, rate limits,
and today/week/all-time stats. omarchy-agent-usage-update runs every
collector it finds and writes the records atomically to
~/.local/state/omarchy/agents/usage/, so anything that displays usage only
ever reads JSON from there.

The Claude collector absorbs what the shell previously did in-process:
transcript scanning, the stats-cache/history fallback, credentials parsing,
and the OAuth limits probe, now with a probe throttle and last-good limits
kept across network failures. The Codex collector is the existing scanner
reshaped to the shared record contract.

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

* Redo the model-usage plugin as omarchy.agents watching usage data files

The panel is now strictly a display. It discovers the JSON records that
omarchy-agent-usage-update maintains under
~/.local/state/omarchy/agents/usage/, watches them for changes, and draws
whatever appears — so adding an agent means shipping a collector, never
touching the panel. Marks resolve by convention (assets/<id>.svg with an
optional -light twin), the limits meters read a generic limits array, and
the per-provider QML adapters and in-plugin scanner scripts are gone.

Cross-device sync aggregation stays in the shell and keeps the snapshot
field names older versions wrote, so mixed-version fleets still merge in
both directions.

With the provider fan-out gone, the widget takes its real name: the plugin
id becomes omarchy.agents. A migration renames it wherever a user's config
mentions it — layout entries keep their settings and position, a disabled
widget stays disabled — then primes the data files once and drops the old
scanner cache. The migration test also drops a stale assertion that expected
migrations to restart the shell themselves, which c992cdff moved to
omarchy update.

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

* Address Codex review: synced-only tabs, limits retry, history fallback

Three data-availability gaps from review. An agent whose records only exist
in synced snapshots — a collector installed on just one machine — now gets
its tab by unioning the synced aggregate into the provider list, with rate
limits blank since those never travel. A Claude limits probe that reaches no
server at all writes retryAdvised into its record, and the shell honors it
with one 30-second retry instead of waiting out the full refresh interval,
restoring the old boot-before-DHCP behavior. And a machine with only
history.jsonl — no transcripts, no stats-cache — still reports today's
prompt and session counts.

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

* Address second Codex pass: history-only visibility, targeted retries

Today's prompt and session counts now count toward an agent's presence in
the bar, so a machine whose only Claude source is history.jsonl shows up
without waiting for limits. And the 30-second limits retry passes the
advising agent ids to the updater, so an outage at one provider no longer
puts every other collector on a retry treadmill.

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

* Drop omarchy-cmd-present jq guards from the agents migrations

jq ships in the default package set, which makes it a runtime invariant per
AGENTS.md — call it directly. The migration tests lose their now-unused
omarchy-cmd-present stubs with it.

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

* Drop the scan infix from the collector command names

Collectors are omarchy-agent-usage-<agent>; the updater skips its own name
when globbing them, and the update test proves it with a decoy.

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

* Keep the credential store out of the printed usage record

The Claude collector now reads .credentials.json once into three scalars —
the access token, its expiry, and the plan label — instead of passing the
parsed store around. The token reaches nothing but the Authorization header
of the limits probe, and only the plan label may travel into the record,
which is what CodeQL's clear-text-logging alert on the record print was
unable to see when the whole dict flowed through.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 15:46:10 +02:00
David Heinemeier Hansson bdcdfeb428 This tmux alert system didn't work as nicely as I imagined 2026-07-27 15:32:56 -07:00
David Heinemeier HanssonandClaude Opus 5 e57f3b286c Send and receive files with Taildrop (#6375)
* Send files to a tailnet machine with Taildrop

The panel gets a send button next to the copy one on every machine that
Tailscale grades as a Taildrop target, and `s` does the same from the
keyboard. Picking runs through the XDG portal chooser, so it looks like
the file dialog every other app opens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJQJfHXXApUk6En8EZisHg

* Save incoming Taildrop files and say so

Linux keeps Taildrop files in the daemon's inbox until someone asks for
them, so nothing arrived until you ran `tailscale file get` by hand. A
user service now stages each delivery next to the downloads directory,
hands it over under a free name, and announces it — with a preview when
it's an image, and a click to open it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJQJfHXXApUk6En8EZisHg

* Float every portal dialog, not just the titled ones

The portal only ever shows dialogs, and the title regex missed any
chooser an app names something else — ours included.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJQJfHXXApUk6En8EZisHg

* Re-run the Taildrop enable now that the unit ships

The unit was never installed to /usr/lib/systemd/user/, so the enable had
nothing to act on and machines that already ran the migration carry a marker
for a no-op. Rename it so they get a working pass, and report what systemctl
says instead of a bare failure line.

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

* Wait for the file chooser on the connection that asked for it

The portal answers a request with a Response signal directed at the connection
that made it, and dbus-daemon delivers directed signals only to that
connection. gdbus monitor registers with AddMatch rather than BecomeMonitor, so
it never saw the reply: every pick left omarchy-file-select blocked on a read
that could not arrive, taking omarchy-tailscale-send down with it before it
reached either its notification or the transfer.

Make the call and wait for the signal on one connection, and give up after ten
minutes so an unanswered dialog cannot strand the caller.

Drop the "Sending to" notification while here, so a send reports once.

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

* Mark Taildrop notifications with the panel's send glyph

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

* Stop a hung tailscale poll from freezing the panel

Each poll is skipped while its own process is still running, so one that never
exits leaves the panel showing whatever it last read, for good: the peer list
keeps a woken machine missing, and opening the panel cannot help because open
runs the same refresh that hits the same guard.

Reap anything still running fifteen seconds after a refresh, well inside the
thirty second interval, so the next tick starts clean.

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

* Place a moved widget where an added one lands

'move omarchy.media left' named a section, not a slot, but the section went
through as an explicit target, which resolves a missing index by appending. The
widget landed on the far end of the row instead of after the section anchor
where 'add' puts it.

Its test has never run: the assertion covering this went in four hours after an
unrelated layout change had already stopped the file, and the runner stops the
whole suite at the first failure.

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

* Keep the config test from failing on things it is not about

The center layout assertion pinned the whole row, so parking the indicators
left of the clock broke a test named for update sitting next to weather. Assert
that adjacency instead.

The package-defaults check reads PKGBUILDs from the omarchy-pkgs repo and blew
up with a traceback wherever that is not a sibling checkout. Skip it when the
checkout is absent, honour OMARCHY_PKGS_ROOT when it is somewhere else, and
keep failing when it is present and wrong.

Between them these stopped the suite eighty files early.

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

* Make the file chooser a Python command rather than a bash host for one

The portal work was a heredoc wedged inside a bash script that existed only to
parse two flags. Drop the host: argparse covers the flags, and the file says at
the top why it is the one command here not written in bash.

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

* Tell a chooser that never opened apart from one that was dismissed

Three fixes from review:

The poll watchdog rearmed on every refresh, so a refresh interval shorter than
its timeout — the setting goes down to five seconds — pushed the deadline ahead
of a hung process forever. Arm it on the launch that needs watching and leave
it alone.

omarchy-file-select exited 1 both for nothing picked and for a chooser that
could not run, and omarchy-tailscale-send read it through a process
substitution, which drops the status anyway. A session bus that was not there
looked exactly like someone changing their mind. Separate the two exits and
read them with a command substitution.

Delivery picked a free name and then renamed, which overwrites anything that
takes the name in between. Link to the name instead: link(2) refuses one that
is taken, so the check and the claim are the same step.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 19:07:11 -07:00
David Heinemeier HanssonandClaude Opus 5 603408a73d Drop the never-set binary override in the CLI router
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 12:15:02 -07:00
David Heinemeier HanssonandClaude Opus 5 3f7e4c4708 Share the command record emitter in the CLI router
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 12:14:19 -07:00
David Heinemeier HanssonandClaude Opus 4.8 a382be2645 Indicate and jump to tmux panes waiting for attention
Show a bar indicator whenever tmux has flagged a window, the same state
that highlights the tab, and jump to it on click or with Super + Ctrl + J.
Tmux hooks push the state to the shell, so nothing polls while no pane is
waiting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 17:40:47 -07:00
David Heinemeier HanssonandClaude Opus 4.8 84ad03b8d2 Add omarchy display text size to scale text everywhere
One knob for apparent text size, anchored to the 12px shell default: it sets
the shell font base-size (~/.config/omarchy/shell.toml), GNOME/GTK's
text-scaling-factor (12px -> 1.0), and the terminal font point size
(12px -> 9pt) in lockstep. Accepts 9-20px; reset returns all three to
default. Terminals live-reload where they can (alacritty/kitty/ghostty);
foot gets a single restart nudge that replaces itself instead of stacking.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 18:08:17 -07:00
David Heinemeier Hansson 055ffaccd4 Split omarchy-plugin into siblings and consolidate bar config into omarchy-bar
omarchy-plugin mixed plugin lifecycle, clone/edit, and bar-layout mutation.
The bar layout was mutated by two separate engines (an embedded Python
mutate_bar here and jq in omarchy-config-shell-bar), each with its own
manifest walker.

- omarchy-plugin is now a ~220-line router; clone and edit move to
  omarchy-plugin-clone and omarchy-plugin-edit, matching the existing
  plugin-{source,add,update,remove,available,validate,scan} sibling pattern
- omarchy-config-shell-bar is replaced by omarchy-bar, the single bar engine
  (show/layout/list/options/use/reset/add/move/remove/set/replace/position/
  transparent/settings) with one jq pipeline; the Python mutate_bar and its
  python3 dependency are gone
- omarchy-plugin-catalog is the shared manifest scanner used by omarchy-bar
  (widget/option enumeration, add validation) and omarchy-plugin-clone
  (source enumeration), replacing three find|jq re-implementations
- service install/remove and refresh-shell call omarchy-bar; docs and tests
  updated to the new command surface
2026-07-02 11:10:24 -07:00
David Heinemeier Hansson d136585ef4 Rename AC power helper 2026-06-24 13:38:09 +02:00
David Heinemeier Hansson b30758dd2d Add optional service widgets on shell refresh 2026-06-23 16:22:27 +02:00
Ryan Hughes babfafa5e9 Split user defaults into skel seed, finalize, and resync
Reorganizes Omarchy 4 around three layers for populating $HOME:

  Seed:     omarchy-settings ships defaults to /etc/skel; useradd -m
            copies them on user creation
  Finalize: omarchy-finalize-user (renamed from omarchy-setup-user)
            handles only the runtime tweaks /etc/skel can't do — skill
            symlinks, xdg-user-dirs, default browser/mailto, vconsole→hypr
            keyboard sync, and install/user/all.sh
  Resync:   omarchy-reinstall-configs is the explicit, destructive
            resync of /etc/skel into an existing user's $HOME

Package-owned files move out of config/ into default/, where the
omarchy-settings PKGBUILD installs them to real system paths:

  config/environment.d/fcitx.conf            -> /usr/lib/environment.d/
  config/fontconfig/fonts.conf               -> /usr/share/fontconfig/conf.avail/
  config/mimeapps.list                       -> /usr/share/applications/
  config/omarchy.ttf                         -> /usr/share/fonts/omarchy/
  config/systemd/user/*.service              -> /usr/lib/systemd/user/
  config/uwsm/default                        -> /usr/share/omarchy/default/uwsm/
  config/uwsm/env                            -> /usr/share/uwsm/env.d/10-omarchy
  config/xdg-terminals.list                  -> /usr/share/xdg-terminal-exec/

omarchy-upgrade-to-4 grows a 'retire' action (renamed from 'move' to
clarify nothing is copied — the system path is owned by the new package
once the user's hash-matched ~/.config copy is removed). Mismatched
copies are kept as backups so user overrides survive the upgrade.

Other simplifications:

  - Single env bootstrap at default/bash/env-bootstrap sourced by
    /etc/profile.d/omarchy.sh, /etc/skel/.bashrc,
    /usr/share/uwsm/env.d/10-omarchy, and default/bash/envs. PATH
    prepend only in dev-link mode (production uses /usr/bin/omarchy-*).
  - omarchy-refresh-config reads from /etc/skel/.config so refresh
    means 'snap to skel'.
  - omarchy-reinstall-configs collapses to 'cp -af /etc/skel/. ~/'
    plus limine/plymouth/nvim refresh.
  - omarchy-font-set uses awk against our own 30-omarchy.conf instead
    of xmlstarlet; xmlstarlet dropped from omarchy-base.packages.
  - Defer user systemd enables (bt-agent, sleep-lock,
    recover-internal-monitor) to first-run via
    install/user/first-run/enable-user-units.sh; delete
    omarchy-user-systemctl-enable and the per-hardware install
    scripts that called it.
  - Wireplumber bluetooth-a2dp-autoconnect.conf moves to config/ so
    /etc/skel ships it; install/user/hardware/bluetooth.sh deleted.
  - Default terminal switched to foot.desktop.
  - docs/file-layout.md documents the three-layer model and the
    build-time repo→path map.
2026-06-04 18:38:25 -04:00
David Heinemeier Hansson f1f75ee11b Switch from npm to mise for the lazy-loaded tools 2026-05-25 16:49:18 +02:00
Ryan Hughes 7e81e04110 Add plugin management util 2026-05-22 23:35:41 -04:00
David Heinemeier Hansson 4cd23d9584 Extract stats and clipboard helpers 2026-05-21 11:58:43 +02:00
David Heinemeier Hansson 25c3752051 Simplify Bluetooth device actions 2026-05-21 11:29:55 +02:00
David Heinemeier Hansson d9622d6b99 Extract shell panel status commands 2026-05-21 10:54:23 +02:00
David Heinemeier Hansson deae101d6a Extract network status shell logic 2026-05-21 10:44:05 +02:00
David Heinemeier Hansson b0f5d941ba Switch to running quickshell as a systemd service that is auto-restarted if it crashes 2026-05-18 13:58:07 +02:00
David Heinemeier Hansson 27497b19bf Expose DNS setting in the network widget 2026-05-17 19:51:29 +02:00
David Heinemeier Hansson d92c277e87 It's npm, not npx 2026-05-17 09:41:04 +02:00
David Heinemeier Hansson 1eab0cffc9 Integrate swaybg and swayosd into the new shell 2026-05-16 20:34:09 +02:00
Ryan Hughes c101591284 Replace mako with quickshell-backed notification daemon
Adds first-party omarchy.notifications service plugin that hosts a
freedesktop notification server and renders popups + a history popup
inside the shell. Uninstalls mako and retargets every helper, keybind,
indicator, and migration entry to the new daemon.

Plugin (default/quickshell/omarchy-shell/plugins/notifications/):
- Service.qml: NotificationServer, popupModel + pendingModel + pastModel
  (two-tier history, see below), DND via PersistentProperties +
  cache-file backstop, image cache for /tmp screenshots, IpcHandler with
  toggleDnd/setDnd/isDnd/showHistory/clear/clearPending/markAllSeen/
  dismissAll/dismissOne/invokeLast/dismiss, per-theme override file
  ~/.config/omarchy/current/theme/notifications.json honoring
  borderColor/backgroundColor/textColor/countdownColor.
- components/NotificationCard.qml: theme-driven card (Color.foreground/
  background/border tokens from Commons/Color.qml), 32x32 icon slot,
  Nerd Font glyph fallback via omarchy-glyph hint, hero image strip
  for screenshot/image-path notifications, hover-pause progress bar,
  uses bar.fontFamily so all surfaces share one font.

Filtering and DND:
- transient hint and CLI-style senders (app_name in notify-send /
  omarchy-action) bypass history but still pop.
- DND only allows omarchy-action toasts and notify-send -u critical
  through; real-app urgency=critical (Discord, Slack, Vesktop) is
  silenced and lands in pending instead.
- Pending vs past split surfaced via tabs in the bar widget popup;
  past tab is auto-pruned at the 15-minute mark.
- Click-to-jump: notifications without a libnotify default action focus
  the matching Hyprland window via class lookup.

Shell host:
- shell.qml: generic first-party service loader (mirrors the existing
  noctalia-compat path) and an alias for the bar so plugins can read
  barSize / barHidden / position for anchoring.
- Commons/Color.qml: parses the theme's hyprland.conf for
  $activeBorderColor so notifications match Hyprland window borders;
  picks the explicit accent= key over the color4= alias.

Bar widget rebase (plugins/bar/widgets/notificationCenter.qml):
- Drops the chunk-1 stub server, binds count/dnd state to the service,
  hosts the history popup via PopupCard so it drops down from the
  notification glyph the same way Quick Settings does.
- Pending/Past tabs, dismiss-individual close X, mark-all-as-seen and
  clear-recent action buttons, theme-driven palette.

Quick Settings rework (plugins/bar/widgets/controlCenter.qml):
- DND tile binds directly to service.doNotDisturb for instant feedback.
- Drops the volume slider (already in audioPanel) and the no-op Theme
  tile; adds a Bluetooth toggle bound to Quickshell.Bluetooth.
- Bigger 44x44 wallet was scaled back to 32x32 for tighter rows.

Notification scripts (bin/omarchy-*):
- omarchy-notification-send: passes glyph as a custom hint instead of
  prepending to the summary; adds -a omarchy-action and -u urgency
  automatically; supports -e/--transient passthrough.
- User-action toasts in the capture / toggle / hyprland / default-*
  scripts and bindings/utilities.lua now tag themselves
  -a omarchy-action so DND treats them as intent-based bypass.
- omarchy-toggle-notification-silencing, omarchy-notification-dismiss,
  default/waybar/indicators/notification-silencing.sh, and the Hyprland
  comma-keybinds all route through omarchy-shell-ipc notifications.
- omarchy-capture-screenshot / -screenrecording set the image-path
  hint properly so the hero-image rendering kicks in.

Mako removal (migrations/1778743515.sh):
- pkill -x mako, systemctl --user stop mako.service, pacman -Rns mako
  (uninstalling deletes /usr/lib/systemd/user/mako.service so D-Bus
  activation can't respawn it). Removes ~/.config/mako/ and the legacy
  toggle file. Restarts quickshell so it claims the bus name.
- Drops mako from install/omarchy-base.packages, autostart.lua,
  install/config/theme.sh + toggles.sh, default/themed/mako.ini.tpl,
  default/mako/, the omarchy-menu Mako restart row, bin/omarchy
  GROUP_DESCRIPTIONS, the settings panel catalogue, and the
  default/omarchy-skill paths table.
- Removed scripts: bin/omarchy-restart-mako,
  bin/omarchy-style-corners-mako.
- bin/omarchy-style-corners summary updated; corner radius for the
  notification card reads ~/.local/state/omarchy/toggles/quickshell-menu.json
  alongside the rest of the shell.
2026-05-14 14:21:07 -04:00
David Heinemeier Hansson 5738583319 RetroArch game launcher installer (#5753)
* Agents should use the notification helper

* Turn a single RetroArch game into its own application launcher

* Tweak installer

* Extract selection logic into cli

* Use consistent glyph

* One more
2026-05-11 13:01:45 +02:00
David Heinemeier Hansson 2e29714eee Add integrated Style > Corner controls across hyprland, mako, walker 2026-05-10 14:29:51 +02:00
David Heinemeier Hansson 887c7e3751 Set mako corners round or sharp 2026-05-10 11:50:19 +02:00
David Heinemeier Hansson 30f9a8da54 Not worth the extraction 2026-05-08 20:52:29 +02:00
David Heinemeier Hansson 45db959daf Split fido2 and fingerprint setups into setup and remove (#5670)
* Split fido2 and fingerprint setups into setup and remove

Don't make one thing do two things

* Extract helpers and clean up

* No need to hide them

* Don't need these
2026-05-08 16:41:20 +02:00
David Heinemeier Hansson 7702e837e1 Add About screen branding and make everything generic and available through cli 2026-05-08 16:07:36 +02:00
David Heinemeier Hansson 129c39448c Reminders (#5669)
* Extract notification command for using the correct spacing

* Add easy to set reminders

* More human

* Clear and direct hotkeys

* Split

* Bake reminders into the skill
2026-05-08 11:58:12 +02:00
David Heinemeier Hansson 95d8125e59 Set default terminal, browser, editor explicitly (#5651)
* Set default terminal, browser, editor explicitly

* Consistent glyphs and setup

* Tweaks

* Always there

* Proper order

* Don't make a browser the default just because it's getting installed
2026-05-07 16:11:48 +02:00
David Heinemeier Hansson 81aaade827 Make sub matches show which commands are available under it 2026-05-07 12:09:30 +02:00
David Heinemeier Hansson 6b6d71a9d2 Add live weather (#5633)
* Add live weather

* Just use jq

* Add Weather app and make it click target

* Simplify

* Looks better

* Nicer flow

* Simplify

* Move to using the notification instead of tooltip

* No longer needed
2026-05-07 10:48:32 +02:00
David Heinemeier Hansson f284cda94c Not necessary to show either 2026-05-06 13:23:12 +02:00
David Heinemeier Hansson cc378a1f7b Hide more irrelevant stuff for users 2026-05-06 13:20:34 +02:00
David Heinemeier Hansson feea828e07 Not relevant for most 2026-05-06 13:06:09 +02:00
David Heinemeier Hansson 60156309a4 No need to list this twice 2026-05-06 13:05:20 +02:00
David Heinemeier Hansson fb117e56d8 Hide certain commands from the list that aren't relevant to the vast majority 2026-05-06 12:56:51 +02:00
David Heinemeier Hansson b8fc1bb6d9 Add omarchy menu transcoding 2026-05-05 13:55:21 +02:00
Ryan Hughes 6253d46622 Add a simple way to set the screensaver to an ascii version of an image 2026-05-04 19:43:18 -04:00
David Heinemeier Hansson 21cfaab07d This moved 2026-05-04 13:31:32 +02:00
David Heinemeier Hansson fcba6237fe No longer needed 2026-05-04 13:28:00 +02:00
David Heinemeier Hansson eeb409588a This was actually correct using an alias 2026-05-01 18:04:42 +02:00