Compare commits
46 Commits
f2b99e0f75
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72f7e7b93d | ||
|
|
20de3d4f97 | ||
|
|
2a301a049f | ||
| bd7e5a5706 | |||
|
|
af8fa321ff | ||
|
|
6238f41e43 | ||
|
|
fb4d5d7acc | ||
|
|
99a6c7d547 | ||
|
|
85ef8745d7 | ||
|
|
b82954a7b5 | ||
|
|
66c98949ab | ||
| 07e2d5c51c | |||
| 2529ca114f | |||
| 94927952db | |||
| 0930458418 | |||
|
|
95101fda3f | ||
|
|
6e0d17b859 | ||
|
|
27d1506b54 | ||
|
|
90f07ae75c | ||
|
|
bfd95cb40b | ||
|
|
9283403d8f | ||
|
|
7bf4c3c637 | ||
|
|
ec6046793e | ||
|
|
2b6d452509 | ||
|
|
ac846f4b03 | ||
|
|
03968e5d0d | ||
|
|
d264371b46 | ||
|
|
9c672953bc | ||
|
|
7fa909ddf4 | ||
|
|
5ddb15ffef | ||
|
|
46738c3663 | ||
|
|
9be4363f4b | ||
|
|
f93eb7435f | ||
|
|
6b2c678669 | ||
|
|
ac4d66e54d | ||
|
|
098cd42ac8 | ||
|
|
158ae308cc | ||
|
|
c1895eefd4 | ||
|
|
74e2dc34e3 | ||
|
|
3510a51492 | ||
|
|
7064108ce7 | ||
|
|
bef7be01b8 | ||
|
|
d4f50afc62 | ||
|
|
2f18d4efcf | ||
|
|
329dc009b6 | ||
|
|
0af1395df2 |
102
.forgejo/workflows/check.yml
Normal file
102
.forgejo/workflows/check.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
# Nomarchy CI — eval + lint.
|
||||
#
|
||||
# Catches the regressions that hurt today:
|
||||
# 1. Flake stops evaluating (broken option ref, missing import, etc.).
|
||||
# 2. A `nomarchy-*` shell script has a syntax error or a shellcheck
|
||||
# error-severity issue.
|
||||
# 3. `docs/SCRIPTS.md` drifts from the repo state because somebody
|
||||
# added / removed / renamed a script and didn't run the generator
|
||||
# (the pre-commit hook handles this, but only when enabled per-clone).
|
||||
#
|
||||
# Doesn't build ISOs — that needs a binary cache. Add a separate job
|
||||
# once Cachix/Attic is in place.
|
||||
|
||||
name: Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
eval-and-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
# Match the runner's effective channel. Nomarchy itself tracks
|
||||
# nixos-25.11 via flake.nix; the installer-action default is fine.
|
||||
extra-conf: |
|
||||
experimental-features = nix-command flakes
|
||||
|
||||
- name: nix flake check --no-build
|
||||
run: nix flake check --no-build
|
||||
|
||||
- name: Lint nomarchy-* scripts (bash -n + shellcheck)
|
||||
run: |
|
||||
# Mirror what .githooks/pre-commit runs locally, but across the
|
||||
# whole tree instead of just changed files. Pre-commit gates
|
||||
# individual commits; CI gates branches (including --no-verify
|
||||
# bypasses).
|
||||
set -e
|
||||
fail=0
|
||||
while IFS= read -r script; do
|
||||
[[ -f "$script" ]] || continue
|
||||
# Python helpers ship under the same nomarchy- prefix
|
||||
# (e.g. nomarchy-haptic-touchpad). Skip non-bash.
|
||||
head -1 "$script" | grep -qE '^#!.*\bbash\b' || continue
|
||||
if ! bash -n "$script"; then
|
||||
echo "::error file=$script::bash syntax error"
|
||||
fail=1
|
||||
fi
|
||||
if ! nix shell nixpkgs#shellcheck --command shellcheck \
|
||||
--severity=error --shell=bash "$script"; then
|
||||
echo "::error file=$script::shellcheck error-severity issue"
|
||||
fail=1
|
||||
fi
|
||||
done < <(find features/scripts/utils core/system/scripts \
|
||||
themes/engine/scripts \
|
||||
-maxdepth 1 -type f -name 'nomarchy-*')
|
||||
exit "$fail"
|
||||
|
||||
- name: docs/SCRIPTS.md is up to date
|
||||
run: |
|
||||
# Regenerate to a temp file and compare. If different, the
|
||||
# contributor forgot to run the generator (or skipped the
|
||||
# pre-commit hook). Fail loudly and tell them the fix.
|
||||
./bin/utils/nomarchy-docs-scripts --out /tmp/SCRIPTS.regen.md
|
||||
if ! diff -q docs/SCRIPTS.md /tmp/SCRIPTS.regen.md >/dev/null; then
|
||||
echo "::error::docs/SCRIPTS.md is stale."
|
||||
echo "Run: ./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md"
|
||||
echo "Then commit the regenerated file."
|
||||
echo "--- diff ---"
|
||||
diff -u docs/SCRIPTS.md /tmp/SCRIPTS.regen.md || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: installer/hardware-db.sh references real nixos-hardware modules
|
||||
run: |
|
||||
# Every 4th-pipe-field in HARDWARE_DB is a nixos-hardware module
|
||||
# name. Half the DB used to point at modules that don't exist
|
||||
# (e.g. microsoft-surface-pro-8 — there's only -pro-intel and
|
||||
# -pro-9), which made the install fail at eval time with
|
||||
# cryptic "attribute not found" errors on real laptops. This
|
||||
# step catches that regression class.
|
||||
awk -F'|' '/^ "/ { gsub(/"/,"",$4); gsub(/^[[:space:]]+|[[:space:]]+$/,"",$4); if ($4) print $4 }' \
|
||||
installer/hardware-db.sh | sort -u > /tmp/db-refs.txt
|
||||
nix eval --impure --json --expr '
|
||||
let
|
||||
nh = (builtins.getFlake (toString ./.)).inputs.nixos-hardware.nixosModules;
|
||||
in builtins.attrNames nh' \
|
||||
| nix shell nixpkgs#jq --command jq -r '.[]' | sort -u > /tmp/db-real.txt
|
||||
missing=$(comm -23 /tmp/db-refs.txt /tmp/db-real.txt)
|
||||
if [[ -n "$missing" ]]; then
|
||||
echo "::error::hardware-db.sh references nixos-hardware modules that don't exist:"
|
||||
printf ' - %s\n' $missing
|
||||
echo "Either fix the name (check the actual attr in nixos-hardware) or drop the row."
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,6 +1,6 @@
|
||||
# 👑 Nomarchy
|
||||
|
||||
**Nomarchy** is a professional-grade NixOS distribution that replicates the Omarchy Wayland workflow with a strictly declarative, flake-based architecture. It provides a highly polished, "it just works" experience for power users who want a beautiful Hyprland environment without sacrificing the reliability of NixOS.
|
||||
**Nomarchy** is a professional-grade NixOS distribution that ships a highly curated Hyprland desktop on a strictly declarative, flake-based foundation. It provides a highly polished, "it just works" experience for power users who want a beautiful Wayland environment without sacrificing the reliability of NixOS.
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
@@ -40,7 +40,8 @@ This builds a full graphical VM of the installer environment. Once inside, click
|
||||
### 2. Build the Installer ISO
|
||||
To install on physical hardware, generate your own bootable image:
|
||||
```bash
|
||||
nix build .#nixosConfigurations.nomarchy-installer.config.system.build.isoImage
|
||||
./features/scripts/utils/nomarchy-build-iso # Minimal TTY installer
|
||||
./features/scripts/utils/nomarchy-build-live-iso # Graphical try-before-install
|
||||
```
|
||||
The ISO will be located at `./result/iso/nixos-*.iso`. Flash it to a USB drive and boot.
|
||||
|
||||
@@ -114,4 +115,4 @@ Nomarchy includes dozens of productivity scripts available in your PATH. Some hi
|
||||
- `nomarchy-menu`: The central hub for all utilities and pickers.
|
||||
|
||||
---
|
||||
*Built with ❤️ using NixOS, Hyprland, Stylix, and the spirit of Omarchy.*
|
||||
*Built with ❤️ using NixOS, Hyprland, Stylix, and the Nomarchy Community.*
|
||||
|
||||
@@ -15,8 +15,7 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
sources=(
|
||||
"core/home/config/nomarchy/default/hypr/bindings/utilities.conf|Utilities"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/tiling.conf|Tiling"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf|Tiling (v2)"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf|Tiling"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/clipboard.conf|Clipboard"
|
||||
"core/home/config/nomarchy/default/hypr/bindings/media.conf|Media keys"
|
||||
"features/desktop/hyprland/config/bindings.conf|Apps & web shortcuts"
|
||||
|
||||
@@ -81,13 +81,34 @@ ref_files_per_cmd() {
|
||||
# Final char must be alphanumeric — dropping trailing-dash matches like
|
||||
# `nomarchy-pkg-` that come from glob references (`for c in nomarchy-pkg-*`).
|
||||
# Restrict to grep_includes so binaries / tmpfiles don't pollute the set.
|
||||
# We also filter out common prefix-only tokens that are false positives from
|
||||
# wildcards/expansions.
|
||||
all_refs=$(grep -rohE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
# The first `grep -vE` drops lines where `nomarchy-*` is a derivation /
|
||||
# tmp file / sudoers basename / systemd unit / flake output / docker
|
||||
# container identifier rather than a shell invocation.
|
||||
# The second `grep -vE` is a token-level safety net for prefix-only
|
||||
# tokens left over from wildcards/expansions (e.g. `nomarchy-pkg-*`).
|
||||
all_refs=$(grep -rhE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE \
|
||||
-e '(pname|name)[[:space:]]*=[[:space:]]*"nomarchy-' \
|
||||
-e '/tmp/nomarchy-' \
|
||||
-e '/etc/sudoers\.d/[^"[:space:]]*nomarchy-' \
|
||||
-e 'nixosConfigurations\.nomarchy-' \
|
||||
-e 'packages\.[^.]+\.nomarchy-' \
|
||||
-e '\./result/bin/run-nomarchy-' \
|
||||
-e 'mktemp[[:space:]]+[^|]*-t[[:space:]]+nomarchy-' \
|
||||
-e '(TIMER_NAME|NOPASSWD_FILE|UNIT_NAME)=.*nomarchy-' \
|
||||
-e 'docker[[:space:]]+[^|]*nomarchy-' \
|
||||
| grep -oE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
| grep -vE '^(nomarchy-launch|nomarchy-brightness|nomarchy-cmd|nomarchy-pkg|nomarchy-restart|nomarchy-toggle|nomarchy-theme|nomarchy-webapp-handler|nomarchy-font-selector|nomarchy-theme-selector|nomarchy-wallpaper-selector|nomarchy-setup|nomarchy-refresh|nomarchy-scripts|nomarchy-system-scripts|nomarchy-theme-engine-scripts)$' \
|
||||
| grep -vE '^(nomarchy-plymouth|nomarchy-sddm-theme|nomarchy-live|nomarchy-rev|nomarchy-windows)$' \
|
||||
| sort -u)
|
||||
# The second denylist covers identifiers whose ambiguity survives the line
|
||||
# filter: `nomarchy-plymouth` / `nomarchy-sddm-theme` are Nix derivation
|
||||
# names referenced as bare idents in `[...]` lists, `nomarchy-live` is an
|
||||
# ISO label that shows up in comments, `nomarchy-rev` is `/etc/nomarchy-rev`
|
||||
# (written by the ISO), and `nomarchy-windows` is a docker container name
|
||||
# in compose heredocs.
|
||||
|
||||
# --- Render: header --------------------------------------------------------
|
||||
|
||||
|
||||
16
core/branding/about.txt
Normal file
16
core/branding/about.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
# About Nomarchy
|
||||
|
||||
Nomarchy is a highly curated, NixOS-based distribution designed for power users.
|
||||
It features a customized Hyprland desktop environment with a declarative
|
||||
theming engine and a suite of integrated utility scripts.
|
||||
|
||||
Built on a foundation of:
|
||||
- NixOS (Linux)
|
||||
- Hyprland (Window Manager)
|
||||
- Waybar (Status Bar)
|
||||
- Walker (Application Launcher & Menu)
|
||||
- Stylix (Theming Engine)
|
||||
|
||||
Version: 2026.05.04
|
||||
Docs: https://github.com/nomarchy/nomarchy/docs
|
||||
Manual: nomarchy-manual (Command)
|
||||
11
core/branding/screensaver.txt
Normal file
11
core/branding/screensaver.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
# Nomarchy Screensaver Configuration
|
||||
|
||||
Nomarchy uses hyprlock for locking and hypridle for idle management.
|
||||
To configure the screensaver/lock screen visuals, edit:
|
||||
~/.config/hypr/hyprlock.conf
|
||||
|
||||
To configure idle timeouts and actions, edit:
|
||||
~/.config/hypr/hypridle.conf
|
||||
|
||||
You can also toggle the screensaver/idle management via the Nomarchy Menu:
|
||||
Trigger > Toggle > Idle Lock
|
||||
@@ -1,94 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
# Behavior Configuration Module
|
||||
#
|
||||
# This module deploys non-visual configuration files (keybindings, input settings,
|
||||
# window rules, etc.) with lib.mkDefault, allowing downstream users to override.
|
||||
#
|
||||
# Visual/theme configs are handled separately by theme-loader.nix and stylix.nix.
|
||||
#
|
||||
# Behavior configs include:
|
||||
# - Keybindings (bindings, media keys, clipboard)
|
||||
# - Input settings (keyboard, mouse, touchpad)
|
||||
# - Window rules and layouts
|
||||
# - Autostart applications
|
||||
# - Environment variables
|
||||
|
||||
let
|
||||
configDir = ./config;
|
||||
overridesDir = "${config.home.homeDirectory}/.config/nomarchy/overrides";
|
||||
|
||||
# Behavior config categories with their source paths
|
||||
behaviorConfigs = {
|
||||
# Hyprland behavior (non-visual)
|
||||
"nomarchy/default/hypr/bindings.conf" = "hypr/bindings.conf";
|
||||
"nomarchy/default/hypr/bindings/media.conf" = "hypr/bindings/media.conf";
|
||||
"nomarchy/default/hypr/bindings/clipboard.conf" = "hypr/bindings/clipboard.conf";
|
||||
"nomarchy/default/hypr/bindings/tiling-v2.conf" = "hypr/bindings/tiling-v2.conf";
|
||||
"nomarchy/default/hypr/bindings/utilities.conf" = "hypr/bindings/utilities.conf";
|
||||
"nomarchy/default/hypr/input.conf" = "hypr/input.conf";
|
||||
"nomarchy/default/hypr/windows.conf" = "hypr/windows.conf";
|
||||
"nomarchy/default/hypr/autostart.conf" = "hypr/autostart.conf";
|
||||
"nomarchy/default/hypr/envs.conf" = "hypr/envs.conf";
|
||||
"nomarchy/default/hypr/looknfeel.conf" = "hypr/looknfeel.conf";
|
||||
|
||||
# App-specific window rules (behavior, not visual)
|
||||
"nomarchy/default/hypr/apps.conf" = "hypr/apps.conf";
|
||||
"nomarchy/default/hypr/apps/qemu.conf" = "hypr/apps/qemu.conf";
|
||||
"nomarchy/default/hypr/apps/steam.conf" = "hypr/apps/steam.conf";
|
||||
"nomarchy/default/hypr/apps/terminals.conf" = "hypr/apps/terminals.conf";
|
||||
"nomarchy/default/hypr/apps/walker.conf" = "hypr/apps/walker.conf";
|
||||
"nomarchy/default/hypr/apps/browser.conf" = "hypr/apps/browser.conf";
|
||||
"nomarchy/default/hypr/apps/1password.conf" = "hypr/apps/1password.conf";
|
||||
"nomarchy/default/hypr/apps/bitwarden.conf" = "hypr/apps/bitwarden.conf";
|
||||
"nomarchy/default/hypr/apps/pip.conf" = "hypr/apps/pip.conf";
|
||||
"nomarchy/default/hypr/apps/system.conf" = "hypr/apps/system.conf";
|
||||
"nomarchy/default/hypr/apps/localsend.conf" = "hypr/apps/localsend.conf";
|
||||
"nomarchy/default/hypr/apps/telegram.conf" = "hypr/apps/telegram.conf";
|
||||
"nomarchy/default/hypr/apps/geforce.conf" = "hypr/apps/geforce.conf";
|
||||
"nomarchy/default/hypr/apps/moonlight.conf" = "hypr/apps/moonlight.conf";
|
||||
"nomarchy/default/hypr/apps/retroarch.conf" = "hypr/apps/retroarch.conf";
|
||||
"nomarchy/default/hypr/apps/webcam-overlay.conf" = "hypr/apps/webcam-overlay.conf";
|
||||
"nomarchy/default/hypr/apps/davinci-resolve.conf" = "hypr/apps/davinci-resolve.conf";
|
||||
"nomarchy/default/hypr/apps/hyprshot.conf" = "hypr/apps/hyprshot.conf";
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
options.nomarchy.behavior = {
|
||||
hyprland = {
|
||||
bindings = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default Hyprland keybindings.";
|
||||
};
|
||||
input = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default input settings.";
|
||||
};
|
||||
windowRules = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default window rules.";
|
||||
};
|
||||
autostart = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to deploy default autostart configuration.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
# Note: The actual config deployment is handled by configs.nix
|
||||
# This module provides the options and documentation for behavior configs
|
||||
# The separation allows users to selectively disable behavior categories
|
||||
|
||||
# Ensure behavior config directories exist in overrides
|
||||
home.activation.createBehaviorOverrideDirs = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
mkdir -p "${overridesDir}/hypr/bindings"
|
||||
mkdir -p "${overridesDir}/hypr/apps"
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -8,7 +8,7 @@ description: >
|
||||
monitors, gaps, borders, blur, opacity, waybar, walker, terminal config, themes,
|
||||
wallpaper, night light, idle, lock screen, screenshots, layer rules, workspace
|
||||
settings, display config, and user-facing nomarchy commands. Excludes Nomarchy
|
||||
source development in ~/.local/share/nomarchy/ and nomarchy-dev-* workflows.
|
||||
source development in ~/.local/share/nomarchy/ and repo-internal workflows.
|
||||
---
|
||||
|
||||
# Nomarchy Skill
|
||||
@@ -34,7 +34,7 @@ It is not for contributing to Nomarchy source code.
|
||||
|
||||
**If you're about to edit a config file in ~/.config/ on this system, STOP and use this skill first.**
|
||||
|
||||
**Do NOT use this skill for Nomarchy development tasks** (editing files in `~/.local/share/nomarchy/`, creating migrations, or running `nomarchy-dev-*` workflows).
|
||||
**Do NOT use this skill for Nomarchy development tasks** — editing files in `~/.local/share/nomarchy/` or modifying repo internals.
|
||||
|
||||
## Critical Safety Rules
|
||||
|
||||
@@ -244,6 +244,9 @@ nomarchy-theme-set <name> # Apply theme (use "Tokyo Night" not "tokyo-nig
|
||||
nomarchy-theme-next # Cycle to next theme
|
||||
nomarchy-theme-bg-next # Cycle wallpaper
|
||||
nomarchy-theme-install <url> # Install from git repo
|
||||
nomarchy-theme-remove <name> # Remove an installed extra theme
|
||||
nomarchy-theme-refresh # Re-apply current theme from templates
|
||||
nomarchy-theme-bg-install # Open backgrounds dir to drop in custom images
|
||||
```
|
||||
|
||||
### Keybindings
|
||||
@@ -311,10 +314,48 @@ nomarchy-debug --no-sudo --print # Debug info (ALWAYS use these flags)
|
||||
nomarchy-lock-screen # Lock screen
|
||||
nomarchy-system-shutdown # Shutdown
|
||||
nomarchy-system-reboot # Reboot
|
||||
nomarchy-sudo-passwordless-toggle # Toggle 15-min passwordless sudo
|
||||
nomarchy-sudo-reset # Clear sudo lockout / faillock
|
||||
nomarchy-restart-trackpad # Reload intel_quicki2c (fixes dead THC trackpad)
|
||||
```
|
||||
|
||||
**IMPORTANT:** Always run `nomarchy-debug` with `--no-sudo --print` flags to avoid interactive sudo prompts that will hang the terminal.
|
||||
|
||||
### Custom App Launchers
|
||||
|
||||
```bash
|
||||
nomarchy-webapp-install # Add a web app launcher (interactive)
|
||||
nomarchy-webapp-remove [name...] # Remove web apps (interactive if no name)
|
||||
nomarchy-webapp-remove-all # Bulk-remove every web app
|
||||
nomarchy-tui-install # Add a TUI launcher for a terminal program
|
||||
nomarchy-tui-remove [name...] # Remove TUI launchers
|
||||
nomarchy-tui-remove-all # Bulk-remove every TUI launcher
|
||||
```
|
||||
|
||||
Both families write `.desktop` files into `~/.local/share/applications/` so they appear in the app launcher (walker / rofi).
|
||||
|
||||
### Voice dictation (Voxtype)
|
||||
|
||||
```bash
|
||||
nomarchy-voxtype-install # Install Voxtype + AI model (~150MB)
|
||||
nomarchy-voxtype-remove # Uninstall Voxtype
|
||||
nomarchy-voxtype-status # Running state (also shown in waybar)
|
||||
```
|
||||
|
||||
Toggle dictation with `SUPER+CTRL+X` after install.
|
||||
|
||||
### Virtualization
|
||||
|
||||
```bash
|
||||
nomarchy-windows-vm install # Provision a Windows VM via docker-compose
|
||||
nomarchy-windows-vm launch # Connect to the VM (auto-stop on disconnect)
|
||||
nomarchy-windows-vm launch -k # Connect, keep VM running after disconnect
|
||||
nomarchy-windows-vm stop # Shut the VM down
|
||||
nomarchy-windows-vm status # Show current state
|
||||
```
|
||||
|
||||
Requires KVM (`/dev/kvm`) and Docker (enable via `nomarchy.system.virtualization.docker`).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
@@ -325,6 +366,7 @@ nomarchy-debug --no-sudo --print
|
||||
nomarchy-upload-log
|
||||
|
||||
# Reset specific config to defaults
|
||||
# Examples: nomarchy-refresh-fastfetch, nomarchy-refresh-hyprland, nomarchy-refresh-waybar
|
||||
nomarchy-refresh-<app>
|
||||
|
||||
# Refresh specific config file
|
||||
@@ -352,7 +394,7 @@ When user requests system changes:
|
||||
This skill intentionally does not cover Nomarchy source development. Do not use this skill for:
|
||||
- Editing files in `~/.local/share/nomarchy/` (`bin/`, `config/`, `default/`, `themes/`, `migrations/`, etc.)
|
||||
- Creating or editing migrations
|
||||
- Running `nomarchy-dev-*` commands
|
||||
- Modifying Nomarchy's own source tree
|
||||
|
||||
## Example Requests
|
||||
|
||||
|
||||
@@ -3,5 +3,4 @@ export SUDO_EDITOR="$EDITOR"
|
||||
export BAT_THEME=ansi
|
||||
|
||||
# Duplicated from .config/uwsm/env so SSH works too
|
||||
export NOMARCHY_PATH=$HOME/.local/share/nomarchy
|
||||
export PATH=$NOMARCHY_PATH/bin:$PATH:$HOME/.local/bin
|
||||
export PATH=$PATH:$HOME/.local/bin
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# If not running interactively, don't do anything (leave this at the top of this file)
|
||||
[[ $- != *i* ]] && return
|
||||
|
||||
# All the default Nomarchy aliases and functions
|
||||
# (don't mess with these directly, just overwrite them here!)
|
||||
source ~/.config/nomarchy/default/bash/rc
|
||||
|
||||
# Add your own exports, aliases, and functions here.
|
||||
#
|
||||
# Make an alias for invoking commands you use constantly
|
||||
# alias p='python'
|
||||
@@ -32,8 +32,7 @@ end
|
||||
function GetEntries()
|
||||
local entries = {}
|
||||
local user_theme_dir = os.getenv("HOME") .. "/.config/nomarchy/themes"
|
||||
local nomarchy_path = os.getenv("NOMARCHY_PATH") or ""
|
||||
local default_theme_dir = nomarchy_path .. "/themes"
|
||||
local default_theme_dir = os.getenv("HOME") .. "/.local/share/nomarchy/themes"
|
||||
|
||||
local seen_themes = {}
|
||||
|
||||
|
||||
@@ -12,5 +12,5 @@ bindd = SUPER, O, Obsidian, exec, obsidian -disable-gpu
|
||||
bindd = SUPER, SLASH, Password manager, exec, $passwordManager
|
||||
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/media.conf
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/tiling.conf
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/tiling-v2.conf
|
||||
source = ~/.config/nomarchy/default/hypr/bindings/utilities.conf
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
# This is now a deprecated file meant for those who did not wish to learn the latest Nomarchy hotkeys.
|
||||
# Do not make changes here, but bring them to tiling-v2.conf instead.
|
||||
|
||||
# Close windows
|
||||
bindd = SUPER, Q, Close window, killactive,
|
||||
bindd = CTRL ALT, DELETE, Close all windows, exec, nomarchy-hyprland-window-close-all
|
||||
|
||||
# Control tiling
|
||||
bindd = SUPER, J, Toggle window split, togglesplit, # dwindle
|
||||
bindd = SUPER, P, Pseudo window, pseudo, # dwindle
|
||||
bindd = SUPER SHIFT, V, Toggle window floating/tiling, togglefloating,
|
||||
bindd = SHIFT, F11, Force full screen, fullscreen, 0
|
||||
bindd = ALT, F11, Full width, fullscreen, 1
|
||||
|
||||
# Move focus with SUPER + arrow keys
|
||||
bindd = SUPER, LEFT, Move focus left, movefocus, l
|
||||
bindd = SUPER, RIGHT, Move focus right, movefocus, r
|
||||
bindd = SUPER, UP, Move focus up, movefocus, u
|
||||
bindd = SUPER, DOWN, Move focus down, movefocus, d
|
||||
|
||||
# Switch workspaces with SUPER + [0-9]
|
||||
bindd = SUPER, code:10, Switch to workspace 1, workspace, 1
|
||||
bindd = SUPER, code:11, Switch to workspace 2, workspace, 2
|
||||
bindd = SUPER, code:12, Switch to workspace 3, workspace, 3
|
||||
bindd = SUPER, code:13, Switch to workspace 4, workspace, 4
|
||||
bindd = SUPER, code:14, Switch to workspace 5, workspace, 5
|
||||
bindd = SUPER, code:15, Switch to workspace 6, workspace, 6
|
||||
bindd = SUPER, code:16, Switch to workspace 7, workspace, 7
|
||||
bindd = SUPER, code:17, Switch to workspace 8, workspace, 8
|
||||
bindd = SUPER, code:18, Switch to workspace 9, workspace, 9
|
||||
bindd = SUPER, code:19, Switch to workspace 10, workspace, 10
|
||||
|
||||
# Move active window to a workspace with SUPER + SHIFT + [0-9]
|
||||
bindd = SUPER SHIFT, code:10, Move window to workspace 1, movetoworkspace, 1
|
||||
bindd = SUPER SHIFT, code:11, Move window to workspace 2, movetoworkspace, 2
|
||||
bindd = SUPER SHIFT, code:12, Move window to workspace 3, movetoworkspace, 3
|
||||
bindd = SUPER SHIFT, code:13, Move window to workspace 4, movetoworkspace, 4
|
||||
bindd = SUPER SHIFT, code:14, Move window to workspace 5, movetoworkspace, 5
|
||||
bindd = SUPER SHIFT, code:15, Move window to workspace 6, movetoworkspace, 6
|
||||
bindd = SUPER SHIFT, code:16, Move window to workspace 7, movetoworkspace, 7
|
||||
bindd = SUPER SHIFT, code:17, Move window to workspace 8, movetoworkspace, 8
|
||||
bindd = SUPER SHIFT, code:18, Move window to workspace 9, movetoworkspace, 9
|
||||
bindd = SUPER SHIFT, code:19, Move window to workspace 10, movetoworkspace, 10
|
||||
|
||||
# TAB between workspaces
|
||||
bindd = SUPER, TAB, Next workspace, workspace, e+1
|
||||
bindd = SUPER SHIFT, TAB, Previous workspace, workspace, e-1
|
||||
bindd = SUPER CTRL, TAB, Former workspace, workspace, previous
|
||||
|
||||
# Swap active window with the one next to it with SUPER + SHIFT + arrow keys
|
||||
bindd = SUPER SHIFT, LEFT, Swap window to the left, swapwindow, l
|
||||
bindd = SUPER SHIFT, RIGHT, Swap window to the right, swapwindow, r
|
||||
bindd = SUPER SHIFT, UP, Swap window up, swapwindow, u
|
||||
bindd = SUPER SHIFT, DOWN, Swap window down, swapwindow, d
|
||||
|
||||
# Cycle through applications on active workspace
|
||||
bindd = ALT, TAB, Cycle to next window, cyclenext
|
||||
bindd = ALT SHIFT, TAB, Cycle to prev window, cyclenext, prev
|
||||
bindd = ALT, TAB, Reveal active window on top, bringactivetotop
|
||||
bindd = ALT SHIFT, TAB, Reveal active window on top, bringactivetotop
|
||||
|
||||
# Resize active window
|
||||
bindd = SUPER, code:20, Expand window left, resizeactive, -100 0 # - key
|
||||
bindd = SUPER, code:21, Shrink window left, resizeactive, 100 0 # = key
|
||||
bindd = SUPER SHIFT, code:20, Shrink window up, resizeactive, 0 -100
|
||||
bindd = SUPER SHIFT, code:21, Expand window down, resizeactive, 0 100
|
||||
|
||||
# Scroll through existing workspaces with SUPER + scroll
|
||||
bindd = SUPER, MOUSE_DOWN, Scroll active workspace forward, workspace, e+1
|
||||
bindd = SUPER, MOUSE_UP, Scroll active workspace backward, workspace, e-1
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindmd = SUPER, mouse:272, Move window, movewindow
|
||||
bindmd = SUPER, mouse:273, Resize window, resizewindow
|
||||
@@ -51,5 +51,17 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
xdg.configFile = configMappings;
|
||||
xdg.configFile = configMappings // {
|
||||
# mako reads ~/.config/mako/config by default. The themed Nomarchy
|
||||
# config (urgency rules, app filters, button handlers) lives under
|
||||
# nomarchy/default/mako/core.ini for organizational reasons, so wire
|
||||
# it explicitly here. Without this, mako silently falls back to its
|
||||
# built-in defaults and every Nomarchy notification customization is
|
||||
# inert.
|
||||
"mako/config".source = lib.mkDefault ./config/nomarchy/default/mako/core.ini;
|
||||
};
|
||||
|
||||
home.file.".XCompose" = lib.mkDefault {
|
||||
source = ./config/nomarchy/default/xcompose;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
./options.nix
|
||||
./state.nix
|
||||
./overrides.nix
|
||||
./behavior.nix
|
||||
./fonts.nix
|
||||
./configs.nix
|
||||
./security.nix
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# Defaults live in lib/state-schema.nix so they can't drift between this
|
||||
# file, core/system/options.nix, and core/home/state.nix's `or` fallbacks.
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
options.nomarchy = {
|
||||
toggles = {
|
||||
suspend = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.suspend;
|
||||
description = "Whether to show suspend in system menu.";
|
||||
};
|
||||
screensaver = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.screensaver;
|
||||
description = "Whether the screensaver is enabled.";
|
||||
};
|
||||
idle = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.idle;
|
||||
description = "Whether the idle lock is enabled.";
|
||||
};
|
||||
nightlight = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.home.nightlight;
|
||||
description = "Whether the nightlight is enabled.";
|
||||
};
|
||||
waybar = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.home.waybar;
|
||||
description = "Whether the top bar is enabled.";
|
||||
};
|
||||
skipVsCodeTheme = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to skip theme changes in VSCode.";
|
||||
};
|
||||
};
|
||||
nightlightTemperature = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 4000;
|
||||
default = schema.home.nightlightTemperature;
|
||||
description = "Temperature for the nightlight.";
|
||||
};
|
||||
theme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "summer-night";
|
||||
default = schema.home.theme;
|
||||
description = "System theme name.";
|
||||
};
|
||||
formFactor = lib.mkOption {
|
||||
@@ -58,35 +58,35 @@
|
||||
};
|
||||
wallpaper = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
default = schema.home.wallpaper;
|
||||
description = "System wallpaper path.";
|
||||
};
|
||||
panelPosition = lib.mkOption {
|
||||
type = lib.types.enum [ "top" "bottom" ];
|
||||
default = "top";
|
||||
default = schema.home.panelPosition;
|
||||
description = "Waybar panel position.";
|
||||
};
|
||||
hyprland = {
|
||||
gaps_in = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5;
|
||||
default = schema.home.hyprland.gaps_in;
|
||||
description = "Inner gaps for Hyprland.";
|
||||
};
|
||||
gaps_out = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
default = schema.home.hyprland.gaps_out;
|
||||
description = "Outer gaps for Hyprland.";
|
||||
};
|
||||
border_size = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2;
|
||||
default = schema.home.hyprland.border_size;
|
||||
description = "Border size for Hyprland.";
|
||||
};
|
||||
};
|
||||
fonts = {
|
||||
monospace = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "JetBrainsMono Nerd Font";
|
||||
default = schema.home.font;
|
||||
description = "System monospace font.";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,97 +1,34 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
# File-based override system for Nomarchy
|
||||
# File-based override system for Nomarchy.
|
||||
#
|
||||
# Users can place config files in ~/.config/nomarchy/overrides/ to completely
|
||||
# replace upstream defaults. Override priority (highest to lowest):
|
||||
# 1. User Nix options
|
||||
# 2. User file overrides (~/.config/nomarchy/overrides/)
|
||||
# 3. Upstream defaults
|
||||
# STATUS: option surface only — the actual override mechanism is NOT yet
|
||||
# implemented. The options are kept so configs that already set
|
||||
# `nomarchy.overrides.enable = …;` continue to evaluate; setting them has
|
||||
# no effect today. Tracked in docs/ROADMAP.md.
|
||||
#
|
||||
# Supported override paths:
|
||||
# - hypr/ - Hyprland configs (bindings.conf, input.conf, etc.)
|
||||
# - waybar/ - Waybar config and style
|
||||
# - alacritty/ - Alacritty terminal config
|
||||
# - walker/ - Walker launcher config
|
||||
# - kitty/ - Kitty terminal config
|
||||
# - btop/ - Btop resource monitor config
|
||||
# - apps/ - Other application configs
|
||||
# When implemented, this module should substitute sources in
|
||||
# `xdg.configFile.<path>.source` based on the presence of matching files
|
||||
# under ~/.config/nomarchy/overrides/.
|
||||
|
||||
let
|
||||
overridesDir = "${config.home.homeDirectory}/.config/nomarchy/overrides";
|
||||
|
||||
# Helper to get override from options
|
||||
getOverrideOrDefault = { path, default }:
|
||||
config.nomarchy.overrides.paths.${path} or default;
|
||||
|
||||
in
|
||||
{
|
||||
options.nomarchy.overrides = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable file-based override loading from ~/.config/nomarchy/overrides/";
|
||||
description = ''
|
||||
Reserved for the future file-based override loader. Currently a
|
||||
no-op — setting this has no effect. See docs/ROADMAP.md.
|
||||
'';
|
||||
};
|
||||
|
||||
paths = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.path;
|
||||
default = {};
|
||||
description = "Override paths discovered at build time. Populated by the override system.";
|
||||
description = ''
|
||||
Reserved for the future file-based override loader. Currently
|
||||
unused.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.nomarchy.overrides.enable {
|
||||
# Create the overrides directory structure if it doesn't exist
|
||||
home.activation.createOverridesDir = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
mkdir -p "${overridesDir}"
|
||||
mkdir -p "${overridesDir}/hypr"
|
||||
mkdir -p "${overridesDir}/waybar"
|
||||
mkdir -p "${overridesDir}/apps"
|
||||
'';
|
||||
|
||||
# Document the override system
|
||||
xdg.configFile."nomarchy/overrides/README.md".text = lib.mkDefault ''
|
||||
# Nomarchy Configuration Overrides
|
||||
|
||||
Place files in this directory to override upstream Nomarchy defaults.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
overrides/
|
||||
├── hypr/
|
||||
│ ├── bindings.conf # Keybindings
|
||||
│ ├── input.conf # Input settings
|
||||
│ ├── monitors.conf # Monitor layout
|
||||
│ ├── rules.conf # Window rules
|
||||
│ └── autostart.conf # Startup apps
|
||||
├── waybar/
|
||||
│ ├── config.jsonc # Waybar layout
|
||||
│ └── style.css # Waybar styling
|
||||
├── apps/
|
||||
│ ├── alacritty.toml # Terminal behavior
|
||||
│ └── ...
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Override Priority
|
||||
|
||||
1. **Nix Options** (highest) - Set in your flake/config
|
||||
2. **File Overrides** - Files in this directory
|
||||
3. **Upstream Defaults** (lowest) - Nomarchy defaults
|
||||
|
||||
## Usage
|
||||
|
||||
1. Copy the file you want to customize from the upstream config
|
||||
2. Place it in the appropriate directory here
|
||||
3. Edit to your preferences
|
||||
4. Run `nixos-rebuild switch` or `home-manager switch`
|
||||
|
||||
## Tips
|
||||
|
||||
- For keybindings, copy `~/.config/hypr/bindings.conf` to `overrides/hypr/`
|
||||
- For Waybar styling, copy `~/.config/waybar/style.css` to `overrides/waybar/`
|
||||
- Changes here persist across Nomarchy updates
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,42 +2,51 @@
|
||||
|
||||
let
|
||||
nomarchyLib = import ../../lib { inherit lib; };
|
||||
# Single source of truth for default values when state.json is missing
|
||||
# a key. Both core/system/options.nix and core/home/options.nix read
|
||||
# from this same file — changing a default in one place updates
|
||||
# everywhere. (Was: each consumer hardcoded its own `or X` literal,
|
||||
# which is how the summer-night/nord split lived for so long.)
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
assetsPath = ../../themes/palettes;
|
||||
|
||||
# Read unified state from ~/.config/nomarchy/state.json
|
||||
togglesState = nomarchyLib.readHomeState config.home.homeDirectory;
|
||||
in
|
||||
{
|
||||
# Every assignment uses lib.mkDefault so a downstream /etc/nixos/home.nix
|
||||
# can override the state.json-derived value. Without mkDefault, every
|
||||
# option here would resolve at default priority and conflict on
|
||||
# assignment from the user's config.
|
||||
config = {
|
||||
nomarchy = {
|
||||
toggles = {
|
||||
suspend = togglesState.suspend or true;
|
||||
screensaver = togglesState.screensaver or true;
|
||||
idle = togglesState.idle or true;
|
||||
nightlight = togglesState.nightlight or false;
|
||||
waybar = togglesState.waybar or true;
|
||||
skipVsCodeTheme = togglesState.skipVsCodeTheme or false;
|
||||
suspend = lib.mkDefault (togglesState.suspend or schema.home.suspend);
|
||||
screensaver = lib.mkDefault (togglesState.screensaver or schema.home.screensaver);
|
||||
idle = lib.mkDefault (togglesState.idle or schema.home.idle);
|
||||
nightlight = lib.mkDefault (togglesState.nightlight or schema.home.nightlight);
|
||||
waybar = lib.mkDefault (togglesState.waybar or schema.home.waybar);
|
||||
};
|
||||
nightlightTemperature = togglesState.nightlightTemperature or 4000;
|
||||
theme = togglesState.theme or "summer-night";
|
||||
wallpaper = togglesState.wallpaper or "";
|
||||
panelPosition = togglesState.panelPosition or "top";
|
||||
nightlightTemperature = lib.mkDefault (togglesState.nightlightTemperature or schema.home.nightlightTemperature);
|
||||
theme = lib.mkDefault (togglesState.theme or schema.home.theme);
|
||||
wallpaper = lib.mkDefault (togglesState.wallpaper or schema.home.wallpaper);
|
||||
panelPosition = lib.mkDefault (togglesState.panelPosition or schema.home.panelPosition);
|
||||
hyprland = {
|
||||
gaps_in = togglesState.hyprland.gaps_in or 5;
|
||||
gaps_out = togglesState.hyprland.gaps_out or 10;
|
||||
border_size = togglesState.hyprland.border_size or 2;
|
||||
gaps_in = lib.mkDefault (togglesState.hyprland.gaps_in or schema.home.hyprland.gaps_in);
|
||||
gaps_out = lib.mkDefault (togglesState.hyprland.gaps_out or schema.home.hyprland.gaps_out);
|
||||
border_size = lib.mkDefault (togglesState.hyprland.border_size or schema.home.hyprland.border_size);
|
||||
};
|
||||
fonts.monospace = togglesState.font or "JetBrainsMono Nerd Font";
|
||||
fonts.monospace = lib.mkDefault (togglesState.font or schema.home.font);
|
||||
|
||||
# Derived properties from the theme directory
|
||||
isLightMode = nomarchyLib.isThemeLightMode {
|
||||
themeName = togglesState.theme or "summer-night";
|
||||
isLightMode = lib.mkDefault (nomarchyLib.isThemeLightMode {
|
||||
themeName = togglesState.theme or schema.home.theme;
|
||||
inherit assetsPath;
|
||||
};
|
||||
iconsTheme = nomarchyLib.getIconsTheme {
|
||||
themeName = togglesState.theme or "summer-night";
|
||||
});
|
||||
iconsTheme = lib.mkDefault (nomarchyLib.getIconsTheme {
|
||||
themeName = togglesState.theme or schema.home.theme;
|
||||
inherit assetsPath;
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ let
|
||||
pname = "nomarchy-font";
|
||||
version = "1.0";
|
||||
# Point directly to the font file
|
||||
src = ./../home/config/Nomarchy.ttf;
|
||||
src = ./../branding/Nomarchy.ttf;
|
||||
# No archive to unpack
|
||||
unpackPhase = "true";
|
||||
installPhase = ''
|
||||
|
||||
@@ -70,8 +70,47 @@ in
|
||||
})
|
||||
|
||||
(mkIf config.nomarchy.system.features.hybridGPU {
|
||||
# supergfxd manages mode switching (Integrated / Hybrid / Vfio /
|
||||
# AsusEgpu). It blacklists/unblacklists the nvidia kernel module via
|
||||
# /etc/modprobe.d/ depending on the active mode. ExecStartPre sleep
|
||||
# gives udev time to settle so the daemon doesn't see a half-attached
|
||||
# GPU on cold boot.
|
||||
services.supergfxd.enable = true;
|
||||
systemd.services.supergfxd.serviceConfig.ExecStartPre = "-${pkgs.coreutils}/bin/sleep 5";
|
||||
|
||||
# Load the NVIDIA driver so the dGPU has something to drive. Without
|
||||
# these, supergfxd switches modes successfully but the X/Wayland
|
||||
# stack has no NVIDIA driver loaded — render-offload silently no-ops
|
||||
# and Hyprland renders everything on the iGPU regardless of mode.
|
||||
# mkDefault throughout so downstream system.nix can override
|
||||
# (pin to a beta driver, flip to the open kernel module, etc.).
|
||||
services.xserver.videoDrivers = lib.mkDefault [ "nvidia" ];
|
||||
hardware.graphics.enable = lib.mkDefault true;
|
||||
hardware.graphics.enable32Bit = lib.mkDefault true;
|
||||
hardware.nvidia = {
|
||||
modesetting.enable = lib.mkDefault true;
|
||||
powerManagement.enable = lib.mkDefault true;
|
||||
open = lib.mkDefault false;
|
||||
package = lib.mkDefault config.boot.kernelPackages.nvidiaPackages.stable;
|
||||
};
|
||||
# Required for Wayland compositors (Hyprland) to render via NVIDIA.
|
||||
boot.kernelParams = [ "nvidia-drm.modeset=1" ];
|
||||
|
||||
# PRIME render-offload (the part that lets `nvidia-offload <cmd>`
|
||||
# actually use the dGPU) needs bus IDs, which are per-machine.
|
||||
# We deliberately don't enable `hardware.nvidia.prime.offload.enable`
|
||||
# here — without the correct intelBusId / nvidiaBusId the nvidia
|
||||
# kernel module panics on load. The user adds this to their own
|
||||
# /etc/nixos/system.nix after running `lspci -D`:
|
||||
#
|
||||
# hardware.nvidia.prime = {
|
||||
# offload.enable = true;
|
||||
# offload.enableOffloadCmd = true;
|
||||
# intelBusId = "PCI:0:2:0"; # or amdgpuBusId for AMD iGPU
|
||||
# nvidiaBusId = "PCI:1:0:0";
|
||||
# };
|
||||
#
|
||||
# See docs/OPTIONS.md for the full recipe.
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ in
|
||||
settings.Login = {
|
||||
HandleLidSwitch = lib.mkDefault "suspend-then-hibernate";
|
||||
HandleLidSwitchExternalPower = lib.mkDefault "suspend";
|
||||
HandlePowerKey = "hibernate";
|
||||
IdleAction = "suspend-then-hibernate";
|
||||
IdleActionSec = toString (cfg.idleMinutes * 60);
|
||||
HandlePowerKey = lib.mkDefault "hibernate";
|
||||
IdleAction = lib.mkDefault "suspend-then-hibernate";
|
||||
IdleActionSec = lib.mkDefault (toString (cfg.idleMinutes * 60));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,13 +10,39 @@ in
|
||||
|
||||
options.nomarchy.system.impermanence = {
|
||||
enable = lib.mkEnableOption "Erase Your Darlings (Impermanence) root wipe on boot";
|
||||
|
||||
# The disko layout names the main LUKS mapping `crypted` on single-disk
|
||||
# installs and `crypted_main` on multi-disk installs (see
|
||||
# installer/disko-config.nix: `mainLuksName`). The rollback hook must
|
||||
# mount the right device, otherwise initrd fails on every boot and the
|
||||
# @ → root-blank snapshot is never restored.
|
||||
mainLuksName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "crypted";
|
||||
description = ''
|
||||
Name of the /dev/mapper entry holding the BTRFS root. Set to
|
||||
"crypted_main" on multi-disk installs to match the disko layout.
|
||||
'';
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nomarchy";
|
||||
description = ''
|
||||
Primary user whose home subset (.ssh, .gnupg, keyrings, common
|
||||
directories) survives the rootfs wipe. Must match the user
|
||||
created via `users.users.<name>` — otherwise the persistence
|
||||
block is silently inert and the user's home directory is wiped
|
||||
on every boot. The installer writes this for you.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# 1. The Rollback Script: Runs in initrd before filesystems are mounted
|
||||
boot.initrd.postDeviceCommands = lib.mkAfter ''
|
||||
mkdir -p /btrfs_tmp
|
||||
mount -o subvol=/ /dev/mapper/crypted /btrfs_tmp
|
||||
mount -o subvol=/ /dev/mapper/${cfg.mainLuksName} /btrfs_tmp
|
||||
|
||||
if [[ -e /btrfs_tmp/@ ]]; then
|
||||
mkdir -p /btrfs_tmp/old_roots
|
||||
@@ -58,7 +84,7 @@ in
|
||||
"/etc/machine-id"
|
||||
"/etc/supergfxd.conf"
|
||||
];
|
||||
users.nomarchy = {
|
||||
users.${cfg.user} = {
|
||||
directories = [
|
||||
".ssh"
|
||||
".gnupg"
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
|
||||
# Optimize storage by hard-linking identical files
|
||||
auto-optimise-store = lib.mkDefault true;
|
||||
|
||||
# Bump the substituter download buffer from the 64 MiB default to
|
||||
# 512 MiB. Large NARs (kernels, electron apps, the full NixOS
|
||||
# closure on first install) overrun 64 MiB and Nix prints
|
||||
# "download buffer is full" until the consumer catches up — the
|
||||
# warning is harmless but slows substitution and looks like an
|
||||
# error. 512 MiB comfortably covers everything in our closure.
|
||||
download-buffer-size = 524288000;
|
||||
};
|
||||
|
||||
# Populates NIX_PATH with the nixpkgs input from the flake.
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# Defaults live in lib/state-schema.nix so they can't drift between this
|
||||
# file, core/home/options.nix, and core/home/state.nix's `or` fallbacks.
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
options.nomarchy.system = {
|
||||
dns = lib.mkOption {
|
||||
type = lib.types.enum [ "Cloudflare" "Google" "DHCP" "Custom" ];
|
||||
default = "DHCP";
|
||||
default = schema.system.dns;
|
||||
description = "Selected DNS provider.";
|
||||
};
|
||||
customDns = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
default = schema.system.customDns;
|
||||
description = "List of custom DNS servers.";
|
||||
};
|
||||
wifi = {
|
||||
powersave = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
default = schema.system.wifi.powersave;
|
||||
description = "Whether to enable wifi power saving.";
|
||||
};
|
||||
};
|
||||
timezone = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "UTC";
|
||||
default = schema.system.timezone;
|
||||
description = "System timezone.";
|
||||
};
|
||||
formFactor = lib.mkOption {
|
||||
@@ -39,23 +44,23 @@
|
||||
features = {
|
||||
fingerprint = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.system.features.fingerprint;
|
||||
description = "Whether to enable fingerprint support.";
|
||||
};
|
||||
fido2 = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.system.features.fido2;
|
||||
description = "Whether to enable FIDO2 support.";
|
||||
};
|
||||
hybridGPU = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
default = schema.system.features.hybridGPU;
|
||||
description = "Whether to enable hybrid GPU support (supergfxd).";
|
||||
};
|
||||
};
|
||||
theme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "summer-night";
|
||||
default = schema.system.theme;
|
||||
description = "Selected system theme.";
|
||||
};
|
||||
|
||||
|
||||
@@ -55,8 +55,7 @@ pkgs.stdenv.mkDerivation {
|
||||
for file in $out/bin/*; do
|
||||
if [ -f "$file" ]; then
|
||||
wrapProgram "$file" \
|
||||
--prefix PATH : "$deps" \
|
||||
--set NOMARCHY_PATH "/etc/nixos/nomarchy"
|
||||
--prefix PATH : "$deps"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
@@ -2,4 +2,13 @@
|
||||
|
||||
{
|
||||
environment.systemPackages = [ pkgs.nomarchy-system-scripts ];
|
||||
|
||||
# /etc/nixos is owned by root, but `nomarchy-env-update` (and `nix
|
||||
# flake` invocations) run as the user and shell out to git. Without
|
||||
# this, git refuses with "dubious ownership in repository" and HM
|
||||
# evaluation fails. Mark both the standard and impermanence-relocated
|
||||
# paths as safe at the system level so every user is covered.
|
||||
programs.git.config = {
|
||||
safe.directory = [ "/etc/nixos" "/persist/etc/nixos" ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Returns true if a battery is present on the system.
|
||||
# Used by the battery monitor and other battery-related checks.
|
||||
|
||||
for bat in /sys/class/power_supply/BAT*; do
|
||||
[[ -r $bat/present ]] &&
|
||||
[[ $(cat $bat/present) == "1" ]] &&
|
||||
[[ $(cat $bat/type) == "Battery" ]] &&
|
||||
exit 0
|
||||
done
|
||||
|
||||
exit 1
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Prompt for sudo once and keep the credential alive in the background.
|
||||
# Source this script so the trap applies to the calling shell:
|
||||
# source nomarchy-sudo-keepalive
|
||||
|
||||
sudo -v
|
||||
while true; do sudo -n true; sleep 60; done 2>/dev/null &
|
||||
SUDO_KEEPALIVE_PID=$!
|
||||
trap "kill $SUDO_KEEPALIVE_PID 2>/dev/null" EXIT
|
||||
@@ -2,19 +2,28 @@
|
||||
|
||||
let
|
||||
nomarchyLib = import ../../lib { inherit lib; };
|
||||
# Same canonical schema as core/home/state.nix and the options.nix
|
||||
# files — keeps every state default in one place.
|
||||
schema = import ../../lib/state-schema.nix { inherit lib; };
|
||||
systemState = nomarchyLib.readSystemState;
|
||||
in
|
||||
{
|
||||
# Every assignment is lib.mkDefault so a downstream /etc/nixos/system.nix
|
||||
# can still set e.g. `nomarchy.system.features.hybridGPU = true;`
|
||||
# without colliding with the state.json-derived value. Without
|
||||
# mkDefault, every state.json-driven option was unoverridable from
|
||||
# Nix — flipping hybridGPU required jq'ing the state file rather
|
||||
# than declaring it in your config.
|
||||
config.nomarchy.system = {
|
||||
dns = systemState.dns or "DHCP";
|
||||
customDns = systemState.customDns or [];
|
||||
wifi.powersave = systemState.wifi.powersave or true;
|
||||
timezone = systemState.timezone or "UTC";
|
||||
dns = lib.mkDefault (systemState.dns or schema.system.dns);
|
||||
customDns = lib.mkDefault (systemState.customDns or schema.system.customDns);
|
||||
wifi.powersave = lib.mkDefault (systemState.wifi.powersave or schema.system.wifi.powersave);
|
||||
timezone = lib.mkDefault (systemState.timezone or schema.system.timezone);
|
||||
features = {
|
||||
fingerprint = systemState.features.fingerprint or false;
|
||||
fido2 = systemState.features.fido2 or false;
|
||||
hybridGPU = systemState.features.hybridGPU or false;
|
||||
fingerprint = lib.mkDefault (systemState.features.fingerprint or schema.system.features.fingerprint);
|
||||
fido2 = lib.mkDefault (systemState.features.fido2 or schema.system.features.fido2);
|
||||
hybridGPU = lib.mkDefault (systemState.features.hybridGPU or schema.system.features.hybridGPU);
|
||||
};
|
||||
theme = systemState.theme or "nord";
|
||||
theme = lib.mkDefault (systemState.theme or schema.system.theme);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -41,8 +41,7 @@ core/ Foundational OS + user defaults. Don't put apps here.
|
||||
scripts/ Low-level system scripts (battery, brightness, hardware).
|
||||
home/ Home Manager modules.
|
||||
options.nix Most home-side nomarchy.* options.
|
||||
behavior.nix nomarchy.behavior.* (deploy-default-config toggles).
|
||||
overrides.nix File-based overrides from ~/.config/nomarchy/overrides/.
|
||||
overrides.nix nomarchy.overrides.* (reserved; currently no-op — see ROADMAP).
|
||||
config/ Plain dotfiles symlinked into ~/.config.
|
||||
|
||||
features/ Apps and desktop components. Add new apps here.
|
||||
|
||||
@@ -59,63 +59,6 @@ _Source: `core/home/config/nomarchy/default/hypr/bindings/utilities.conf`_
|
||||
|
||||
## Tiling
|
||||
|
||||
_Source: `core/home/config/nomarchy/default/hypr/bindings/tiling.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
| --- | --- | --- |
|
||||
| SUPER | Q | Close window |
|
||||
| CTRL ALT | DELETE | Close all windows |
|
||||
| SUPER | J | Toggle window split |
|
||||
| SUPER | P | Pseudo window |
|
||||
| SUPER SHIFT | V | Toggle window floating/tiling |
|
||||
| SHIFT | F11 | Force full screen |
|
||||
| ALT | F11 | Full width |
|
||||
| SUPER | LEFT | Move focus left |
|
||||
| SUPER | RIGHT | Move focus right |
|
||||
| SUPER | UP | Move focus up |
|
||||
| SUPER | DOWN | Move focus down |
|
||||
| SUPER | 1 | Switch to workspace 1 |
|
||||
| SUPER | 2 | Switch to workspace 2 |
|
||||
| SUPER | 3 | Switch to workspace 3 |
|
||||
| SUPER | 4 | Switch to workspace 4 |
|
||||
| SUPER | 5 | Switch to workspace 5 |
|
||||
| SUPER | 6 | Switch to workspace 6 |
|
||||
| SUPER | 7 | Switch to workspace 7 |
|
||||
| SUPER | 8 | Switch to workspace 8 |
|
||||
| SUPER | 9 | Switch to workspace 9 |
|
||||
| SUPER | 0 | Switch to workspace 10 |
|
||||
| SUPER SHIFT | 1 | Move window to workspace 1 |
|
||||
| SUPER SHIFT | 2 | Move window to workspace 2 |
|
||||
| SUPER SHIFT | 3 | Move window to workspace 3 |
|
||||
| SUPER SHIFT | 4 | Move window to workspace 4 |
|
||||
| SUPER SHIFT | 5 | Move window to workspace 5 |
|
||||
| SUPER SHIFT | 6 | Move window to workspace 6 |
|
||||
| SUPER SHIFT | 7 | Move window to workspace 7 |
|
||||
| SUPER SHIFT | 8 | Move window to workspace 8 |
|
||||
| SUPER SHIFT | 9 | Move window to workspace 9 |
|
||||
| SUPER SHIFT | 0 | Move window to workspace 10 |
|
||||
| SUPER | TAB | Next workspace |
|
||||
| SUPER SHIFT | TAB | Previous workspace |
|
||||
| SUPER CTRL | TAB | Former workspace |
|
||||
| SUPER SHIFT | LEFT | Swap window to the left |
|
||||
| SUPER SHIFT | RIGHT | Swap window to the right |
|
||||
| SUPER SHIFT | UP | Swap window up |
|
||||
| SUPER SHIFT | DOWN | Swap window down |
|
||||
| ALT | TAB | Cycle to next window |
|
||||
| ALT SHIFT | TAB | Cycle to prev window |
|
||||
| ALT | TAB | Reveal active window on top |
|
||||
| ALT SHIFT | TAB | Reveal active window on top |
|
||||
| SUPER | code:20 | Expand window left |
|
||||
| SUPER | code:21 | Shrink window left |
|
||||
| SUPER SHIFT | code:20 | Shrink window up |
|
||||
| SUPER SHIFT | code:21 | Expand window down |
|
||||
| SUPER | MOUSE_DOWN | Scroll active workspace forward |
|
||||
| SUPER | MOUSE_UP | Scroll active workspace backward |
|
||||
| SUPER | mouse:272 | Move window |
|
||||
| SUPER | mouse:273 | Resize window |
|
||||
|
||||
## Tiling (v2)
|
||||
|
||||
_Source: `core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf`_
|
||||
|
||||
| Modifiers | Key | Action |
|
||||
|
||||
@@ -210,7 +210,7 @@ and it's whichever has higher Nix priority. Fix these explicitly:
|
||||
| Graphics | `hardware.graphics.enable = true` (was `hardware.opengl`) | Probably already enabled — fine |
|
||||
| User groups | needs `video render networkmanager` | Add to your `users.users.<user>.extraGroups` |
|
||||
| `/etc/os-release` | `ID=nomarchy`, `NAME=Nomarchy` | A few third-party scripts grep `ID=nixos` — adjust them or rely on `ID_LIKE` (TBD) |
|
||||
| autoLogin | `enable = true; user = "nomarchy";` (mkDefault) | Override with `services.displayManager.autoLogin.user = "<your user>"` or disable |
|
||||
| autoLogin | `enable = false; user = "nomarchy";` (mkDefault) | Off by default — opt in with `services.displayManager.autoLogin = { enable = true; user = "<your user>"; };` if you want it |
|
||||
|
||||
Impermanence is **off** unless you set `nomarchy.system.impermanence.enable = true`,
|
||||
and it requires a BTRFS layout with a `root-blank` snapshot. Don't enable it
|
||||
|
||||
@@ -53,7 +53,25 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
|
||||
### `nomarchy.system.features.hybridGPU`
|
||||
|
||||
`bool`, default `false`. Enables `services.supergfxd.enable` for laptops with switchable GPUs.
|
||||
`bool`, default `false`. NVIDIA-hybrid laptop support. Wires:
|
||||
|
||||
- `services.supergfxd.enable` for runtime mode switching (`Integrated` / `Hybrid` / `Vfio` / `AsusEgpu`), driven by `nomarchy-toggle-hybrid-gpu`.
|
||||
- The NVIDIA driver stack (`services.xserver.videoDrivers = ["nvidia"]`, `hardware.graphics.{enable,enable32Bit}`, `hardware.nvidia.{modesetting,powerManagement}.enable`, `boot.kernelParams = ["nvidia-drm.modeset=1"]`).
|
||||
|
||||
All driver knobs use `lib.mkDefault`, so a downstream `system.nix` can pin a beta driver or flip to the open kernel module without forking the module.
|
||||
|
||||
**You still have to add bus IDs** — they're per-machine and can't be derived from any flag. Find them with `lspci -D | grep -E 'VGA|3D'`, then in your `/etc/nixos/system.nix`:
|
||||
|
||||
```nix
|
||||
hardware.nvidia.prime = {
|
||||
offload.enable = true;
|
||||
offload.enableOffloadCmd = true;
|
||||
intelBusId = "PCI:0:2:0"; # or `amdgpuBusId` for AMD iGPU
|
||||
nvidiaBusId = "PCI:1:0:0";
|
||||
};
|
||||
```
|
||||
|
||||
Without prime config, supergfxd still switches modes but render-offload via `nvidia-offload <cmd>` is unavailable.
|
||||
|
||||
### `nomarchy.system.snapper.enable`
|
||||
|
||||
@@ -135,10 +153,18 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
|
||||
`bool`, default `false`. Intel IPU7 camera support (kernel modules + firmware).
|
||||
|
||||
### `impermanence.enable`
|
||||
### `nomarchy.system.impermanence.enable`
|
||||
|
||||
`bool`, default `false`. Erase Your Darlings root wipe on boot. Defined in `core/system/impermanence.nix`. The installer writes the flag based on the impermanence prompt.
|
||||
|
||||
### `nomarchy.system.impermanence.mainLuksName`
|
||||
|
||||
`str`, default `"crypted"`. Name of the `/dev/mapper` entry holding the BTRFS root. The disko layout uses `"crypted"` on single-disk installs and `"crypted_main"` once multiple drives are selected — the installer writes the matching value automatically.
|
||||
|
||||
### `nomarchy.system.impermanence.user`
|
||||
|
||||
`str`, default `"nomarchy"`. Primary user whose home subset (`.ssh`, `.gnupg`, `.local/share/keyrings`, `Documents`, `Downloads`, `Pictures`, `Videos`, `Projects`) survives the rootfs wipe. Must match the user created via `users.users.<name>` — otherwise the persistence block is silently inert and the user's home directory is wiped on every boot. The installer writes this for you.
|
||||
|
||||
---
|
||||
|
||||
## Home Manager options (`home.nix`)
|
||||
@@ -179,10 +205,6 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
|
||||
`bool`, default `true`. Whether the top bar is deployed at all.
|
||||
|
||||
### `nomarchy.toggles.skipVsCodeTheme`
|
||||
|
||||
`bool`, default `false`. Skip theme overrides in VSCode — useful if you manage VSCode themes yourself.
|
||||
|
||||
### `nomarchy.nightlightTemperature`
|
||||
|
||||
`int`, default `4000`. Nightlight color temperature (Kelvin).
|
||||
@@ -205,11 +227,11 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
|
||||
### `nomarchy.iconsTheme`
|
||||
|
||||
`str`, default `"Yaru-blue"`. GTK/Qt icon theme name.
|
||||
`str`, default derived from the active theme (falls back to `"Yaru-blue"`). GTK/Qt icon theme name. `core/home/state.nix` computes this from the theme's palette metadata; override to pin a specific icon theme regardless of palette.
|
||||
|
||||
### `nomarchy.isLightMode`
|
||||
|
||||
`bool`, default `false`. Whether the active theme is a light theme. Affects nightlight defaults and a few app theme decisions.
|
||||
`bool`, default derived from the active theme. Whether the active theme is a light theme. `core/home/state.nix` computes this from the theme directory; affects nightlight defaults and a few app theme decisions. Override only if you need to force a specific value.
|
||||
|
||||
### `nomarchy.cursor.name`
|
||||
|
||||
@@ -221,23 +243,7 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
|
||||
### `nomarchy.configOverrides`
|
||||
|
||||
`nullOr path`, default `null`. Path to a directory containing config overrides. See "Overrides" below.
|
||||
|
||||
### `nomarchy.behavior.hyprland.bindings`
|
||||
|
||||
`bool`, default `true`. Deploy the default Hyprland keybindings. Set to `false` if you want to write `bindings.conf` from scratch.
|
||||
|
||||
### `nomarchy.behavior.hyprland.input`
|
||||
|
||||
`bool`, default `true`. Deploy default input settings (kb_layout, mouse accel, etc).
|
||||
|
||||
### `nomarchy.behavior.hyprland.windowRules`
|
||||
|
||||
`bool`, default `true`. Deploy default window rules.
|
||||
|
||||
### `nomarchy.behavior.hyprland.autostart`
|
||||
|
||||
`bool`, default `true`. Deploy the default `autostart.conf` (hypridle, mako, swayosd, nm-applet, etc).
|
||||
`nullOr path`, default `null`. Path to a replacement config directory. When set, the items listed in `core/home/configs.nix` (`fastfetch`, `fcitx5`, `fontconfig`, `git`, `imv`, `nautilus-python`, `nomarchy`, `nomarchy-skill`, `uwsm`, `wiremix`, plus the loose files) are read from `<this-path>/<name>` instead of the bundled defaults. Distinct from `nomarchy.overrides.*` below — `configOverrides` is a working bulk redirect; `overrides.*` is a reserved option surface (currently a no-op).
|
||||
|
||||
### `nomarchy.apps.opencode.enable`
|
||||
|
||||
@@ -253,19 +259,19 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
|
||||
### `nomarchy.themeLoader.enable`
|
||||
|
||||
`bool`, default `true`. Auto-load theme-specific app configs (btop, waybar, mako, kitty, alacritty) from the active theme. Disable if you want to provide your own.
|
||||
`bool`, default `true`. Auto-load theme-specific app configs from the active theme's `apps/` directory. Disable if you want to provide your own.
|
||||
|
||||
### `nomarchy.themeLoader.apps.{btop,waybar,mako,kitty,alacritty}`
|
||||
### `nomarchy.themeLoader.apps.btop`
|
||||
|
||||
`bool`, default `true` each. Per-app toggles for the theme loader — pick which apps follow the active theme.
|
||||
`bool`, default `true`. Deploy the active theme's `apps/btop.theme` to `~/.config/btop/themes/nomarchy.theme`. The only per-app toggle in this group — waybar themes inline from `colorScheme` in `features/desktop/waybar`; kitty and alacritty are themed by stylix targets (`themes/engine/stylix.nix`); mako has no theme integration yet.
|
||||
|
||||
### `nomarchy.overrides.enable`
|
||||
|
||||
`bool`, default `true`. Enable file-based overrides loaded from `~/.config/nomarchy/overrides/`. With this on, Nomarchy looks for matching files in that directory and substitutes them for the bundled defaults.
|
||||
`bool`, default `true`. **Reserved — currently a no-op.** Intended to gate a future file-based override loader (drop a file under `~/.config/nomarchy/overrides/`, have it substitute the bundled default for that path). The option exists so configs that set it don't fail to evaluate; setting it has no effect today. Use `nomarchy.configOverrides` for bulk redirection, or set `xdg.configFile.<path>.source` directly in your `home.nix` for per-file overrides — Nomarchy's defaults use `lib.mkDefault` and yield to higher-priority assignments. Tracked in `docs/ROADMAP.md`.
|
||||
|
||||
### `nomarchy.overrides.paths`
|
||||
|
||||
`attrsOf path`, default `{}`. Override paths discovered at build time. Populated by the override system — you don't normally set this directly.
|
||||
`attrsOf path`, default `{}`. **Reserved — currently unused.** Will be populated by the future override loader.
|
||||
|
||||
---
|
||||
|
||||
@@ -297,15 +303,17 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
||||
}
|
||||
```
|
||||
|
||||
### Disable Nomarchy's default Hyprland keybindings to ship your own
|
||||
### Ship your own Hyprland keybindings instead of Nomarchy's defaults
|
||||
|
||||
Nomarchy deploys its `bindings.conf` with `lib.mkDefault`, so a higher-priority assignment from your own `home.nix` wins:
|
||||
|
||||
```nix
|
||||
{
|
||||
nomarchy.behavior.hyprland.bindings = false;
|
||||
xdg.configFile."hypr/bindings.conf".source = ./my-bindings.conf;
|
||||
}
|
||||
```
|
||||
|
||||
Then put your own `bindings.conf` at `~/.config/nomarchy/overrides/hypr/bindings.conf` (with `nomarchy.overrides.enable = true;`, which is the default).
|
||||
The same pattern works for any file Nomarchy deploys via `xdg.configFile.<path>.source = lib.mkDefault …` — point at your own file and skip the default.
|
||||
|
||||
---
|
||||
|
||||
@@ -315,7 +323,6 @@ Then put your own `bindings.conf` at `~/.config/nomarchy/overrides/hypr/bindings
|
||||
- `core/system/hardware.nix` — `nomarchy.hardware.*`
|
||||
- `core/system/impermanence.nix` — `impermanence.enable`
|
||||
- `core/home/options.nix` — most home-side `nomarchy.*` options
|
||||
- `core/home/behavior.nix` — `nomarchy.behavior.*`
|
||||
- `core/home/overrides.nix` — `nomarchy.overrides.*`
|
||||
- `core/home/overrides.nix` — `nomarchy.overrides.*` (reserved; currently no-op)
|
||||
- `themes/engine/loader.nix` — `nomarchy.themeLoader.*`
|
||||
- `features/apps/vscode.nix` — `nomarchy.vscode.*`
|
||||
|
||||
@@ -19,13 +19,16 @@ Guardrails (apply when adding anything):
|
||||
|
||||
### Now (ready to pick up)
|
||||
|
||||
- **Thorough Out-of-the-Box QA Audit.** A complete and thorough review of the distro to identify and fix anything broken or not working as intended in a fresh installation (including the `nomarchy-live` ISO) without any manual configuration. Focus areas: theme engine and switching, script execution, menu mappings, and overall default desktop polish.
|
||||
- **Full QA audit of shipped features.** Walk every feature/component end-to-end on a real install, fix what's small, log what's not. Runs as per-component PR sweeps — methodology in [Pillar 8](#8-pillar-qa-audit--features--components).
|
||||
- **Installer: "What's installed?" summary on first boot.** Surface what the installer actually wrote (theme, font, profiles, drives, form factor) from `state.json` + `nomarchy-system-scripts` introspection so the user can verify before they start customising. Detail in [Pillar 4](#4-pillar-installer).
|
||||
- **Installer: optional non-LUKS branch.** Let users explicitly opt out of FDE during install. Detail in [Pillar 4](#4-pillar-installer).
|
||||
|
||||
### Next (bigger lifts that build on Now)
|
||||
|
||||
- **Accessibility — home-side companion.** Hyprland-side bits the system preset can't reach: slower `input.repeat_rate` / `repeat_delay` defaults, `SUPER+ALT+S` keybinding to launch Orca, and a high-contrast palette under `themes/palettes/`. Gated on a new `nomarchy.accessibility.enable` mirror of the system option.
|
||||
- **Gaming — declarative flathub remote.** `services.flatpak.enable` doesn't ship a declarative remote API in nixpkgs. Either add the `flatpak-managed-install` overlay, write a one-shot systemd unit that runs `flatpak remote-add --if-not-exists flathub …`, or surface the manual step in `nomarchy-welcome`.
|
||||
- **Plymouth theme variants per palette.** Currently one Plymouth theme; could template per-palette so the boot splash matches the active theme.
|
||||
- **Implement `nomarchy.overrides.*` file-based override loader.** The option surface is declared in `core/home/overrides.nix` but the loader doesn't exist — files dropped under `~/.config/nomarchy/overrides/` are ignored. Spec: when `overrides.enable = true`, for each `xdg.configFile.<path>` Nomarchy deploys with `lib.mkDefault`, check whether `~/.config/nomarchy/overrides/<path>` exists at build time; if so, use it as the source. Requires deciding whether discovery happens at activation time (cheap, but rebuild-required to pick up new files) or via a populated `paths` attrset (Nix-side, evaluated once per rebuild). Until shipped, document the per-file workaround (`xdg.configFile.<path>.source = ./mine`) in OPTIONS.md.
|
||||
|
||||
### Later (speculative or research-shaped)
|
||||
|
||||
@@ -37,6 +40,12 @@ Guardrails (apply when adding anything):
|
||||
- **Forgejo release pipeline.** `vYY.MM.x` tags matching the upstream NixOS channel; the pipeline pushes the three ISOs and an updated `flake.lock` snapshot.
|
||||
- **Optional `nomarchy-installer-vm`** rebuilt as a real flake app (not a one-off shell script) so users can install Nomarchy into a libvirt VM declaratively.
|
||||
- **Surface support module** via the relevant `nixos-hardware` profile + Surface kernel patches behind a `nomarchy.hardware.isSurface` toggle.
|
||||
- **Consolidate palette imports in `flake.nix` via `nomarchyLib`.** `flake.nix:79-80` re-imports `./themes/palettes` and recomputes `themeNames` even though `lib/default.nix` already exports both. Two computations, same result today — drift risk tomorrow. Import `nomarchyLib = import ./lib { inherit lib; }` once and use `nomarchyLib.{palettes,themeNames}` to make `lib/default.nix` the single source of truth for the theme list.
|
||||
- **Decide what to do about `features/apps/chromium/Default/Preferences`.** The module deploys a static 204-byte `Default/Preferences` (setting `extensions.theme.use_system = false`, `browser.theme.color_scheme = 2`) into chromium's mutable profile directory via Home Manager symlink. Chromium expects to write that file at runtime, so either the symlink is silently replaced on first save (losing the static defaults) or the write fails silently. The real chromium theming work happens via managed policies in `core/system/browser.nix`. Probably the user-profile deployment should be removed; needs someone with chromium-internals knowledge to confirm before deletion.
|
||||
- **`themes/templates/*.tpl` — decide what these are for.** Eleven mustache-style templates (`alacritty.toml.tpl`, `btop.theme.tpl`, `kitty.conf.tpl`, etc.) are deployed to `~/.local/share/nomarchy/templates/` via `themes/engine/files.nix`, but no script in the tree consumes them. Likely vestigial from a pre-stylix templating system. Either delete the directory + the `xdg.dataFile` deployment, or document them as user-reference assets and explain how to use them.
|
||||
- **Move `programs.uwsm` Hyprland session out of `core/system/virtualization.nix`.** Session-manager config is wired in the virtualization module by historical accident — it's loaded unconditionally on every install and has nothing to do with libvirt/docker. Move to a dedicated `core/system/session.nix` (or fold into the Hyprland feature module) so the location matches the responsibility.
|
||||
- **Route installer keymap into Hyprland's Wayland session.** `core/home/config/nomarchy/default/hypr/input.conf:3` hardcodes `kb_layout = us`. The installer writes `services.xserver.xkb.layout = "$KEYMAP_LAYOUT"` (and `console.keyMap`), but Hyprland reads its own input config on native Wayland, so a non-US user's chosen layout works in XWayland apps and the TTY console but not in native Wayland apps — surprising and inconsistent. Fix paths: (a) template `input.conf` from a new `nomarchy.keymap.{layout,variant}` home option that the installer writes alongside `formFactor`, or (b) propagate `XKB_DEFAULT_LAYOUT` via session env so Hyprland's fallback kicks in. Option (a) is the durable fix; needs the installer's heredoc to add the option write.
|
||||
- **Make `nomarchy.toggles.waybar` a Nix-level gate, or document it as runtime-only.** Today the toggle is exported as `NOMARCHY_TOGGLE_WAYBAR` env, consumed only by `nomarchy-toggle-waybar` (which pkill/exec's at runtime). The Nix module always sets `programs.waybar.enable = lib.mkDefault true`, so waybar comes back on every rebuild/reboot regardless of the toggle. Inconsistent with `toggles.idle`, which correctly gates `services.hypridle.enable`. Either gate `programs.waybar.enable` on the toggle (persistent) or rename the option to make its session-only nature obvious.
|
||||
|
||||
## 3. Pillar: Script & menu audit
|
||||
|
||||
@@ -73,31 +82,31 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes,
|
||||
|
||||
## 4. Pillar: Installer
|
||||
|
||||
- Software-profile multi-select (Now).
|
||||
- "What's installed?" summary screen on boot of a freshly-installed system, sourced from `state.json` + `nomarchy-system-scripts` introspection (Now).
|
||||
- Optional non-LUKS branch in the installer for users who explicitly opt out of FDE (Now).
|
||||
- Richer disk metadata (Shipped).
|
||||
- Form-factor → laptop preset (Now, depends on Pillar 5).
|
||||
- `disko-golden.nix` variants for software-RAID and BTRFS-pool-as-root (Shipped).
|
||||
- Pre-flight resume polish (Next).
|
||||
- "What's installed?" summary screen on boot of a freshly-installed system, sourced from `state.json` + `nomarchy-system-scripts` introspection.
|
||||
- Optional non-LUKS branch in the installer for users who explicitly opt out of FDE.
|
||||
- Pre-flight resume polish (Shipped).
|
||||
- Software-profile multi-select (Shipped).
|
||||
- Form-factor → laptop preset (Shipped).
|
||||
|
||||
## 5. Pillar: Power, hardware, presets
|
||||
|
||||
- Laptop preset (Next): TLP, upower, brightness, lid, hypridle tuning.
|
||||
- Desktop preset (Next): performance governor, no laptop UI (already filtered), ZFS hooks.
|
||||
- Accessibility preset (Next).
|
||||
- Gaming preset (Next).
|
||||
- Vendor matchers in `installer/hardware-db.sh`: Steam Deck, Surface, ROG Ally, Snapdragon X laptops.
|
||||
- Auto-detect dGPU presence in `installer/hardware-db.sh` and pre-fill `hardware.nvidia.prime.{intel,nvidia}BusId` in the generated `system.nix` (driver stack itself is Shipped — see entry below).
|
||||
- Surface support behind `nomarchy.hardware.isSurface` (Later).
|
||||
- Auto-detect dGPU presence and offer `programs.envycontrol`-style switching for the hybrid case (already gated behind `nomarchy.system.features.hybridGPU`, but the wiring is minimal).
|
||||
- Laptop preset: TLP, upower, brightness, lid, hypridle tuning (Shipped).
|
||||
- Desktop preset: performance governor, no laptop UI (already filtered), ZFS hooks (Shipped).
|
||||
- Accessibility preset (Shipped).
|
||||
- Gaming preset (Shipped).
|
||||
- Vendor matchers in `installer/hardware-db.sh` (Shipped — ROG Ally added; Surface/Framework/Lenovo entries corrected; Steam Deck + Snapdragon X documented as nixos-hardware-unsupported. CI now lints DB references).
|
||||
|
||||
## 6. Pillar: Onboarding & docs
|
||||
|
||||
- `nomarchy-welcome` first-run wizard (Next).
|
||||
- `nomarchy-welcome` first-run wizard (Shipped).
|
||||
- `docs/KEYBINDINGS.md` auto-generator (Shipped).
|
||||
- `docs/TROUBLESHOOTING.md` (Next).
|
||||
- `docs/index.md` (or just enrich `README.md`) so `OPTIONS.md`, `STRUCTURE.md`, `MIGRATION.md`, `ROADMAP.md`, `SCRIPTS.md`, and `creating-themes.md` are all one click from the front page.
|
||||
- `nomarchy-manual` — orphaned reference today; either implement as a curated `xdg-open` to the docs index, or delete.
|
||||
- `docs/TROUBLESHOOTING.md` (Shipped).
|
||||
- `docs/index.md` / README docs index (Shipped — `README.md` links every doc in `docs/`).
|
||||
- `nomarchy-manual` — opens the local `~/.local/share/nomarchy/README.md` via `xdg-open` (Shipped).
|
||||
|
||||
## 7. Pillar: Test, CI, release
|
||||
|
||||
@@ -109,20 +118,32 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes,
|
||||
- `nixosTest` per palette: boots `default` in a VM, screenshots the SDDM splash and the Hyprland desktop, diffs vs golden. Failure surfaces as CI red.
|
||||
- A small `bin/utils/nomarchy-bench-iso-build` that records ISO build time + size into a per-commit JSON so we notice regressions.
|
||||
|
||||
## 8. Pillar: Distro Branding
|
||||
## 8. Pillar: QA audit — features & components
|
||||
|
||||
Nomarchy is moving away from being a "flavor" of Omarchy to its own distinct identity. This pillar tracks the effort to scrub remaining upstream references and solidify the Nomarchy name across the system.
|
||||
Nomarchy now spans an installer, ~159 `nomarchy-*` scripts, a Hyprland desktop stack (Hyprland + waybar + walker + nightlight + idle), curated apps, a 22-palette theme engine, and two ISO hosts. Pillar 3 audited script *existence*; this pillar audits feature *behavior*. The goal: walk every shipped feature end-to-end on a real install, fix every bug or surprise inline when small, and capture the rest as new roadmap rows.
|
||||
|
||||
- **ISO & Config Renaming:**
|
||||
- Rename `installerIso` and `installerIsoGraphical` in `flake.nix` to `nomarchy-installer` and `nomarchy-live`.
|
||||
- Update `hosts/nomarchy-installer.nix` and `hosts/nomarchy-live.nix` internal metadata.
|
||||
- **Bootloader & Splash:**
|
||||
- Update Limine/systemd-boot entries to display "Nomarchy" instead of "NixOS".
|
||||
- Scrub "Omarchy" from `themes/engine/plymouth/nomarchy.script`.
|
||||
- Ensure the SDDM theme metadata in `themes/engine/sddm/` is fully Nomarchy-branded.
|
||||
- **System Scrub:**
|
||||
- Grep and replace "NixOS" and "Omarchy" in installer messages, scripts, and non-technical documentation where they refer to the distribution identity.
|
||||
- Update `/etc/os-release` via `environment.etc."os-release"` to ensure `NAME` and `PRETTY_NAME` reflect Nomarchy.
|
||||
Runs as **per-component sweeps**. One PR per component, branch `wave/qa-<component>`. Don't grow scope mid-PR — bugs that need a new option, refactor, or missing module become a new **Now**/**Next** row.
|
||||
|
||||
Components (each is one sweep):
|
||||
|
||||
1. **Installer** — `installer/install.sh`, `installer/hardware-db.sh`, disko configs. Fresh install + `--resume` + `--dry-run`, on laptop and desktop, with FDE (non-LUKS branch is Later). Verify every generated file (`flake.nix`, `system.nix`, `home.nix`, `hardware-selection.nix`, `state.json`) is correct and idempotent.
|
||||
2. **First-boot UX** — `nomarchy-welcome`, generated `home.nix`, SDDM and Plymouth metadata, default theme/font/panel position. Re-run on a clean VM; note every prompt that confuses and every default that's wrong.
|
||||
3. **Core system modules** — `core/system/*` (laptop, desktop, accessibility, gaming, hybridGPU, impermanence, network, hardware, branding). For each: enable → rebuild → observe the claimed effect → disable → rebuild → observe it's gone. Cross-check against `docs/OPTIONS.md`.
|
||||
4. **Core home modules** — `core/home/*` (options, state, behavior, overrides, deployed config). Verify every home-side `nomarchy.*` option does what its description claims; confirm `~/.config/nomarchy/overrides/` actually overrides.
|
||||
5. **Desktop stack** — Hyprland (keybindings, window rules, monitors, input), waybar (every module × both panel positions × both form factors), walker (every launcher mode), idle, nightlight, notifications (mako). Reconcile `docs/KEYBINDINGS.md` against runtime.
|
||||
6. **Apps** — `features/apps/*`. Each app: launches, themed via Stylix, configured as expected. Catches the "we package it but nobody configured it" class.
|
||||
7. **Theme engine + palettes** — `nomarchy-theme-set` across all 22 palettes, font and wallpaper switchers, light-mode toggle. Verify per-palette Stylix targets render correctly across SDDM, Plymouth, GTK, Qt, terminals, browsers, waybar, walker.
|
||||
8. **Scripts (runtime behavior)** — Pillar 3 confirmed existence; this sweep runs every user-visible script (especially every `nomarchy-menu` entry) on current NixOS and confirms it actually does the thing.
|
||||
9. **ISOs** — boot `nomarchy-installer` and `nomarchy-live`; verify the `nomarchy-test-live-iso` flow; check the installer ISO ships every tool `install.sh` calls (regression class: `hardware-db.sh` missing, already shipped).
|
||||
10. **Lib + state schema** — `lib/state-schema.nix`, color resolution, path helpers. Cross every codepath that produces `state.json` (installer, welcome wizard, hand-edit) against the schema; confirm bad inputs are rejected with a useful message.
|
||||
|
||||
Per-PR deliverable:
|
||||
|
||||
- PR body lists what was tested, what was broken, what was fixed inline, what was deferred (with the new roadmap row linked).
|
||||
- Doc updates ride with the change per `docs/AGENT.md` §5.4.
|
||||
- Don't bundle fixes across components — keep one component per branch so reviewers can spot-check end-to-end without context-switching.
|
||||
|
||||
Pillar is **done** when every component has a closed `wave/qa-<component>` PR and the roadmap captures every deferred finding.
|
||||
|
||||
## 9. Process notes
|
||||
|
||||
@@ -136,6 +157,23 @@ Nomarchy is moving away from being a "flavor" of Omarchy to its own distinct ide
|
||||
|
||||
(Move items here when they land — keep them brief, link the commit/PR.)
|
||||
|
||||
- _2026-05-18_ — Hardware DB correctness pass + ROG Ally support + CI lint. Audited every `nomarchy-hardware-db` entry against `inputs.nixos-hardware.nixosModules` and found **21 of 43 entries (49%) referenced modules that don't exist** — `microsoft-surface-pro-8`, `lenovo-thinkpad-x1-carbon-gen11`, `framework-13-11th-gen-intel`, etc. were all eval-time failures waiting for a real user. Rewrote the DB to use only valid module names: Framework gens dropped the "13-" prefix in nixos-hardware (`framework-11th-gen-intel`, not `framework-13-11th-gen-intel`); ThinkPad X1 modules are `x1-Nth-gen`, not `x1-carbon-genN`; Surface Pro 6/7/8/10 all share `microsoft-surface-pro-intel`; Surface Book / Intel Surface Laptop have no module (rows dropped, generic detection still emits sensible `common-pc-laptop` + cpu/gpu). Added matchers for **ROG Ally** (RC71L / RC72LA / "ROG Ally" via `asus-ally-rc71l`). Documented Steam Deck and Snapdragon X as nixos-hardware-unsupported in a footer comment (Steam Deck → Jovian-NixOS; Snapdragon X → installer is x86_64 only). Added a CI step (`.forgejo/workflows/check.yml`) that fails on any DB entry whose module name isn't in `nixos-hardware.nixosModules` — closes this regression class.
|
||||
- _2026-05-18_ — `nomarchy-manual` re-targeted at local docs. The script's `xdg-open` previously pointed at `https://learn.omacom.io/2/the-nomarchy-manual` — an upstream Omarchy URL that opened an unrelated page when users hit the menu's Help entry. Now opens `~/.local/share/nomarchy/README.md` (the local docs index per `SKILL.md`'s "Out of Scope" note), with a `notify-send` fallback if the source tree isn't synced.
|
||||
- _2026-05-18_ — Docs hygiene: STRUCTURE.md "Root Directory" + Pillar 6 reality-check. `docs/STRUCTURE.md` listed three top-level files that don't exist (`GEMINI.md`, root-level `STRUCTURE.md`, `TODO.md`) — replaced with an accurate root listing plus a `docs/` sub-tree that names every doc. Pillar 6 in this file had `nomarchy-welcome`, `docs/TROUBLESHOOTING.md`, and the "docs index" bullet still marked Next despite all three shipping on 2026-04-26 — moved to `(Shipped)`. `nomarchy-manual` bullet's "orphaned reference today" claim was stale (the script is called from `nomarchy-menu` and `nomarchy-theme-install`); rewritten to reflect the real remaining issue — its hardcoded `xdg-open https://learn.omacom.io/2/the-nomarchy-manual` is an Omarchy URL.
|
||||
- _2026-05-18_ — Installer state.json is now schema-driven. Replaced the heredoc in `installer/install.sh` that hardcoded the JSON literal (theme/dns/wifi/features/etc.) with a `nix eval` of `lib/state-schema.nix`'s `system` block, overlaid with the installer-chosen timezone. Closes the last source-of-truth split after the centralization batch — adding a new default in the schema now reaches the installer with no further plumbing. Output is identical modulo alphabetical key ordering (Nix's `builtins.toJSON` sorts keys; toggle scripts read/write via `jq` so it's invisible to them). Dry-run path unchanged (still bind-mounts a fake `/mnt` so the generator's absolute paths resolve correctly). `bash -n` + `shellcheck --severity=error` clean.
|
||||
- _2026-05-18_ — Complete the hybrid-GPU wiring + fix unoverridable state-derived options. Two related fixes shipped together. **(1)** `nomarchy.system.features.hybridGPU = true` now wires the full NVIDIA driver stack (`services.xserver.videoDrivers = ["nvidia"]`, `hardware.graphics.{enable,enable32Bit}`, `hardware.nvidia.{modesetting,powerManagement}.enable`, `package = nvidiaPackages.stable`, `boot.kernelParams += "nvidia-drm.modeset=1"`) — was previously enabling only `supergfxd` mode-switching while leaving the system with no NVIDIA driver loaded, so mode switches silently no-op'd. All knobs use `lib.mkDefault` so a downstream `system.nix` can pin a beta driver, flip to the open kernel module, etc. Bus-ID prime config (per-machine) stays user-supplied — `docs/OPTIONS.md` has the full recipe. **(2)** Both `core/system/state.nix` and `core/home/state.nix` now use `lib.mkDefault` on every state.json-derived assignment, fixing a class of "I set X in my system.nix but it doesn't take effect" bugs (the state-derived value was at default priority and conflicted with the user's same-priority override). Side-effect cleanup: `core/system/state.nix` now also reads from `lib/state-schema.nix` like `core/home/state.nix` does, completing the schema-centralization started two batches ago. Verified `nix flake check` + an override test that flips hybridGPU via an overlay and confirms the entire driver stack engages.
|
||||
- _2026-05-18_ — Pillar 4: pre-flight resume polish. Fixed four resume-flow gaps in `installer/install.sh`: (1) `--resume` with a missing state file now errors loudly with a tmpfs explanation instead of silently falling through to a fresh prompt cycle (the most common operator confusion was "rebooted, forgot tmpfs eats /tmp/, watched the installer start over without realising"); (2) on resume, the saved target drive is validated as a block device before any disk-phase step runs — catches the live-ISO USB-unplugged / non-deterministic /dev/sdX class of mid-install failures; (3) `save_state` now stamps an ISO-8601 timestamp and `load_state` shows a `(saved Xm ago)` banner plus a `Target: /dev/X → user @ host` summary line, so the user can `Ctrl-C` if they're resuming onto the wrong host before any destructive prompt fires; (4) `--help` now documents the tmpfs limitation. `shellcheck --severity=error` passes.
|
||||
- _2026-05-18_ — Declarative-state defaults centralization. Made `lib/state-schema.nix` the single source of truth for every state-default that previously lived in three places (the schema itself, `core/system/options.nix` / `core/home/options.nix` `default = …` clauses, and `core/home/state.nix` `or …` fallbacks). Replaced ~25 hardcoded literals with `schema.<scope>.<key>` reads. Side-effect: fixed a lingering bug where `core/home/options.nix:theme` still defaulted to `"summer-night"` after the system-side was moved to `"nord"` — half the codebase's home option resolved to the wrong theme when state.json was missing/blank. `nix flake check --no-build` confirms zero semantic change for every other field. Doesn't touch the installer-written `state.json` (separate batch — needs schema → JSON generation).
|
||||
- _2026-05-18_ — Pillar 7 first step: Forgejo Actions CI (eval + lint). New `.forgejo/workflows/check.yml` runs on every push to `main` and every PR: (1) `nix flake check --no-build` to catch eval regressions, (2) `bash -n` + `shellcheck --severity=error` over every `nomarchy-*` bash script (whole-tree, not just changed files — gates branches that bypass the pre-commit hook), (3) `docs/SCRIPTS.md` drift check (fails loudly if a script change didn't regenerate the audit doc). All three checks pass locally on the current tree. Activation requires enabling Actions on the Forgejo repo and registering a `forgejo-runner`; the workflow itself is dormant until then. ISO build job is intentionally deferred — needs a binary cache (Cachix/Attic) to be tractable.
|
||||
- _2026-05-18_ — **Pillar 3 Phase B: complete.** Final batch (restart/sudo/theme/misc clusters) cleared the last 13 `unused?` rows. Deleted five truly dead scripts: `nomarchy-restart-{hyprctl,mako}` (theme switching calls `hyprctl reload`/`makoctl reload` directly now), `nomarchy-restart-tmux` (one-liner of marginal value), `nomarchy-battery-present` (battery monitor checks `/sys/class/power_supply/BAT*` inline), `nomarchy-sudo-keepalive` (intended-to-be-sourced building block with no users). Surfaced eight useful tools in `SKILL.md` so the audit catches them as `kept` and AI assistants can discover them: `nomarchy-restart-trackpad` (intel_quicki2c reload), `nomarchy-sudo-{passwordless-toggle,reset}`, `nomarchy-theme-{bg-install,refresh,remove}`, `nomarchy-refresh-fastfetch`, `nomarchy-windows-vm` (new Virtualization section). Final state: 159 scripts, all `kept`, `unused?` = 0, missing references = 0.
|
||||
- _2026-05-18_ — Pillar 3 Phase B: webapp/tui/voxtype install-remove pair triage. Deleted two dead webapp URI handlers (`nomarchy-webapp-handler-hey`, `nomarchy-webapp-handler-zoom`) — no `.desktop` MimeType registration anywhere routed `mailto:`/`zoom:` URIs to them, so the handlers could never fire. Surfaced six useful CLI tools in `SKILL.md` "Common Tasks" so they're discoverable by AI assistants and tagged `kept` by the audit: `nomarchy-webapp-{remove,remove-all}`, `nomarchy-tui-{remove,remove-all}`, `nomarchy-voxtype-{install,remove}`. Script count 166 → 164; `unused?` 21 → 13.
|
||||
- _2026-05-18_ — Pillar 3 Phase B: dead-code sweep (NixOS-irrelevant Omarchy ports). Deleted five scripts that duplicated NixOS-native facilities or referenced infrastructure Nomarchy doesn't ship: `nomarchy-rollback` (boot-menu generations + `nixos-rebuild rollback` already cover this), `nomarchy-snapshot` (used `snapper`; impermanence and BTRFS subvolumes are the Nomarchy answer), `nomarchy-migrate-state` (one-shot pre-unification migration, no current callers), `nomarchy-config-direct-boot` (added an EFI entry for a UKI we never build), and `nomarchy-npx-install` (Arch idiom — `nix-shell -p nodejs` is the NixOS path). Kept `nomarchy-build-iso` and `nomarchy-build-live-iso` and surfaced them in README §2 so the audit tags them `kept`. Script count 171 → 166.
|
||||
- _2026-05-18_ — Pillar 3 Phase B: missing-references triage. (1) Wrote `themes/engine/scripts/nomarchy-theme-next` so `SKILL.md`'s documented "cycle to next theme" command resolves; (2) scrubbed three stale `nomarchy-dev-*` references from `core/home/config/nomarchy-skill/SKILL.md`; (3) added a line-context filter to both `nomarchy-docs-scripts` generators that drops `nomarchy-*` tokens appearing in Nix `pname`/derivation idents, `/tmp/` & `/etc/sudoers.d/` paths, `nixosConfigurations.*` / `packages.*` flake outputs, `mktemp -t` prefixes, systemd unit vars, `./result/bin/run-` binaries, and `docker` container references; (4) 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. `docs/SCRIPTS.md` "Missing references" section is now empty (was 15).
|
||||
- _2026-05-04_ — Pillar 8: Distro Branding. (1) Scrubbed remaining "Omarchy" and "Spirit of Omarchy" references from README, scripts, and welcome wizard; (2) Updated `nomarchy-welcome` banner and `nomarchy-version` codename ("Sovereign"); (3) Verified existing `core/system/branding.nix` handles OS-release and bootloader labels; (4) Confirmed SDDM and Plymouth metadata are already Nomarchy-branded.
|
||||
- _2026-05-04_ — Thorough Out-of-the-Box QA Audit. (1) Restored automatic wallpaper switching by removing image filters from deployed themes; (2) Fixed broken "Style" menu entries by creating missing `about.txt` and `screensaver.txt` branding files; (3) Cleaned up conflicting keybindings by removing deprecated `tiling.conf` and updating the doc generator; (4) Removed legacy Nord theme hack from `nomarchy-theme-set`; (5) Fixed JSON parse error in `summer-day` waybar theme.
|
||||
- _2026-05-03_ — Fixed multi-disk LUKS/BTRFS boot hang. (1) Moved temporary LUKS keyfile to `/tmp/` so Disko correctly omits it from the runtime configuration; (2) Injected `x-systemd.requires` and `x-systemd.device-timeout=0` into BTRFS mount options to ensure all LUKS drives are decrypted before mounting.
|
||||
- _2026-05-03_ — Fixed CLI wrappers and removed obsolete code. (1) Updated `nomarchy-font`, `nomarchy-theme`, and `nomarchy-wallpaper` CLI wrappers to use modern Walker menus; (2) Removed the obsolete and broken `themes/engine/switcher.nix` and its associated Nix-inlined scripts; (3) Cleaned up remaining `$NOMARCHY_PATH` references from the Omarchy era.
|
||||
- _2026-05-03_ — Fixed `/etc/nixos` ownership after installation. Added a `chown -R $USERNAME:users /etc/nixos` step via `nixos-enter` at the end of `installer/install.sh` so the main user owns their configuration and can run `home-manager` commands without `sudo`.
|
||||
- _2026-05-01_ — Installer & Script Audit Polish. (1) Fixed a critical bash dynamic scoping bug in `installer/install.sh` where `rc=0` assignments inside functions (Impermanence, Form Factor) were clobbering the main loop's return code, causing the installer to abort when "No" was selected; (2) Polished `hosts/nomarchy-live.nix` with auto-login for the `nixos` user and passwordless sudo for the `wheel` group; (3) Repurposed `nomarchy-toggle-suspend` to execute `systemctl suspend` directly and updated `nomarchy-menu` to reflect this; (4) Updated `nomarchy-launch-wifi` to use `nmtui` in Alacritty; (5) Regenerated `docs/SCRIPTS.md` to reflect the updated script mappings.
|
||||
- _2026-04-30_ — `set -e` sweep across `nomarchy-*` scripts. Added `set -e` to 142 of 169 bash scripts that lacked it (27 already had it). Halts a class of "command failed silently in the middle of a chain, system left in half-applied state" bugs that produced repeat-fix commits. One deliberate exception: `nomarchy-menu` runs without `set -e` because it's an interactive UX loop where action failures should re-display the menu rather than abort the script. Pre-commit hook now enforces `bash -n` + `shellcheck --severity=error` so future scripts can't regress this.
|
||||
- _2026-04-30_ — Installer disk-phase reliability. Hardened `installer/install.sh` and consolidated the disko configs: (1) `select_disk` now hides the live-ISO boot device(s) so the installer can't format its own boot media (`NOMARCHY_INSTALL_ALLOW_ISO_TARGET=1` to override); (2) added a 10 GiB minimum-capacity preflight; (3) `prewipe_target_drive` enumerates every active dm-crypt mapping backed by the target drive and closes them, drops the silent `|| true` from `wipefs`/`sgdisk`/`dd`, bounds `udevadm settle` to 30s, and refuses to continue if anything is still mounted; (4) wrapped the disko call in `run_disko_with_retry` with last-30-lines + Retry / View full log / Abort dialog on failure; (5) replaced the sed-templated `disko-golden.nix` + `disko-btrfs-multi.nix` pair with a single `disko-config.nix` Nix function called via `--argstr mainDrive … --arg extraDrives '[…]'` — eliminates a class of escaping bugs (cf. `3aadc36`); (6) added an EXIT trap so the tmpfs LUKS key file is removed even on early abort.
|
||||
|
||||
100
docs/SCRIPTS.md
100
docs/SCRIPTS.md
@@ -24,22 +24,21 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
- `delete-dead` — Phase B verdict: remove and update callers.
|
||||
- `stub-with-notify` — Phase B verdict: temporary `notify-send` stub.
|
||||
|
||||
## Scripts (170)
|
||||
## Scripts (159)
|
||||
|
||||
| Script | Location | Callers | Status | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `nomarchy-backup` | `features/scripts/utils` | features/scripts/utils/nomarchy-sync | `kept` | |
|
||||
| `nomarchy-battery-capacity` | `core/system/scripts` | core/system/scripts/nomarchy-battery-status | `kept` | |
|
||||
| `nomarchy-battery-monitor` | `core/system/scripts` | features/scripts/battery-monitor.nix | `kept` | |
|
||||
| `nomarchy-battery-present` | `core/system/scripts` | — | `unused?` | |
|
||||
| `nomarchy-battery-remaining` | `core/system/scripts` | core/system/scripts/nomarchy-battery-monitor,core/system/scripts/nomarchy-battery-status | `kept` | |
|
||||
| `nomarchy-battery-remaining-time` | `core/system/scripts` | core/system/scripts/nomarchy-battery-status | `kept` | |
|
||||
| `nomarchy-battery-status` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/system/scripts/nomarchy-battery-capacity, +1 more | `kept` | |
|
||||
| `nomarchy-brightness-display` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/media.conf,core/home/config/nomarchy/default/hypr/bindings/utilities.conf | `kept` | |
|
||||
| `nomarchy-brightness-display-apple` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf | `kept` | |
|
||||
| `nomarchy-brightness-keyboard` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/media.conf | `kept` | |
|
||||
| `nomarchy-build-iso` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-build-live-iso` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-build-iso` | `features/scripts/utils` | README.md | `kept` | |
|
||||
| `nomarchy-build-live-iso` | `features/scripts/utils` | README.md | `kept` | |
|
||||
| `nomarchy-cmd-audio-switch` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/media.conf | `kept` | |
|
||||
| `nomarchy-cmd-present` | `features/scripts/utils` | core/home/config/nomarchy/hooks/battery-low.sample,features/scripts/utils/nomarchy-launch-editor, +4 more | `kept` | |
|
||||
| `nomarchy-cmd-screenrecord` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc, +1 more | `kept` | |
|
||||
@@ -47,15 +46,14 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
| `nomarchy-cmd-screenshot` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-cmd-share` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-cmd-terminal-cwd` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf | `kept` | |
|
||||
| `nomarchy-config-direct-boot` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-debug` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-docs-keybindings` | `features/scripts/utils` | bin/utils/nomarchy-docs-keybindings | `kept` | |
|
||||
| `nomarchy-docs-scripts` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts | `kept` | |
|
||||
| `nomarchy-drive-info` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-select | `kept` | |
|
||||
| `nomarchy-drive-select` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-info,features/scripts/utils/nomarchy-drive-set-password | `kept` | |
|
||||
| `nomarchy-drive-set-password` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-select,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-env-update` | `features/scripts/utils` | core/home/bash.nix,core/system/scripts/nomarchy-pkg-add, +7 more | `kept` | |
|
||||
| `nomarchy-font` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy-skill/SKILL.md, +7 more | `kept` | |
|
||||
| `nomarchy-env-update` | `core/system/scripts` | core/home/bash.nix,core/system/scripts.nix, +7 more | `kept` | |
|
||||
| `nomarchy-font` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy-skill/SKILL.md, +6 more | `kept` | |
|
||||
| `nomarchy-font-current` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-font-list` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-font, +2 more | `kept` | |
|
||||
| `nomarchy-font-set` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-font, +4 more | `kept` | |
|
||||
@@ -69,7 +67,7 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
| `nomarchy-hw-vulkan` | `core/system/scripts` | features/scripts/utils/nomarchy-voxtype-install | `kept` | |
|
||||
| `nomarchy-hyprland-active-window-transparency-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf | `kept` | |
|
||||
| `nomarchy-hyprland-monitor-scaling-cycle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||
| `nomarchy-hyprland-window-close-all` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling.conf,core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf, +3 more | `kept` | |
|
||||
| `nomarchy-hyprland-window-close-all` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf,core/system/scripts/nomarchy-system-logout, +2 more | `kept` | |
|
||||
| `nomarchy-hyprland-window-gaps-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-hyprland-window-pop` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/tiling-v2.conf | `kept` | |
|
||||
| `nomarchy-hyprland-window-single-square-aspect-toggle` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
@@ -87,16 +85,14 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
| `nomarchy-launch-or-focus-webapp` | `features/scripts/utils` | features/desktop/hyprland/config/bindings.conf | `kept` | |
|
||||
| `nomarchy-launch-screensaver` | `features/scripts/utils` | features/desktop/idle.nix,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-launch-tui` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/hyprland/config/bindings.conf, +2 more | `kept` | |
|
||||
| `nomarchy-launch-walker` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/clipboard.conf,core/home/config/nomarchy/default/hypr/bindings/utilities.conf, +1 more | `kept` | |
|
||||
| `nomarchy-launch-webapp` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf, +7 more | `kept` | |
|
||||
| `nomarchy-launch-walker` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/clipboard.conf,core/home/config/nomarchy/default/hypr/bindings/utilities.conf, +4 more | `kept` | |
|
||||
| `nomarchy-launch-webapp` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf, +5 more | `kept` | |
|
||||
| `nomarchy-launch-wifi` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy/default/mako/core.ini, +4 more | `kept` | |
|
||||
| `nomarchy-lock-screen` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy/extensions/menu.sh, +3 more | `kept` | |
|
||||
| `nomarchy-manual` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu,themes/engine/scripts/nomarchy-theme-install | `kept` | |
|
||||
| `nomarchy-manual` | `features/scripts/utils` | core/branding/about.txt,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||
| `nomarchy-menu` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/hypr/bindings/utilities.conf, +10 more | `kept` | |
|
||||
| `nomarchy-menu-keybindings` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy/default/mako/core.ini, +2 more | `kept` | |
|
||||
| `nomarchy-migrate-state` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-notification-dismiss` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini | `kept` | |
|
||||
| `nomarchy-npx-install` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-on-boot` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/autostart.conf | `kept` | |
|
||||
| `nomarchy-pkg-add` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-pkg-install, +2 more | `kept` | |
|
||||
| `nomarchy-pkg-aur-add` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
@@ -104,42 +100,36 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
| `nomarchy-pkg-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-pkg-remove` | `core/system/scripts` | features/scripts/utils/nomarchy-pkg-drop | `kept` | |
|
||||
| `nomarchy-powerprofiles-list` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-preflight-migration` | `core/system/scripts` | features/scripts/utils/nomarchy-env-update,features/scripts/utils/nomarchy-migrate-state | `kept` | |
|
||||
| `nomarchy-preflight-migration` | `core/system/scripts` | core/system/scripts/nomarchy-env-update | `kept` | |
|
||||
| `nomarchy-refresh-config` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-refresh-fastfetch | `kept` | |
|
||||
| `nomarchy-refresh-fastfetch` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-refresh-fastfetch` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-refresh-hyprland` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-refresh-waybar` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-reinstall` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-restart-app` | `features/scripts/utils` | core/system/scripts/nomarchy-restart-xcompose,features/scripts/utils/nomarchy-restart-hypridle, +3 more | `kept` | |
|
||||
| `nomarchy-restart-bluetooth` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-btop` | `features/scripts/utils` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-restart-hyprctl` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-restart-hypridle` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-hyprsunset` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-mako` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-restart-opencode` | `features/scripts/utils` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-restart-pipewire` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-swayosd` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-terminal` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-restart-tmux` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-restart-trackpad` | `core/system/scripts` | — | `unused?` | |
|
||||
| `nomarchy-restart-trackpad` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-restart-walker` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||
| `nomarchy-restart-waybar` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu, +4 more | `kept` | |
|
||||
| `nomarchy-restart-wifi` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-restart-xcompose` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-rollback` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-setup-dns` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-setup-fido2` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-setup-fido2` | `core/system/scripts` | features/scripts/utils/nomarchy-menu,installer/install.sh | `kept` | |
|
||||
| `nomarchy-setup-fingerprint` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-show-done` | `themes/engine/scripts` | features/scripts/utils/nomarchy-launch-floating-terminal-with-presentation | `kept` | |
|
||||
| `nomarchy-show-logo` | `themes/engine/scripts` | features/scripts/utils/nomarchy-launch-floating-terminal-with-presentation | `kept` | |
|
||||
| `nomarchy-skill` | `features/scripts/utils` | core/home/configs.nix | `kept` | |
|
||||
| `nomarchy-snapshot` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-state` | `features/scripts/utils` | core/system/scripts/nomarchy-system-reboot,core/system/scripts/nomarchy-system-shutdown, +2 more | `kept` | |
|
||||
| `nomarchy-state-write` | `features/scripts/utils` | features/scripts/utils/nomarchy-welcome | `kept` | |
|
||||
| `nomarchy-sudo-keepalive` | `core/system/scripts` | — | `unused?` | |
|
||||
| `nomarchy-sudo-passwordless-toggle` | `core/system/scripts` | — | `unused?` | |
|
||||
| `nomarchy-sudo-reset` | `core/system/scripts` | — | `unused?` | |
|
||||
| `nomarchy-sudo-passwordless-toggle` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-sudo-reset` | `core/system/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-swayosd-brightness` | `core/system/scripts` | core/system/scripts/nomarchy-brightness-display,core/system/scripts/nomarchy-brightness-display-apple | `kept` | |
|
||||
| `nomarchy-swayosd-kbd-brightness` | `core/system/scripts` | core/system/scripts/nomarchy-brightness-keyboard | `kept` | |
|
||||
| `nomarchy-sync` | `features/scripts/utils` | features/scripts/utils/nomarchy-backup,README.md | `kept` | |
|
||||
@@ -151,14 +141,15 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
| `nomarchy-test-live-iso` | `features/scripts/utils` | hosts/nomarchy-live.nix | `kept` | |
|
||||
| `nomarchy-test-vm` | `features/scripts/utils` | features/scripts/utils/nomarchy-test-live-iso | `kept` | |
|
||||
| `nomarchy-theme` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/elephant/nomarchy_background_selector.lua, +17 more | `kept` | |
|
||||
| `nomarchy-theme-bg-install` | `themes/engine/scripts` | — | `unused?` | |
|
||||
| `nomarchy-theme-bg-install` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-bg-next` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-wallpaper, +1 more | `kept` | |
|
||||
| `nomarchy-theme-bg-set` | `themes/engine/scripts` | core/home/config/nomarchy/default/elephant/nomarchy_background_selector.lua | `kept` | |
|
||||
| `nomarchy-theme-current` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-bg-set` | `themes/engine/scripts` | core/home/config/nomarchy/default/elephant/nomarchy_background_selector.lua,features/scripts/utils/nomarchy-wallpaper | `kept` | |
|
||||
| `nomarchy-theme-current` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,themes/engine/scripts/nomarchy-theme-next | `kept` | |
|
||||
| `nomarchy-theme-install` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-list` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-theme, +1 more | `kept` | |
|
||||
| `nomarchy-theme-refresh` | `themes/engine/scripts` | — | `unused?` | |
|
||||
| `nomarchy-theme-remove` | `themes/engine/scripts` | — | `unused?` | |
|
||||
| `nomarchy-theme-list` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-theme, +2 more | `kept` | |
|
||||
| `nomarchy-theme-next` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-refresh` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-remove` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-theme-set` | `themes/engine/scripts` | core/home/config/nomarchy/default/elephant/nomarchy_themes.lua,core/home/config/nomarchy-skill/SKILL.md, +9 more | `kept` | |
|
||||
| `nomarchy-theme-set-keyboard` | `themes/engine/scripts` | features/scripts/utils/nomarchy-on-boot | `kept` | |
|
||||
| `nomarchy-theme-set-keyboard-asus-rog` | `themes/engine/scripts` | features/scripts/utils/nomarchy-on-boot,themes/engine/scripts/nomarchy-theme-set-keyboard | `kept` | |
|
||||
@@ -167,37 +158,35 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
||||
| `nomarchy-theme-set-templates` | `themes/engine/scripts` | themes/engine/scripts/nomarchy-theme-set | `kept` | |
|
||||
| `nomarchy-themes-prebuild` | `themes/engine/scripts` | installer/install.sh | `kept` | |
|
||||
| `nomarchy-theme-update` | `themes/engine/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-hybrid-gpu` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-hybrid-gpu` | `core/system/scripts` | features/scripts/utils/nomarchy-menu,features/scripts/utils/nomarchy-sys-update, +1 more | `kept` | |
|
||||
| `nomarchy-toggle-idle` | `core/system/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +2 more | `kept` | |
|
||||
| `nomarchy-toggle-nightlight` | `themes/engine/scripts` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-toggle-notification-silencing` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
||||
| `nomarchy-toggle-screensaver` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-suspend` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-toggle-waybar` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
||||
| `nomarchy-tui-install` | `features/scripts/utils` | features/scripts/utils/nomarchy-tui-remove-all | `kept` | |
|
||||
| `nomarchy-tui-remove` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-tui-remove-all` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-tz-select` | `core/system/scripts` | features/desktop/waybar/config/config.jsonc,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-tui-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-tui-remove-all | `kept` | |
|
||||
| `nomarchy-tui-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-tui-remove-all` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-tz-select` | `core/system/scripts` | features/desktop/waybar/config/config.jsonc,features/scripts/utils/nomarchy-menu, +2 more | `kept` | |
|
||||
| `nomarchy-update` | `core/system/scripts` | core/home/config/nomarchy/default/mako/core.ini,core/home/config/nomarchy-skill/SKILL.md, +4 more | `kept` | |
|
||||
| `nomarchy-update-available` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-update-firmware` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-update-time` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||
| `nomarchy-upload-log` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-debug | `kept` | |
|
||||
| `nomarchy-version` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-debug, +1 more | `kept` | |
|
||||
| `nomarchy-version` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-debug | `kept` | |
|
||||
| `nomarchy-voxtype-config` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-voxtype-install` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-voxtype-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-voxtype-model` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-voxtype-remove` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-voxtype-status` | `features/scripts/utils` | features/desktop/waybar/config/config.jsonc,features/desktop/waybar/themes/summer-night/config.jsonc | `kept` | |
|
||||
| `nomarchy-wallpaper` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/hypr/autostart.conf, +3 more | `kept` | |
|
||||
| `nomarchy-webapp-handler-hey` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-webapp-handler-zoom` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-webapp-install` | `features/scripts/utils` | features/scripts/utils/nomarchy-webapp-remove-all | `kept` | |
|
||||
| `nomarchy-webapp-remove` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-webapp-remove-all` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-voxtype-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-voxtype-status` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
||||
| `nomarchy-wallpaper` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/hypr/autostart.conf, +2 more | `kept` | |
|
||||
| `nomarchy-webapp-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-webapp-remove-all | `kept` | |
|
||||
| `nomarchy-webapp-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-webapp-remove-all` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
| `nomarchy-welcome` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/autostart.conf | `kept` | |
|
||||
| `nomarchy-wifi-powersave` | `core/system/scripts` | — | `unused?` | |
|
||||
| `nomarchy-windows-vm` | `features/scripts/utils` | — | `unused?` | |
|
||||
| `nomarchy-wifi-powersave` | `core/system/scripts` | features/scripts/utils/nomarchy-sys-update,installer/install.sh | `kept` | |
|
||||
| `nomarchy-windows-vm` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||
|
||||
## Missing references
|
||||
|
||||
@@ -205,21 +194,6 @@ Tokens grepped from `core/`, `features/`, `themes/`, `installer/`, `hosts/`, `bi
|
||||
|
||||
| Token | Referenced in | Status |
|
||||
| --- | --- | --- |
|
||||
| `nomarchy-dev` | core/home/config/nomarchy-skill/SKILL.md | `missing` |
|
||||
| `nomarchy-dryrun` | installer/install.sh | `missing` |
|
||||
| `nomarchy-installer` | features/scripts/utils/nomarchy-build-iso,README.md | `missing` |
|
||||
| `nomarchy-live` | features/scripts/utils/nomarchy-build-live-iso,features/scripts/utils/nomarchy-test-live-iso | `missing` |
|
||||
| `nomarchy-luks` | installer/disko-config.nix,installer/install.sh | `missing` |
|
||||
| `nomarchy-menu-rows` | bin/utils/nomarchy-docs-scripts,features/scripts/utils/nomarchy-docs-scripts | `missing` |
|
||||
| `nomarchy-nopasswd` | core/system/scripts/nomarchy-sudo-passwordless-toggle | `missing` |
|
||||
| `nomarchy-nopasswd-expire` | core/system/scripts/nomarchy-sudo-passwordless-toggle | `missing` |
|
||||
| `nomarchy-plymouth` | themes/engine/plymouth.nix | `missing` |
|
||||
| `nomarchy-screenrecord-filename` | features/scripts/utils/nomarchy-cmd-screenrecord | `missing` |
|
||||
| `nomarchy-sddm-theme` | themes/engine/sddm.nix | `missing` |
|
||||
| `nomarchy-theme-next` | core/home/config/nomarchy-skill/SKILL.md | `missing` |
|
||||
| `nomarchy-themes-no-images` | themes/engine/files.nix | `missing` |
|
||||
| `nomarchy-vm` | features/scripts/utils/nomarchy-test-vm | `missing` |
|
||||
| `nomarchy-windows` | features/scripts/utils/nomarchy-windows-vm | `missing` |
|
||||
|
||||
## Menu items
|
||||
|
||||
|
||||
@@ -33,10 +33,19 @@ While the system is defined declaratively, Nomarchy uses a small, local state fi
|
||||
- `nixosModules.home`: Exports the application and desktop logic (`./features`).
|
||||
- `nixosConfigurations`: Defines pre-configured targets like `nomarchy-installer`, `nomarchy-live`, and a testing `vm`.
|
||||
- **`flake.lock`**: Locks dependency versions for reproducible builds.
|
||||
- **`GEMINI.md`**: Foundational mandates and architectural rules for the Nomarchy Agent.
|
||||
- **`STRUCTURE.md`**: (This file) Detailed architectural documentation.
|
||||
- **`README.md`**: Project overview, installation instructions, and basic usage.
|
||||
- **`TODO.md`**: Roadmap and pending tasks.
|
||||
- **`docs/`**: All long-form documentation. Key entry points:
|
||||
- **`AGENT.md`**: Onboarding for AI coding agents picking up Nomarchy.
|
||||
- **`STRUCTURE.md`**: (This file) Detailed architectural documentation.
|
||||
- **`OPTIONS.md`**: Reference for every `nomarchy.*` option.
|
||||
- **`ROADMAP.md`**: Now / Next / Later board and the Shipped log.
|
||||
- **`MIGRATION.md`**: Layering Nomarchy onto an existing NixOS install.
|
||||
- **`KEYBINDINGS.md`**: Auto-generated keybinding reference.
|
||||
- **`SCRIPTS.md`**: Auto-generated `nomarchy-*` script audit.
|
||||
- **`TROUBLESHOOTING.md`**: Common rebuild errors and fixes.
|
||||
- **`creating-themes.md`**: Theme palette authoring guide.
|
||||
- **`.forgejo/workflows/`**: Forgejo Actions CI. Runs `nix flake check --no-build`, lints every `nomarchy-*` bash script with `bash -n` + `shellcheck --severity=error`, and verifies `docs/SCRIPTS.md` is up to date on every push to `main` and every PR. To activate: enable Actions on the repo in Forgejo and register a `forgejo-runner` (any Docker-capable Linux host works; the workflow uses `ubuntu-latest` and installs Nix itself).
|
||||
- **`.githooks/`**: Optional per-clone git hooks (`pre-commit` lints changed scripts and regenerates `docs/SCRIPTS.md`). Enable with `git config core.hooksPath .githooks`. CI enforces the same invariants tree-wide.
|
||||
|
||||
---
|
||||
|
||||
@@ -61,8 +70,8 @@ The `core/` directory contains the foundational modules required for a functiona
|
||||
- **`default.nix`**: The entry point for the base Home Manager module.
|
||||
- **`options.nix`**: Defines the `nomarchy` user options (Toggles, Theme, Fonts, etc.).
|
||||
- **`state.nix`**: Loads and applies user-level state (from `~/.config/nomarchy/state.json`).
|
||||
- **`behavior.nix`**: Deploys non-visual configs (Keybindings, Input settings, Window rules) with `lib.mkDefault`.
|
||||
- **`configs.nix`**: Manages static configuration files and directories in `~/.config/`.
|
||||
- **`overrides.nix`**: Declares `nomarchy.overrides.*` (reserved for a future file-based override loader; currently no-op).
|
||||
- **`configs.nix`**: Manages static configuration files and directories in `~/.config/`. Honors `nomarchy.configOverrides` as a bulk redirect to a replacement config dir.
|
||||
- **`bash.nix`**: Shell environment, aliases, and specialized `env-update` hooks.
|
||||
- **`security.nix`**: Polkit, keyring management, and GPG settings.
|
||||
- **`config/`**: Contains the physical source files for the base user configuration (e.g., `starship.toml`, `hypr/` behavior configs).
|
||||
@@ -93,7 +102,6 @@ The theming system is the "soul" of Nomarchy, providing dynamic, consistent aest
|
||||
### `themes/engine/` (The Logic)
|
||||
- **`loader.nix`**: The core theme loader. It reads the active theme from state and selectively deploys app-specific themed configs (e.g., `btop.theme`, `kitty.conf`) to `~/.config/`.
|
||||
- **`stylix.nix`**: Integration with Stylix for base color palette and wallpaper management.
|
||||
- **`switcher.nix`**: Provides the `nomarchy-theme-selector` and `nomarchy-wallpaper-selector` tools.
|
||||
- **`plymouth.nix`** & **`sddm.nix`**: System-level theming for the boot screen and login manager.
|
||||
|
||||
### `themes/palettes/` (The Data)
|
||||
@@ -126,7 +134,6 @@ The `lib/` directory provides centralized logic and data structures to maintain
|
||||
### `installer/` (Bootstrap)
|
||||
- **`install.sh`**: The interactive TTY-based installer. It handles disk partitioning, NixOS installation, and generating a clean "Downstream" flake for the user.
|
||||
- **`disko-config.nix`**: The disko partition layout (BTRFS on top of LUKS2). A Nix function of `{ mainDrive, extraDrives ? [] }` — single-disk path is `extraDrives = []`; multi-disk adds BTRFS `-d single -m raid1` across the extras. Invoked by `install.sh` via `disko --argstr mainDrive … --arg extraDrives '[…]'`.
|
||||
- **`disko-btrfs-luks.nix`**: A simpler reference layout for disk management (not used by the installer).
|
||||
|
||||
### `hosts/` (Targets)
|
||||
- **`nomarchy-installer.nix`**: Configuration for the minimal, TTY-based installation ISO.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
general.import = [ "~/.config/nomarchy/current/theme/alacritty.toml" ]
|
||||
|
||||
[env]
|
||||
TERM = "xterm-256color"
|
||||
|
||||
[terminal]
|
||||
osc52 = "CopyPaste"
|
||||
|
||||
[font]
|
||||
normal = { family = "JetBrainsMono Nerd Font", style = "Regular" }
|
||||
bold = { family = "JetBrainsMono Nerd Font", style = "Bold" }
|
||||
italic = { family = "JetBrainsMono Nerd Font", style = "Italic" }
|
||||
size = 9
|
||||
|
||||
[window]
|
||||
padding.x = 14
|
||||
padding.y = 14
|
||||
decorations = "None"
|
||||
|
||||
[keyboard]
|
||||
bindings = [
|
||||
{ key = "Insert", mods = "Shift", action = "Paste" },
|
||||
{ key = "Insert", mods = "Control", action = "Copy" },
|
||||
{ key = "Return", mods = "Shift", chars = "\u001B\r" }
|
||||
]
|
||||
@@ -1,6 +1,8 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
home.packages = [ pkgs.lua ];
|
||||
|
||||
programs.walker = {
|
||||
enable = lib.mkDefault true;
|
||||
runAsService = lib.mkDefault true;
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
|
||||
let
|
||||
nomarchyLib = import ../lib { inherit lib; };
|
||||
userPackagesFile = "${config.home.homeDirectory}/.config/home-manager/user-packages.json";
|
||||
userPackages = if builtins.pathExists userPackagesFile then
|
||||
let
|
||||
pkgNames = builtins.fromJSON (builtins.readFile userPackagesFile);
|
||||
# Filter to only packages that exist in pkgs to prevent build failures
|
||||
validPkgs = builtins.filter (name: builtins.hasAttr name pkgs) pkgNames;
|
||||
in builtins.map (name: pkgs.${name}) validPkgs
|
||||
else [];
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
@@ -21,7 +13,6 @@ in
|
||||
../themes/engine/files.nix
|
||||
../themes/engine/scripts.nix
|
||||
../themes/engine/stylix.nix
|
||||
../themes/engine/switcher.nix
|
||||
./apps/alacritty/default.nix
|
||||
./apps/btop/default.nix
|
||||
./apps/chromium/default.nix
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# paths to stylesheets on the filesystem which should be applied to the application
|
||||
#
|
||||
# relative paths are resolved relative to the location of the config file
|
||||
stylesheets: ["../nomarchy/current/theme/hyprland-preview-share-picker.css"]
|
||||
# default page selected when the picker is opened
|
||||
default_page: outputs
|
||||
|
||||
window:
|
||||
# height of the application window
|
||||
height: 500
|
||||
# width of the application window
|
||||
width: 1000
|
||||
|
||||
image:
|
||||
# size to which the images should be internally resized to reduce the memory footprint
|
||||
resize_size: 500
|
||||
# target size of the longer side of the image widget
|
||||
widget_size: 150
|
||||
|
||||
classes:
|
||||
# css classname of the window
|
||||
window: window
|
||||
# css classname of the card containing an image and a label
|
||||
image_card: card
|
||||
# css classname of the card containing an image and a label when the image is still being loaded
|
||||
image_card_loading: card-loading
|
||||
# css classname of the image inside the card
|
||||
image: image
|
||||
# css classname of the label inside the card
|
||||
image_label: image-label
|
||||
# css classname of the notebook containing all pages
|
||||
notebook: notebook
|
||||
# css classname of a label of the notebook
|
||||
tab_label: tab-label
|
||||
# css classname of a notebook page (e.g. windows container)
|
||||
notebook_page: page
|
||||
# css classname of the region selection button
|
||||
region_button: region-button
|
||||
# css classname of the button containing the session restore checkbox and label
|
||||
restore_button: restore-button
|
||||
|
||||
windows:
|
||||
# minimum amount of image cards per row on the windows page
|
||||
min_per_row: 3
|
||||
# maximum amount of image cards per row on the windows page
|
||||
max_per_row: 999
|
||||
# number of clicks needed to select a window
|
||||
clicks: 1
|
||||
# spacing in pixels between the window cards
|
||||
spacing: 12
|
||||
|
||||
outputs:
|
||||
# number of clicks needed to select an output
|
||||
clicks: 1
|
||||
# spacing in pixels between the outputs in the layout
|
||||
# note: the spacing is applied from both sides (the gap is `spacing * 2`)
|
||||
spacing: 6
|
||||
# show the label with the output name
|
||||
show_label: false
|
||||
# size the output cards respectively to their scaling
|
||||
respect_output_scaling: true
|
||||
|
||||
region:
|
||||
# command to run for region selection
|
||||
# the output needs to be in the <output>@<x>,<y>,<w>,<h> (e.g. DP-3@2789,436,756,576) format
|
||||
command: slurp -f '%o@%x,%y,%w,%h'
|
||||
|
||||
# hide the token restore checkbox and use the default value instead
|
||||
hide_token_restore: true
|
||||
# enable debug logs by default
|
||||
debug: false
|
||||
@@ -1,2 +0,0 @@
|
||||
# Extra autostart processes
|
||||
# exec-once = uwsm-app -- my-service
|
||||
@@ -1,43 +0,0 @@
|
||||
source = ~/.config/nomarchy/current/theme/hyprlock.conf
|
||||
|
||||
general {
|
||||
ignore_empty_input = true
|
||||
}
|
||||
|
||||
background {
|
||||
monitor =
|
||||
color = $color
|
||||
path = ~/.config/nomarchy/current/background
|
||||
blur_passes = 3
|
||||
}
|
||||
|
||||
animations {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
input-field {
|
||||
monitor =
|
||||
size = 650, 100
|
||||
position = 0, 0
|
||||
halign = center
|
||||
valign = center
|
||||
|
||||
inner_color = $inner_color
|
||||
outer_color = $outer_color
|
||||
outline_thickness = 4
|
||||
|
||||
font_family = JetBrainsMono Nerd Font
|
||||
font_color = $font_color
|
||||
|
||||
placeholder_text = Enter Password
|
||||
check_color = $check_color
|
||||
fail_text = <i>$FAIL ($ATTEMPTS)</i>
|
||||
|
||||
rounding = 0
|
||||
shadow_passes = 0
|
||||
fade_on_empty = false
|
||||
}
|
||||
|
||||
auth {
|
||||
fingerprint:enabled = false
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
# Makes hyprsunset do nothing to the screen by default
|
||||
# Without this, the default applies some tint to the monitor
|
||||
profile {
|
||||
time = 07:00
|
||||
identity = true
|
||||
}
|
||||
|
||||
# To enable auto switch to nightlight, set in your .config/hypr/autostart:
|
||||
# exec-once = uwsm app -- hyprsunset
|
||||
# and use the following:
|
||||
# profile {
|
||||
# time = 20:00
|
||||
# temperature = 4000
|
||||
# }
|
||||
@@ -1,34 +0,0 @@
|
||||
# Change the default Nomarchy look'n'feel
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#general
|
||||
general {
|
||||
# No gaps between windows or borders
|
||||
# gaps_in = 0
|
||||
# gaps_out = 0
|
||||
# border_size = 0
|
||||
|
||||
# Change to niri-like side-scrolling layout
|
||||
# layout = scrolling
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
# Use round window corners
|
||||
# rounding = 8
|
||||
|
||||
# Dim unfocused windows (0.0 = no dim, 1.0 = fully dimmed)
|
||||
# dim_inactive = true
|
||||
# dim_strength = 0.15
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||
animations {
|
||||
# Disable all animations
|
||||
# enabled = no
|
||||
}
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#layout
|
||||
layout {
|
||||
# Avoid overly wide single-window layouts on wide screens
|
||||
# single_window_aspect_ratio = 1 1
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
# Straight 1x setup for low-resolution displays like 1080p or 1440p
|
||||
# Or for ultrawide monitors like 34" 3440x1440 or 49" 5120x1440
|
||||
env = GDK_SCALE,1
|
||||
monitor=,preferred,auto,1
|
||||
monitor=,highres,auto,1
|
||||
|
||||
# Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°)
|
||||
# monitor = DP-2, preferred, auto, 1, transform, 1
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
screencopy {
|
||||
allow_token_by_default = true
|
||||
custom_picker_binary = hyprland-preview-share-picker
|
||||
}
|
||||
@@ -48,13 +48,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
# Deploy Hyprland configuration files
|
||||
# Deploy Hyprland configuration files. Only the files that nomarchy.conf
|
||||
# actually sources are deployed here — looknfeel.conf and autostart.conf
|
||||
# live under ~/.config/nomarchy/default/hypr/ and are deployed by the
|
||||
# core/home bulk-nomarchy dir, so duplicating them here was dead surface.
|
||||
xdg.configFile."hypr/nomarchy.conf".source = ./config/nomarchy.conf;
|
||||
xdg.configFile."hypr/monitors.conf".source = lib.mkDefault ./config/monitors.conf;
|
||||
xdg.configFile."hypr/input.conf".source = lib.mkDefault ./config/input.conf;
|
||||
xdg.configFile."hypr/bindings.conf".source = lib.mkDefault ./config/bindings.conf;
|
||||
xdg.configFile."hypr/looknfeel.conf".source = lib.mkDefault ./config/looknfeel.conf;
|
||||
xdg.configFile."hypr/autostart.conf".source = lib.mkDefault ./config/autostart.conf;
|
||||
|
||||
# Run swaybg as a proper systemd user service rather than a Hyprland exec-once.
|
||||
# exec-once fails silently (black screen with no visible error) when timing
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"8": [],
|
||||
"9": [],
|
||||
"10": []
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
"custom/launcher": {
|
||||
@@ -79,7 +79,7 @@
|
||||
"default": ["", "", ""]
|
||||
},
|
||||
"on-click-right": "pavucontrol",
|
||||
"on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle",
|
||||
"on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle"
|
||||
},
|
||||
|
||||
"network": {
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
@import "../colors/everforest-light.css";
|
||||
@define-color bg_dim #efebd4;
|
||||
@define-color bg0 #fdf6e3;
|
||||
@define-color bg1 #f4f0d9;
|
||||
@define-color bg2 #efebd4;
|
||||
@define-color bg3 #e6e2cc;
|
||||
@define-color bg4 #e0dcc7;
|
||||
@define-color bg5 #bdc3af;
|
||||
@define-color fg #5c6a72;
|
||||
@define-color red #f85552;
|
||||
@define-color orange #f57d26;
|
||||
@define-color yellow #dfa000;
|
||||
@define-color green #8da101;
|
||||
@define-color aqua #35a77c;
|
||||
@define-color blue #3a94c5;
|
||||
@define-color purple #df69ba;
|
||||
@define-color grey0 #a6b0a0;
|
||||
@define-color grey1 #939f91;
|
||||
@define-color grey2 #829181;
|
||||
|
||||
/* margin: top right bottom left */
|
||||
/* Spacing outside the element */
|
||||
@@ -21,7 +38,7 @@ window#waybar {
|
||||
transition-duration: .5s;
|
||||
|
||||
border-bottom-width: 5px;
|
||||
border-bottom-color: #2e3538;
|
||||
border-bottom-color: #3d4a52;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
@@ -60,14 +77,14 @@ window#waybar {
|
||||
margin-bottom: -5px;
|
||||
|
||||
border-bottom-width: 5px;
|
||||
border-bottom-color: #1c4a62;
|
||||
border-bottom-color: #1e6791;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
#custom-launcher {
|
||||
background-color: @green;
|
||||
color: @bg0;
|
||||
border-bottom-color: #465000;
|
||||
border-bottom-color: #5d6b00;
|
||||
|
||||
margin-left: 15px;
|
||||
padding-left: 20px;
|
||||
@@ -77,7 +94,7 @@ window#waybar {
|
||||
#custom-powermenu {
|
||||
background-color: @red;
|
||||
color: @bg0;
|
||||
border-bottom-color: #9e0906;
|
||||
border-bottom-color: #b32f2c;
|
||||
|
||||
margin-right: 15px;
|
||||
padding-left: 20px;
|
||||
|
||||
@@ -71,7 +71,6 @@ let
|
||||
NOMARCHY_TOGGLE_IDLE = if config.nomarchy.toggles.idle then "true" else "false";
|
||||
NOMARCHY_TOGGLE_NIGHTLIGHT = if config.nomarchy.toggles.nightlight then "true" else "false";
|
||||
NOMARCHY_TOGGLE_WAYBAR = if config.nomarchy.toggles.waybar then "true" else "false";
|
||||
NOMARCHY_TOGGLE_SKIP_VSCODE_THEME = if config.nomarchy.toggles.skipVsCodeTheme then "true" else "false";
|
||||
NOMARCHY_MONOSPACE_FONT = config.nomarchy.fonts.monospace;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Add an EFI boot entry for the Nomarchy UKI, allowing the system to boot directly
|
||||
# without a bootloader like Limine. Requires UEFI firmware and a built UKI.
|
||||
|
||||
if [[ ! -d /sys/firmware/efi ]]; then
|
||||
echo "Error: System is not booted in UEFI mode" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! efibootmgr &>/dev/null; then
|
||||
echo "Error: efibootmgr is not available or not functional" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if cat /sys/class/dmi/id/bios_vendor 2>/dev/null | grep -qi "American Megatrends"; then
|
||||
echo "Error: American Megatrends firmware may not safely support custom EFI entries" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if cat /sys/class/dmi/id/bios_vendor 2>/dev/null | grep -qi "Apple"; then
|
||||
echo "Error: Apple firmware uses its own boot manager" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
uki_file=$(find /boot/EFI/Linux/ -name "nomarchy*.efi" -printf "%f\n" 2>/dev/null | head -1)
|
||||
|
||||
if [[ -z $uki_file ]]; then
|
||||
echo "Error: No Nomarchy UKI found in /boot/EFI/Linux/" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
boot_source=$(findmnt -n -o SOURCE /boot)
|
||||
disk=$(echo "$boot_source" | sed 's/p\?[0-9]*$//')
|
||||
part=$(echo "$boot_source" | grep -o 'p\?[0-9]*$' | sed 's/^p//')
|
||||
|
||||
if gum confirm "Setup direct boot (so snapshot booting must be done via bios)?"; then
|
||||
echo "Creating EFI boot entry for $uki_file"
|
||||
|
||||
sudo efibootmgr --create \
|
||||
--disk "$disk" \
|
||||
--part "$part" \
|
||||
--label "Nomarchy" \
|
||||
--loader "\\EFI\\Linux\\$uki_file"
|
||||
fi
|
||||
@@ -82,10 +82,32 @@ ref_files_per_cmd() {
|
||||
# Final char must be alphanumeric — dropping trailing-dash matches like
|
||||
# `nomarchy-pkg-` that come from glob references (`for c in nomarchy-pkg-*`).
|
||||
# Restrict to grep_includes so binaries / tmpfiles don't pollute the set.
|
||||
all_refs=$(grep -rohE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
# The middle `grep -vE` drops lines where `nomarchy-*` is a derivation /
|
||||
# tmp file / sudoers basename / systemd unit / flake output / docker
|
||||
# container identifier — not a shell invocation — so they don't show up
|
||||
# as fake "missing" references.
|
||||
all_refs=$(grep -rhE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
"${grep_includes[@]}" \
|
||||
"${search_dirs[@]}" 2>/dev/null \
|
||||
| grep -vE \
|
||||
-e '(pname|name)[[:space:]]*=[[:space:]]*"nomarchy-' \
|
||||
-e '/tmp/nomarchy-' \
|
||||
-e '/etc/sudoers\.d/[^"[:space:]]*nomarchy-' \
|
||||
-e 'nixosConfigurations\.nomarchy-' \
|
||||
-e 'packages\.[^.]+\.nomarchy-' \
|
||||
-e '\./result/bin/run-nomarchy-' \
|
||||
-e 'mktemp[[:space:]]+[^|]*-t[[:space:]]+nomarchy-' \
|
||||
-e '(TIMER_NAME|NOPASSWD_FILE|UNIT_NAME)=.*nomarchy-' \
|
||||
-e 'docker[[:space:]]+[^|]*nomarchy-' \
|
||||
| grep -oE 'nomarchy-[a-z0-9]([a-z0-9-]*[a-z0-9])?' \
|
||||
| grep -vE '^(nomarchy-plymouth|nomarchy-sddm-theme|nomarchy-live|nomarchy-rev|nomarchy-windows)$' \
|
||||
| sort -u)
|
||||
# The token-level denylist above covers identifiers whose ambiguity survives
|
||||
# the line filter: `nomarchy-plymouth` / `nomarchy-sddm-theme` are Nix
|
||||
# derivation names referenced as bare idents in `[...]` lists,
|
||||
# `nomarchy-live` is an ISO label that shows up in comments, `nomarchy-rev`
|
||||
# is `/etc/nomarchy-rev` (a file written by the ISO), and
|
||||
# `nomarchy-windows` is a docker container name in compose heredocs.
|
||||
|
||||
# --- Render: header --------------------------------------------------------
|
||||
|
||||
|
||||
19
features/scripts/utils/nomarchy-env-update
Normal file → Executable file
19
features/scripts/utils/nomarchy-env-update
Normal file → Executable file
@@ -1,12 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Environment Update Script
|
||||
# 1. Runs the pre-flight state migration
|
||||
# 2. Applies user-level Home Manager changes (Standalone)
|
||||
# Standalone Home Manager iteration path. Use this for fast dotfile and
|
||||
# theme changes that don't need a full system rebuild. For first-boot
|
||||
# dotfiles and any system-level change, the NixOS module activation
|
||||
# from `sudo nixos-rebuild switch` is the source of truth.
|
||||
|
||||
set -e
|
||||
|
||||
# Detect the repository location
|
||||
if [ -f "/etc/nixos/flake.nix" ]; then
|
||||
REPO_DIR="/etc/nixos"
|
||||
elif [ -f "/etc/nomarchy/flake.nix" ]; then
|
||||
@@ -16,13 +17,19 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use the pre-flight migration script to ensure the state is synced before evaluation
|
||||
if command -v nomarchy-preflight-migration >/dev/null 2>&1; then
|
||||
nomarchy-preflight-migration
|
||||
fi
|
||||
|
||||
# Apply Home Manager changes from the local flake (Standalone)
|
||||
echo "Applying user-level changes from $REPO_DIR#$USER..."
|
||||
home-manager switch --flake "$REPO_DIR#$USER" --impure
|
||||
if command -v home-manager >/dev/null 2>&1; then
|
||||
home-manager switch --flake "$REPO_DIR#$USER" --impure
|
||||
else
|
||||
# Bootstrap path: HM hasn't put `home-manager` on PATH yet (e.g. running
|
||||
# straight after a partial install). Pull it from the flake registry.
|
||||
nix --extra-experimental-features 'nix-command flakes' \
|
||||
run 'home-manager/release-25.11' \
|
||||
-- switch --flake "$REPO_DIR#$USER" --impure
|
||||
fi
|
||||
|
||||
echo "Environment update complete."
|
||||
|
||||
@@ -15,6 +15,9 @@ case "$COMMAND" in
|
||||
nomarchy-font-list
|
||||
;;
|
||||
selector|*)
|
||||
nomarchy-font-selector
|
||||
theme=$(echo -e "$(nomarchy-font-list)" | nomarchy-launch-walker --dmenu --width 350 -p "Font...")
|
||||
if [[ -n "$theme" && "$theme" != "CNCLD" ]]; then
|
||||
nomarchy-font-set "$theme"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Nomarchy Manual Script
|
||||
# Opens the Nomarchy manual in the default web browser.
|
||||
# Open the Nomarchy docs index in the default handler.
|
||||
# On an installed system the source tree lives at ~/.local/share/nomarchy/
|
||||
# (see SKILL.md's "Out of Scope" section), so the README — which links every
|
||||
# doc in docs/ — is the canonical "open the manual" target.
|
||||
|
||||
URL="https://learn.omacom.io/2/the-nomarchy-manual"
|
||||
README="$HOME/.local/share/nomarchy/README.md"
|
||||
|
||||
echo "Opening Nomarchy manual: $URL"
|
||||
xdg-open "$URL"
|
||||
if [[ -f "$README" ]]; then
|
||||
echo "Opening Nomarchy manual: $README"
|
||||
xdg-open "$README"
|
||||
else
|
||||
notify-send "Nomarchy Manual" \
|
||||
"Source tree not found at $README. Try \`nomarchy-update\` to sync it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Nomarchy State Migration Script
|
||||
# Migrates state from old locations to unified ~/.config/nomarchy/state.json
|
||||
|
||||
set -e
|
||||
|
||||
NEW_STATE_DIR="$HOME/.config/nomarchy"
|
||||
NEW_STATE_FILE="$NEW_STATE_DIR/state.json"
|
||||
OLD_HOME_STATE="$HOME/.config/home-manager/state.json"
|
||||
OLD_SYSTEM_STATE="/etc/nixos/state.json"
|
||||
|
||||
mkdir -p "$NEW_STATE_DIR"
|
||||
|
||||
# Initialize new state file if it doesn't exist
|
||||
if [[ ! -f "$NEW_STATE_FILE" ]]; then
|
||||
echo "{}" > "$NEW_STATE_FILE"
|
||||
fi
|
||||
|
||||
# Function to safely merge JSON
|
||||
merge_json() {
|
||||
local source="$1"
|
||||
if [[ -f "$source" ]]; then
|
||||
echo "Migrating from $source..."
|
||||
TMP_FILE=$(mktemp)
|
||||
# Merge source into new state (new state values take precedence if conflict)
|
||||
jq -s '.[0] * .[1]' "$source" "$NEW_STATE_FILE" > "$TMP_FILE" && mv "$TMP_FILE" "$NEW_STATE_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Migrate old home-manager state
|
||||
if [[ -f "$OLD_HOME_STATE" ]] && [[ "$OLD_HOME_STATE" != "$NEW_STATE_FILE" ]]; then
|
||||
merge_json "$OLD_HOME_STATE"
|
||||
echo "Old home state migrated. You can remove: $OLD_HOME_STATE"
|
||||
fi
|
||||
|
||||
# Check if system state exists and user wants to sync it
|
||||
if [[ -f "$OLD_SYSTEM_STATE" ]]; then
|
||||
echo ""
|
||||
echo "System state found at $OLD_SYSTEM_STATE"
|
||||
echo "Note: System state will continue to be read from /etc/nixos/state.json"
|
||||
echo " for system-level NixOS configuration."
|
||||
fi
|
||||
|
||||
# Run the preflight migration for any legacy formats
|
||||
if command -v nomarchy-preflight-migration &> /dev/null; then
|
||||
nomarchy-preflight-migration
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Migration complete!"
|
||||
echo "New state location: $NEW_STATE_FILE"
|
||||
echo ""
|
||||
echo "Current state:"
|
||||
jq '.' "$NEW_STATE_FILE"
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Install an npx wrapper for a given npm package.
|
||||
# Usage: nomarchy-npx-install <package> [command-name]
|
||||
#
|
||||
# If command-name is omitted, it defaults to the package name.
|
||||
# Example: nomarchy-npx-install opencode-ai opencode
|
||||
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Usage: nomarchy-npx-install <package> [command-name]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
package=$1
|
||||
command=${2:-$1}
|
||||
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
|
||||
cat > "$HOME/.local/bin/$command" <<EOF
|
||||
#!/bin/bash
|
||||
exec npx --yes $package "\$@"
|
||||
EOF
|
||||
|
||||
chmod +x "$HOME/.local/bin/$command"
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Reload hyprland configuration (used by the Nomarchy theme switching).
|
||||
|
||||
hyprctl reload >/dev/null
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Reload mako configuration (used by the Nomarchy theme switching).
|
||||
|
||||
makoctl reload
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Restart tmux if running with the latest configuration
|
||||
|
||||
if pgrep -x tmux; then
|
||||
tmux source-file ~/.config/tmux/tmux.conf
|
||||
fi
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Nomarchy Rollback Script
|
||||
# Reverts the system to a previous working generation.
|
||||
|
||||
set -e
|
||||
|
||||
if command -v snapper &>/dev/null; then
|
||||
echo "BTRFS Snapper detected. Listing snapshots..."
|
||||
sudo snapper list
|
||||
echo ""
|
||||
echo "To rollback to a specific snapshot, run: sudo snapper rollback <number>"
|
||||
echo "Or to rollback the current NixOS generation only:"
|
||||
fi
|
||||
|
||||
echo "Rolling back NixOS generation..."
|
||||
sudo nixos-rebuild rollback
|
||||
|
||||
echo "Rollback complete. Please reboot if you performed a BTRFS rollback."
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
COMMAND="$1"
|
||||
NOMARCHY_PATH=${NOMARCHY_PATH:-$HOME/.local/share/nomarchy}
|
||||
|
||||
if [[ -z $COMMAND ]]; then
|
||||
echo "Usage: nomarchy-snapshot <create|restore>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v snapper &>/dev/null; then
|
||||
exit 127 # nomarchy-update can use this to just ignore if snapper is not available
|
||||
fi
|
||||
|
||||
case "$COMMAND" in
|
||||
create)
|
||||
DESC="$(nomarchy-version)"
|
||||
|
||||
echo -e "\e[32mCreate system snapshot\e[0m"
|
||||
|
||||
# Get existing snapper config names from CSV output
|
||||
mapfile -t CONFIGS < <(sudo snapper --csvout list-configs | awk -F, 'NR>1 {print $1}')
|
||||
|
||||
for config in "${CONFIGS[@]}"; do
|
||||
sudo snapper -c "$config" create -c number -d "$DESC"
|
||||
done
|
||||
echo
|
||||
;;
|
||||
restore)
|
||||
sudo limine-snapper-restore
|
||||
;;
|
||||
esac
|
||||
@@ -15,8 +15,20 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Apply NixOS changes from the local flake
|
||||
echo "Applying system-level changes from $REPO_DIR..."
|
||||
sudo nixos-rebuild switch --flake "$REPO_DIR#default" --impure
|
||||
# The installer generates `nixosConfigurations.<hostname>` (see
|
||||
# installer/install.sh: `nixosConfigurations.$HOSTNAME`), so the flake target
|
||||
# must match the current host. The previous `#default` literal worked only
|
||||
# for a development host that happened to be named "default" and silently
|
||||
# broke every toggle script (nomarchy-tz-select, nomarchy-wifi-powersave,
|
||||
# nomarchy-setup-{dns,fido2,fingerprint}, nomarchy-toggle-hybrid-gpu) on a
|
||||
# real install.
|
||||
HOSTNAME_ATTR=$(hostname)
|
||||
if [ -z "$HOSTNAME_ATTR" ]; then
|
||||
echo "Error: could not determine hostname for flake attribute." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Applying system-level changes from $REPO_DIR#$HOSTNAME_ATTR..."
|
||||
sudo nixos-rebuild switch --flake "$REPO_DIR#$HOSTNAME_ATTR"
|
||||
|
||||
echo "System update complete."
|
||||
|
||||
@@ -15,6 +15,6 @@ case "$COMMAND" in
|
||||
nomarchy-theme-list
|
||||
;;
|
||||
selector|*)
|
||||
nomarchy-theme-selector
|
||||
nomarchy-launch-walker -m menus:nomarchythemes --width 800 --minheight 400
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -5,6 +5,6 @@ set -e
|
||||
# Prints the current Nomarchy version based on the upstream NixOS channel.
|
||||
|
||||
VERSION="25.11.0"
|
||||
CODENAME="Markhor"
|
||||
CODENAME="Sovereign"
|
||||
|
||||
echo "Nomarchy v${VERSION} (${CODENAME})"
|
||||
|
||||
@@ -10,14 +10,12 @@ case "$COMMAND" in
|
||||
set)
|
||||
shift
|
||||
# Wallpaper set usually involves writing to state.json and calling swww
|
||||
# We can reuse the logic from nomarchy-wallpaper-selector if we extract it,
|
||||
# but for now let's just trigger the selector.
|
||||
nomarchy-wallpaper-selector
|
||||
nomarchy-theme-bg-set "$@"
|
||||
;;
|
||||
next)
|
||||
nomarchy-theme-bg-next
|
||||
;;
|
||||
selector|*)
|
||||
nomarchy-wallpaper-selector
|
||||
nomarchy-launch-walker -m menus:nomarchyBackgroundSelector --width 800 --minheight 400
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
url="$1"
|
||||
web_url="https://app.hey.com"
|
||||
|
||||
# Handle mailto: URLs
|
||||
if [[ $url =~ ^mailto: ]]; then
|
||||
email=$(echo "$url" | sed 's/mailto://')
|
||||
web_url="https://app.hey.com/messages/new?to=$email"
|
||||
fi
|
||||
|
||||
exec nomarchy-launch-webapp "$web_url"
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
url="$1"
|
||||
web_url="https://app.zoom.us/wc/home"
|
||||
|
||||
if [[ $url =~ ^zoom(mtg|us):// ]]; then
|
||||
confno=$(echo "$url" | sed -n 's/.*[?&]confno=\([^&]*\).*/\1/p')
|
||||
|
||||
if [[ -n $confno ]]; then
|
||||
pwd=$(echo "$url" | sed -n 's/.*[?&]pwd=\([^&]*\).*/\1/p')
|
||||
|
||||
if [[ -n $pwd ]]; then
|
||||
web_url="https://app.zoom.us/wc/join/$confno?pwd=$pwd"
|
||||
else
|
||||
web_url="https://app.zoom.us/wc/join/$confno"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
exec nomarchy-launch-webapp "$web_url"
|
||||
@@ -21,23 +21,32 @@ fi
|
||||
gum style \
|
||||
--foreground 212 --border-foreground 212 --border double \
|
||||
--align center --width 50 --margin "1 2" --padding "2 4" \
|
||||
"Nomarchy" "The NixOS Distribution with Nomarchy Flavour"
|
||||
"Nomarchy" "The Professional NixOS Desktop"
|
||||
|
||||
echo "Welcome! Let's personalize your new system."
|
||||
echo ""
|
||||
|
||||
# 1. Select initial theme
|
||||
echo "Step 1: Choose your starting theme"
|
||||
nomarchy-theme-set "$(nomarchy-theme-list | gum filter --placeholder 'Select a theme...')" --no-update
|
||||
SELECTED_THEME="$(nomarchy-theme-list | gum filter --placeholder 'Select a theme...')"
|
||||
if [[ -n "$SELECTED_THEME" ]]; then
|
||||
THEME_ID=$(echo "$SELECTED_THEME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
|
||||
nomarchy-theme-set "$THEME_ID" --no-update
|
||||
fi
|
||||
|
||||
# 2. Select initial font
|
||||
echo "Step 2: Choose your preferred font"
|
||||
nomarchy-font-set "$(nomarchy-font-list | gum filter --placeholder 'Select a font...')" --no-update
|
||||
SELECTED_FONT="$(nomarchy-font-list | gum filter --placeholder 'Select a font...')"
|
||||
if [[ -n "$SELECTED_FONT" ]]; then
|
||||
nomarchy-font-set "$SELECTED_FONT" --no-update
|
||||
fi
|
||||
|
||||
# 3. Select panel position
|
||||
echo "Step 3: Choose your preferred panel position"
|
||||
POSITION=$(gum choose "top" "bottom")
|
||||
nomarchy-state-write panelPosition "$POSITION"
|
||||
if [[ -n "$POSITION" ]]; then
|
||||
nomarchy-state-write panelPosition "$POSITION"
|
||||
fi
|
||||
|
||||
# Skip system-modifying steps in the Live ISO environment
|
||||
if [[ "$USER" == "nixos" ]]; then
|
||||
@@ -50,39 +59,9 @@ if [[ "$USER" == "nixos" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 4. Starter home.nix
|
||||
# 4. Setup Local Repo (Crucial for nomarchy-env-update to work)
|
||||
echo ""
|
||||
echo "Step 4: Starter home.nix"
|
||||
HOME_NIX="$HOME/.config/home-manager/home.nix"
|
||||
if [ ! -f "$HOME_NIX" ]; then
|
||||
echo "It looks like you don't have a ~/.config/home-manager/home.nix file yet."
|
||||
echo "Nomarchy uses this file to manage your user-level packages and settings."
|
||||
if gum confirm "Would you like to generate a starter home.nix?"; then
|
||||
mkdir -p "$(dirname "$HOME_NIX")"
|
||||
cat <<EOF > "$HOME_NIX"
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
# Nomarchy starter home.nix
|
||||
# Add your user packages here.
|
||||
home.packages = with pkgs; [
|
||||
btop
|
||||
fastfetch
|
||||
chromium
|
||||
# Add more packages here
|
||||
];
|
||||
|
||||
# home.stateVersion = "25.11"; # Consult docs/MIGRATION.md if you change this
|
||||
}
|
||||
EOF
|
||||
echo "Starter home.nix generated at $HOME_NIX"
|
||||
fi
|
||||
else
|
||||
echo "Detected existing home.nix at $HOME_NIX. Skipping generation."
|
||||
fi
|
||||
|
||||
# 5. Setup Local Repo (Crucial for nomarchy-env-update to work)
|
||||
echo ""
|
||||
echo "Step 5: Git Repository Check"
|
||||
echo "Step 4: Git Repository Check"
|
||||
echo "Nomarchy relies on a local git repository for declarative updates."
|
||||
if [ ! -d "/etc/nixos/.git" ]; then
|
||||
echo "Warning: /etc/nixos is not a git repository. Declarative updates might fail."
|
||||
@@ -93,7 +72,7 @@ if [ ! -d "/etc/nixos/.git" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# 6. Success
|
||||
# 5. Success
|
||||
echo ""
|
||||
echo "Applying all changes..."
|
||||
nomarchy-env-update
|
||||
|
||||
@@ -40,12 +40,6 @@ install_windows() {
|
||||
|
||||
mkdir -p "$HOME/.windows"
|
||||
mkdir -p "$HOME/.config/windows"
|
||||
mkdir -p "$HOME/.local/share/applications/icons"
|
||||
|
||||
# Install Windows VM icon and desktop file
|
||||
if [[ -f $NOMARCHY_PATH/applications/icons/windows.png ]]; then
|
||||
cp "$NOMARCHY_PATH/applications/icons/windows.png" "$HOME/.local/share/applications/icons/windows.png"
|
||||
fi
|
||||
|
||||
cat << EOF | tee "$HOME/.local/share/applications/windows-vm.desktop" > /dev/null
|
||||
[Desktop Entry]
|
||||
|
||||
@@ -168,10 +168,10 @@
|
||||
# Live-ISO-only welcome. Pops a notification a few seconds
|
||||
# after the graphical session is up and opens a terminal
|
||||
# parked at the installer command, so the user never has to
|
||||
# hunt for it. Force preferred monitor detection as some
|
||||
# hunt for it. Force highres monitor detection as some
|
||||
# hardware defaults to 1024x768.
|
||||
wayland.windowManager.hyprland.extraConfig = nixpkgs.lib.mkAfter ''
|
||||
monitor = , preferred, auto, 1
|
||||
monitor = , highres, auto, 1
|
||||
exec-once = sh -c 'sleep 3; notify-send -u critical -t 0 "Welcome to Nomarchy" "Run \`sudo /etc/install.sh\` in the open terminal — or \`--dry-run\` to preview."'
|
||||
|
||||
exec-once = sh -c 'sleep 4; alacritty --title "Nomarchy Installer" -e bash -lc "echo; echo \"Welcome to the Nomarchy live ISO.\"; echo; echo \" sudo /etc/install.sh # install\"; echo \" sudo /etc/install.sh --dry-run # preview only\"; echo \" sudo /etc/install.sh --resume # resume after an interrupt\"; echo; exec bash"'
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
parted
|
||||
btrfs-progs
|
||||
cryptsetup
|
||||
mkpasswd
|
||||
inputs.disko.packages.${pkgs.stdenv.hostPlatform.system}.disko
|
||||
(pkgs.makeDesktopItem {
|
||||
name = "install-nomarchy";
|
||||
@@ -64,6 +65,15 @@
|
||||
|
||||
environment.etc."nomarchy".source = inputs.self;
|
||||
|
||||
# Embed the git revision the ISO was built from so install.sh can pin the
|
||||
# generated flake to the exact same commit. `inputs.self.rev` exists only
|
||||
# when the flake is built from a clean git tree; from a dirty worktree we
|
||||
# fall back to dirtyRev (which won't be resolvable by `git+https`, so the
|
||||
# installer treats it as "unpinned"). Empty file = unpinned.
|
||||
environment.etc."nomarchy-rev".text =
|
||||
if inputs.self ? rev then inputs.self.rev
|
||||
else "";
|
||||
|
||||
# Auto-login to the graphical session
|
||||
services.displayManager.autoLogin.enable = true;
|
||||
services.displayManager.autoLogin.user = "nixos";
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
disko.devices = {
|
||||
disk = {
|
||||
main = {
|
||||
type = "disk";
|
||||
device = "@TARGET_DRIVE@";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
ESP = {
|
||||
priority = 1;
|
||||
name = "ESP";
|
||||
start = "1M";
|
||||
end = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted";
|
||||
settings.allowDiscards = true;
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = [ "-f" ];
|
||||
subvolumes = {
|
||||
"@" = {
|
||||
mountpoint = "/";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
};
|
||||
"@persist" = {
|
||||
mountpoint = "/persist";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
};
|
||||
"@home" = {
|
||||
mountpoint = "/home";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
};
|
||||
"@nix" = {
|
||||
mountpoint = "/nix";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
};
|
||||
"@log" = {
|
||||
mountpoint = "/var/log";
|
||||
mountOptions = [ "compress=zstd" "noatime" ];
|
||||
};
|
||||
};
|
||||
postCreateHook = ''
|
||||
MNTPOINT=$(mktemp -d)
|
||||
mount -t btrfs /dev/mapper/crypted $MNTPOINT
|
||||
btrfs subvolume snapshot -r $MNTPOINT/@ $MNTPOINT/root-blank
|
||||
umount $MNTPOINT
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -44,8 +44,8 @@ let
|
||||
content = {
|
||||
type = "luks";
|
||||
name = extraLuks drive;
|
||||
passwordFile = "/tmp/nomarchy-luks.key";
|
||||
settings.allowDiscards = true;
|
||||
settings.passwordFile = "/dev/shm/nomarchy-luks.key";
|
||||
content.type = "btrfs";
|
||||
};
|
||||
};
|
||||
@@ -70,16 +70,24 @@ let
|
||||
# snapshot) targets the right /dev/mapper entry.
|
||||
mainLuksName = if hasExtras then "crypted_main" else "crypted";
|
||||
|
||||
# Multi-device BTRFS on LUKS requires that we explicitly tell systemd-initrd
|
||||
# to wait for ALL LUKS devices to be decrypted before attempting to mount
|
||||
# the filesystem, otherwise it might try to mount as soon as the first one
|
||||
# appears and then hang or fail.
|
||||
allLuksNames = [ mainLuksName ] ++ map extraLuks extraDrives;
|
||||
btrfsMountOptions = [ "compress=zstd" "noatime" "x-systemd.device-timeout=0" ]
|
||||
++ map (n: "x-systemd.requires=/dev/mapper/" + n) allLuksNames;
|
||||
|
||||
rootBtrfs = {
|
||||
type = "btrfs";
|
||||
extraArgs = btrfsExtraArgs;
|
||||
subvolumes = {
|
||||
"@" = { mountpoint = "/"; mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
"@persist" = { mountpoint = "/persist"; mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
"@home" = { mountpoint = "/home"; mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
"@nix" = { mountpoint = "/nix"; mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
"@log" = { mountpoint = "/var/log"; mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
"@snapshots" = { mountpoint = "/.snapshots"; mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
"@" = { mountpoint = "/"; mountOptions = btrfsMountOptions; };
|
||||
"@persist" = { mountpoint = "/persist"; mountOptions = btrfsMountOptions; };
|
||||
"@home" = { mountpoint = "/home"; mountOptions = btrfsMountOptions; };
|
||||
"@nix" = { mountpoint = "/nix"; mountOptions = btrfsMountOptions; };
|
||||
"@log" = { mountpoint = "/var/log"; mountOptions = btrfsMountOptions; };
|
||||
"@snapshots" = { mountpoint = "/.snapshots"; mountOptions = btrfsMountOptions; };
|
||||
};
|
||||
postCreateHook = ''
|
||||
MNTPOINT=$(mktemp -d)
|
||||
@@ -116,8 +124,8 @@ in {
|
||||
content = {
|
||||
type = "luks";
|
||||
name = mainLuksName;
|
||||
passwordFile = "/tmp/nomarchy-luks.key";
|
||||
settings.allowDiscards = true;
|
||||
settings.passwordFile = "/dev/shm/nomarchy-luks.key";
|
||||
content = rootBtrfs;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,13 +19,17 @@
|
||||
|
||||
HARDWARE_DB=(
|
||||
# Framework ---------------------------------------------------------------
|
||||
# Module names follow nixos-hardware's actual attrs — for Framework 13
|
||||
# the per-generation modules dropped the "13-" prefix.
|
||||
"Framework|Laptop 16.*AMD|isFramework=true|framework-16-7040-amd"
|
||||
"Framework|Laptop 13.*AMD Ryzen AI 300|isFramework=true|framework-13-amd-ai-300-series"
|
||||
"Framework|Laptop 13.*AMD Ryzen 7040|isFramework=true|framework-13-7040-amd"
|
||||
"Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13-13th-gen-intel"
|
||||
"Framework|Laptop 13.*12th Gen Intel|isFramework=true|framework-13-12th-gen-intel"
|
||||
"Framework|Laptop 13.*11th Gen Intel|isFramework=true|framework-13-11th-gen-intel"
|
||||
"Framework|Laptop \(13.*|isFramework=true|framework-13-11th-gen-intel"
|
||||
"Framework|Laptop 16.*Ryzen AI 300|isFramework=true|framework-16-amd-ai-300-series"
|
||||
"Framework|Laptop 13.*Ryzen AI 300|isFramework=true|framework-amd-ai-300-series"
|
||||
"Framework|Laptop 13.*Ryzen 7040|isFramework=true|framework-13-7040-amd"
|
||||
"Framework|Laptop 13.*Core Ultra|isFramework=true|framework-intel-core-ultra-series1"
|
||||
"Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13th-gen-intel"
|
||||
"Framework|Laptop 13.*12th Gen Intel|isFramework=true|framework-12th-gen-intel"
|
||||
"Framework|Laptop 13.*11th Gen Intel|isFramework=true|framework-11th-gen-intel"
|
||||
"Framework|Laptop \(13.*|isFramework=true|framework"
|
||||
|
||||
# Dell XPS / Precision / Latitude ----------------------------------------
|
||||
"Dell|XPS 15 9500|isXPS=true|dell-xps-15-9500"
|
||||
@@ -36,40 +40,61 @@ HARDWARE_DB=(
|
||||
"Dell|XPS 13 9380|isXPS=true|dell-xps-13-9380"
|
||||
"Dell|XPS 13 7390|isXPS=true|dell-xps-13-7390"
|
||||
"Dell|Precision 5530|_|dell-precision-5530"
|
||||
"Dell|Latitude 7480|_|dell-latitude-7480"
|
||||
"Dell|Latitude 5400|_|dell-latitude-5400"
|
||||
"Dell|Latitude 7490|_|dell-latitude-7490"
|
||||
"Dell|Latitude 7430|_|dell-latitude-7430"
|
||||
"Dell|Latitude 7420|_|dell-latitude-7420"
|
||||
|
||||
# Lenovo ThinkPad --------------------------------------------------------
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 11|_|lenovo-thinkpad-x1-carbon-gen11"
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 10|_|lenovo-thinkpad-x1-carbon-gen10"
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 9|_|lenovo-thinkpad-x1-carbon-gen9"
|
||||
# X1 Carbon: the per-gen modules are named "x1-Nth-gen", not
|
||||
# "x1-carbon-genN" — both naming schemes appeared in nixos-hardware and
|
||||
# the old DB references picked the wrong one. Carbon-specific quirks
|
||||
# match the X1 modules because the X1 series IS the Carbon line.
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 11|_|lenovo-thinkpad-x1-11th-gen"
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 10|_|lenovo-thinkpad-x1-10th-gen"
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 9|_|lenovo-thinkpad-x1-9th-gen"
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 7|_|lenovo-thinkpad-x1-7th-gen"
|
||||
"LENOVO|ThinkPad X1 Carbon Gen 6|_|lenovo-thinkpad-x1-6th-gen"
|
||||
"LENOVO|ThinkPad X1 Extreme|_|lenovo-thinkpad-x1-extreme"
|
||||
"LENOVO|ThinkPad X1 Nano|_|lenovo-thinkpad-x1-nano-gen1"
|
||||
"LENOVO|ThinkPad T14 Gen 3|_|lenovo-thinkpad-t14-amd-gen3"
|
||||
"LENOVO|ThinkPad T14 Gen 2|_|lenovo-thinkpad-t14-amd-gen2"
|
||||
"LENOVO|ThinkPad T14 Gen 1|_|lenovo-thinkpad-t14-amd-gen1"
|
||||
"LENOVO|ThinkPad T480|_|lenovo-thinkpad-t480"
|
||||
"LENOVO|ThinkPad L13|_|lenovo-thinkpad-l13"
|
||||
"LENOVO|ThinkPad P14s|_|lenovo-thinkpad-p14s"
|
||||
"LENOVO|ThinkPad P14s.*Gen 5|_|lenovo-thinkpad-p14s-amd-gen5"
|
||||
"LENOVO|ThinkPad P14s.*Gen 4|_|lenovo-thinkpad-p14s-amd-gen4"
|
||||
"LENOVO|ThinkPad P14s.*Gen 3|_|lenovo-thinkpad-p14s-amd-gen3"
|
||||
|
||||
# Microsoft Surface ------------------------------------------------------
|
||||
# nixos-hardware ships per-chip modules, not per-revision: Intel Surface
|
||||
# Pros (6 through 10) all use `microsoft-surface-pro-intel`; AMD Surface
|
||||
# Laptops use `microsoft-surface-laptop-amd`. Surface Pro 9 has its own
|
||||
# variant for the SQ3 / ARM model — kept separate. Surface Book and
|
||||
# Intel-based Surface Laptops have no dedicated module; we fall back to
|
||||
# the common detection (chassis + cpu + gpu).
|
||||
"Microsoft|Surface Pro 10|_|microsoft-surface-pro-intel"
|
||||
"Microsoft|Surface Pro 9|_|microsoft-surface-pro-9"
|
||||
"Microsoft|Surface Pro 8|_|microsoft-surface-pro-8"
|
||||
"Microsoft|Surface Pro 7|_|microsoft-surface-pro-7"
|
||||
"Microsoft|Surface Pro 6|_|microsoft-surface-pro-6"
|
||||
"Microsoft|Surface Laptop 5|_|microsoft-surface-laptop-5"
|
||||
"Microsoft|Surface Laptop 4|_|microsoft-surface-laptop-4"
|
||||
"Microsoft|Surface Laptop 3|_|microsoft-surface-laptop-3"
|
||||
"Microsoft|Surface Pro 8|_|microsoft-surface-pro-intel"
|
||||
"Microsoft|Surface Pro 7|_|microsoft-surface-pro-intel"
|
||||
"Microsoft|Surface Pro 6|_|microsoft-surface-pro-intel"
|
||||
"Microsoft|Surface Pro 3|_|microsoft-surface-pro-3"
|
||||
"Microsoft|Surface Laptop.*Ryzen|_|microsoft-surface-laptop-amd"
|
||||
"Microsoft|Surface Go|_|microsoft-surface-go"
|
||||
"Microsoft|Surface Book 3|_|microsoft-surface-book-3"
|
||||
"Microsoft|Surface Book 2|_|microsoft-surface-book-2"
|
||||
|
||||
# ASUS ROG / Zephyrus ----------------------------------------------------
|
||||
"ASUS.*|ROG Zephyrus G14.*2024|_|asus-zephyrus-ga403"
|
||||
"ASUS.*|ROG Zephyrus G14.*2023|_|asus-zephyrus-ga402"
|
||||
"ASUS.*|ROG Zephyrus G14.*2021|_|asus-zephyrus-ga401"
|
||||
# ASUS ROG Ally / Zephyrus / Strix --------------------------------------
|
||||
# Ally is the handheld (Z1 Extreme / Z1). RC71L is the original Ally,
|
||||
# RC72LA is the Ally X — both share the same nixos-hardware module
|
||||
# currently.
|
||||
"ASUS.*|RC71L|_|asus-ally-rc71l"
|
||||
"ASUS.*|RC72LA|_|asus-ally-rc71l"
|
||||
"ASUS.*|ROG Ally|_|asus-ally-rc71l"
|
||||
"ASUS.*|ROG Zephyrus G14.*GA402X|_|asus-zephyrus-ga402x"
|
||||
"ASUS.*|ROG Zephyrus G14.*GA402|_|asus-zephyrus-ga402"
|
||||
"ASUS.*|ROG Zephyrus G14.*GA401|_|asus-zephyrus-ga401"
|
||||
"ASUS.*|ROG Zephyrus G15|_|asus-zephyrus-ga503"
|
||||
"ASUS.*|ROG Strix G15|_|asus-rog-strix-g513"
|
||||
"ASUS.*|Zenbook UX|_|asus-zenbook-ux"
|
||||
"ASUS.*|ROG Zephyrus.*GU603|_|asus-zephyrus-gu603h"
|
||||
"ASUS.*|ROG Strix G513|_|asus-rog-strix-g513im"
|
||||
"ASUS.*|ROG Strix G533|_|asus-rog-strix-g533zw"
|
||||
|
||||
# Apple (T2 Intel; M-series falls back to asahi elsewhere) ---------------
|
||||
"Apple.*|MacBookPro15|isT2Mac=true|apple-t2"
|
||||
@@ -86,9 +111,14 @@ HARDWARE_DB=(
|
||||
"System76|Galago Pro.*|_|system76"
|
||||
"System76|Pangolin.*|_|system76"
|
||||
|
||||
# Raspberry Pi (ARM) — listed for completeness; installer is x86_64 only -
|
||||
# "Raspberry Pi|Raspberry Pi 5|_|raspberry-pi-5"
|
||||
# "Raspberry Pi|Raspberry Pi 4|_|raspberry-pi-4"
|
||||
# Devices nixos-hardware doesn't cover (yet) -----------------------------
|
||||
# Listed here so future contributors know they're known-unsupported, not
|
||||
# accidentally missing:
|
||||
# - Valve Steam Deck (Galileo / Jupiter): try Jovian-NixOS as a flake
|
||||
# input instead — separate ecosystem, not in nixos-hardware.
|
||||
# - Snapdragon X laptops (Surface Pro 11, Lenovo Yoga Slim 7x, …):
|
||||
# aarch64-only and the Nomarchy installer is x86_64 only.
|
||||
# - Raspberry Pi (ARM): same — installer is x86_64 only.
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
@@ -32,6 +32,7 @@ TARGET_DRIVE=""
|
||||
USERNAME=""
|
||||
LUKS_PASSWORD=""
|
||||
USER_PASSWORD=""
|
||||
USER_PASSWORD_HASH=""
|
||||
TIMEZONE="UTC"
|
||||
KEYMAP_LAYOUT=""
|
||||
KEYMAP_VARIANT=""
|
||||
@@ -73,6 +74,9 @@ Usage: install.sh [--dry-run] [--resume] [-h|--help]
|
||||
Doesn't touch the disk, doesn't run nixos-install.
|
||||
--resume Reuse answers from a previous interrupted run
|
||||
(saved at $STATE_FILE — passwords excluded).
|
||||
NOTE: the live ISO uses tmpfs, so the state file is lost
|
||||
on reboot. --resume only works within the same live-ISO
|
||||
session as the original interrupted run.
|
||||
-h, --help Print this message.
|
||||
USAGE
|
||||
}
|
||||
@@ -92,20 +96,83 @@ parse_args() {
|
||||
# Persist non-secret answers so an interrupted install can pick up where it
|
||||
# left off. Uses `declare -p` so each line is a self-contained `declare --`
|
||||
# statement that `source` re-establishes verbatim.
|
||||
#
|
||||
# USER_PASSWORD_HASH is intentionally NOT persisted, even though a SHA-512
|
||||
# crypt hash isn't reversible. The contract is: after --resume, the password
|
||||
# prompt re-runs. configure_user's early-return guard at the top of the
|
||||
# function checks `[[ -n "$USER_PASSWORD_HASH" ]]` for exactly this reason —
|
||||
# if you ever change that guard to skip on USERNAME+HOSTNAME alone, --resume
|
||||
# will silently install a system with an empty password hash and lock the
|
||||
# user out. Keep the guard checking the hash.
|
||||
save_state() {
|
||||
declare -p \
|
||||
TARGET_DRIVE USERNAME HOSTNAME TIMEZONE \
|
||||
KEYMAP_LAYOUT KEYMAP_VARIANT LOCALE FORM_FACTOR \
|
||||
ENABLE_IMPERMANENCE HARDWARE_MODULES NOMARCHY_HW_OPTS \
|
||||
SELECTED_PROFILES NOMARCHY_REV \
|
||||
> "$STATE_FILE"
|
||||
# The leading timestamp lets --resume surface "how old is this state?"
|
||||
# and is parsed back via NOMARCHY_INSTALL_STATE_SAVED_AT.
|
||||
{
|
||||
echo "NOMARCHY_INSTALL_STATE_SAVED_AT=\"$(date -Iseconds)\""
|
||||
declare -p \
|
||||
TARGET_DRIVE USERNAME HOSTNAME TIMEZONE \
|
||||
KEYMAP_LAYOUT KEYMAP_VARIANT LOCALE FORM_FACTOR \
|
||||
ENABLE_IMPERMANENCE HARDWARE_MODULES NOMARCHY_HW_OPTS \
|
||||
SELECTED_PROFILES NOMARCHY_REV
|
||||
} > "$STATE_FILE"
|
||||
}
|
||||
|
||||
# Pretty-print "X minutes/hours/days ago" from an ISO-8601 timestamp.
|
||||
# Falls back to the raw string if `date -d` can't parse it (defensive —
|
||||
# the timestamp is always produced by `date -Iseconds` above, but we
|
||||
# don't want a stale state file to crash --resume).
|
||||
format_age() {
|
||||
local saved="$1" saved_epoch now_epoch diff
|
||||
saved_epoch=$(date -d "$saved" +%s 2>/dev/null) || { echo "$saved"; return; }
|
||||
now_epoch=$(date +%s)
|
||||
diff=$(( now_epoch - saved_epoch ))
|
||||
if (( diff < 60 )); then echo "${diff}s ago"
|
||||
elif (( diff < 3600 )); then echo "$((diff / 60))m ago"
|
||||
elif (( diff < 86400 )); then echo "$((diff / 3600))h $((diff % 3600 / 60))m ago"
|
||||
else echo "$((diff / 86400))d ago"
|
||||
fi
|
||||
}
|
||||
|
||||
load_state() {
|
||||
if [[ "$RESUME" == "true" ]] && [[ -f "$STATE_FILE" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "$STATE_FILE"
|
||||
info "Resumed from $STATE_FILE"
|
||||
if [[ "$RESUME" != "true" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# --resume with no state file is almost always operator error — the
|
||||
# most common cause is "rebooted the live ISO and forgot tmpfs eats
|
||||
# /tmp/". Fail loudly so the user doesn't sit through a fresh prompt
|
||||
# cycle thinking it was resumed.
|
||||
if [[ ! -f "$STATE_FILE" ]]; then
|
||||
error "--resume was passed but no saved state exists at $STATE_FILE."
|
||||
info "The live ISO uses tmpfs — saved state doesn't survive a reboot."
|
||||
info "Re-run install.sh without --resume to start fresh."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
source "$STATE_FILE"
|
||||
|
||||
# If the saved target drive isn't visible right now, every later
|
||||
# disk-phase step will fail with cryptic errors. Catch it here.
|
||||
# Live ISOs frequently get their non-boot USB sticks unplugged
|
||||
# between sessions, and dev hosts sometimes have non-deterministic
|
||||
# /dev/sdX numbering.
|
||||
if [[ -n "${TARGET_DRIVE:-}" ]] && [[ ! -b "$TARGET_DRIVE" ]]; then
|
||||
error "Saved target drive $TARGET_DRIVE is no longer a block device."
|
||||
info "The drive may have been unplugged or renamed since the saved run."
|
||||
info "Delete $STATE_FILE and re-run without --resume."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show what we're resuming into so the user can Ctrl-C if they're on
|
||||
# the wrong host before any password / disk-wipe prompts fire.
|
||||
local age="unknown age"
|
||||
if [[ -n "${NOMARCHY_INSTALL_STATE_SAVED_AT:-}" ]]; then
|
||||
age=$(format_age "$NOMARCHY_INSTALL_STATE_SAVED_AT")
|
||||
fi
|
||||
info "Resumed from $STATE_FILE (saved $age)"
|
||||
if [[ -n "${USERNAME:-}" || -n "${HOSTNAME:-}" || -n "${TARGET_DRIVE:-}" ]]; then
|
||||
info " Target: ${TARGET_DRIVE:-?} → ${USERNAME:-?} @ ${HOSTNAME:-?}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -128,7 +195,7 @@ clear_step_state() {
|
||||
case "$1" in
|
||||
select_disk) TARGET_DRIVE="" ;;
|
||||
get_luks_passphrase) LUKS_PASSWORD="" ;;
|
||||
configure_user) USERNAME=""; HOSTNAME=""; USER_PASSWORD="" ;;
|
||||
configure_user) USERNAME=""; HOSTNAME=""; USER_PASSWORD=""; USER_PASSWORD_HASH="" ;;
|
||||
select_keymap_locale) KEYMAP_LAYOUT=""; KEYMAP_VARIANT=""; LOCALE="" ;;
|
||||
select_timezone) TIMEZONE="" ;;
|
||||
select_hardware) HARDWARE_MODULES=""; NOMARCHY_HW_OPTS="" ;;
|
||||
@@ -206,13 +273,32 @@ check_environment() {
|
||||
# Capture the exact commit we're installing from. The generated flake
|
||||
# pins `nomarchy.url` to this revision so the installed system can't
|
||||
# silently drift onto a newer (possibly breaking) main.
|
||||
if command -v git >/dev/null 2>&1 && [[ -d "$NOMARCHY_REPO/.git" ]]; then
|
||||
#
|
||||
# Three sources, in priority order:
|
||||
# 1. /etc/nomarchy-rev — written at ISO build time from `inputs.self.rev`
|
||||
# (the only source that works on a normal live-ISO install, because
|
||||
# `inputs.self` strips .git from the Nix store copy at /etc/nomarchy).
|
||||
# 2. `git rev-parse HEAD` in the repo — works when running the installer
|
||||
# from a dev checkout instead of the live ISO.
|
||||
# 3. Empty → unpinned, user gets a loud confirmation prompt below.
|
||||
if [[ -z "$NOMARCHY_REV" ]] && [[ -f /etc/nomarchy-rev ]]; then
|
||||
NOMARCHY_REV=$(tr -d '[:space:]' < /etc/nomarchy-rev)
|
||||
fi
|
||||
if [[ -z "$NOMARCHY_REV" ]] && command -v git >/dev/null 2>&1 && [[ -d "$NOMARCHY_REPO/.git" ]]; then
|
||||
NOMARCHY_REV=$(git -C "$NOMARCHY_REPO" rev-parse HEAD 2>/dev/null || echo "")
|
||||
fi
|
||||
if [[ -n "$NOMARCHY_REV" ]]; then
|
||||
success "Pinning Nomarchy to $NOMARCHY_REV"
|
||||
else
|
||||
info "Could not determine Nomarchy revision; downstream flake will track main."
|
||||
error "Could not determine Nomarchy revision."
|
||||
info "The installed system would silently track upstream main, which"
|
||||
info "defeats the point of locking inputs at install time."
|
||||
if [[ "$DRY_RUN" != "true" ]]; then
|
||||
if ! nrun gum confirm --default=false \
|
||||
"Continue anyway with an unpinned (tracking main) configuration?"; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check internet
|
||||
@@ -452,8 +538,8 @@ configure_user() {
|
||||
section "User Configuration"
|
||||
|
||||
if [[ -n "$USERNAME" && -n "$HOSTNAME" ]]; then
|
||||
# Password check skipped in dry run or if already set
|
||||
if [[ "$DRY_RUN" == "true" ]] || [[ -n "$USER_PASSWORD" ]]; then
|
||||
# Password check skipped in dry run or if already hashed in this session.
|
||||
if [[ "$DRY_RUN" == "true" ]] || [[ -n "$USER_PASSWORD_HASH" ]]; then
|
||||
success "User $USERNAME @ $HOSTNAME configured"
|
||||
return 0
|
||||
fi
|
||||
@@ -493,6 +579,9 @@ configure_user() {
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
info "Dry run: skipping user password prompt."
|
||||
USER_PASSWORD="dryrun-not-used"
|
||||
# Stable placeholder hash so generated system.nix still parses as Nix.
|
||||
# Never lands on a real install — dry-run skips nixos-install.
|
||||
USER_PASSWORD_HASH='$6$dryrun$3xxK3aQ.0bGcv0fM2RhV4Q9oN3p1mYxz5kSjQ.bC8tZpZ7QnFv2cN0Yhd5lDqJ8X9mP2K1L0vR6BqWqzNk7Yo/'
|
||||
save_state
|
||||
return
|
||||
fi
|
||||
@@ -521,6 +610,20 @@ configure_user() {
|
||||
fi
|
||||
done
|
||||
|
||||
# Hash now so we never have to embed the cleartext in /etc/nixos/system.nix
|
||||
# (where it would be world-readable and break Nix parsing on quotes/backslash).
|
||||
# mkpasswd is added to the live ISO via hosts/nomarchy-live.nix.
|
||||
if ! command -v mkpasswd >/dev/null 2>&1; then
|
||||
error "mkpasswd not found on the live ISO — cannot hash the user password."
|
||||
exit 1
|
||||
fi
|
||||
USER_PASSWORD_HASH=$(printf '%s' "$USER_PASSWORD" | mkpasswd -m sha-512 -s)
|
||||
if [[ -z "$USER_PASSWORD_HASH" ]]; then
|
||||
error "mkpasswd produced an empty hash."
|
||||
exit 1
|
||||
fi
|
||||
unset pass1 pass2 USER_PASSWORD
|
||||
|
||||
success "User password set"
|
||||
save_state
|
||||
}
|
||||
@@ -869,17 +972,27 @@ configure_impermanence() {
|
||||
info "This provides a clean, reproducible system."
|
||||
echo ""
|
||||
|
||||
rc=0
|
||||
gum confirm "Enable Impermanence?" || rc=$?
|
||||
if [[ $rc -eq 0 ]]; then
|
||||
ENABLE_IMPERMANENCE="true"
|
||||
success "Impermanence enabled"
|
||||
else
|
||||
if [[ $rc -eq 130 ]]; then return 130; fi
|
||||
ENABLE_IMPERMANENCE="false"
|
||||
info "Impermanence disabled (traditional persistent root)"
|
||||
fi
|
||||
local rc=0
|
||||
nrun gum confirm "Enable Impermanence?" || rc=$?
|
||||
case "$rc" in
|
||||
0)
|
||||
ENABLE_IMPERMANENCE="true"
|
||||
success "Impermanence enabled"
|
||||
;;
|
||||
1)
|
||||
ENABLE_IMPERMANENCE="false"
|
||||
info "Impermanence disabled (traditional persistent root)"
|
||||
;;
|
||||
130)
|
||||
return 130
|
||||
;;
|
||||
*)
|
||||
ENABLE_IMPERMANENCE="false"
|
||||
info "Impermanence disabled (traditional persistent root)"
|
||||
;;
|
||||
esac
|
||||
save_state
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
@@ -1079,11 +1192,15 @@ prewipe_target_drive() {
|
||||
success "Pre-wipe complete"
|
||||
}
|
||||
|
||||
_LUKS_KEY_PATH="/dev/shm/nomarchy-luks.key"
|
||||
_LUKS_KEY_PATH="/tmp/nomarchy-luks.key"
|
||||
|
||||
# Wrap the disko invocation so a failure surfaces the last few lines of
|
||||
# output and offers Retry / View full log / Abort. set -e is suspended for
|
||||
# the disko call so we can inspect its exit code; restored on every path.
|
||||
#
|
||||
# By default disko's chatty output is hidden behind a `gum spin` spinner;
|
||||
# the full log is captured and shown on failure or via `gum pager`. Set
|
||||
# NOMARCHY_VERBOSE_DISKO=1 to stream disko output live instead.
|
||||
run_disko_with_retry() {
|
||||
local main_drive="$1"
|
||||
local extras_nix="$2"
|
||||
@@ -1093,13 +1210,35 @@ run_disko_with_retry() {
|
||||
|
||||
while true; do
|
||||
local rc=0
|
||||
set +e
|
||||
disko --mode destroy,format,mount \
|
||||
--argstr mainDrive "$main_drive" \
|
||||
--arg extraDrives "$extras_nix" \
|
||||
"$disko_file" 2>&1 | tee "$log"
|
||||
rc=${PIPESTATUS[0]}
|
||||
set -e
|
||||
if [[ "$NOMARCHY_VERBOSE_DISKO" == "1" ]]; then
|
||||
set +e
|
||||
disko --mode destroy,format,mount \
|
||||
--yes-wipe-all-disks \
|
||||
--argstr mainDrive "$main_drive" \
|
||||
--arg extraDrives "$extras_nix" \
|
||||
"$disko_file" 2>&1 | tee "$log"
|
||||
rc=${PIPESTATUS[0]}
|
||||
set -e
|
||||
else
|
||||
# Silent path: run disko in the background, write all output to
|
||||
# $log, and show a spinner. Use a status file for the exit code
|
||||
# because `gum spin` doesn't propagate the wrapped command's rc.
|
||||
local status_file
|
||||
status_file=$(mktemp --suffix=.disko.rc)
|
||||
set +e
|
||||
nrun gum spin --spinner dot --title "Partitioning disk(s) with disko..." -- \
|
||||
bash -c '
|
||||
disko --mode destroy,format,mount \
|
||||
--yes-wipe-all-disks \
|
||||
--argstr mainDrive "$1" \
|
||||
--arg extraDrives "$2" \
|
||||
"$3" > "$4" 2>&1
|
||||
echo $? > "$5"
|
||||
' _ "$main_drive" "$extras_nix" "$disko_file" "$log" "$status_file"
|
||||
set -e
|
||||
rc=$(cat "$status_file" 2>/dev/null || echo 1)
|
||||
rm -f "$status_file"
|
||||
fi
|
||||
|
||||
if [[ $rc -eq 0 ]]; then
|
||||
rm -f "$log"
|
||||
@@ -1197,11 +1336,11 @@ execute_installation() {
|
||||
info "Initializing git repository..."
|
||||
(
|
||||
cd /mnt/etc/nixos
|
||||
nrun git git init -q
|
||||
nrun git git add .
|
||||
nrun git git config user.name "Nomarchy Installer"
|
||||
nrun git git config user.email "installer@nomarchy"
|
||||
nrun git git commit -qm "Initial Nomarchy configuration"
|
||||
nrun git init -q
|
||||
nrun git add .
|
||||
nrun git config user.name "Nomarchy Installer"
|
||||
nrun git config user.email "installer@nomarchy"
|
||||
nrun git commit -qm "Initial Nomarchy configuration"
|
||||
)
|
||||
success "Git repository initialized"
|
||||
|
||||
@@ -1211,7 +1350,7 @@ execute_installation() {
|
||||
mkdir -p /mnt/persist/etc
|
||||
mv /mnt/etc/nixos /mnt/persist/etc/
|
||||
mkdir -p /mnt/etc
|
||||
ln -s /persist/etc/nixos /mnt/etc/nixos
|
||||
ln -s ../persist/etc/nixos /mnt/etc/nixos
|
||||
success "Impermanence configured"
|
||||
fi
|
||||
|
||||
@@ -1220,24 +1359,10 @@ execute_installation() {
|
||||
nixos-install --flake "/mnt/etc/nixos#$HOSTNAME" --no-root-passwd
|
||||
success "Nomarchy installed"
|
||||
|
||||
# 9.8 Activate Home Manager for $USERNAME inside the new system so the
|
||||
# user's first login already has Nomarchy's dotfiles. `home-manager
|
||||
# switch` must run as the target user with a real $HOME, so we use
|
||||
# `runuser` (sudo -u keeps the caller's HOME → files land in /root).
|
||||
info "Activating Home Manager for $USERNAME..."
|
||||
if nixos-enter --root /mnt -- bash -c "
|
||||
set -e
|
||||
install -d -o '$USERNAME' -g users -m 0755 '/home/$USERNAME'
|
||||
runuser -u '$USERNAME' -- env HOME='/home/$USERNAME' \
|
||||
nix --extra-experimental-features 'nix-command flakes' \
|
||||
run 'home-manager/release-25.11' -- switch \
|
||||
--flake '/etc/nixos#$USERNAME' --impure
|
||||
"; then
|
||||
success "Home Manager activated"
|
||||
else
|
||||
error "Home Manager activation failed (non-fatal)."
|
||||
info "Run \`nomarchy-env-update\` after the first login to retry."
|
||||
fi
|
||||
# 9.8 (Removed) Standalone Home Manager activation in a chroot.
|
||||
# HM is now wired as a NixOS module in the generated flake, so
|
||||
# `nixos-install` above already activated the user's dotfiles as part
|
||||
# of system activation. No chroot dance required.
|
||||
|
||||
# 9.9 Pre-flight: catch evaluation errors in the freshly-installed
|
||||
# configuration *now*, while we can still fix them with `vi`, instead of
|
||||
@@ -1252,6 +1377,11 @@ execute_installation() {
|
||||
info "The system is installed; fix /etc/nixos before rebooting if possible."
|
||||
fi
|
||||
|
||||
# 9.10 Set ownership of /etc/nixos to the main user
|
||||
info "Setting ownership of /etc/nixos for $USERNAME..."
|
||||
nixos-enter --root /mnt -- chown -R "$USERNAME:users" /etc/nixos
|
||||
success "Ownership updated"
|
||||
|
||||
success "Installation complete!"
|
||||
rm -f "$STATE_FILE"
|
||||
}
|
||||
@@ -1319,9 +1449,17 @@ EOF
|
||||
# ============================================================================
|
||||
|
||||
generate_flake_config() {
|
||||
# Impermanence must mount the same /dev/mapper name that disko created.
|
||||
# disko-config.nix uses "crypted" for single-disk and "crypted_main" once
|
||||
# extraDrives is non-empty — keep these in sync.
|
||||
local impermanence_opt=""
|
||||
if [[ "$ENABLE_IMPERMANENCE" == "true" ]]; then
|
||||
impermanence_opt="nomarchy.system.impermanence.enable = true;"
|
||||
local _main_luks_name="crypted"
|
||||
local _drives=($TARGET_DRIVE)
|
||||
if (( ${#_drives[@]} > 1 )); then
|
||||
_main_luks_name="crypted_main"
|
||||
fi
|
||||
impermanence_opt=$'nomarchy.system.impermanence.enable = true;\n nomarchy.system.impermanence.mainLuksName = "'"$_main_luks_name"$'";\n nomarchy.system.impermanence.user = "'"$USERNAME"$'";'
|
||||
fi
|
||||
|
||||
local PROFILE_SYSTEM_OPTS=""
|
||||
@@ -1373,11 +1511,15 @@ generate_flake_config() {
|
||||
};
|
||||
|
||||
# Two-track Nomarchy workflow:
|
||||
# * System changes → sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME
|
||||
# * Dotfiles/themes → nomarchy-env-update (home-manager switch, no rebuild)
|
||||
# * System + dotfiles (full) → sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME
|
||||
# * Dotfiles only (fast iter) → nomarchy-env-update (standalone home-manager switch)
|
||||
#
|
||||
# Both consume the same \`pkgs\` below so overlays and allowUnfree stay in
|
||||
# sync across the two paths.
|
||||
# Home Manager is wired both ways:
|
||||
# - As a NixOS module under \`nixosConfigurations.$HOSTNAME\` so first boot
|
||||
# after install already has dotfiles in place and every nixos-rebuild
|
||||
# reconciles them. This is what makes the install actually usable.
|
||||
# - As a standalone \`homeConfigurations.$USERNAME\` so theme switches and
|
||||
# dotfile iteration don't require a full system rebuild.
|
||||
outputs = { self, nomarchy, ... }@inputs:
|
||||
let
|
||||
inherit (nomarchy.inputs) nixpkgs home-manager;
|
||||
@@ -1390,19 +1532,34 @@ generate_flake_config() {
|
||||
in
|
||||
{
|
||||
nixosConfigurations.$HOSTNAME = nixpkgs.lib.nixosSystem {
|
||||
inherit pkgs;
|
||||
specialArgs = { inputs = nomarchy.inputs; };
|
||||
modules = [
|
||||
{
|
||||
nixpkgs.hostPlatform = system;
|
||||
nixpkgs.overlays = [ nomarchy.overlays.default ];
|
||||
}
|
||||
./hardware-configuration.nix
|
||||
./hardware-selection.nix
|
||||
nomarchy.nixosModules.system
|
||||
./system.nix
|
||||
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.backupFileExtension = "hm-bak";
|
||||
home-manager.extraSpecialArgs = { inputs = nomarchy.inputs; };
|
||||
home-manager.users.$USERNAME = {
|
||||
imports = [ nomarchy.nixosModules.home ./home.nix ];
|
||||
home.stateVersion = "25.11";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# Standalone Home Manager — \`home-manager switch --flake /etc/nixos#$USERNAME\`
|
||||
# (which is what \`nomarchy-env-update\` runs). Kept separate from the
|
||||
# NixOS config so dotfile/theme iterations don't rebuild the system.
|
||||
# (which is what \`nomarchy-env-update\` runs). Kept alongside the NixOS
|
||||
# module above so dotfile/theme iterations can skip a full system rebuild.
|
||||
homeConfigurations.$USERNAME = home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
extraSpecialArgs = { inputs = nomarchy.inputs; };
|
||||
@@ -1445,6 +1602,11 @@ EOF
|
||||
networking.hostName = "$HOSTNAME";
|
||||
time.timeZone = "$TIMEZONE";
|
||||
|
||||
# UEFI bootloader. Disko lays out a 1 GiB ESP at /boot — switch to
|
||||
# boot.loader.grub if you're installing on a legacy-BIOS machine.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# Keyboard & language — set by the installer.
|
||||
console.keyMap = "$KEYMAP_LAYOUT";
|
||||
i18n.defaultLocale = "$LOCALE";
|
||||
@@ -1483,7 +1645,9 @@ $xkb_variant_line
|
||||
|
||||
users.users."$USERNAME" = {
|
||||
isNormalUser = true;
|
||||
initialPassword = "$USER_PASSWORD";
|
||||
# SHA-512 crypt hash generated by mkpasswd during install. Cleartext
|
||||
# never touches /etc/nixos. Change later with \`passwd\`.
|
||||
initialHashedPassword = "$USER_PASSWORD_HASH";
|
||||
extraGroups = [ "networkmanager" "wheel" "video" "audio" "render" ];
|
||||
};
|
||||
|
||||
@@ -1634,6 +1798,30 @@ EOF
|
||||
# Extra Home Manager modules go here (program configs, services, etc.).
|
||||
}
|
||||
EOF
|
||||
|
||||
# state.json — consumed by core/system/state.nix at every nixos-rebuild
|
||||
# and mutated by toggle scripts (nomarchy-tz-select, nomarchy-setup-fido2,
|
||||
# nomarchy-toggle-hybrid-gpu, nomarchy-wifi-powersave, ...). Those scripts
|
||||
# `jq` the file in place and fail hard if it doesn't exist or isn't
|
||||
# valid JSON, so a fresh install MUST ship one.
|
||||
#
|
||||
# Source of truth: lib/state-schema.nix. We eval its `system` block and
|
||||
# overlay the installer-chosen timezone, so this generator no longer
|
||||
# drifts from the schema or the *.nix consumers — the previous heredoc
|
||||
# was the last source-of-truth split after the state centralization.
|
||||
# Adding a new default in the schema now reaches the installer without
|
||||
# any further plumbing.
|
||||
local _state_tz="${TIMEZONE:-UTC}"
|
||||
nix --extra-experimental-features 'nix-command flakes' eval \
|
||||
--impure --raw \
|
||||
--expr "
|
||||
let
|
||||
flake = builtins.getFlake \"$NOMARCHY_REPO\";
|
||||
lib = flake.inputs.nixpkgs.lib;
|
||||
schema = import \"$NOMARCHY_REPO/lib/state-schema.nix\" { inherit lib; };
|
||||
state = schema.system // { timezone = \"$_state_tz\"; };
|
||||
in builtins.toJSON state
|
||||
" | nrun jq '.' > /mnt/etc/nixos/state.json
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
@@ -1654,15 +1842,25 @@ finish() {
|
||||
echo " 4. Your configuration lives at /etc/nixos/"
|
||||
echo ""
|
||||
echo "Rebuild commands:"
|
||||
echo " • System: sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME"
|
||||
echo " • Dotfiles: nomarchy-env-update (runs home-manager switch)"
|
||||
echo " • System + dotfiles: sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME"
|
||||
echo " • Dotfiles only: nomarchy-env-update (fast standalone home-manager switch)"
|
||||
echo ""
|
||||
echo "Tip: run 'nomarchy-themes-prebuild' once to pre-cache every theme"
|
||||
echo " variant. Theme switches after that are instant (no rebuild)."
|
||||
echo ""
|
||||
|
||||
# Unmount /mnt before either reboot or returning to the live shell:
|
||||
# - Reboot: clean unmount avoids dirty BTRFS, which would otherwise
|
||||
# force a longer first-boot fsck/replay.
|
||||
# - Decline: leaving /mnt mounted blocks a second `install.sh` run on
|
||||
# the same live ISO (disko refuses to wipe a busy device).
|
||||
# `-R` recursively unmounts /mnt/boot, /mnt/home, /mnt/nix, etc.; the
|
||||
# `|| true` absorbs the case where /mnt was already torn down.
|
||||
if nrun gum confirm "Reboot now?"; then
|
||||
umount -R /mnt 2>/dev/null || true
|
||||
reboot
|
||||
else
|
||||
umount -R /mnt 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,6 @@ let
|
||||
in {
|
||||
inherit
|
||||
palettes
|
||||
readState
|
||||
readHomeState
|
||||
readSystemState
|
||||
resolveWallpaper
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
# Nomarchy State Schema
|
||||
# Defines the complete state shape with defaults for both home and system state
|
||||
#
|
||||
# Defines the default values for every state.json field that's consumed by a
|
||||
# Nix option. Read by core/{system,home}/options.nix (for `default = …`) and
|
||||
# by core/{system,home}/state.nix (for `or` fallbacks).
|
||||
#
|
||||
# state.json may also hold runtime-only fields that aren't declared here —
|
||||
# notably `welcome_done`, managed by `nomarchy-welcome`. Those are intentionally
|
||||
# off-schema because no Nix option reads them; the schema is the "consumed by
|
||||
# Nix" surface, not the full state.json shape.
|
||||
{ lib }:
|
||||
|
||||
{
|
||||
# Home state defaults (user preferences)
|
||||
home = {
|
||||
# Theme and appearance
|
||||
theme = "nord";
|
||||
theme = "summer-night";
|
||||
wallpaper = "";
|
||||
font = "JetBrainsMono Nerd Font";
|
||||
panelPosition = "top";
|
||||
@@ -18,7 +26,6 @@
|
||||
idle = true;
|
||||
nightlight = false;
|
||||
waybar = true;
|
||||
skipVsCodeTheme = false;
|
||||
|
||||
# Hyprland window manager settings
|
||||
hyprland = {
|
||||
@@ -31,7 +38,7 @@
|
||||
# System state defaults (system-level configuration)
|
||||
system = {
|
||||
# Theme (can differ from home for system-level theming)
|
||||
theme = "nord";
|
||||
theme = "summer-night";
|
||||
|
||||
# Timezone
|
||||
timezone = "UTC";
|
||||
@@ -50,18 +57,7 @@
|
||||
fingerprint = false;
|
||||
fido2 = false;
|
||||
hybridGPU = false;
|
||||
makima = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Get a value from state with fallback to default
|
||||
getWithDefault = state: path: default:
|
||||
let
|
||||
pathList = lib.splitString "." path;
|
||||
getValue = obj: remaining:
|
||||
if remaining == [] then obj
|
||||
else if builtins.isAttrs obj && builtins.hasAttr (builtins.head remaining) obj
|
||||
then getValue obj.${builtins.head remaining} (builtins.tail remaining)
|
||||
else default;
|
||||
in getValue state pathList;
|
||||
}
|
||||
|
||||
@@ -74,21 +74,19 @@ in
|
||||
xdg.configFile."nomarchy/branding/logo.svg".source = ../../core/branding/logo.svg;
|
||||
xdg.configFile."nomarchy/branding/icon.png".source = ../../core/branding/icon.png;
|
||||
xdg.configFile."nomarchy/branding/icon.txt".source = ../../core/branding/icon.txt;
|
||||
xdg.configFile."nomarchy/branding/screensaver.txt".source = ../../core/branding/screensaver.txt;
|
||||
xdg.configFile."nomarchy/branding/about.txt".source = ../../core/branding/about.txt;
|
||||
|
||||
# Expose all themes to the system via local share for script accessibility
|
||||
# We filter out images to prevent Nix Store bloat
|
||||
xdg.dataFile."nomarchy/themes".source = builtins.path {
|
||||
name = "nomarchy-themes-no-images";
|
||||
name = "nomarchy-themes";
|
||||
path = ../palettes;
|
||||
filter = path: type:
|
||||
let
|
||||
baseName = baseNameOf path;
|
||||
in
|
||||
! (type == "regular" && (
|
||||
lib.hasSuffix ".jpg" baseName ||
|
||||
lib.hasSuffix ".png" baseName ||
|
||||
lib.hasSuffix ".jpeg" baseName
|
||||
));
|
||||
};
|
||||
|
||||
# Expose all theme templates to the system via local share
|
||||
xdg.dataFile."nomarchy/templates".source = builtins.path {
|
||||
name = "nomarchy-templates";
|
||||
path = ../templates;
|
||||
};
|
||||
|
||||
# Nautilus python extensions
|
||||
|
||||
@@ -54,31 +54,16 @@ in
|
||||
};
|
||||
|
||||
apps = {
|
||||
# waybar, kitty, alacritty, and mako are intentionally absent. Waybar
|
||||
# themes inline in features/desktop/waybar via colorScheme; kitty and
|
||||
# alacritty are themed by stylix targets (themes/engine/stylix.nix); mako
|
||||
# has no theme integration yet. Only btop is loaded from the active
|
||||
# theme's apps/ directory.
|
||||
btop = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to load btop theme from active theme.";
|
||||
};
|
||||
waybar = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to load waybar CSS from active theme.";
|
||||
};
|
||||
mako = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to load mako config from active theme.";
|
||||
};
|
||||
kitty = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to load kitty config from active theme.";
|
||||
};
|
||||
alacritty = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to load alacritty config from active theme.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ let
|
||||
for file in $out/bin/*; do
|
||||
if [ -f "$file" ]; then
|
||||
wrapProgram "$file" \
|
||||
--prefix PATH : "$deps" \
|
||||
--set NOMARCHY_PATH "/etc/nixos/nomarchy"
|
||||
--prefix PATH : "$deps"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
set -e
|
||||
|
||||
{
|
||||
find ~/.config/nomarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n'
|
||||
find "$NOMARCHY_PATH/assets/themes/" -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
|
||||
find ~/.config/nomarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n' 2>/dev/null || true
|
||||
find ~/.local/share/nomarchy/themes/ -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null || true
|
||||
} | sort -u | while read -r name; do
|
||||
echo "$name" | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
|
||||
done
|
||||
|
||||
24
themes/engine/scripts/nomarchy-theme-next
Executable file
24
themes/engine/scripts/nomarchy-theme-next
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Cycles to the next available theme (wraps from last back to first).
|
||||
|
||||
mapfile -t THEMES < <(nomarchy-theme-list)
|
||||
TOTAL=${#THEMES[@]}
|
||||
|
||||
if (( TOTAL == 0 )); then
|
||||
notify-send "No themes available"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT=$(nomarchy-theme-current)
|
||||
INDEX=-1
|
||||
for i in "${!THEMES[@]}"; do
|
||||
if [[ "${THEMES[$i]}" == "$CURRENT" ]]; then
|
||||
INDEX=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
NEXT_INDEX=$(((INDEX + 1) % TOTAL))
|
||||
nomarchy-theme-set "${THEMES[$NEXT_INDEX]}"
|
||||
@@ -29,7 +29,7 @@ fi
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
if [ ! -d "$THEMES_DIR/$THEME_NAME" ] && ! [[ "$THEME_NAME" == "nord" ]]; then
|
||||
if [ ! -d "$THEMES_DIR/$THEME_NAME" ]; then
|
||||
echo "Theme '$THEME_NAME' not found in $THEMES_DIR"
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
TEMPLATES_DIR="$NOMARCHY_PATH/themes/templates"
|
||||
TEMPLATES_DIR="$HOME/.local/share/nomarchy/templates"
|
||||
USER_TEMPLATES_DIR="$HOME/.config/nomarchy/themes/templates"
|
||||
NEXT_THEME_DIR="$HOME/.config/nomarchy/current/theme"
|
||||
COLORS_FILE="$NEXT_THEME_DIR/colors.toml"
|
||||
|
||||
@@ -27,8 +27,12 @@ in
|
||||
|
||||
services.displayManager.defaultSession = lib.mkDefault "hyprland-uwsm";
|
||||
|
||||
# autoLogin defaults off so hand-migrated configs (no installer-written
|
||||
# username) don't try to log in as a nonexistent "nomarchy" user. The
|
||||
# installer-generated system.nix sets both `enable = true;` and
|
||||
# `user = "$USERNAME";` at normal priority, overriding these defaults.
|
||||
services.displayManager.autoLogin = {
|
||||
enable = lib.mkDefault true;
|
||||
enable = lib.mkDefault false;
|
||||
user = lib.mkDefault "nomarchy";
|
||||
};
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
nomarchyLib = import ../../lib { inherit lib; };
|
||||
themeList = builtins.concatStringsSep "\\n" nomarchyLib.themeNames;
|
||||
|
||||
nomarchy-theme-selector = pkgs.writeShellScriptBin "nomarchy-theme-selector" ''
|
||||
SELECTED_THEME=$(echo -e "${themeList}" | walker --dmenu)
|
||||
|
||||
if [ -n "$SELECTED_THEME" ]; then
|
||||
nomarchy-theme-set "$SELECTED_THEME"
|
||||
fi
|
||||
'';
|
||||
|
||||
nomarchy-font-selector = pkgs.writeShellScriptBin "nomarchy-font-selector" ''
|
||||
STATE_DIR="${config.home.homeDirectory}/.config/nomarchy"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
# Simple list of common nerd fonts, could be expanded
|
||||
FONTS="JetBrainsMono Nerd Font\nRobotoMono Nerd Font\nFiraCode Nerd Font\nUbuntuMono Nerd Font"
|
||||
SELECTED_FONT=$(echo -e "$FONTS" | walker --dmenu)
|
||||
|
||||
if [ -n "$SELECTED_FONT" ]; then
|
||||
TMP_JSON=$(mktemp)
|
||||
jq --arg font "$SELECTED_FONT" '.font = $font' "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
nomarchy-env-update
|
||||
fi
|
||||
'';
|
||||
|
||||
nomarchy-wallpaper-selector = pkgs.writeShellScriptBin "nomarchy-wallpaper-selector" ''
|
||||
STATE_DIR="${config.home.homeDirectory}/.config/nomarchy"
|
||||
STATE_FILE="$STATE_DIR/state.json"
|
||||
THEMES_DIR="${config.xdg.dataHome}/nomarchy/themes"
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||
|
||||
# List all images in all themes backgrounds
|
||||
# We search in the system-wide flake source for distro wallpapers to avoid Nix Store bloat
|
||||
WALLPAPERS=$(find "${config.xdg.dataHome}/nomarchy/themes" -type f \( -name "*.jpg" -o -name "*.png" \) 2>/dev/null)
|
||||
DISTRO_THEMES="/etc/nixos/nomarchy/assets/themes"
|
||||
if [ -d "$DISTRO_THEMES" ]; then
|
||||
WALLPAPERS="$WALLPAPERS\n$(find "$DISTRO_THEMES" -type f \( -name "*.jpg" -o -name "*.png" \))"
|
||||
fi
|
||||
# Include user themes if they exist
|
||||
if [ -d "${config.home.homeDirectory}/.config/nomarchy/themes" ]; then
|
||||
WALLPAPERS="$WALLPAPERS\n$(find "${config.home.homeDirectory}/.config/nomarchy/themes" -type f \( -name "*.jpg" -o -name "*.png" \))"
|
||||
fi
|
||||
SELECTED_WP=$(echo -e "$WALLPAPERS" | walker --dmenu)
|
||||
|
||||
if [ -n "$SELECTED_WP" ]; then
|
||||
TMP_JSON=$(mktemp)
|
||||
jq --arg wp "$SELECTED_WP" '.wallpaper = $wp' "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||
swww img "$SELECTED_WP" --transition-type outer --transition-pos 0.85,0.97 --transition-step 90 &
|
||||
nomarchy-env-update
|
||||
fi
|
||||
'';
|
||||
in
|
||||
{
|
||||
home.packages = [ nomarchy-theme-selector nomarchy-font-selector nomarchy-wallpaper-selector ];
|
||||
}
|
||||
86
themes/palettes/summer-day/apps/btop.theme
Normal file
86
themes/palettes/summer-day/apps/btop.theme
Normal file
@@ -0,0 +1,86 @@
|
||||
# Main background, empty for terminal default, need to be empty if you want transparent background
|
||||
theme[main_bg]="#fdf6e3"
|
||||
|
||||
# Main text color
|
||||
theme[main_fg]="#5c6a72"
|
||||
|
||||
# Title color for boxes
|
||||
theme[title]="#5c6a72"
|
||||
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#f85552"
|
||||
|
||||
# Background color of selected items
|
||||
theme[selected_bg]="#e6e2cc"
|
||||
|
||||
# Foreground color of selected items
|
||||
theme[selected_fg]="#dfa000"
|
||||
|
||||
# Color of inactive/disabled text
|
||||
theme[inactive_fg]="#bdc3af"
|
||||
|
||||
# Color of text appearing on top of graphs, i.e uptime and current network graph scaling
|
||||
theme[graph_text]="#5c6a72"
|
||||
|
||||
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||
theme[proc_misc]="#8da101"
|
||||
|
||||
# Cpu box outline color
|
||||
theme[cpu_box]="#bdc3af"
|
||||
|
||||
# Memory/disks box outline color
|
||||
theme[mem_box]="#bdc3af"
|
||||
|
||||
# Net up/down box outline color
|
||||
theme[net_box]="#bdc3af"
|
||||
|
||||
# Processes box outline color
|
||||
theme[proc_box]="#bdc3af"
|
||||
|
||||
# Box divider line and small boxes line color
|
||||
theme[div_line]="#bdc3af"
|
||||
|
||||
# Temperature graph colors
|
||||
theme[temp_start]="#8da101"
|
||||
theme[temp_mid]="#dfa000"
|
||||
theme[temp_end]="#f85552"
|
||||
|
||||
# CPU graph colors
|
||||
theme[cpu_start]="#8da101"
|
||||
theme[cpu_mid]="#dfa000"
|
||||
theme[cpu_end]="#f85552"
|
||||
|
||||
# Mem/Disk free meter
|
||||
theme[free_start]="#f85552"
|
||||
theme[free_mid]="#dfa000"
|
||||
theme[free_end]="#8da101"
|
||||
|
||||
# Mem/Disk cached meter
|
||||
theme[cached_start]="#3a94c5"
|
||||
theme[cached_mid]="#35a77c"
|
||||
theme[cached_end]="#8da101"
|
||||
|
||||
# Mem/Disk available meter
|
||||
theme[available_start]="#f85552"
|
||||
theme[available_mid]="#dfa000"
|
||||
theme[available_end]="#8da101"
|
||||
|
||||
# Mem/Disk used meter
|
||||
theme[used_start]="#8da101"
|
||||
theme[used_mid]="#dfa000"
|
||||
theme[used_end]="#f85552"
|
||||
|
||||
# Download graph colors
|
||||
theme[download_start]="#8da101"
|
||||
theme[download_mid]="#35a77c"
|
||||
theme[download_end]="#3a94c5"
|
||||
|
||||
# Upload graph colors
|
||||
theme[upload_start]="#dfa000"
|
||||
theme[upload_mid]="#df69ba"
|
||||
theme[upload_end]="#f85552"
|
||||
|
||||
# Process box color gradient for threads, mem and cpu usage
|
||||
theme[process_start]="#8da101"
|
||||
theme[process_mid]="#f85552"
|
||||
theme[process_end]="#f85552"
|
||||
16
themes/palettes/summer-day/apps/neovim.lua
Normal file
16
themes/palettes/summer-day/apps/neovim.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
return {
|
||||
{ "neanias/everforest-nvim" },
|
||||
{
|
||||
"LazyVim/LazyVim",
|
||||
opts = {
|
||||
colorscheme = "everforest",
|
||||
background = "soft",
|
||||
},
|
||||
},
|
||||
{
|
||||
"LazyVim/LazyVim",
|
||||
init = function()
|
||||
vim.opt.background = "light"
|
||||
end,
|
||||
},
|
||||
}
|
||||
143
themes/palettes/summer-day/apps/rofi.rasi
Normal file
143
themes/palettes/summer-day/apps/rofi.rasi
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Nomarchy Summer Day Rofi Theme
|
||||
* Converted from everforest.rasi and config
|
||||
*/
|
||||
|
||||
configuration {
|
||||
modi: "drun";
|
||||
show-icons: true;
|
||||
icon-theme: "Papirus-Light";
|
||||
terminal: "kitty";
|
||||
drun-display-format: "{name}";
|
||||
case-sensitive: false;
|
||||
location: 0;
|
||||
disable-history: false;
|
||||
hide-scrollbar: true;
|
||||
display-drun: "Search";
|
||||
}
|
||||
|
||||
* {
|
||||
/* Summer Day color definitions */
|
||||
bg0: #fdf6e3;
|
||||
fg: #5c6a72;
|
||||
red: #f85552;
|
||||
yellow: #dfa000;
|
||||
green: #8da101;
|
||||
aqua: #35a77c;
|
||||
blue: #3a94c5;
|
||||
purple: #df69ba;
|
||||
grey0: #a6b0a0;
|
||||
|
||||
font: "Iosevka Nerd Font 17";
|
||||
background-color: transparent;
|
||||
text-color: @fg;
|
||||
}
|
||||
|
||||
window {
|
||||
transparency: "real";
|
||||
background-color: @fg;
|
||||
text-color: @bg0;
|
||||
border-bottom: 5px;
|
||||
border-color: @yellow;
|
||||
border-radius: 15px;
|
||||
width: 40%;
|
||||
height: 50%;
|
||||
location: center;
|
||||
anchor: center;
|
||||
x-offset: 0;
|
||||
y-offset: 0;
|
||||
}
|
||||
|
||||
mainbox {
|
||||
background-color: transparent;
|
||||
children: [ inputbar, listview ];
|
||||
spacing: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
inputbar {
|
||||
children: [ prompt, entry ];
|
||||
background-color: @green;
|
||||
text-color: @bg0;
|
||||
expand: false;
|
||||
border-bottom: 5px;
|
||||
border-color: @grey0;
|
||||
border-radius: 10px;
|
||||
margin: 15px;
|
||||
padding: 10px;
|
||||
spacing: 15px;
|
||||
}
|
||||
|
||||
prompt {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
|
||||
entry {
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
cursor: text;
|
||||
placeholder: "Type to search...";
|
||||
placeholder-color: @bg0;
|
||||
}
|
||||
|
||||
listview {
|
||||
background-color: transparent;
|
||||
columns: 1;
|
||||
lines: 8;
|
||||
spacing: 0px;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
layout: vertical;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
element {
|
||||
background-color: transparent;
|
||||
text-color: @bg0;
|
||||
orientation: horizontal;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
spacing: 15px;
|
||||
}
|
||||
|
||||
element-icon {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
size: 40px;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
element-text {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
highlight: bold;
|
||||
cursor: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
}
|
||||
|
||||
element selected {
|
||||
background-color: @bg0;
|
||||
text-color: @fg;
|
||||
border-bottom: 5px;
|
||||
border-color: #bdc3af;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
element-text selected {
|
||||
text-color: @fg;
|
||||
}
|
||||
|
||||
element-icon selected {
|
||||
text-color: @fg;
|
||||
}
|
||||
|
||||
scrollbar {
|
||||
width: 0px;
|
||||
background-color: transparent;
|
||||
handle-width: 0px;
|
||||
handle-color: transparent;
|
||||
border: 0px;
|
||||
}
|
||||
4
themes/palettes/summer-day/apps/vscode.json
Normal file
4
themes/palettes/summer-day/apps/vscode.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Everforest Light",
|
||||
"extension": "sainnhe.everforest"
|
||||
}
|
||||
34
themes/palettes/summer-day/apps/walker/style.css
Normal file
34
themes/palettes/summer-day/apps/walker/style.css
Normal file
@@ -0,0 +1,34 @@
|
||||
#window {
|
||||
background-color: #fdf6e3;
|
||||
color: #5c6a72;
|
||||
border-bottom: 5px solid #dfa000;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
#search {
|
||||
background-color: #8da101;
|
||||
color: #fdf6e3;
|
||||
border-bottom: 5px solid #bdc3af;
|
||||
border-radius: 10px;
|
||||
margin: 15px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#input {
|
||||
color: #5c6a72;
|
||||
}
|
||||
|
||||
#list {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.item {
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.item.active {
|
||||
background-color: #e6e2cc;
|
||||
color: #5c6a72;
|
||||
border-bottom: 5px solid #bdc3af;
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
accent = "#83b6af"
|
||||
cursor = "#d3c6aa"
|
||||
foreground = "#d3c6aa"
|
||||
background = "#2d353b"
|
||||
selection_foreground = "#d3c6aa"
|
||||
selection_background = "#505a60"
|
||||
accent = "#3a94c5"
|
||||
cursor = "#5c6a72"
|
||||
foreground = "#5c6a72"
|
||||
background = "#fdf6e3"
|
||||
selection_foreground = "#5c6a72"
|
||||
selection_background = "#d3dbc8"
|
||||
|
||||
color0 = "#3c474d"
|
||||
color1 = "#e68183"
|
||||
color2 = "#a7c080"
|
||||
color3 = "#d9bb80"
|
||||
color4 = "#83b6af"
|
||||
color5 = "#d39bb6"
|
||||
color6 = "#87c095"
|
||||
color7 = "#868d80"
|
||||
color8 = "#868d80"
|
||||
color9 = "#e68183"
|
||||
color10 = "#a7c080"
|
||||
color11 = "#d9bb80"
|
||||
color12 = "#83b6af"
|
||||
color13 = "#d39bb6"
|
||||
color14 = "#87c095"
|
||||
color15 = "#868d80"
|
||||
color0 = "#5c6a72"
|
||||
color1 = "#f85552"
|
||||
color2 = "#8da101"
|
||||
color3 = "#dfa000"
|
||||
color4 = "#3a94c5"
|
||||
color5 = "#df69ba"
|
||||
color6 = "#35a77c"
|
||||
color7 = "#fdf6e3"
|
||||
color8 = "#829181"
|
||||
color9 = "#f85552"
|
||||
color10 = "#8da101"
|
||||
color11 = "#dfa000"
|
||||
color12 = "#3a94c5"
|
||||
color13 = "#df69ba"
|
||||
color14 = "#35a77c"
|
||||
color15 = "#fdf6e3"
|
||||
|
||||
@@ -1 +1 @@
|
||||
Everforest-Dark
|
||||
Yaru-blue
|
||||
|
||||
1
themes/palettes/summer-day/light.mode
Normal file
1
themes/palettes/summer-day/light.mode
Normal file
@@ -0,0 +1 @@
|
||||
# This will set "prefer-light" and use "Adwaita" as the theme
|
||||
@@ -1,5 +0,0 @@
|
||||
include=~/.config/nomarchy/default/mako/core.ini
|
||||
|
||||
text-color={{ foreground }}
|
||||
border-color={{ accent }}
|
||||
background-color={{ background }}
|
||||
Reference in New Issue
Block a user