nomarchy-launch-walker guarded its manual elephant start with
`pgrep -x elephant`, which never matches the Home Manager service's actual
process name `.elephant-wrapped` (Linux truncates comm to 15 chars). So every
menu invocation spawned a second elephant that races elephant.service for the
socket — a latent source of menus intermittently coming up empty.
Gate on `systemctl --user is-active elephant.service` first, with a working
`pgrep -f elephant-wrapped` fallback for non-service setups; do the same for
walker.service. Verified in a headless system.build.vm: opening the theme menu
now keeps the elephant process count at 1 (was 2) and the menu still renders.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These existed only to ease muscle-memory from Arch-based distros and add
no behavior on a Nix-native system:
- nomarchy-pkg-install — alias for nomarchy-pkg-add
- nomarchy-pkg-drop — alias for nomarchy-pkg-remove
- nomarchy-pkg-aur-add — stub that only printed "AUR doesn't exist on NixOS"
The single code caller (nomarchy-voxtype-remove) was removed in the prior
commit, so the shims have no remaining references. SKILL.md updated to use
nomarchy-pkg-add and to point at `nix search nixpkgs` instead of the AUR.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Voxtype voice-typing was a full feature (5 scripts, a waybar widget, a
keybind, and a NixOS option) that this install does not use. The
nomarchy.system.voxtype option had no consumer — nothing read it — so the
widget and SUPER+CTRL+X bind were never actually gated by it.
Removes the scripts, default config, the SUPER+CTRL+X bind, the waybar
module (main + summer-night theme + css), the dead option, the installer
comment, and the docs. SCRIPTS.md/KEYBINDINGS.md regenerated; OPTIONS.md
and SKILL.md hand-updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Found by driving the menu's observable actions live in a VM with the real
session env imported. All three are also bound to keybindings.
1. nomarchy-hyprland-window-single-square-aspect-toggle (1-Window Ratio,
SUPER CTRL BACKSPACE): read/set layout:single_window_aspect_ratio, which
is "no such option" in Hyprland 0.52.1 — the option lives under dwindle:.
The getoption returned nothing and the keyword set was silently dropped,
so the toggle did nothing. Point it at dwindle:single_window_aspect_ratio.
2. nomarchy-hyprland-workspace-layout-toggle (Workspace Layout, SUPER L):
read .tiledLayout off `hyprctl activeworkspace -j` (no such key → always
null) and switched to "scrolling" (not a built-in layout — hyprctl
layouts lists only dwindle/master), so it silently no-op'd. Rewrite to
toggle the real general:layout between dwindle and master.
3. show_setup_menu offered Power Profile unconditionally, but powerprofilesctl
is absent everywhere (power-profiles-daemon is force-off on laptop in
favour of TLP and never enabled on desktop), so the entry died with
"command not found". Gate it behind `command -v powerprofilesctl`.
Verified (1) and (2) against live Hyprland in the VM: aspect flips
[0,0]<->[1,1], layout flips dwindle<->master.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All three confirmed real on inspection.
1. nomarchy-refresh-config was dead on every system: it read
/etc/nixos/nomarchy/{core/home/config,features} (the source tree never
lands there — only /etc/nomarchy on VM-guest/live ISO) and fell back to
~/.local/share/nomarchy/config, which nothing deployed despite SKILL.md
documenting it. Deploy the pristine core/home/config tree to
~/.local/share/nomarchy/config via xdg.dataFile and read from there, so it
works without a source checkout; its live caller nomarchy-refresh-fastfetch
now succeeds. Fix two stale SKILL.md examples (waybar/, hypr/) that pointed
at non-existent stock paths.
2. nomarchy-docs-scripts shipped a stale divergent copy in
features/scripts/utils/ (in the user nomarchy-system-scripts package)
beside the canonical bin/utils dev tool — it errored outside the repo.
Grounding it surfaced the identical bug in nomarchy-docs-keybindings.
Delete both duplicates, add them to the generator's self-reference
denylist so they don't show as false `missing`, regenerate docs/SCRIPTS.md.
3. Home ~/.config/nomarchy/state.json was never seeded on non-installer
systems, so nomarchy-installed-summary rendered "—" for theme/font/panel.
Add an idempotent home-manager activation seed in core/home/state.nix that
backfills the resolved values (defaults * existing — user choices and
runtime-only keys like welcome_done always win).
Verified: flake check + full eval matrix clean; refresh-config happy/error
paths and the seed deep-merge proven by hand.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Booting the VM showed "line 31: compgen: command not found" from
nomarchy-installed-summary on first boot. compgen is a bash
programmable-completion builtin, and the non-interactive bash the script
gets wrapped with (via makeWrapper + patchShebangs) is compiled without
progcomp. Beyond the visible error, the battery-presence check silently
failed to the else branch, so a laptop was always reported as "desktop".
Replace `compgen -G` with a nullglob array (a shopt, always available).
The installer's identical check runs under the ISO's interactive bash, so
it was unaffected — this script is the only compgen user.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
show_setup_config_menu was an Omarchy holdover where users edited
mutable config files at runtime. In Nomarchy:
- hyprland.conf, hypridle.conf, hyprsunset.conf, walker/config.toml,
waybar/config.jsonc are all Home-Manager-generated from declarative
settings — a `home-manager switch` clobbers any edit.
- hyprlock.conf and swayosd/config.toml point at paths the modules
don't deploy at all; open_in_editor created empty files.
- ~/.XCompose is a HM symlink into /nix/store — read-only.
Dropped the entire submenu function and the " Config" item from
show_setup_menu (and the matching *Config*) case branch). Persistent
settings go through the relevant nomarchy.* option in
/etc/nixos/home.nix (or system.nix); when the nomarchy.overrides.*
loader ships, a successor menu can route through
~/.config/nomarchy/overrides/.
Side effect (caught by the SCRIPTS.md regen): nomarchy-restart-xcompose
is now `unused?` — its only caller was the XCompose case I just
removed. Left for a future Pillar 3 cleanup rather than widening
this PR.
`bash -n` clean.
features/desktop/waybar/default.nix previously set
`programs.waybar.{enable,systemd.enable} = lib.mkDefault true`
unconditionally. The toggle script wrote .waybar to state.json and
pkill/exec'd waybar for instant feedback, but the next rebuild
re-enabled it because the Nix module didn't read the toggle. Result:
the bar came back on every rebuild/reboot regardless of the persisted
state — inconsistent with toggles.idle (gates services.hypridle.enable)
and now toggles.nightlight (gates services.hyprsunset.enable).
programs.waybar.{enable,systemd.enable} now follow
config.nomarchy.toggles.waybar. nomarchy-toggle-waybar flips the
running systemd user unit (`systemctl --user start/stop waybar.service`)
for instant feedback and writes .waybar back to state.json so the next
rebuild realigns. Disabled toggle now means no waybar across rebuilds
+ reboots, matching the option's documented meaning ("Whether the top
bar is enabled").
`nix flake check --no-build` + `bash -n` clean.
New nomarchy-installed-summary script renders a markdown table via
gum format with the install shape the user should verify before they
start customising:
- theme / font / panel position (~/.config/nomarchy/state.json)
- timezone / DNS / hybrid GPU (/etc/nixos/state.json)
- form factor (BAT* sysfs presence)
- software profiles (presence of marker packages)
- FDE (any crypt entry in lsblk)
- drives (lsblk filtered to disk/part/crypt)
nomarchy-welcome calls it as Step 0 — before the theme/font/panel
pickers — and gates progression on a gum input prompt so the user has
to acknowledge before customisation rewrites anything. The script is
also callable standalone from any terminal: `nomarchy-installed-summary`.
Self-contained — no installer-side changes. Software profiles are
detected heuristically (the installer bakes the user's pick into the
generated home.nix as concrete home.packages rather than persisting a
profile list), which is good enough for verification but won't catch
manually-removed profile packages. gum is in the existing categoryDeps
so no new tools are needed; falls back to plain markdown when gum
isn't on PATH (recovery contexts).
Closes the "Installer: What's installed? summary on first boot"
Now-column item from Pillar 4.
nomarchy-build-iso and nomarchy-build-live-iso both ran under set -e
but then wrapped nix build in an if [ \$? -eq 0 ] block with an else
that printed "Error: ISO build failed." and exit 1. set -e aborts the
script the instant nix build returns non-zero, so the else branch was
never reached — the user saw nix build's own error output and the
script exited.
Removed the dead conditional. Behaviour is identical.
Three issues in features/scripts/utils/nomarchy-menu:
(1) "Learn → Nomarchy" called nomarchy-launch-webapp on
https://learn.omacom.io/2/the-nomarchy-manual — an upstream Omarchy
URL, the same one fixed in nomarchy-manual on 2026-05-18. Now calls
nomarchy-manual, which opens the local ~/.local/share/nomarchy/
README.md (or notifies if the source tree isn't synced).
(2) "Style → Hyprland" tried to open ~/.config/hypr/looknfeel.conf,
which is not the path looknfeel.conf is deployed to. The actual file
lives at ~/.config/nomarchy/default/hypr/looknfeel.conf (sourced by
nomarchy.conf via the chain). Updated the path.
(3) The setup-config case statement had an *Overrides* branch but no
matching menu option, so it was unreachable. The overrides loader
(nomarchy.overrides.*) is still in the Next column of the roadmap;
when it ships, both the option AND the case will get added together.
nomarchy-menu:330 and nomarchy-launch-screensaver:16 referenced
\$NNOMARCHY_TOGGLE_SUSPEND and \$NNOMARCHY_TOGGLE_SCREENSAVER with a
double-N. The real env vars injected by features/scripts/default.nix:69-73
are single-N. Both reads always resolved to the empty string, so:
- nomarchy.toggles.suspend = false; still showed "Suspend" in the
system menu (the condition is "!= false", so empty != false → true).
- nomarchy.toggles.screensaver = false; still launched the screensaver
on hypridle's 150s timeout (the gate "== false" never hit on empty,
so the early-exit was skipped).
Both toggles documented in docs/OPTIONS.md were vacuous in practice.
Two clusters of documented-but-non-functional options surfaced during
the Pillar 8 audit, both setting toggles that have zero runtime effect.
1. `nomarchy.toggles.skipVsCodeTheme` was declared in
core/home/options.nix, defaulted from lib/state-schema.nix, and
surfaced as `NOMARCHY_TOGGLE_SKIP_VSCODE_THEME` env var in
features/scripts/default.nix — but `features/apps/vscode.nix` always
sets `workbench.colorTheme` unconditionally, and no script reads the
env var. Setting the toggle to true did nothing. Removed from
options, schema, state, env-var export, and OPTIONS.md.
2. `nomarchy.themeLoader.apps.{waybar,mako,kitty,alacritty}` were
declared in themes/engine/loader.nix but only `btop` is actually
wired (line 87 gates the per-theme btop.theme deploy). The other
four had no consumer. The actual theming pipeline for those apps is
elsewhere: waybar themes inline from `colorScheme` in waybar.nix;
kitty and alacritty are themed by stylix targets in
themes/engine/stylix.nix; mako has no theme integration at all.
Removed the four dead options + updated OPTIONS.md to list only
btop with a note about where the other apps' theming lives.
`nomarchy-welcome` wrote a "starter" `~/.config/home-manager/home.nix`
for users without one. Two problems:
1. Wrong path. The installer-generated canonical home.nix lives at
`/etc/nixos/home.nix` and is imported via the flake (both
home-manager.users and the standalone homeConfigurations). Nothing
in the installer flow ever reads `~/.config/home-manager/home.nix`
— it's a dead file.
2. Broken content. The starter is missing `home.username`,
`home.homeDirectory`, `home.stateVersion`, and doesn't import
`nomarchy.nixosModules.home`. Even on a hand-migration path it
wouldn't evaluate as a standalone HM config.
So in the installer flow it's dead, and in the migration flow it's
broken. Removed Step 4 entirely. The git-init step (was Step 5) is
now Step 4. Hand-migrated users follow `docs/MIGRATION.md`, which has
the correct home.nix template.
Found during Pillar 8 audit of first-boot UX.
- Update lib/state-schema.nix to default both home and system themes to 'summer-night'.
- Fix 'nomarchy-theme-list' and 'nomarchy-theme-set-templates' to resolve themes and templates from '~/.local/share/nomarchy' instead of the obsolete '$NOMARCHY_PATH' (fixing failures on Live ISO).
- Update 'nomarchy-welcome' to properly convert Title Case theme display names back to kebab-case identifiers and add input validation to prevent crashes.
- Fix installer impermanence symlink by using a relative path ('../persist/etc/nixos'), ensuring it resolves during 'nixos-install' both inside and outside the chroot.
- Deploy '~/.XCompose' symlink via Home Manager and add 'nomarchy-restart-xcompose' to the menu.
- Relocate 'Nomarchy.ttf' to 'core/branding/' and move user-level scripts ('pkg-add', 'pkg-remove', 'env-update', 'preflight-migration') to 'features/scripts/utils/' to align with the distro architecture.
- Remove obsolete '$NOMARCHY_PATH' exports and redundant 'bashrc' template.
- Export theme templates via 'xdg.dataFile' for script accessibility.
The script hardcoded `xdg-open https://learn.omacom.io/2/the-nomarchy-manual`
— an upstream Omarchy page. Users hitting "Help → Manual" in nomarchy-menu
were sent to an unrelated site, and there's no nomarchy.org canonical
docs URL to point at instead.
Now opens `$HOME/.local/share/nomarchy/README.md`, which lives on every
installed system (per SKILL.md's "Out of Scope" note about
`~/.local/share/nomarchy/`) and links every doc in `docs/`. Falls back
to a notify-send "run nomarchy-update?" message if the source tree
isn't synced.
Pillar 6 entry in docs/ROADMAP.md updated to (Shipped).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pillar 3 Phase B, batch 4 (final). Triages the last 13 `unused?` rows:
five deletes and eight SKILL.md surfacings.
Deleted (no callers anywhere, work duplicated inline or marginal value):
- `nomarchy-restart-hyprctl` and `nomarchy-restart-mako`: stale comments
claimed "used by theme switching" but no Nomarchy script calls them.
Theme-set and refresh paths call `hyprctl reload` / `makoctl reload`
directly (see nomarchy-refresh-hyprland).
- `nomarchy-restart-tmux`: 3-line pgrep+source-file wrapper. Users can
`tmux source-file ~/.config/tmux/tmux.conf` themselves.
- `nomarchy-battery-present`: the battery monitor reads
`/sys/class/power_supply/BAT*` inline; the helper never got wired in.
- `nomarchy-sudo-keepalive`: intended to be `source`d from longer-running
scripts (nomarchy-update, etc.) but nothing sources it. Resurrect from
git history if a future caller actually needs it.
Surfaced in SKILL.md (now tagged `kept` by the audit):
- Themes: `nomarchy-theme-{remove,refresh,bg-install}`
- System: `nomarchy-sudo-{passwordless-toggle,reset}`,
`nomarchy-restart-trackpad` (intel_quicki2c THC reload — a real laptop
bug fix worth documenting)
- New Virtualization section: `nomarchy-windows-vm {install,launch,stop,status}`
- Enriched Troubleshooting's generic `nomarchy-refresh-<app>` example with
literal `nomarchy-refresh-fastfetch` so the audit catches it.
Verified `nix flake check --no-build` still passes and zero callers
reference the deleted scripts.
**Phase B is now complete.** Final audit state: 164 → 159 scripts, all
tagged `kept`, `unused?` = 0, missing references = 0. The audit table is
now a clean reference of what Nomarchy ships, not a triage backlog.
Logged in `docs/ROADMAP.md` Shipped.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pillar 3 Phase B, batch 3 — Batch A of the unused? clusters.
Deleted two dead webapp URI handlers:
- `nomarchy-webapp-handler-hey`
- `nomarchy-webapp-handler-zoom`
Neither was registered as a MimeType handler anywhere — a grep across
`*.desktop` files in `core/`, `features/`, `themes/`, `installer/`, and
`hosts/` returned zero matches. Without a `.desktop` registration the
system never routes `mailto:`/`zoom:`/`zoomus:` URIs to them, so the
handlers were unreachable code.
Kept the six remaining install/remove pairs (they're real CLI tools, just
unwired into any menu) and surfaced them in `SKILL.md` "Common Tasks" so
AI assistants can discover them on user request and the audit tags them
`kept`:
- Custom App Launchers: webapp-{install,remove,remove-all},
tui-{install,remove,remove-all}
- Voice dictation: voxtype-{install,remove,status}
Menu-wiring these (e.g. a "Setup → Apps" submenu in nomarchy-menu) is a
separate Pillar 6 onboarding job, not scoped here.
Regenerated `docs/SCRIPTS.md` — script count 166 → 164, `unused?` 21 → 13.
Logged in `docs/ROADMAP.md` Shipped.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pillar 3 Phase B, batch 2. Five `unused?` scripts that either duplicate
NixOS-native facilities or reference infrastructure Nomarchy doesn't
ship. All five had no callers anywhere in the tree.
- `nomarchy-rollback`: ran `nixos-rebuild rollback` after listing
`snapper` snapshots. NixOS already exposes the previous generation in
the boot menu and `nixos-rebuild --rollback`; Nomarchy uses
impermanence, not snapper.
- `nomarchy-snapshot`: wrapped `snapper create/restore`. Same reason —
snapper isn't part of Nomarchy. The script's "nomarchy-update can use
this" comment never came true; nomarchy-update has no reference to it.
- `nomarchy-migrate-state`: one-time migration from old
`~/.config/home-manager/state.json` and `/etc/nixos/state.json` to the
unified `~/.config/nomarchy/state.json`. The installer now seeds the
unified file directly; no current install needs the migration.
- `nomarchy-config-direct-boot`: added an EFI boot entry for a Nomarchy
UKI. We don't build a UKI (no references anywhere in `core/` or
`hosts/`), so the script targeted nonexistent infrastructure.
- `nomarchy-npx-install`: generated npx wrappers in `~/.local/bin/`. An
Arch idiom — on NixOS the path is `nix-shell -p nodejs` or a
declarative `home.packages` entry.
Kept `nomarchy-build-iso` and `nomarchy-build-live-iso` (the user-flagged
useful build wrappers) and surfaced them in README §2 in place of the
raw `nix build` command, which both removes the audit's `unused?` flag
on them and shortens the docs.
Regenerated docs/SCRIPTS.md (171 → 166 scripts; 28 `unused?` → 21).
Logged in docs/ROADMAP.md Shipped.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The installer generates `nixosConfigurations.<hostname>` (see
installer/install.sh: `nixosConfigurations.$HOSTNAME`), but the system
update script was rebuilding `.#default` and using `--impure`. The
`#default` literal worked only on dev hosts that happened to be named
"default" and silently broke every toggle script on real installs.
Now resolves `$(hostname)` at runtime and aborts with a clear error if
empty. Dropped `--impure` — the flake doesn't need it.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The audit's "missing references" table held 15 rows — 2 real doc bugs and
13 grep false-positives — making Pillar 3 Phase B triage noisier than it
needed to be.
- Wrote themes/engine/scripts/nomarchy-theme-next so SKILL.md's documented
"cycle to next theme" command actually resolves.
- Scrubbed three stale `nomarchy-dev-*` references from SKILL.md (skill
frontmatter, body, and Out-of-Scope list) — they hallucinated a workflow
that doesn't exist and broke AI-assisted use of the skill.
- Added a line-context filter to both nomarchy-docs-scripts generators
that drops `nomarchy-*` tokens appearing in Nix pname/derivation idents,
/tmp/ and /etc/sudoers.d/ paths, nixosConfigurations.* / packages.*
flake outputs, mktemp -t prefixes, systemd unit vars, ./result/bin/run-
binaries, and docker container references.
- Added a small token-level denylist for five residual non-script
identifiers (nomarchy-plymouth, nomarchy-sddm-theme, nomarchy-live,
nomarchy-rev, nomarchy-windows) that survive line filtering because
they appear as bare Nix list refs, comment backticks, or compose-heredoc
identifiers.
Regenerated docs/SCRIPTS.md; the "Missing references" section is now
empty. Logged in docs/ROADMAP.md Shipped.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Scrubbed remaining upstream references and solidified Nomarchy's identity:
- Replaced 'Omarchy' and 'Spirit of Omarchy' with brand-independent terms in README.md and scripts.
- Updated nomarchy-welcome banner to 'The Professional NixOS Desktop'.
- Set nomarchy-version codename to 'Sovereign'.
- Verified core/system/branding.nix for OS-release and bootloader labels.
- Verified SDDM and Plymouth metadata for correct branding.
- Updated ROADMAP.md board.
- installer: set recursive ownership of /etc/nixos to main user post-install
- themes: fix NOMARCHY_PATH and discovery logic for Lua theme menu
- scripts: update CLI wrappers (font, theme, wallpaper) to use Walker menus
- core: remove obsolete NOMARCHY_PATH and cleanup dead code
- features: add pkgs.lua for Walker and remove obsolete switcher.nix
- docs: update ROADMAP.md, SCRIPTS.md and STRUCTURE.md
The post-install standalone HM activation kept failing in new ways
(daemon access, git ownership, missing PATH on first boot). Wire HM as
a NixOS module in the generated flake instead, so first-boot dotfiles
are activated by `nixos-install` itself with proper system context. The
standalone `homeConfigurations.<user>` is kept alongside for fast
iteration via `nomarchy-env-update`. Also:
- Drop the chroot HM activation block from the installer entirely.
- Move `nomarchy-env-update` from `features/scripts/utils/` to
`core/system/scripts/` so it ships in `nomarchy-system-scripts` and
exists on a freshly-installed system regardless of HM state.
- Set system-wide git `safe.directory` for /etc/nixos and the
impermanence-relocated /persist/etc/nixos so the user-mode HM run
doesn't trip on the root-owned flake repo.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HM activation inside `nixos-enter` failed with `big.lock: Permission
denied` because the chroot has no systemd and therefore no nix-daemon —
the user-level `nix run` fell back to single-user mode and couldn't
write /nix/var/nix/db. Launch nix-daemon manually for the activation
window and force NIX_REMOTE=daemon. Also mark /etc/nixos (and the
impermanence path) as a git safe.directory so HM doesn't trip over
git's dubious-ownership check on the root-owned repo. Make
nomarchy-env-update self-bootstrap via `nix run home-manager` when
home-manager isn't on PATH so the recovery hint actually works on a
freshly-installed system.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fix critical bash dynamic scoping bug in install.sh (Impermanence/Form Factor).
- Polished Live ISO with auto-login and passwordless sudo.
- Repurposed nomarchy-toggle-suspend to directly execute systemctl suspend.
- Updated nomarchy-launch-wifi to use nmtui in alacritty.
- Optimized nomarchy-welcome to avoid redundant rebuilds via --no-update flag.
- Enabled nomarchy-welcome in Hyprland autostart.
- Wrapped Live ISO-modifying steps in welcome wizard to prevent failures.
- Removed obsolete hardware auto-detection from nomarchy-on-boot.
- Hardened script doc generator against false-positive wildcard tokens.
- Regenerated docs/SCRIPTS.md and updated docs/ROADMAP.md.
Sweep across the three script directories: features/scripts/utils,
core/system/scripts, themes/engine/scripts. 142 of 169 bash scripts
gained `set -e`; 27 already had it; the one Python helper
(nomarchy-haptic-touchpad) was skipped via shebang detection.
Why: bash's default behavior is to continue past a failed command,
which means a script that does "do A; do B; do C" leaves the system
in a half-applied state when B fails - and the user gets no signal.
Several recent fix commits (theme partial-apply, waybar reload race,
installer prewipe silent failures) all trace back to this. set -e
turns silent corruption into a loud abort the user can act on.
The 11 scripts with explicit `|| true` markers stay safe under set -e
because || true coerces the exit to zero; the markers continue to
mean "I deliberately tolerate this failure here."
Deliberate exception: nomarchy-menu runs WITHOUT set -e. It is an
interactive UX loop where action branches do `cmd; back_to <self>`
so a failed action would abort the script under set -e and the menu
would disappear without feedback. Soft-failure - menu re-displays,
user picks again - is the right semantic. Documented inline.
Validation: bash -n on every modified script (zero failures). The
new pre-commit hook (27f5663) was just updated to filter by shebang
so it doesn't try to bash-syntax-check the Python helper - that
filter was uncovered by this sweep.
Risk: set -e can surface latent bugs in scripts that previously
relied on silent continuation. If anything breaks, it's a real bug
that was already broken and is now visible. Easy per-script revert
if any UX glitches show up.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previous behavior: `pkill -x $1` (no wait) followed by an immediate
background `setsid uwsm-app`. The new instance attached its wayland
surface while the old one's surface was still mapped. Layer-shell
apps got the same visible ghosting that waybar showed on theme switch
before the SIGUSR2 fix (386da51), and non-layer apps got brief double
instances.
Fix:
- Quote $1 (was unquoted, breaks if app name has whitespace - rare
but cost-free to fix while we're here).
- After SIGTERM, poll pgrep for up to ~1.5s in 100ms ticks.
- If anything is still alive after the poll window, SIGKILL it -
prevents a misbehaving process from holding the surface forever.
- Only spawn the new instance after the old one is confirmed gone.
Affects every caller that hits the non-systemd-managed restart path
(menu's update-process actions, voxtype install/remove, font-change
follow-ups, etc.).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
After the cancel-branch sweep, the remaining UX inconsistency was in
action branches: changing one setting kicked the user out of the menu,
forcing a relaunch to change the next. Brought 16 actions across 5
submenus into the same return-to-self pattern theme/background got.
Classification rule applied:
- Quick-state actions (toggle, set, restart-service - finishes in
milliseconds, no window opens) -> back_to <self>, so the user can
chain "toggle nightlight, then toggle gaps, then restart waybar"
without rerunning nomarchy-menu each time.
- Window-opening actions (editor, floating terminal, audio/wifi/bt
launcher, browser, hyprpicker overlay, screenshot, screenrecord,
share dialogs, lock/shutdown/logout) stay as one-shot exits -
re-popping the menu over the new window would be visual noise.
Submenus changed:
- show_toggle_menu (8 toggles): screensaver, nightlight, idle, top
bar, workspace layout, window gaps, 1-window ratio, display scaling.
- show_setup_power_menu: powerprofilesctl set returns; cancel still
goes up to show_setup_menu (different destinations on each branch,
so the if/else stays).
- show_font_menu: nomarchy-font-set returns; cancel still goes up.
- show_setup_system_menu: the suspend toggle (quick) returns;
hibernate enable/disable (terminal) still exit.
- show_update_process_menu (5 service restarts): hypridle, hyprsunset,
swayosd, walker, waybar.
For dynamically-rendered menus (show_setup_system_menu rebuilds its
options each invocation based on current state) this also gives free
visual feedback - the toggle's label flips between "Enable Suspend"
and "Disable Suspend" when the menu re-renders.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Audit of all show_*_menu functions after the theme/background fix found
11 more cancel branches that called their parent directly instead of
back_to. None are reachable from current keybindings (today's direct
invocations target submenus that already use back_to), so the bug is
latent — but any future `nomarchy-menu <area>` keybinding into one of
these would bounce the user into the parent on Esc instead of exiting
cleanly, the exact bug that prompted the previous commit's fix to
show_theme_menu / show_background_menu.
Mechanical sweep:
*) show_main_menu ;; -> *) back_to show_main_menu ;; (5 sites)
*) show_setup_menu ;; -> *) back_to show_setup_menu ;; (3 sites)
*) show_update_menu ;; -> *) back_to show_update_menu ;; (3 sites)
Behavior under nested navigation (BACK_TO_EXIT=false) is unchanged:
back_to falls through to calling the parent function by name. Only
direct-invocation cancel paths gain the correct exit-0 behavior.
Action branches and go_to_menu's dispatch table intentionally still use
direct calls — those are forward navigation, not cancel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The menu navigation contract: a submenu invoked directly via keybinding
(BACK_TO_EXIT=true, set by go_to_menu when nomarchy-menu is launched
with a target argument) should `exit 0` after the user's action; a
submenu invoked from a parent menu (BACK_TO_EXIT=false) should call
`back_to <parent>` to return where the user came from. back_to() honors
both modes.
Three submenus violated the contract:
- show_theme_menu and show_background_menu shell out to walker's
Elephant plugin and don't call back_to. After picking a theme or
wallpaper from Main -> Style -> Theme, the script exits silently
instead of returning to Style; the user has to relaunch the menu
from scratch to change anything else.
- show_hardware_menu's cancel branch called show_trigger_menu directly
instead of back_to show_trigger_menu, which would have bounced a
direct-keybinding caller into Trigger instead of exiting cleanly.
Adds the missing back_to call to the two walker-backed submenus
(parented to show_style_menu) and converts the hardware cancel branch
to back_to. The 16 other show_*_menu functions already conform.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Theme-switching ran systemctl --user restart waybar.service, which tears
down waybar's wayland layer-shell surface and creates a new one
back-to-back. Hyprland needs a frame to clear the destroyed surface; the
new instance attaches its surface immediately, so for a frame or two the
old waybar pixels remain visible behind/under the new bar - the
"artifacts and old colors on top of new" symptom most visible on the
fresh compositor of the live ISO.
Switch to SIGUSR2 reload, which makes waybar re-read config.jsonc and
CSS (including @import-ed files like ~/.config/nomarchy/current/theme/
waybar.css that theme-switch rewrites) without destroying the surface.
Full systemctl start is kept for the cold-start case.
Drive-by: replace the `systemctl list-unit-files` presence check with
`systemctl cat` - list-unit-files returns 0 even on no-match, so the
old check would always pick the systemctl branch and never fall through
to the pkill fallback on systems where waybar isn't a systemd unit.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Added nomarchy.panelPosition option and state persistence.
- Updated Waybar to respect the panelPosition setting.
- Refactored nomarchy-welcome to use state.json instead of a flag file.
- Added prompts for theme, font, panel position, and starter home.nix generation.
- Updated documentation and roadmap.
- Rename installerIso and installerIsoGraphical to nomarchy-installer and nomarchy-live.
- Update host configurations with proper Nomarchy branding and volume IDs.
- Fix nomarchy-test-live-iso QEMU launch by using -drive if=pflash for UEFI firmware.
- Add nomarchy-build-live-iso utility script.
- Scrub remaining Omarchy references in Plymouth, installer messages, and docs.
- Regenerate docs/SCRIPTS.md to reflect new and renamed utilities.
Two detector bugs fixed:
1. grep_includes missed *.lua, *.ini, *.desktop, *.json — so callers in
elephant providers (lua), mako on-button-* hooks (ini), and any future
MimeType-registered URL handlers (.desktop) were invisible. Adding them
reclassifies nomarchy-notification-dismiss and nomarchy-theme-bg-set
from `unused?` to `kept` (true callers in mako/core.ini and the
elephant background_selector lua).
2. The all_refs regex `nomarchy-[a-z0-9][a-z0-9-]+` greedily captured
trailing dashes, producing junk missing-tokens like `nomarchy-pkg-`,
`nomarchy-cmd-`, `nomarchy-restart-`, etc. from glob references like
`for c in nomarchy-pkg-*`. Tightened to require an alphanumeric end
character. Also restricted to grep_includes so the binary tmpfile
path `nomarchy-menu-rows` no longer leaks in.
New .githooks/pre-commit re-runs the generator and stages docs/SCRIPTS.md
whenever a nomarchy-* script changes. Enable per clone with
`git config core.hooksPath .githooks` (now mentioned in docs/AGENT.md).
Net audit shift after regen: unused? scripts 31→29, missing tokens 30→28,
no false-positive prefix tokens remain.
- Implement nomarchy-skill, nomarchy-manual, nomarchy-backup, nomarchy-install
- Implement nomarchy-install-docker-dbs (stub)
- Port nomarchy-docs-keybindings and nomarchy-docs-scripts to packaged scripts
- Add installerVm to flake.nix nixosConfigurations, packages, and apps
- Update nomarchy-test-installer to use nix run .#installerVm
- Add docker support to virtualization.nix and options.nix
- Add glow to script dependencies
- Finalize docs/SCRIPTS.md update
- Implement nomarchy-version, nomarchy-debug, nomarchy-reinstall, nomarchy-rollback, nomarchy-upload-log
- Implement nomarchy-refresh-hyprland and nomarchy-refresh-waybar
- Update docs/SCRIPTS.md with 'kept' status for new scripts
- Move 18 Hyprland/desktop scripts from features/desktop/scripts/ to packaged directories
- Add nomarchy.hardware.fwupd option (default false) and enable service
- Implement nomarchy-update-firmware wrapper for fwupdmgr
- Add hyprland, swayosd, and fwupd to nomarchy-system-scripts dependencies
- Update docs/SCRIPTS.md with 'kept' status for ported scripts
- Installer prompts for keyboard layout (with optional variant) and locale
via curated short list + Other… fallback into the full localectl list;
applies to the live session immediately (loadkeys + hyprctl) so the
rest of the install types correctly. Generated system.nix emits
console.keyMap, i18n.defaultLocale, and services.xserver.xkb.{layout,
variant}.
- New nomarchy.{system,}.formFactor enum (laptop|desktop, default laptop).
Installer auto-detects via /sys/class/power_supply/BAT* and lets the
user flip the answer. Waybar drops the battery widget on desktop;
battery-monitor service is gated on the same option.
- Lift waybar tray out of the collapsed group/tray-expander in the default
theme so nm-applet's icon is visible without expanding the drawer.
- Live ISOs (TTY + graphical) get baseline mkDefault keyMap/locale so the
installer's runtime override always wins.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tier A removals — small, half-wired modules nobody had asked for:
- makima (Copilot-key remapper): drop core/system/makima.nix, the
features/apps/makima/ keyboard.toml, the nomarchy-restart-makima script,
the `nomarchy.system.features.makima` option, the state-file binding,
the import in core/system/default.nix, and the "Key Remapping" entry
in nomarchy-menu. ~50 LoC + a service nobody asked for.
- Typora theme dir (core/home/config/Typora/) — Typora is a paid tool
Nomarchy doesn't even ship; the SUPER+SHIFT+W keybinding pointed at a
binary that wasn't on PATH.
- xournalpp settings (core/home/config/xournalpp/) — referenced
/usr/share paths that don't exist on NixOS.
- core/home/config/environment.d/fcitx.conf — manual env vars are
redundant once fcitx5 routes through NixOS's i18n.inputMethod.
Optionalization — three half-wired features now sit behind explicit
toggles, all default off (except keyring which keeps its existing
default-on):
- nomarchy.system.inputMethod.enable: new core/system/input-method.nix
uses NixOS's i18n.inputMethod with fcitx5 + mozc/chinese/table addons.
Drops the Hyprland exec-once line — i18n.inputMethod handles autostart.
- nomarchy.system.voxtype.enable: marker option for users who install
voxtype out-of-band (it's not in nixpkgs). Today it just documents
intent; the existing keybinding + waybar widget no-op gracefully.
- nomarchy.apps.opencode.enable: gates the existing
features/apps/opencode/default.nix xdg.configFile so the opencode
config only deploys when the user opts in.
Installer:
- system.nix and home.nix templates now surface the new toggles in their
"Optional Nomarchy modules" comment blocks.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>