Commit Graph
8 Commits
Author SHA1 Message Date
Spencer BullandClaude Fable 5.1 73a2b91cf5 Install Hermes Desktop whenever Hermes is chosen as the default agent
Hermes is only ever installed through the app. Choosing it as the default agent used to stand aside for a hermes that worked but came from somewhere else, and to refuse one that predated seeded sessions; both left the machine on a Hermes that was not the app's, which is the one Omarchy prepares for in-app updates and hands the theme to. Now --check answers only for the app's own Hermes, and --now installs the app whatever answered to hermes before, saving the previous command aside as it always did for the app path. The desktop installer no longer adds the package itself, since the shared install does.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 23:11:16 -05:00
7eb818e37b Install Hermes for the default agent as the desktop app's self-updating runtime
Choosing Hermes as the default agent built it through mise: a pipx environment with no checkout, so `hermes update` had nothing to move, and the only Hermes that could update itself was the one Hermes Desktop set up. Both paths now run the same setup. omarchy-install-hermes-cli installs the hermes-desktop package and runs upstream's installer from it, pinned to the packaged release and started on main, exactly as Install > AI did; omarchy-install-ai-hermes is that plus opening the app. The terminal, the default agent and the app share one runtime, and it updates itself.

--check answers whether --now has anything left to do, not merely whether a hermes runs: choosing Hermes from the menu asks first and opens a terminal only on a no, so a yes has to mean no minutes-long step would run where nobody can see it. With the app installed that means the runtime's own command, its completion marker and the seeded packaged app; a finished runtime whose command is gone, somebody else's, or its own but unable to run gets it back from upstream's path stage without bootstrapping again. Either way the command has to be the one PATH finds, because omarchy-agent runs bare `hermes` and Omarchy puts mise's shims ahead of ~/.local/bin; a command in the way is named rather than installed over. The modes are named outright because the app's launcher used to call this command with no arguments to reconcile a mise copy; a default of --now would turn every launch into an install. --check still refuses to run the retired wrapper, since running it built Hermes through mise, and a machine whose migration is pending can still have it on PATH.

Provisioning no longer writes the wrapper, Remove Preinstalls no longer looks for it, and the wrapper, the environment it built and what proves them Omarchy's are known to the installer alone: --retire-mise is the migration's whole job, and --now runs the same removal once the runtime installer has saved the wrapper aside, so a user who chose Hermes before their migration ran is not left with mise's shim answering `hermes`. Only the wrapper proves the environment is Omarchy's, at its path or in that saved copy, so the environment goes first and the wrapper last, judged by mise neither having it installed nor still requesting it; a removal that leaves either behind, or a listing that cannot be read, mise missing included, stops with the commands to finish by hand and leaves the migration pending. The migration that once installed the wrapper is kept as a no-op for late updaters, and one whose default agent was Hermes is told to choose it again.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Codex XHigh <noreply@openai.com>
2026-09-21 19:26:02 -05:00
Spencer Bull 27f10ffd97 Fix Hermes desktop installation after module split 2026-09-08 12:50:04 -05:00
Spencer BullandGPT-6 Codex 827266fbed Prepare a consistent Hermes release for its first update
Align main with the packaged release and fetch connected history so the updater detects and rebuilds the first update. Guard local branch work before upstream installation, force only the admitted incomplete release pin, preserve existing command files, and explain incompatible packages. Exercise empty-directory publication races and delayed launches.

Co-Authored-By: GPT-6 Codex (xhigh) <noreply@openai.com>
2026-09-07 03:39:05 -05:00
Spencer BullandGPT-6 Codex aa3868b345 Prepare Hermes native desktop for in-app updates
Use the packaged upstream installer and matching prebuilt app to prepare the writable user installation before launch. Preserve existing builds and modified sources; record the upstream build stamp only for a matching prebuilt app.

Co-Authored-By: GPT-6 Codex (xhigh) <noreply@openai.com>
2026-09-07 02:55:06 -05:00
Spencer BullandCodex XHigh 8569d1cadc Harden the Hermes skin hand-over
Hermes' YAML reader breaks lines on carriage return, NEL and the Unicode line and paragraph separators, and stops at NUL, none of which grep treats as a line end, so a comment line carrying one could put a root-level key such as banner_logo past the validator and into Rich markup on Hermes' terminal surfaces. The lines grep accepted also did not add up to the YAML Hermes needs: a colour before colors:, a second colors:, or a key over YAML's simple-key limit all passed and loaded as no palette at all, which Hermes shows as its default. The validator now counts every byte outside printable ASCII first, then walks the file in order: the name, at most one plain description, colors:, and only #rrggbb colour lines after it.

omarchy-theme-set releases its lock before the hooks run, so the rendered skin can change under this one between the check and the copy. The check is made on a private copy and that copy is what gets published, both on the first pass and on the republish a minute after activation, which used to copy whatever the theme had become by then, unchecked.

A theme switch reads the config of the profile named in active_profile, which is the one Hermes reads, and a profile exists to Hermes once its directory does, with or without a config; it ends early only for a config plainly naming another skin, since only the default is ever replaced, and leaves anything Hermes might read as the default for Hermes to answer. Hermes is run by the path the readiness probe vets, ~/.local/bin/hermes, bounded the way the probe bounds it; an answer that did not come is not taken for the default, and a write Hermes refuses is reported rather than failed, being cosmetic.

A profile that cannot take the skin no longer costs the others or the activation; a directory at the skin's path is an error rather than a place mv puts the temp file; a temp file the copy could not fill is removed. Remove stops the unit the installer left waiting, so a removal within the waiter's half hour does not hand the theme to a Hermes installed some other way or recreate the skin under a home the user asked to delete. The migration no longer swallows the hook's exit: what is not ready or refused is reported and done with inside the hook, so only Omarchy's own failures return, and those keep the migration pending as the guide requires.

Comments are cut to what the code cannot say; the reasoning is here.

Co-Authored-By: Codex XHigh <noreply@openai.com>
2026-09-05 23:28:46 -05:00
Spencer Bull 6baae0f556 Make Hermes follow the Omarchy theme as a skin
Hermes Desktop installed under Install > AI kept its own palette while every other agent app retinted with the theme. Hermes' skin is its one theme unit for the desktop app, the TUI and the CLI, and its gateway watches the active skin file and broadcasts changes to every surface, so Omarchy publishes a skin named omarchy from a template on every theme switch and nothing Omarchy-specific goes upstream.

Activation goes through hermes config set, which writes the active profile's config and touches the skin so a running gateway repaints at once, and it only replaces Hermes' default skin so a choice made in Hermes stays. A theme switch runs that activation too when the desktop package is present and Hermes is still on its default, so a hand-over the installer missed is finished by the next switch; once the config names the skin a switch never starts Hermes. The desktop adopts a skin from a change broadcast rather than from the config it finds at connect time, and its first launch builds the runtime over minutes, so the installer starts --wait as a transient user unit that outlives the install terminal, activates once the runtime marker appears, republishes after the gateway is up, and reports to the journal. A migration hands the skin to existing Hermes Desktop installs through --activate, which also renders the skin for a theme applied before the template existed.

The generated file is validated before it is published, because Hermes parses it as YAML: only the name, a plain description and #rrggbb colours pass, so an unresolved palette key or a cloned theme's own hermes.yaml leaves the previous skin in place.

🤖 Generated by Fable 5.1 in Claude Code. Reviewed by Fable 5.1 code-review at high.
2026-09-05 23:05:10 -05:00
a12a21c02f Add Hermes as a desktop app and a coding agent
Hermes joins Install > AI as a desktop app, sits beside it under Remove > AI,
and becomes a choice in the default-agent list. The CLI installs through
omarchy-install-hermes-cli rather than a bare `mise use`, so its interpreter
is pinned before mise builds it.

Rebased onto quattro. Ori claimed U+E909 in #7709 while this branch was open,
so the Hermes mark moves to U+E90A in the icon font, the menu entries, the
font README, and the charset the menu test pins. The glyph outline itself is
unchanged; it is spliced in beside Ori rather than over it.

Co-Authored-By: witcheer <witcheer.eth@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SySdB3RtCA8BNv6Am246BP
2026-08-26 18:04:41 +02:00