Compare commits
48 Commits
46738c3663
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
802acfdc86 | ||
|
|
1ae27cd302 | ||
|
|
67e5cd6014 | ||
|
|
af2d9ffd8e | ||
|
|
b078be3209 | ||
|
|
3a269d73eb | ||
|
|
fb4755fdbf | ||
|
|
9b06b6c243 | ||
|
|
893fa91fbf | ||
|
|
4de8afbea9 | ||
|
|
577b3aeb91 | ||
|
|
b52aec28ce | ||
|
|
8d3ce2d841 | ||
|
|
0486e037df | ||
|
|
40b62124e6 | ||
|
|
72443fd69f | ||
|
|
641ab0cfb0 | ||
|
|
0297ec268f | ||
|
|
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 |
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,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"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -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()
|
function GetEntries()
|
||||||
local entries = {}
|
local entries = {}
|
||||||
local user_theme_dir = os.getenv("HOME") .. "/.config/nomarchy/themes"
|
local user_theme_dir = os.getenv("HOME") .. "/.config/nomarchy/themes"
|
||||||
local nomarchy_path = os.getenv("NOMARCHY_PATH") or "/etc/nixos"
|
local default_theme_dir = os.getenv("HOME") .. "/.local/share/nomarchy/themes"
|
||||||
local default_theme_dir = nomarchy_path .. "/themes/palettes"
|
|
||||||
|
|
||||||
local seen_themes = {}
|
local seen_themes = {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
# App-specific tweaks
|
# App-specific tweaks. All rules are class- or title-gated, so sourcing
|
||||||
|
# unconditionally is harmless when the app isn't installed or running.
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/1password.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/bitwarden.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/browser.conf
|
source = ~/.config/nomarchy/default/hypr/apps/browser.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/davinci-resolve.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/geforce.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/hyprshot.conf
|
source = ~/.config/nomarchy/default/hypr/apps/hyprshot.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/localsend.conf
|
source = ~/.config/nomarchy/default/hypr/apps/localsend.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/moonlight.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/pip.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/qemu.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/retroarch.conf
|
source = ~/.config/nomarchy/default/hypr/apps/retroarch.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/steam.conf
|
||||||
|
source = ~/.config/nomarchy/default/hypr/apps/system.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/telegram.conf
|
source = ~/.config/nomarchy/default/hypr/apps/telegram.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/terminals.conf
|
source = ~/.config/nomarchy/default/hypr/apps/terminals.conf
|
||||||
source = ~/.config/nomarchy/default/hypr/apps/walker.conf
|
source = ~/.config/nomarchy/default/hypr/apps/walker.conf
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
# Deprecated bindings file. New installations include everything directly.
|
|
||||||
|
|
||||||
bindd = SUPER, RETURN, Terminal, exec, $terminal
|
|
||||||
bindd = SUPER, F, File manager, exec, $fileManager
|
|
||||||
bindd = SUPER, B, Web browser, exec, $browser
|
|
||||||
bindd = SUPER, M, Music player, exec, $music
|
|
||||||
bindd = SUPER, N, Neovim, exec, $terminal -e nvim
|
|
||||||
bindd = SUPER, T, Top, exec, $terminal -e btop
|
|
||||||
bindd = SUPER, D, Lazy Docker, exec, $terminal -e lazydocker
|
|
||||||
bindd = SUPER, G, Messenger, exec, $messenger
|
|
||||||
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-v2.conf
|
|
||||||
source = ~/.config/nomarchy/default/hypr/bindings/utilities.conf
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# Application bindings
|
|
||||||
bindd = SUPER, RETURN, Terminal, exec, uwsm-app -- xdg-terminal-exec --dir="$(nomarchy-cmd-terminal-cwd)"
|
|
||||||
bindd = SUPER SHIFT, RETURN, Browser, exec, nomarchy-launch-browser
|
|
||||||
bindd = SUPER SHIFT, F, File manager, exec, uwsm-app -- nautilus --new-window
|
|
||||||
bindd = SUPER ALT SHIFT, F, File manager (cwd), exec, uwsm-app -- nautilus --new-window "$(nomarchy-cmd-terminal-cwd)"
|
|
||||||
bindd = SUPER SHIFT, B, Browser, exec, nomarchy-launch-browser
|
|
||||||
bindd = SUPER SHIFT ALT, B, Browser (private), exec, nomarchy-launch-browser --private
|
|
||||||
bindd = SUPER SHIFT, N, Editor, exec, nomarchy-launch-editor
|
|
||||||
|
|
||||||
# Add extra bindings
|
|
||||||
# bindd = SUPER SHIFT, A, ChatGPT, exec, nomarchy-launch-webapp "https://chatgpt.com"
|
|
||||||
# bindd = SUPER SHIFT, R, exec, alacritty -e ssh your-server
|
|
||||||
|
|
||||||
# Overwrite existing bindings, like putting Nomarchy Menu on Super + Space
|
|
||||||
# unbind = SUPER, SPACE
|
|
||||||
# bindd = SUPER, SPACE, Nomarchy menu, exec, nomarchy-menu
|
|
||||||
@@ -51,5 +51,17 @@ let
|
|||||||
|
|
||||||
in
|
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
|
./options.nix
|
||||||
./state.nix
|
./state.nix
|
||||||
./overrides.nix
|
./overrides.nix
|
||||||
./behavior.nix
|
|
||||||
./fonts.nix
|
./fonts.nix
|
||||||
./configs.nix
|
./configs.nix
|
||||||
./security.nix
|
./security.nix
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
{ lib, pkgs, ... }:
|
{ 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 = {
|
options.nomarchy = {
|
||||||
toggles = {
|
toggles = {
|
||||||
suspend = lib.mkOption {
|
suspend = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = schema.home.suspend;
|
||||||
description = "Whether to show suspend in system menu.";
|
description = "Whether to show suspend in system menu.";
|
||||||
};
|
};
|
||||||
screensaver = lib.mkOption {
|
screensaver = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = schema.home.screensaver;
|
||||||
description = "Whether the screensaver is enabled.";
|
description = "Whether the screensaver is enabled.";
|
||||||
};
|
};
|
||||||
idle = lib.mkOption {
|
idle = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = schema.home.idle;
|
||||||
description = "Whether the idle lock is enabled.";
|
description = "Whether the idle lock is enabled.";
|
||||||
};
|
};
|
||||||
nightlight = lib.mkOption {
|
nightlight = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = schema.home.nightlight;
|
||||||
description = "Whether the nightlight is enabled.";
|
description = "Whether the nightlight is enabled.";
|
||||||
};
|
};
|
||||||
waybar = lib.mkOption {
|
waybar = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = schema.home.waybar;
|
||||||
description = "Whether the top bar is enabled.";
|
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 {
|
nightlightTemperature = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
default = 4000;
|
default = schema.home.nightlightTemperature;
|
||||||
description = "Temperature for the nightlight.";
|
description = "Temperature for the nightlight.";
|
||||||
};
|
};
|
||||||
theme = lib.mkOption {
|
theme = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "summer-night";
|
default = schema.home.theme;
|
||||||
description = "System theme name.";
|
description = "System theme name.";
|
||||||
};
|
};
|
||||||
formFactor = lib.mkOption {
|
formFactor = lib.mkOption {
|
||||||
@@ -58,35 +58,35 @@
|
|||||||
};
|
};
|
||||||
wallpaper = lib.mkOption {
|
wallpaper = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "";
|
default = schema.home.wallpaper;
|
||||||
description = "System wallpaper path.";
|
description = "System wallpaper path.";
|
||||||
};
|
};
|
||||||
panelPosition = lib.mkOption {
|
panelPosition = lib.mkOption {
|
||||||
type = lib.types.enum [ "top" "bottom" ];
|
type = lib.types.enum [ "top" "bottom" ];
|
||||||
default = "top";
|
default = schema.home.panelPosition;
|
||||||
description = "Waybar panel position.";
|
description = "Waybar panel position.";
|
||||||
};
|
};
|
||||||
hyprland = {
|
hyprland = {
|
||||||
gaps_in = lib.mkOption {
|
gaps_in = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
default = 5;
|
default = schema.home.hyprland.gaps_in;
|
||||||
description = "Inner gaps for Hyprland.";
|
description = "Inner gaps for Hyprland.";
|
||||||
};
|
};
|
||||||
gaps_out = lib.mkOption {
|
gaps_out = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
default = 10;
|
default = schema.home.hyprland.gaps_out;
|
||||||
description = "Outer gaps for Hyprland.";
|
description = "Outer gaps for Hyprland.";
|
||||||
};
|
};
|
||||||
border_size = lib.mkOption {
|
border_size = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
default = 2;
|
default = schema.home.hyprland.border_size;
|
||||||
description = "Border size for Hyprland.";
|
description = "Border size for Hyprland.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
fonts = {
|
fonts = {
|
||||||
monospace = lib.mkOption {
|
monospace = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "JetBrainsMono Nerd Font";
|
default = schema.home.font;
|
||||||
description = "System monospace font.";
|
description = "System monospace font.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,97 +1,34 @@
|
|||||||
{ config, lib, ... }:
|
{ 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
|
# STATUS: option surface only — the actual override mechanism is NOT yet
|
||||||
# replace upstream defaults. Override priority (highest to lowest):
|
# implemented. The options are kept so configs that already set
|
||||||
# 1. User Nix options
|
# `nomarchy.overrides.enable = …;` continue to evaluate; setting them has
|
||||||
# 2. User file overrides (~/.config/nomarchy/overrides/)
|
# no effect today. Tracked in docs/ROADMAP.md.
|
||||||
# 3. Upstream defaults
|
|
||||||
#
|
#
|
||||||
# Supported override paths:
|
# When implemented, this module should substitute sources in
|
||||||
# - hypr/ - Hyprland configs (bindings.conf, input.conf, etc.)
|
# `xdg.configFile.<path>.source` based on the presence of matching files
|
||||||
# - waybar/ - Waybar config and style
|
# under ~/.config/nomarchy/overrides/.
|
||||||
# - alacritty/ - Alacritty terminal config
|
|
||||||
# - walker/ - Walker launcher config
|
|
||||||
# - kitty/ - Kitty terminal config
|
|
||||||
# - btop/ - Btop resource monitor config
|
|
||||||
# - apps/ - Other application configs
|
|
||||||
|
|
||||||
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 = {
|
options.nomarchy.overrides = {
|
||||||
enable = lib.mkOption {
|
enable = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
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 {
|
paths = lib.mkOption {
|
||||||
type = lib.types.attrsOf lib.types.path;
|
type = lib.types.attrsOf lib.types.path;
|
||||||
default = {};
|
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
|
let
|
||||||
nomarchyLib = import ../../lib { inherit lib; };
|
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;
|
assetsPath = ../../themes/palettes;
|
||||||
|
|
||||||
# Read unified state from ~/.config/nomarchy/state.json
|
# Read unified state from ~/.config/nomarchy/state.json
|
||||||
togglesState = nomarchyLib.readHomeState config.home.homeDirectory;
|
togglesState = nomarchyLib.readHomeState config.home.homeDirectory;
|
||||||
in
|
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 = {
|
config = {
|
||||||
nomarchy = {
|
nomarchy = {
|
||||||
toggles = {
|
toggles = {
|
||||||
suspend = togglesState.suspend or true;
|
suspend = lib.mkDefault (togglesState.suspend or schema.home.suspend);
|
||||||
screensaver = togglesState.screensaver or true;
|
screensaver = lib.mkDefault (togglesState.screensaver or schema.home.screensaver);
|
||||||
idle = togglesState.idle or true;
|
idle = lib.mkDefault (togglesState.idle or schema.home.idle);
|
||||||
nightlight = togglesState.nightlight or false;
|
nightlight = lib.mkDefault (togglesState.nightlight or schema.home.nightlight);
|
||||||
waybar = togglesState.waybar or true;
|
waybar = lib.mkDefault (togglesState.waybar or schema.home.waybar);
|
||||||
skipVsCodeTheme = togglesState.skipVsCodeTheme or false;
|
|
||||||
};
|
};
|
||||||
nightlightTemperature = togglesState.nightlightTemperature or 4000;
|
nightlightTemperature = lib.mkDefault (togglesState.nightlightTemperature or schema.home.nightlightTemperature);
|
||||||
theme = togglesState.theme or "nord";
|
theme = lib.mkDefault (togglesState.theme or schema.home.theme);
|
||||||
wallpaper = togglesState.wallpaper or "";
|
wallpaper = lib.mkDefault (togglesState.wallpaper or schema.home.wallpaper);
|
||||||
panelPosition = togglesState.panelPosition or "top";
|
panelPosition = lib.mkDefault (togglesState.panelPosition or schema.home.panelPosition);
|
||||||
hyprland = {
|
hyprland = {
|
||||||
gaps_in = togglesState.hyprland.gaps_in or 5;
|
gaps_in = lib.mkDefault (togglesState.hyprland.gaps_in or schema.home.hyprland.gaps_in);
|
||||||
gaps_out = togglesState.hyprland.gaps_out or 10;
|
gaps_out = lib.mkDefault (togglesState.hyprland.gaps_out or schema.home.hyprland.gaps_out);
|
||||||
border_size = togglesState.hyprland.border_size or 2;
|
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
|
# Derived properties from the theme directory
|
||||||
isLightMode = nomarchyLib.isThemeLightMode {
|
isLightMode = lib.mkDefault (nomarchyLib.isThemeLightMode {
|
||||||
themeName = togglesState.theme or "nord";
|
themeName = togglesState.theme or schema.home.theme;
|
||||||
inherit assetsPath;
|
inherit assetsPath;
|
||||||
};
|
});
|
||||||
iconsTheme = nomarchyLib.getIconsTheme {
|
iconsTheme = lib.mkDefault (nomarchyLib.getIconsTheme {
|
||||||
themeName = togglesState.theme or "nord";
|
themeName = togglesState.theme or schema.home.theme;
|
||||||
inherit assetsPath;
|
inherit assetsPath;
|
||||||
};
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ let
|
|||||||
pname = "nomarchy-font";
|
pname = "nomarchy-font";
|
||||||
version = "1.0";
|
version = "1.0";
|
||||||
# Point directly to the font file
|
# Point directly to the font file
|
||||||
src = ./../home/config/Nomarchy.ttf;
|
src = ./../branding/Nomarchy.ttf;
|
||||||
# No archive to unpack
|
# No archive to unpack
|
||||||
unpackPhase = "true";
|
unpackPhase = "true";
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
|||||||
@@ -70,8 +70,47 @@ in
|
|||||||
})
|
})
|
||||||
|
|
||||||
(mkIf config.nomarchy.system.features.hybridGPU {
|
(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;
|
services.supergfxd.enable = true;
|
||||||
systemd.services.supergfxd.serviceConfig.ExecStartPre = "-${pkgs.coreutils}/bin/sleep 5";
|
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 = {
|
settings.Login = {
|
||||||
HandleLidSwitch = lib.mkDefault "suspend-then-hibernate";
|
HandleLidSwitch = lib.mkDefault "suspend-then-hibernate";
|
||||||
HandleLidSwitchExternalPower = lib.mkDefault "suspend";
|
HandleLidSwitchExternalPower = lib.mkDefault "suspend";
|
||||||
HandlePowerKey = "hibernate";
|
HandlePowerKey = lib.mkDefault "hibernate";
|
||||||
IdleAction = "suspend-then-hibernate";
|
IdleAction = lib.mkDefault "suspend-then-hibernate";
|
||||||
IdleActionSec = toString (cfg.idleMinutes * 60);
|
IdleActionSec = lib.mkDefault (toString (cfg.idleMinutes * 60));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,18 @@ in
|
|||||||
"crypted_main" on multi-disk installs to match the disko layout.
|
"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 {
|
config = lib.mkIf cfg.enable {
|
||||||
@@ -72,7 +84,7 @@ in
|
|||||||
"/etc/machine-id"
|
"/etc/machine-id"
|
||||||
"/etc/supergfxd.conf"
|
"/etc/supergfxd.conf"
|
||||||
];
|
];
|
||||||
users.nomarchy = {
|
users.${cfg.user} = {
|
||||||
directories = [
|
directories = [
|
||||||
".ssh"
|
".ssh"
|
||||||
".gnupg"
|
".gnupg"
|
||||||
|
|||||||
@@ -1,27 +1,32 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ 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 = {
|
options.nomarchy.system = {
|
||||||
dns = lib.mkOption {
|
dns = lib.mkOption {
|
||||||
type = lib.types.enum [ "Cloudflare" "Google" "DHCP" "Custom" ];
|
type = lib.types.enum [ "Cloudflare" "Google" "DHCP" "Custom" ];
|
||||||
default = "DHCP";
|
default = schema.system.dns;
|
||||||
description = "Selected DNS provider.";
|
description = "Selected DNS provider.";
|
||||||
};
|
};
|
||||||
customDns = lib.mkOption {
|
customDns = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [];
|
default = schema.system.customDns;
|
||||||
description = "List of custom DNS servers.";
|
description = "List of custom DNS servers.";
|
||||||
};
|
};
|
||||||
wifi = {
|
wifi = {
|
||||||
powersave = lib.mkOption {
|
powersave = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = schema.system.wifi.powersave;
|
||||||
description = "Whether to enable wifi power saving.";
|
description = "Whether to enable wifi power saving.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
timezone = lib.mkOption {
|
timezone = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "UTC";
|
default = schema.system.timezone;
|
||||||
description = "System timezone.";
|
description = "System timezone.";
|
||||||
};
|
};
|
||||||
formFactor = lib.mkOption {
|
formFactor = lib.mkOption {
|
||||||
@@ -39,24 +44,24 @@
|
|||||||
features = {
|
features = {
|
||||||
fingerprint = lib.mkOption {
|
fingerprint = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = schema.system.features.fingerprint;
|
||||||
description = "Whether to enable fingerprint support.";
|
description = "Whether to enable fingerprint support.";
|
||||||
};
|
};
|
||||||
fido2 = lib.mkOption {
|
fido2 = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = schema.system.features.fido2;
|
||||||
description = "Whether to enable FIDO2 support.";
|
description = "Whether to enable FIDO2 support.";
|
||||||
};
|
};
|
||||||
hybridGPU = lib.mkOption {
|
hybridGPU = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = schema.system.features.hybridGPU;
|
||||||
description = "Whether to enable hybrid GPU support (supergfxd).";
|
description = "Whether to enable hybrid GPU support (supergfxd).";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
theme = lib.mkOption {
|
theme = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "nord";
|
default = schema.system.theme;
|
||||||
description = "Selected system theme. Matches lib/state-schema.nix and the installer-written state.json so a missing/blank state file lands on the same theme everywhere.";
|
description = "Selected system theme.";
|
||||||
};
|
};
|
||||||
|
|
||||||
# ----- Tier 1 system features (all opt-in, no behavioural change off) ---
|
# ----- Tier 1 system features (all opt-in, no behavioural change off) ---
|
||||||
|
|||||||
@@ -55,8 +55,7 @@ pkgs.stdenv.mkDerivation {
|
|||||||
for file in $out/bin/*; do
|
for file in $out/bin/*; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
wrapProgram "$file" \
|
wrapProgram "$file" \
|
||||||
--prefix PATH : "$deps" \
|
--prefix PATH : "$deps"
|
||||||
--set NOMARCHY_PATH "/etc/nixos"
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -2,19 +2,28 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
nomarchyLib = import ../../lib { inherit lib; };
|
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;
|
systemState = nomarchyLib.readSystemState;
|
||||||
in
|
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 = {
|
config.nomarchy.system = {
|
||||||
dns = systemState.dns or "DHCP";
|
dns = lib.mkDefault (systemState.dns or schema.system.dns);
|
||||||
customDns = systemState.customDns or [];
|
customDns = lib.mkDefault (systemState.customDns or schema.system.customDns);
|
||||||
wifi.powersave = systemState.wifi.powersave or true;
|
wifi.powersave = lib.mkDefault (systemState.wifi.powersave or schema.system.wifi.powersave);
|
||||||
timezone = systemState.timezone or "UTC";
|
timezone = lib.mkDefault (systemState.timezone or schema.system.timezone);
|
||||||
features = {
|
features = {
|
||||||
fingerprint = systemState.features.fingerprint or false;
|
fingerprint = lib.mkDefault (systemState.features.fingerprint or schema.system.features.fingerprint);
|
||||||
fido2 = systemState.features.fido2 or false;
|
fido2 = lib.mkDefault (systemState.features.fido2 or schema.system.features.fido2);
|
||||||
hybridGPU = systemState.features.hybridGPU or false;
|
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).
|
scripts/ Low-level system scripts (battery, brightness, hardware).
|
||||||
home/ Home Manager modules.
|
home/ Home Manager modules.
|
||||||
options.nix Most home-side nomarchy.* options.
|
options.nix Most home-side nomarchy.* options.
|
||||||
behavior.nix nomarchy.behavior.* (deploy-default-config toggles).
|
overrides.nix nomarchy.overrides.* (reserved; currently no-op — see ROADMAP).
|
||||||
overrides.nix File-based overrides from ~/.config/nomarchy/overrides/.
|
|
||||||
config/ Plain dotfiles symlinked into ~/.config.
|
config/ Plain dotfiles symlinked into ~/.config.
|
||||||
|
|
||||||
features/ Apps and desktop components. Add new apps here.
|
features/ Apps and desktop components. Add new apps here.
|
||||||
|
|||||||
@@ -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 |
|
| 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` |
|
| 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) |
|
| `/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`,
|
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
|
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`
|
### `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`
|
### `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).
|
`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.
|
`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`)
|
## 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.
|
`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`
|
### `nomarchy.nightlightTemperature`
|
||||||
|
|
||||||
`int`, default `4000`. Nightlight color temperature (Kelvin).
|
`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`
|
### `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`
|
### `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`
|
### `nomarchy.cursor.name`
|
||||||
|
|
||||||
@@ -221,23 +243,7 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
|||||||
|
|
||||||
### `nomarchy.configOverrides`
|
### `nomarchy.configOverrides`
|
||||||
|
|
||||||
`nullOr path`, default `null`. Path to a directory containing config overrides. See "Overrides" below.
|
`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.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).
|
|
||||||
|
|
||||||
### `nomarchy.apps.opencode.enable`
|
### `nomarchy.apps.opencode.enable`
|
||||||
|
|
||||||
@@ -253,19 +259,19 @@ Wired in `features/desktop/waybar/default.nix` (filters the battery widget out o
|
|||||||
|
|
||||||
### `nomarchy.themeLoader.enable`
|
### `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`
|
### `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`
|
### `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
|
```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/hardware.nix` — `nomarchy.hardware.*`
|
||||||
- `core/system/impermanence.nix` — `impermanence.enable`
|
- `core/system/impermanence.nix` — `impermanence.enable`
|
||||||
- `core/home/options.nix` — most home-side `nomarchy.*` options
|
- `core/home/options.nix` — most home-side `nomarchy.*` options
|
||||||
- `core/home/behavior.nix` — `nomarchy.behavior.*`
|
- `core/home/overrides.nix` — `nomarchy.overrides.*` (reserved; currently no-op)
|
||||||
- `core/home/overrides.nix` — `nomarchy.overrides.*`
|
|
||||||
- `themes/engine/loader.nix` — `nomarchy.themeLoader.*`
|
- `themes/engine/loader.nix` — `nomarchy.themeLoader.*`
|
||||||
- `features/apps/vscode.nix` — `nomarchy.vscode.*`
|
- `features/apps/vscode.nix` — `nomarchy.vscode.*`
|
||||||
|
|||||||
@@ -19,13 +19,16 @@ Guardrails (apply when adding anything):
|
|||||||
|
|
||||||
### Now (ready to pick up)
|
### Now (ready to pick up)
|
||||||
|
|
||||||
- (Empty for now)
|
- **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).
|
||||||
|
- **Pillar 8 runtime verification pass.** Every Component 1–10 code sweep has shipped, but each closeout entry flagged behaviour that can only be confirmed on a real install: boot the live ISO and eyeball waybar across panel positions × form factors × all 22 palettes; run every `nomarchy-menu` entry and confirm it does the thing; walk every `nomarchy.*` option's enable→rebuild→observe loop. Run the punch-list, fix any new bugs inline, log structural ones as new roadmap rows.
|
||||||
|
|
||||||
### Next (bigger lifts that build on Now)
|
### 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.
|
- **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`.
|
- **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.
|
- **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)
|
### Later (speculative or research-shaped)
|
||||||
|
|
||||||
@@ -37,6 +40,15 @@ 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.
|
- **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.
|
- **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.
|
- **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.
|
||||||
|
- **`nomarchy-menu` "Setup → Config" pattern edits Nix-managed files.** Five of the nine entries in `show_setup_config_menu` open files that Home Manager generates from declarative options (`hypridle.conf` from `services.hypridle.settings`, `hyprsunset.conf` from `services.hyprsunset`, `walker/config.toml` from `programs.walker.config`, `waybar/config.jsonc` from `programs.waybar.settings`, `hyprland.conf` from `wayland.windowManager.hyprland.settings`). The menu pattern is "edit then restart", but a `home-manager switch` clobbers the edit and the file goes back to the Nix-generated content. Two more entries (`hyprlock.conf`, `swayosd/config.toml`) point at paths the modules don't deploy at all — `open_in_editor` creates an empty file. Either remove these entries (the user should edit the Nix module), or rewire each to open the matching Nomarchy option doc / module file path, or document the ephemerality in `notify-send` when entering edit mode. Picked up during Pillar 8 / Component 8.
|
||||||
|
- **`themes/templates/*.tpl` — prune the truly dead, document the rest.** Eleven mustache-style templates deployed to `~/.local/share/nomarchy/templates/` via `themes/engine/files.nix`. Originally flagged as "no script consumes them" — that was wrong: `themes/engine/scripts/nomarchy-theme-set-templates` (called at the end of `nomarchy-theme-set`) reads them, substitutes palette colors, and writes the output to `~/.config/nomarchy/current/theme/<file>` only when no file is already there. Now categorise: **(a) functionally dead** — `alacritty.toml.tpl`, `btop.theme.tpl`, `chromium.theme.tpl`, `swayosd.css.tpl` all produce files at paths nothing reads (alacritty + swayosd are Stylix/Nix-themed; btop reads from `~/.config/btop/themes/nomarchy.theme` not from the theme symlink; chromium.theme references were deleted in `9b06b6c`). **(b) superseded** — `kitty.conf.tpl` and `ghostty.conf.tpl` are now generated by `themes/engine/files.nix` (commit `8d3ce2d`); the template path skips harmlessly via the "if not exists" check. **(c) still relevant** — `hyprland.conf.tpl`, `hyprlock.conf.tpl`, `obsidian.css.tpl`, `keyboard.rgb.tpl`, `hyprland-preview-share-picker.css.tpl` (this last one was orphaned when the share-picker dir was deleted in `20de3d4` — verify before keeping). Delete (a) + (b) + the orphan share-picker tpl; document the rest in `docs/creating-themes.md` as the layered override surface they actually are.
|
||||||
|
- **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.
|
||||||
|
- **Package missing VSCode theme extensions via `extensionFromVscodeMarketplace`.** 15 of the 21 palettes that ship a `themes/palettes/<theme>/apps/vscode.json` declare a theme extension that isn't in `pkgs.vscode-extensions` — including `sainnhe.everforest` which is the default `summer-night` palette's theme. With the `577b3ae` fix in place, the 6 nixpkgs-packaged extensions install by default (catppuccin, catppuccin-latte, nord, tokyo-night, rose-pine, gruvbox), but the other 15 (`sainnhe.everforest`, `qufiwefefwoyn.kanagawa`, `monokai.theme-monokai-pro-vscode`, `oldjobobo.{lumon,miasma,retro-82}-theme`, `Bjarne.{ethereal,hackerman,vantablack,white}-nomarchy`, `shadesOfBuntu.flexoki-light`, `jovejonovski.ocean-green`, `TahaYVR.matteblack`) still leave `workbench.colorTheme` referencing an unloaded theme, so VSCode silently falls back. Fix: extend `features/apps/vscode.nix` to look up the active palette's extension via `pkgs.vscode-utils.extensionFromVscodeMarketplace { publisher; name; version; sha256; }` — each entry pinned by hash. Could be table-driven in `lib/` so a new palette only needs to add a row.
|
||||||
|
- **Reconcile nightlight: systemd-managed hyprsunset vs `pkill`/`hyprctl exec` toggle.** `features/desktop/nightlight.nix` always sets `services.hyprsunset.enable = lib.mkDefault true` and bakes the temperature (`toggles.nightlight ? nightlightTemperature : 6500`) into `extraArgs` at Nix-eval time. The toggle script `themes/engine/scripts/nomarchy-toggle-nightlight` bypasses systemd entirely: `pkill hyprsunset` on disable, `hyprctl dispatch exec hyprsunset --temperature 4000` on enable — racing the systemd-managed instance and ignoring the user's chosen `nightlightTemperature`. The comment "Always enabled, we control via IPC and state" doesn't match the implementation (there's no IPC; the temperature is rebuild-time, not runtime). Pick one: (a) toggle stays as `hyprctl dispatch hyprsunset temperature ${T}` (proper IPC, no daemon restart), with Nix dropping `extraArgs` to just `--temperature 6500` on boot; or (b) gate `services.hyprsunset.enable` on the toggle and run `systemctl --user restart hyprsunset` from the script. Both also need the script to read `nightlightTemperature` instead of hardcoding 4000.
|
||||||
|
|
||||||
## 3. Pillar: Script & menu audit
|
## 3. Pillar: Script & menu audit
|
||||||
|
|
||||||
@@ -73,31 +85,31 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes,
|
|||||||
|
|
||||||
## 4. Pillar: Installer
|
## 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).
|
- 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).
|
- `disko-golden.nix` variants for software-RAID and BTRFS-pool-as-root (Shipped).
|
||||||
- Pre-flight resume polish (Next).
|
- Pre-flight resume polish (Shipped).
|
||||||
- "What's installed?" summary screen on boot of a freshly-installed system, sourced from `state.json` + `nomarchy-system-scripts` introspection.
|
- Software-profile multi-select (Shipped).
|
||||||
- Optional non-LUKS branch in the installer for users who explicitly opt out of FDE.
|
- Form-factor → laptop preset (Shipped).
|
||||||
|
|
||||||
## 5. Pillar: Power, hardware, presets
|
## 5. Pillar: Power, hardware, presets
|
||||||
|
|
||||||
- Laptop preset (Next): TLP, upower, brightness, lid, hypridle tuning.
|
- 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).
|
||||||
- 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.
|
|
||||||
- Surface support behind `nomarchy.hardware.isSurface` (Later).
|
- 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
|
## 6. Pillar: Onboarding & docs
|
||||||
|
|
||||||
- `nomarchy-welcome` first-run wizard (Next).
|
- `nomarchy-welcome` first-run wizard (Shipped).
|
||||||
- `docs/KEYBINDINGS.md` auto-generator (Shipped).
|
- `docs/KEYBINDINGS.md` auto-generator (Shipped).
|
||||||
- `docs/TROUBLESHOOTING.md` (Next).
|
- `docs/TROUBLESHOOTING.md` (Shipped).
|
||||||
- `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.
|
- `docs/index.md` / README docs index (Shipped — `README.md` links every doc in `docs/`).
|
||||||
- `nomarchy-manual` — orphaned reference today; either implement as a curated `xdg-open` to the docs index, or delete.
|
- `nomarchy-manual` — opens the local `~/.local/share/nomarchy/README.md` via `xdg-open` (Shipped).
|
||||||
|
|
||||||
## 7. Pillar: Test, CI, release
|
## 7. Pillar: Test, CI, release
|
||||||
|
|
||||||
@@ -109,6 +121,33 @@ 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.
|
- `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.
|
- 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: QA audit — features & components
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
## 9. Process notes
|
||||||
|
|
||||||
- **Branch naming:** `wave/<pillar>-<short-slug>`. Examples: `wave/audit-pkg-scripts`, `wave/installer-disk-metadata`, `wave/laptop-preset`.
|
- **Branch naming:** `wave/<pillar>-<short-slug>`. Examples: `wave/audit-pkg-scripts`, `wave/installer-disk-metadata`, `wave/laptop-preset`.
|
||||||
@@ -121,6 +160,19 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes,
|
|||||||
|
|
||||||
(Move items here when they land — keep them brief, link the commit/PR.)
|
(Move items here when they land — keep them brief, link the commit/PR.)
|
||||||
|
|
||||||
|
- _2026-05-21_ — **Pillar 8 / Component 9 (ISOs): closeout — Pillar 8 code-audit phase complete.** Code-review-shaped sweep over `hosts/{nomarchy-installer,nomarchy-live}.nix`, the `installation-cd-minimal`/`installation-cd-graphical-base` module chain, and the four ISO build/test scripts. Two minor fixes inline: `nomarchy-build-iso` and `nomarchy-build-live-iso` both ran under `set -e` but then wrapped `nix build` in an `if [ $? -eq 0 ]` block — the `else` branch printing "Error: ISO build failed." was unreachable because `set -e` aborts before the conditional. Removed the dead branches (behaviour identical: the user sees `nix build`'s own error and the script exits). Regression-class check (`hardware-db.sh` precedent): cross-referenced every tool `install.sh` calls against the installer host's `environment.systemPackages` chain — `gptfdisk` (sgdisk) is provided by upstream `profiles/base.nix:21` which `installation-cd-base.nix` chains, `jq` is wrapped in the `nrun` nix-run fallback, and every other direct call (`wipefs`, `dd`, `parted`, `partprobe`, `cryptsetup`, `disko`, `nixos-{install,enter,rebuild}`, `loadkeys`, `timedatectl`, `nmtui`) resolves via either the explicit host packages or the standard base. `nomarchy-live` host shape verified: multi-GPU initrd modules + Xwayland video drivers cover both real hardware and QEMU; auto-login + passwordless sudo + helpful TTY MOTD + Hyprland on-boot exec to a terminal at the install command. `nomarchy-test-live-iso` walks four OVMF candidate paths with KVM detection. With this entry, every code-shaped audit in Pillar 8 has shipped (Components 1–10); the Now-column "Full QA audit" item moves out, replaced by a runtime-verification punch-list entry covering the cross-component "needs runtime verification" notes from each closeout.
|
||||||
|
- _2026-05-21_ — **Pillar 8 / Component 8 (Scripts runtime behavior): closeout.** Code-review-shaped sweep over `features/scripts/utils/nomarchy-menu` (382 lines, 23 submenu functions), every script referenced from those submenus, the schema↔script field-name cross-check, and cross-cutting typo/stale-reference patterns. Four real fixes inline: **(1)** `nomarchy-menu:70` — "Learn → Nomarchy" still called `nomarchy-launch-webapp https://learn.omacom.io/2/the-nomarchy-manual` (an upstream Omarchy URL — the same one fixed in `nomarchy-manual` back on 2026-05-18). Now calls `nomarchy-manual`, which opens the local docs index. **(2)** `nomarchy-menu:179` — "Style → Hyprland" opened `~/.config/hypr/looknfeel.conf`, a path nothing deploys; the actual file lives at `~/.config/nomarchy/default/hypr/looknfeel.conf` (sourced via the chain from `nomarchy.conf`). Updated the path. **(3)** `nomarchy-menu:258` — `*Overrides*) xdg-open ~/.config/nomarchy/overrides/` case branch with no matching menu option, dead code anticipating the still-unimplemented `nomarchy.overrides.*` loader. Removed (will reappear with the option when the loader ships). **(4)** `nomarchy-theme-bg-next:12` — `jq -r '.theme // "nord"'` defaulted to `"nord"` if `.theme` was missing, while `lib/state-schema.nix:17` defines `"summer-night"` as the schema default. On a fresh-or-empty `state.json` the script looked for backgrounds under `palettes/nord/` while the rest of the system treated `summer-night` as active. Matched to the schema default. Cross-cutting sweeps came back clean: no `$NN[A-Z]+` env var typos elsewhere (the prior pair fixed in `40b6212` was the lot), no references to scripts deleted in earlier Pillar 3 batches (`nomarchy-restart-{hyprctl,mako,tmux}`, `nomarchy-battery-present`, `nomarchy-sudo-keepalive`, `nomarchy-rollback`, `nomarchy-snapshot`, `nomarchy-migrate-state`, `nomarchy-config-direct-boot`, `nomarchy-npx-install`, `nomarchy-webapp-handler-{hey,zoom}`), no stray `omarchy`/`omacom` strings outside historical roadmap entries, and every `state.json` field-write resolves against `lib/state-schema.nix` (or the documented off-schema `welcome_done`). One UX-shaped pattern bug logged separately to Later: `show_setup_config_menu` edits Nix-managed files that get clobbered on the next `home-manager switch`. Runtime verification (run every user-visible menu entry and confirm it does the thing) remains on the user.
|
||||||
|
- _2026-05-21_ — **Pillar 8 / Component 7 (Theme engine + palettes): closeout.** Code-review-shaped sweep across `themes/engine/{stylix,stylix-compat,loader,files,scripts}.nix`, the 23 theme-engine scripts, and the 21 palettes' file completeness. Three real fixes inline + targeted dead-surface cleanup: **(1)** `nomarchy-theme-set` printed a warning when the named theme directory didn't exist but continued executing — wrote the bad name into `state.json` and ran `nomarchy-env-update` on a broken state. Now `exit 1` after the warning. **(2)** `nomarchy-theme-bg-set` (called by the walker background-selector menu and by the `nomarchy-wallpaper` CLI) updated the live `~/.config/nomarchy/current/background` symlink + restarted swaybg but never wrote `state.json` — so every wallpaper picked via either path silently reverted to the theme default on the next `home-manager switch` (`themes/engine/files.nix` re-resolves `nomarchy.wallpaper` at every rebuild). Now writes the chosen path into `state.json.wallpaper`, mirroring `nomarchy-theme-bg-next`. Added a file-exists check so a bogus path fails loudly instead of leaving a dangling symlink + a crashed swaybg. **(3)** Palette tree dead-surface cleanup: deleted `themes/palettes/{flexoki-light,lumon,retro-82,rose-pine}/apps/chromium.theme` (9-byte RGB strings nothing reads — chromium is themed via managed policies in `core/system/browser.nix`, not per-palette files) and `themes/palettes/summer-day/apps/kitty/{kitty.conf,everforest-light.conf}` (a 76KB stray kitty config at the wrong nested path, superseded by the `kitty.conf` generator added in `8d3ce2d`). Total: 6 files / 2210 lines. Updated the misleading comment in `nomarchy-themes-prebuild` ("the installer wires this up") to reflect reality (the installer only tips the user to run it). Updated the `themes/templates/*.tpl` Later row with a fact-check + concrete categorisation — the templates ARE consumed by `nomarchy-theme-set-templates`, but most write to paths nothing reads or are now superseded by Nix-side generators. Palette completeness matrix: all 21 palettes have `colors.toml`, `backgrounds/`, `icons.theme`, and `apps/`; 5 carry the `light.mode` marker (catppuccin-latte, flexoki-light, rose-pine, summer-day, white); only tokyo-night ships `keyboard.rgb` for the ASUS ROG path, and the keyboard-set chain isn't wired into `nomarchy-theme-set` so it stays manual — niche enough to leave. Runtime verification (switch through all 22 palettes and eyeball SDDM + Plymouth + GTK + Qt + terminals + browsers + waybar + walker rendering) remains on the user.
|
||||||
|
- _2026-05-21_ — **Pillar 8 / Component 6 (Apps): closeout.** Code-review-shaped sweep over `features/apps/{alacritty,btop,chromium,elephant,ghostty,kitty,lazygit,opencode,swayosd,tmux,vscode,walker}`. Three real theming bugs fixed inline: **(1)** `features/apps/kitty/config/kitty.conf:1` and `features/apps/ghostty/config/config:2` referenced palette-specific include files (`~/.config/nomarchy/current/theme/{kitty,ghostty}.conf`) that didn't exist for any of the 22 palettes — kitty include failed silently, ghostty's was optional (`?`-prefix), and both terminals rendered with their built-in defaults regardless of the active Nomarchy palette. Stylix's `kitty.enable = true` was a no-op because the module uses `xdg.configFile` instead of `programs.kitty`; ghostty has no Stylix target. Added theme-engine generators in `themes/engine/files.nix` mirroring the existing `waybar.css` pattern, mapping `palette.base*` to kitty/ghostty color directives. **(2)** `features/apps/btop/config/btop.conf:5` set `color_theme = "current"` but `themes/engine/loader.nix:72` deploys the active palette's btop theme to `~/.config/btop/themes/nomarchy.theme` — name mismatch, btop fell back to its built-in Default theme on every palette. Renamed to `"nomarchy"`. **(3)** `programs.vscode.profiles.default.userSettings.workbench.colorTheme` was set unconditionally from `themes/palettes/<theme>/apps/vscode.json`, but the matching theme extensions were bundled with `devExtensions` (default `false`) — so VSCode silently fell back to its built-in theme out of the box on every palette. Split `themeExtensions` (always-on, covers the 6 palettes whose theme extension is in nixpkgs) from `devExtensions` (opt-in). The remaining 15 palettes — including the default `summer-night` (`sainnhe.everforest`) — still break because their theme extensions aren't packaged in nixpkgs; logged as a new Later row. Chromium static `Default/Preferences` symlink already had an open Later row; verified the file's contents are duplicate of the managed-policy intent in `core/system/browser.nix`, so the existing entry's hypothesis is correct — left for the user to greenlight deletion. alacritty (Stylix-themed via `programs.alacritty.settings`), elephant (no UI), swayosd (base16 inline), walker (covered in Component 5), lazygit + tmux (terminal ANSI inheritance, transitively fixed by the kitty/ghostty changes), and opencode (minimal opt-in config) are healthy. Runtime verification (launch each app on each palette and eyeball the theming) remains the user's responsibility.
|
||||||
|
- _2026-05-21_ — **Pillar 8 / Component 5 (Desktop stack): closeout.** Code-review-shaped sweep over Hyprland, waybar, walker, hypridle, hyprsunset, mako, KEYBINDINGS.md (the runtime-rendering subset — waybar across panel positions × form factors × all 22 palettes, walker launcher modes, hypridle timeout feel — stays on the user). Five real bugs fixed inline: **(1)** 9 of 17 `~/.config/nomarchy/default/hypr/apps/*.conf` window-rule files were deployed but never sourced, including `system.conf` (the `tag +floating-window` rules every TUI helper class relies on + `class:org.nomarchy.screensaver` fullscreen rule that hypridle's 150s on-timeout depends on) and `pip.conf` (the PiP pin/size rules). `apps.conf` now sources all 17. **(2)** Two `$NNOMARCHY_TOGGLE_*` typos (double-N) in `nomarchy-menu:330` and `nomarchy-launch-screensaver:16` made `toggles.suspend` and `toggles.screensaver` vacuous — Suspend always showed in the system menu and the screensaver always launched at idle regardless of the documented option. **(3)** 4 broken per-palette waybar `style.css` overrides (`catppuccin`, `lumon`, `nord`, `retro-82`) fully replaced the default style with 2–14 lines of only `@define-color` declarations — picking those palettes produced a waybar with zero structural styling. Default style already imports per-palette colors via `themes/engine/files.nix`-generated `theme/waybar.css`, so deletion restores correct rendering; `summer-day`/`summer-night` kept as legitimate 100+-line redesigns. **(4)** `core/home/config/nomarchy/default/hypr/{bindings,plain-bindings}.conf` were explicitly-labeled deprecated files sourced by nothing (plain-bindings.conf referenced undefined `$terminal`/`$browser`/etc. Hyprland vars) — deleted; `docs/SCRIPTS.md` regenerated to drop stale callers and incidentally corrected 4 Origin columns whose scripts moved from `core/system/scripts/` to `features/scripts/utils/`. **(5)** Mako post-fix (commit `2a301a0`) verified: deployment + the 4 referenced scripts (`nomarchy-notification-dismiss`, `nomarchy-launch-wifi`, `nomarchy-launch-floating-terminal-with-presentation`, `nomarchy-menu-keybindings`) all resolve. Two structural inconsistencies logged to Later: keymap routing (already in 72f7e7b) and the new hyprsunset toggle-vs-systemd reconcile. `KEYBINDINGS.md` regenerated with zero diff — generator already covers both binding source locations. Runtime verification (boot live ISO, eyeball waybar/walker/screensaver flows across panel positions and palettes) remains the user's responsibility before declaring Component 5 fully closed.
|
||||||
|
- _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: 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: 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: 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.
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
|||||||
| `nomarchy-cmd-screensaver` | `features/scripts/utils` | features/scripts/utils/nomarchy-launch-screensaver | `kept` | |
|
| `nomarchy-cmd-screensaver` | `features/scripts/utils` | features/scripts/utils/nomarchy-launch-screensaver | `kept` | |
|
||||||
| `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-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-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-cmd-terminal-cwd` | `features/scripts/utils` | features/desktop/hyprland/config/bindings.conf | `kept` | |
|
||||||
| `nomarchy-debug` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
| `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-keybindings` | `features/scripts/utils` | bin/utils/nomarchy-docs-keybindings | `kept` | |
|
||||||
| `nomarchy-docs-scripts` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts | `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-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-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-drive-set-password` | `features/scripts/utils` | features/scripts/utils/nomarchy-drive-select,features/scripts/utils/nomarchy-menu | `kept` | |
|
||||||
| `nomarchy-env-update` | `core/system/scripts` | core/home/bash.nix,core/system/scripts.nix, +7 more | `kept` | |
|
| `nomarchy-env-update` | `features/scripts/utils` | 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` | `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-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-list` | `themes/engine/scripts` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-font, +2 more | `kept` | |
|
||||||
@@ -77,8 +77,8 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
|||||||
| `nomarchy-launch-about` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
| `nomarchy-launch-about` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||||
| `nomarchy-launch-audio` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +2 more | `kept` | |
|
| `nomarchy-launch-audio` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +2 more | `kept` | |
|
||||||
| `nomarchy-launch-bluetooth` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
| `nomarchy-launch-bluetooth` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/bindings/utilities.conf,features/desktop/waybar/config/config.jsonc, +1 more | `kept` | |
|
||||||
| `nomarchy-launch-browser` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,core/home/config/nomarchy-skill/SKILL.md, +1 more | `kept` | |
|
| `nomarchy-launch-browser` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/desktop/hyprland/config/bindings.conf | `kept` | |
|
||||||
| `nomarchy-launch-editor` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/plain-bindings.conf,features/desktop/hyprland/config/bindings.conf, +2 more | `kept` | |
|
| `nomarchy-launch-editor` | `features/scripts/utils` | features/desktop/hyprland/config/bindings.conf,features/scripts/utils/nomarchy-menu, +1 more | `kept` | |
|
||||||
| `nomarchy-launch-floating-terminal-with-presentation` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini,features/desktop/waybar/config/config.jsonc, +3 more | `kept` | |
|
| `nomarchy-launch-floating-terminal-with-presentation` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini,features/desktop/waybar/config/config.jsonc, +3 more | `kept` | |
|
||||||
| `nomarchy-launch-or-focus` | `features/scripts/utils` | core/home/config/nomarchy/extensions/menu.sh,features/desktop/hyprland/config/bindings.conf, +6 more | `kept` | |
|
| `nomarchy-launch-or-focus` | `features/scripts/utils` | core/home/config/nomarchy/extensions/menu.sh,features/desktop/hyprland/config/bindings.conf, +6 more | `kept` | |
|
||||||
| `nomarchy-launch-or-focus-tui` | `features/scripts/utils` | core/home/config/nomarchy/extensions/menu.sh,features/desktop/waybar/config/config.jsonc, +3 more | `kept` | |
|
| `nomarchy-launch-or-focus-tui` | `features/scripts/utils` | core/home/config/nomarchy/extensions/menu.sh,features/desktop/waybar/config/config.jsonc, +3 more | `kept` | |
|
||||||
@@ -86,21 +86,21 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
|||||||
| `nomarchy-launch-screensaver` | `features/scripts/utils` | features/desktop/idle.nix,features/scripts/utils/nomarchy-menu | `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-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, +4 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-webapp` | `features/scripts/utils` | features/desktop/hyprland/config/bindings.conf,features/scripts/utils/nomarchy-launch-or-focus-webapp, +4 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-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-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` | core/branding/about.txt,features/scripts/utils/nomarchy-menu, +1 more | `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` | `features/scripts/utils` | bin/utils/nomarchy-docs-scripts,core/home/config/nomarchy/default/hypr/bindings/utilities.conf, +9 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-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-notification-dismiss` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini | `kept` | |
|
| `nomarchy-notification-dismiss` | `features/scripts/utils` | core/home/config/nomarchy/default/mako/core.ini | `kept` | |
|
||||||
| `nomarchy-on-boot` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/autostart.conf | `kept` | |
|
| `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-add` | `features/scripts/utils` | 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` | |
|
| `nomarchy-pkg-aur-add` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||||
| `nomarchy-pkg-drop` | `features/scripts/utils` | features/scripts/utils/nomarchy-voxtype-remove | `kept` | |
|
| `nomarchy-pkg-drop` | `features/scripts/utils` | features/scripts/utils/nomarchy-voxtype-remove | `kept` | |
|
||||||
| `nomarchy-pkg-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
| `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-pkg-remove` | `features/scripts/utils` | features/scripts/utils/nomarchy-pkg-drop | `kept` | |
|
||||||
| `nomarchy-powerprofiles-list` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
| `nomarchy-powerprofiles-list` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||||
| `nomarchy-preflight-migration` | `core/system/scripts` | core/system/scripts/nomarchy-env-update | `kept` | |
|
| `nomarchy-preflight-migration` | `features/scripts/utils` | features/scripts/utils/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-config` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-refresh-fastfetch | `kept` | |
|
||||||
| `nomarchy-refresh-fastfetch` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
| `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-hyprland` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||||
@@ -169,7 +169,7 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
|||||||
| `nomarchy-tui-remove` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `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-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-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, +3 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-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-firmware` | `features/scripts/utils` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||||
| `nomarchy-update-time` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
| `nomarchy-update-time` | `core/system/scripts` | features/scripts/utils/nomarchy-menu | `kept` | |
|
||||||
@@ -184,7 +184,7 @@ Phase B (per-batch PRs) refines those into `port-from-omarchy`,
|
|||||||
| `nomarchy-webapp-install` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md,features/scripts/utils/nomarchy-webapp-remove-all | `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` | `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-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-welcome` | `features/scripts/utils` | core/home/config/nomarchy/default/hypr/autostart.conf,lib/state-schema.nix | `kept` | |
|
||||||
| `nomarchy-wifi-powersave` | `core/system/scripts` | features/scripts/utils/nomarchy-sys-update,installer/install.sh | `kept` | |
|
| `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` | |
|
| `nomarchy-windows-vm` | `features/scripts/utils` | core/home/config/nomarchy-skill/SKILL.md | `kept` | |
|
||||||
|
|
||||||
|
|||||||
@@ -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`).
|
- `nixosModules.home`: Exports the application and desktop logic (`./features`).
|
||||||
- `nixosConfigurations`: Defines pre-configured targets like `nomarchy-installer`, `nomarchy-live`, and a testing `vm`.
|
- `nixosConfigurations`: Defines pre-configured targets like `nomarchy-installer`, `nomarchy-live`, and a testing `vm`.
|
||||||
- **`flake.lock`**: Locks dependency versions for reproducible builds.
|
- **`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.
|
- **`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.
|
- **`default.nix`**: The entry point for the base Home Manager module.
|
||||||
- **`options.nix`**: Defines the `nomarchy` user options (Toggles, Theme, Fonts, etc.).
|
- **`options.nix`**: Defines the `nomarchy` user options (Toggles, Theme, Fonts, etc.).
|
||||||
- **`state.nix`**: Loads and applies user-level state (from `~/.config/nomarchy/state.json`).
|
- **`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`.
|
- **`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/`.
|
- **`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.
|
- **`bash.nix`**: Shell environment, aliases, and specialized `env-update` hooks.
|
||||||
- **`security.nix`**: Polkit, keyring management, and GPG settings.
|
- **`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).
|
- **`config/`**: Contains the physical source files for the base user configuration (e.g., `starship.toml`, `hypr/` behavior configs).
|
||||||
|
|||||||
@@ -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" }
|
|
||||||
]
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
|
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
|
||||||
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
|
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
|
||||||
color_theme = "current"
|
color_theme = "nomarchy"
|
||||||
|
|
||||||
#* If the theme set background should be shown, set to False if you want terminal background transparency.
|
#* If the theme set background should be shown, set to False if you want terminal background transparency.
|
||||||
theme_background = True
|
theme_background = True
|
||||||
|
|||||||
@@ -7,7 +7,26 @@ let
|
|||||||
else
|
else
|
||||||
{ name = "Default Dark Modern"; };
|
{ name = "Default Dark Modern"; };
|
||||||
|
|
||||||
# Development extensions that match the system theme
|
# Theme extensions matching palette vscode.json `extension` fields. Always
|
||||||
|
# installed because workbench.colorTheme is set unconditionally from the
|
||||||
|
# active palette — without the matching extension VSCode silently falls
|
||||||
|
# back to its default theme. Only the extensions available in
|
||||||
|
# pkgs.vscode-extensions are listed. Palettes whose theme extension is on
|
||||||
|
# the VSCode marketplace but not packaged in nixpkgs (sainnhe.everforest —
|
||||||
|
# affects the DEFAULT summer-night palette — plus qufiwefefwoyn.kanagawa,
|
||||||
|
# monokai.theme-monokai-pro-vscode, oldjobobo.*, Bjarne.*,
|
||||||
|
# shadesOfBuntu.flexoki-light, jovejonovski.ocean-green, TahaYVR.matteblack)
|
||||||
|
# still break and need pkgs.vscode-utils.extensionFromVscodeMarketplace —
|
||||||
|
# tracked in ROADMAP Later.
|
||||||
|
themeExtensions = with pkgs.vscode-extensions; [
|
||||||
|
catppuccin.catppuccin-vsc # catppuccin, catppuccin-latte
|
||||||
|
enkia.tokyo-night # tokyo-night
|
||||||
|
arcticicestudio.nord-visual-studio-code # nord
|
||||||
|
mvllow.rose-pine # rose-pine
|
||||||
|
jdinhlife.gruvbox # gruvbox
|
||||||
|
];
|
||||||
|
|
||||||
|
# Development extensions — opt-in via nomarchy.vscode.devExtensions.
|
||||||
devExtensions = with pkgs.vscode-extensions; [
|
devExtensions = with pkgs.vscode-extensions; [
|
||||||
# Language support
|
# Language support
|
||||||
ms-python.python
|
ms-python.python
|
||||||
@@ -22,13 +41,6 @@ let
|
|||||||
esbenp.prettier-vscode
|
esbenp.prettier-vscode
|
||||||
dbaeumer.vscode-eslint
|
dbaeumer.vscode-eslint
|
||||||
bradlc.vscode-tailwindcss
|
bradlc.vscode-tailwindcss
|
||||||
|
|
||||||
# Theme extensions (provide color themes matching nomarchy palettes)
|
|
||||||
catppuccin.catppuccin-vsc
|
|
||||||
enkia.tokyo-night
|
|
||||||
arcticicestudio.nord-visual-studio-code
|
|
||||||
sainnhe.everforest
|
|
||||||
mvllow.rose-pine
|
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -51,7 +63,10 @@ in
|
|||||||
"editor.fontFamily" = "'${config.nomarchy.fonts.monospace}', 'Droid Sans Mono', monospace";
|
"editor.fontFamily" = "'${config.nomarchy.fonts.monospace}', 'Droid Sans Mono', monospace";
|
||||||
"terminal.integrated.fontFamily" = config.nomarchy.fonts.monospace;
|
"terminal.integrated.fontFamily" = config.nomarchy.fonts.monospace;
|
||||||
};
|
};
|
||||||
extensions = lib.mkIf config.nomarchy.vscode.devExtensions (lib.mkDefault devExtensions);
|
extensions = lib.mkDefault (
|
||||||
|
themeExtensions
|
||||||
|
++ lib.optionals config.nomarchy.vscode.devExtensions devExtensions
|
||||||
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,6 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
nomarchyLib = import ../lib { inherit lib; };
|
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
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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/nomarchy.conf".source = ./config/nomarchy.conf;
|
||||||
xdg.configFile."hypr/monitors.conf".source = lib.mkDefault ./config/monitors.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/input.conf".source = lib.mkDefault ./config/input.conf;
|
||||||
xdg.configFile."hypr/bindings.conf".source = lib.mkDefault ./config/bindings.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.
|
# 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
|
# exec-once fails silently (black screen with no visible error) when timing
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
@define-color foreground #cdd6f4;
|
|
||||||
@define-color background #181824;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
@define-color foreground #d6e2ee;
|
|
||||||
@define-color background #213442;
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
@define-color background #2e3440;
|
|
||||||
@define-color foreground #d8dee9;
|
|
||||||
@define-color accent #88c0d0;
|
|
||||||
|
|
||||||
/* Base style for Nord */
|
|
||||||
* {
|
|
||||||
font-family: JetBrainsMono Nerd Font, FontAwesome;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar {
|
|
||||||
background-color: @background;
|
|
||||||
color: @foreground;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
@define-color bg #00172e;
|
|
||||||
@define-color foreground #f6dcac;
|
|
||||||
@define-color background alpha(@bg, 0.8);
|
|
||||||
@@ -71,7 +71,6 @@ let
|
|||||||
NOMARCHY_TOGGLE_IDLE = if config.nomarchy.toggles.idle then "true" else "false";
|
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_NIGHTLIGHT = if config.nomarchy.toggles.nightlight then "true" else "false";
|
||||||
NOMARCHY_TOGGLE_WAYBAR = if config.nomarchy.toggles.waybar 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;
|
NOMARCHY_MONOSPACE_FONT = config.nomarchy.fonts.monospace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,8 @@ set -e
|
|||||||
# Build the Nomarchy Installer ISO declaratively using the flake.
|
# Build the Nomarchy Installer ISO declaratively using the flake.
|
||||||
|
|
||||||
echo "Building Nomarchy Installer ISO..."
|
echo "Building Nomarchy Installer ISO..."
|
||||||
|
|
||||||
# The output will be a symlink named 'result' in the current directory
|
|
||||||
nix build .#nixosConfigurations.nomarchy-installer.config.system.build.isoImage
|
nix build .#nixosConfigurations.nomarchy-installer.config.system.build.isoImage
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
ISO_PATH=$(readlink -f result/iso/*.iso)
|
||||||
ISO_PATH=$(readlink -f result/iso/*.iso)
|
echo "Success! ISO built at: $ISO_PATH"
|
||||||
echo "Success! ISO built at: $ISO_PATH"
|
echo "You can now burn this to a USB drive using 'dd' or 'etcher'."
|
||||||
echo "You can now burn this to a USB drive using 'dd' or 'etcher'."
|
|
||||||
else
|
|
||||||
echo "Error: ISO build failed."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -4,15 +4,8 @@ set -e
|
|||||||
# Build the Nomarchy Live ISO (Full Desktop Environment) using the flake.
|
# Build the Nomarchy Live ISO (Full Desktop Environment) using the flake.
|
||||||
|
|
||||||
echo "Building Nomarchy Live ISO..."
|
echo "Building Nomarchy Live ISO..."
|
||||||
|
|
||||||
# The output will be a symlink named 'result' in the current directory
|
|
||||||
nix build .#nixosConfigurations.nomarchy-live.config.system.build.isoImage
|
nix build .#nixosConfigurations.nomarchy-live.config.system.build.isoImage
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
ISO_PATH=$(readlink -f result/iso/*.iso)
|
||||||
ISO_PATH=$(readlink -f result/iso/*.iso)
|
echo "Success! Live ISO built at: $ISO_PATH"
|
||||||
echo "Success! Live ISO built at: $ISO_PATH"
|
echo "You can now burn this to a USB drive using 'dd' or 'etcher'."
|
||||||
echo "You can now burn this to a USB drive using 'dd' or 'etcher'."
|
|
||||||
else
|
|
||||||
echo "Error: Live ISO build failed."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pgrep -f org.nomarchy.screensaver && exit 0
|
|||||||
|
|
||||||
# Allow screensaver to be turned off but also force started
|
# Allow screensaver to be turned off but also force started
|
||||||
# Skip if screensaver is disabled in configuration
|
# Skip if screensaver is disabled in configuration
|
||||||
if [[ $NNOMARCHY_TOGGLE_SCREENSAVER == "false" ]] && [[ $1 != "force" ]]; then
|
if [[ $NOMARCHY_TOGGLE_SCREENSAVER == "false" ]] && [[ $1 != "force" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Nomarchy Manual Script
|
# Open the Nomarchy docs index in the default handler.
|
||||||
# Opens the Nomarchy manual in the default web browser.
|
# 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"
|
if [[ -f "$README" ]]; then
|
||||||
xdg-open "$URL"
|
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
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ open_in_editor() {
|
|||||||
show_learn_menu() {
|
show_learn_menu() {
|
||||||
case $(menu "Learn" " Keybindings\n Nomarchy\n Hyprland\n Arch\n Neovim\n Bash") in
|
case $(menu "Learn" " Keybindings\n Nomarchy\n Hyprland\n Arch\n Neovim\n Bash") in
|
||||||
*Keybindings*) nomarchy-menu-keybindings ;;
|
*Keybindings*) nomarchy-menu-keybindings ;;
|
||||||
*Nomarchy*) nomarchy-launch-webapp "https://learn.omacom.io/2/the-nomarchy-manual" ;;
|
*Nomarchy*) nomarchy-manual ;;
|
||||||
*Hyprland*) nomarchy-launch-webapp "https://wiki.hypr.land/" ;;
|
*Hyprland*) nomarchy-launch-webapp "https://wiki.hypr.land/" ;;
|
||||||
*Arch*) nomarchy-launch-webapp "https://wiki.archlinux.org/title/Main_page" ;;
|
*Arch*) nomarchy-launch-webapp "https://wiki.archlinux.org/title/Main_page" ;;
|
||||||
*Bash*) nomarchy-launch-webapp "https://devhints.io/bash" ;;
|
*Bash*) nomarchy-launch-webapp "https://devhints.io/bash" ;;
|
||||||
@@ -176,7 +176,7 @@ show_style_menu() {
|
|||||||
*Theme*) show_theme_menu ;;
|
*Theme*) show_theme_menu ;;
|
||||||
*Font*) show_font_menu ;;
|
*Font*) show_font_menu ;;
|
||||||
*Background*) show_background_menu ;;
|
*Background*) show_background_menu ;;
|
||||||
*Hyprland*) open_in_editor ~/.config/hypr/looknfeel.conf ;;
|
*Hyprland*) open_in_editor ~/.config/nomarchy/default/hypr/looknfeel.conf ;;
|
||||||
*Screensaver*) open_in_editor ~/.config/nomarchy/branding/screensaver.txt ;;
|
*Screensaver*) open_in_editor ~/.config/nomarchy/branding/screensaver.txt ;;
|
||||||
*About*) open_in_editor ~/.config/nomarchy/branding/about.txt ;;
|
*About*) open_in_editor ~/.config/nomarchy/branding/about.txt ;;
|
||||||
*) back_to show_main_menu ;;
|
*) back_to show_main_menu ;;
|
||||||
@@ -255,7 +255,6 @@ show_setup_config_menu() {
|
|||||||
*Walker*) open_in_editor ~/.config/walker/config.toml && nomarchy-restart-walker ;;
|
*Walker*) open_in_editor ~/.config/walker/config.toml && nomarchy-restart-walker ;;
|
||||||
*Waybar*) open_in_editor ~/.config/waybar/config.jsonc && nomarchy-restart-waybar ;;
|
*Waybar*) open_in_editor ~/.config/waybar/config.jsonc && nomarchy-restart-waybar ;;
|
||||||
*XCompose*) open_in_editor ~/.XCompose && nomarchy-restart-xcompose ;;
|
*XCompose*) open_in_editor ~/.XCompose && nomarchy-restart-xcompose ;;
|
||||||
*Overrides*) xdg-open ~/.config/nomarchy/overrides/ ;;
|
|
||||||
*) back_to show_setup_menu ;;
|
*) back_to show_setup_menu ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -327,7 +326,7 @@ show_about() {
|
|||||||
|
|
||||||
show_system_menu() {
|
show_system_menu() {
|
||||||
local options=" Screensaver\n Lock"
|
local options=" Screensaver\n Lock"
|
||||||
[[ $NNOMARCHY_TOGGLE_SUSPEND != "false" ]] && options="$options\n Suspend"
|
[[ $NOMARCHY_TOGGLE_SUSPEND != "false" ]] && options="$options\n Suspend"
|
||||||
nomarchy-hibernation-available && options="$options\n Hibernate"
|
nomarchy-hibernation-available && options="$options\n Hibernate"
|
||||||
options="$options\n Logout\n Restart\n Shutdown"
|
options="$options\n Logout\n Restart\n Shutdown"
|
||||||
|
|
||||||
|
|||||||
@@ -28,16 +28,25 @@ echo ""
|
|||||||
|
|
||||||
# 1. Select initial theme
|
# 1. Select initial theme
|
||||||
echo "Step 1: Choose your starting 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
|
# 2. Select initial font
|
||||||
echo "Step 2: Choose your preferred 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
|
# 3. Select panel position
|
||||||
echo "Step 3: Choose your preferred panel position"
|
echo "Step 3: Choose your preferred panel position"
|
||||||
POSITION=$(gum choose "top" "bottom")
|
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
|
# Skip system-modifying steps in the Live ISO environment
|
||||||
if [[ "$USER" == "nixos" ]]; then
|
if [[ "$USER" == "nixos" ]]; then
|
||||||
@@ -50,39 +59,9 @@ if [[ "$USER" == "nixos" ]]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 4. Starter home.nix
|
# 4. Setup Local Repo (Crucial for nomarchy-env-update to work)
|
||||||
echo ""
|
echo ""
|
||||||
echo "Step 4: Starter home.nix"
|
echo "Step 4: Git Repository Check"
|
||||||
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 "Nomarchy relies on a local git repository for declarative updates."
|
echo "Nomarchy relies on a local git repository for declarative updates."
|
||||||
if [ ! -d "/etc/nixos/.git" ]; then
|
if [ ! -d "/etc/nixos/.git" ]; then
|
||||||
echo "Warning: /etc/nixos is not a git repository. Declarative updates might fail."
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6. Success
|
# 5. Success
|
||||||
echo ""
|
echo ""
|
||||||
echo "Applying all changes..."
|
echo "Applying all changes..."
|
||||||
nomarchy-env-update
|
nomarchy-env-update
|
||||||
|
|||||||
@@ -19,13 +19,17 @@
|
|||||||
|
|
||||||
HARDWARE_DB=(
|
HARDWARE_DB=(
|
||||||
# Framework ---------------------------------------------------------------
|
# 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 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 16.*Ryzen AI 300|isFramework=true|framework-16-amd-ai-300-series"
|
||||||
"Framework|Laptop 13.*AMD Ryzen 7040|isFramework=true|framework-13-7040-amd"
|
"Framework|Laptop 13.*Ryzen AI 300|isFramework=true|framework-amd-ai-300-series"
|
||||||
"Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13-13th-gen-intel"
|
"Framework|Laptop 13.*Ryzen 7040|isFramework=true|framework-13-7040-amd"
|
||||||
"Framework|Laptop 13.*12th Gen Intel|isFramework=true|framework-13-12th-gen-intel"
|
"Framework|Laptop 13.*Core Ultra|isFramework=true|framework-intel-core-ultra-series1"
|
||||||
"Framework|Laptop 13.*11th Gen Intel|isFramework=true|framework-13-11th-gen-intel"
|
"Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13th-gen-intel"
|
||||||
"Framework|Laptop \(13.*|isFramework=true|framework-13-11th-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 / Precision / Latitude ----------------------------------------
|
||||||
"Dell|XPS 15 9500|isXPS=true|dell-xps-15-9500"
|
"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 9380|isXPS=true|dell-xps-13-9380"
|
||||||
"Dell|XPS 13 7390|isXPS=true|dell-xps-13-7390"
|
"Dell|XPS 13 7390|isXPS=true|dell-xps-13-7390"
|
||||||
"Dell|Precision 5530|_|dell-precision-5530"
|
"Dell|Precision 5530|_|dell-precision-5530"
|
||||||
"Dell|Latitude 7480|_|dell-latitude-7480"
|
"Dell|Latitude 7490|_|dell-latitude-7490"
|
||||||
"Dell|Latitude 5400|_|dell-latitude-5400"
|
"Dell|Latitude 7430|_|dell-latitude-7430"
|
||||||
|
"Dell|Latitude 7420|_|dell-latitude-7420"
|
||||||
|
|
||||||
# Lenovo ThinkPad --------------------------------------------------------
|
# Lenovo ThinkPad --------------------------------------------------------
|
||||||
"LENOVO|ThinkPad X1 Carbon Gen 11|_|lenovo-thinkpad-x1-carbon-gen11"
|
# X1 Carbon: the per-gen modules are named "x1-Nth-gen", not
|
||||||
"LENOVO|ThinkPad X1 Carbon Gen 10|_|lenovo-thinkpad-x1-carbon-gen10"
|
# "x1-carbon-genN" — both naming schemes appeared in nixos-hardware and
|
||||||
"LENOVO|ThinkPad X1 Carbon Gen 9|_|lenovo-thinkpad-x1-carbon-gen9"
|
# 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 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 3|_|lenovo-thinkpad-t14-amd-gen3"
|
||||||
"LENOVO|ThinkPad T14 Gen 2|_|lenovo-thinkpad-t14-amd-gen2"
|
"LENOVO|ThinkPad T14 Gen 2|_|lenovo-thinkpad-t14-amd-gen2"
|
||||||
"LENOVO|ThinkPad T14 Gen 1|_|lenovo-thinkpad-t14-amd-gen1"
|
"LENOVO|ThinkPad T14 Gen 1|_|lenovo-thinkpad-t14-amd-gen1"
|
||||||
"LENOVO|ThinkPad T480|_|lenovo-thinkpad-t480"
|
"LENOVO|ThinkPad T480|_|lenovo-thinkpad-t480"
|
||||||
"LENOVO|ThinkPad L13|_|lenovo-thinkpad-l13"
|
"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 ------------------------------------------------------
|
# 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 9|_|microsoft-surface-pro-9"
|
||||||
"Microsoft|Surface Pro 8|_|microsoft-surface-pro-8"
|
"Microsoft|Surface Pro 8|_|microsoft-surface-pro-intel"
|
||||||
"Microsoft|Surface Pro 7|_|microsoft-surface-pro-7"
|
"Microsoft|Surface Pro 7|_|microsoft-surface-pro-intel"
|
||||||
"Microsoft|Surface Pro 6|_|microsoft-surface-pro-6"
|
"Microsoft|Surface Pro 6|_|microsoft-surface-pro-intel"
|
||||||
"Microsoft|Surface Laptop 5|_|microsoft-surface-laptop-5"
|
"Microsoft|Surface Pro 3|_|microsoft-surface-pro-3"
|
||||||
"Microsoft|Surface Laptop 4|_|microsoft-surface-laptop-4"
|
"Microsoft|Surface Laptop.*Ryzen|_|microsoft-surface-laptop-amd"
|
||||||
"Microsoft|Surface Laptop 3|_|microsoft-surface-laptop-3"
|
|
||||||
"Microsoft|Surface Go|_|microsoft-surface-go"
|
"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 Ally / Zephyrus / Strix --------------------------------------
|
||||||
"ASUS.*|ROG Zephyrus G14.*2024|_|asus-zephyrus-ga403"
|
# Ally is the handheld (Z1 Extreme / Z1). RC71L is the original Ally,
|
||||||
"ASUS.*|ROG Zephyrus G14.*2023|_|asus-zephyrus-ga402"
|
# RC72LA is the Ally X — both share the same nixos-hardware module
|
||||||
"ASUS.*|ROG Zephyrus G14.*2021|_|asus-zephyrus-ga401"
|
# 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 Zephyrus G15|_|asus-zephyrus-ga503"
|
||||||
"ASUS.*|ROG Strix G15|_|asus-rog-strix-g513"
|
"ASUS.*|ROG Zephyrus.*GU603|_|asus-zephyrus-gu603h"
|
||||||
"ASUS.*|Zenbook UX|_|asus-zenbook-ux"
|
"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 (T2 Intel; M-series falls back to asahi elsewhere) ---------------
|
||||||
"Apple.*|MacBookPro15|isT2Mac=true|apple-t2"
|
"Apple.*|MacBookPro15|isT2Mac=true|apple-t2"
|
||||||
@@ -86,9 +111,14 @@ HARDWARE_DB=(
|
|||||||
"System76|Galago Pro.*|_|system76"
|
"System76|Galago Pro.*|_|system76"
|
||||||
"System76|Pangolin.*|_|system76"
|
"System76|Pangolin.*|_|system76"
|
||||||
|
|
||||||
# Raspberry Pi (ARM) — listed for completeness; installer is x86_64 only -
|
# Devices nixos-hardware doesn't cover (yet) -----------------------------
|
||||||
# "Raspberry Pi|Raspberry Pi 5|_|raspberry-pi-5"
|
# Listed here so future contributors know they're known-unsupported, not
|
||||||
# "Raspberry Pi|Raspberry Pi 4|_|raspberry-pi-4"
|
# 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.
|
||||||
)
|
)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ Usage: install.sh [--dry-run] [--resume] [-h|--help]
|
|||||||
Doesn't touch the disk, doesn't run nixos-install.
|
Doesn't touch the disk, doesn't run nixos-install.
|
||||||
--resume Reuse answers from a previous interrupted run
|
--resume Reuse answers from a previous interrupted run
|
||||||
(saved at $STATE_FILE — passwords excluded).
|
(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.
|
-h, --help Print this message.
|
||||||
USAGE
|
USAGE
|
||||||
}
|
}
|
||||||
@@ -102,19 +105,74 @@ parse_args() {
|
|||||||
# will silently install a system with an empty password hash and lock the
|
# will silently install a system with an empty password hash and lock the
|
||||||
# user out. Keep the guard checking the hash.
|
# user out. Keep the guard checking the hash.
|
||||||
save_state() {
|
save_state() {
|
||||||
declare -p \
|
# The leading timestamp lets --resume surface "how old is this state?"
|
||||||
TARGET_DRIVE USERNAME HOSTNAME TIMEZONE \
|
# and is parsed back via NOMARCHY_INSTALL_STATE_SAVED_AT.
|
||||||
KEYMAP_LAYOUT KEYMAP_VARIANT LOCALE FORM_FACTOR \
|
{
|
||||||
ENABLE_IMPERMANENCE HARDWARE_MODULES NOMARCHY_HW_OPTS \
|
echo "NOMARCHY_INSTALL_STATE_SAVED_AT=\"$(date -Iseconds)\""
|
||||||
SELECTED_PROFILES NOMARCHY_REV \
|
declare -p \
|
||||||
> "$STATE_FILE"
|
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() {
|
load_state() {
|
||||||
if [[ "$RESUME" == "true" ]] && [[ -f "$STATE_FILE" ]]; then
|
if [[ "$RESUME" != "true" ]]; then
|
||||||
# shellcheck disable=SC1090
|
return
|
||||||
source "$STATE_FILE"
|
fi
|
||||||
info "Resumed from $STATE_FILE"
|
|
||||||
|
# --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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1292,7 +1350,7 @@ execute_installation() {
|
|||||||
mkdir -p /mnt/persist/etc
|
mkdir -p /mnt/persist/etc
|
||||||
mv /mnt/etc/nixos /mnt/persist/etc/
|
mv /mnt/etc/nixos /mnt/persist/etc/
|
||||||
mkdir -p /mnt/etc
|
mkdir -p /mnt/etc
|
||||||
ln -s /persist/etc/nixos /mnt/etc/nixos
|
ln -s ../persist/etc/nixos /mnt/etc/nixos
|
||||||
success "Impermanence configured"
|
success "Impermanence configured"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1401,7 +1459,7 @@ generate_flake_config() {
|
|||||||
if (( ${#_drives[@]} > 1 )); then
|
if (( ${#_drives[@]} > 1 )); then
|
||||||
_main_luks_name="crypted_main"
|
_main_luks_name="crypted_main"
|
||||||
fi
|
fi
|
||||||
impermanence_opt=$'nomarchy.system.impermanence.enable = true;\n nomarchy.system.impermanence.mainLuksName = "'"$_main_luks_name"$'";'
|
impermanence_opt=$'nomarchy.system.impermanence.enable = true;\n nomarchy.system.impermanence.mainLuksName = "'"$_main_luks_name"$'";\n nomarchy.system.impermanence.user = "'"$USERNAME"$'";'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local PROFILE_SYSTEM_OPTS=""
|
local PROFILE_SYSTEM_OPTS=""
|
||||||
@@ -1741,30 +1799,29 @@ EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# state.json — consumed by core/system/state.nix at every nixos-rebuild and
|
# state.json — consumed by core/system/state.nix at every nixos-rebuild
|
||||||
# mutated by toggle scripts (nomarchy-tz-select, nomarchy-setup-fido2,
|
# and mutated by toggle scripts (nomarchy-tz-select, nomarchy-setup-fido2,
|
||||||
# nomarchy-toggle-hybrid-gpu, nomarchy-wifi-powersave, ...). Those scripts
|
# 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
|
# `jq` the file in place and fail hard if it doesn't exist or isn't
|
||||||
# JSON, so a fresh install MUST ship one. Shape must match lib/state-schema.nix.
|
# valid JSON, so a fresh install MUST ship one.
|
||||||
# Quoted heredoc — no shell expansion except the explicit $TIMEZONE below.
|
#
|
||||||
|
# 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}"
|
local _state_tz="${TIMEZONE:-UTC}"
|
||||||
cat > /mnt/etc/nixos/state.json <<JSON_EOF
|
nix --extra-experimental-features 'nix-command flakes' eval \
|
||||||
{
|
--impure --raw \
|
||||||
"theme": "nord",
|
--expr "
|
||||||
"timezone": "${_state_tz}",
|
let
|
||||||
"dns": "DHCP",
|
flake = builtins.getFlake \"$NOMARCHY_REPO\";
|
||||||
"customDns": [],
|
lib = flake.inputs.nixpkgs.lib;
|
||||||
"wifi": {
|
schema = import \"$NOMARCHY_REPO/lib/state-schema.nix\" { inherit lib; };
|
||||||
"powersave": true
|
state = schema.system // { timezone = \"$_state_tz\"; };
|
||||||
},
|
in builtins.toJSON state
|
||||||
"features": {
|
" | nrun jq '.' > /mnt/etc/nixos/state.json
|
||||||
"fingerprint": false,
|
|
||||||
"fido2": false,
|
|
||||||
"hybridGPU": false,
|
|
||||||
"makima": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JSON_EOF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ let
|
|||||||
in {
|
in {
|
||||||
inherit
|
inherit
|
||||||
palettes
|
palettes
|
||||||
readState
|
|
||||||
readHomeState
|
readHomeState
|
||||||
readSystemState
|
readSystemState
|
||||||
resolveWallpaper
|
resolveWallpaper
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
# Nomarchy State Schema
|
# 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 }:
|
{ lib }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# Home state defaults (user preferences)
|
# Home state defaults (user preferences)
|
||||||
home = {
|
home = {
|
||||||
# Theme and appearance
|
# Theme and appearance
|
||||||
theme = "nord";
|
theme = "summer-night";
|
||||||
wallpaper = "";
|
wallpaper = "";
|
||||||
font = "JetBrainsMono Nerd Font";
|
font = "JetBrainsMono Nerd Font";
|
||||||
panelPosition = "top";
|
panelPosition = "top";
|
||||||
@@ -18,7 +26,6 @@
|
|||||||
idle = true;
|
idle = true;
|
||||||
nightlight = false;
|
nightlight = false;
|
||||||
waybar = true;
|
waybar = true;
|
||||||
skipVsCodeTheme = false;
|
|
||||||
|
|
||||||
# Hyprland window manager settings
|
# Hyprland window manager settings
|
||||||
hyprland = {
|
hyprland = {
|
||||||
@@ -31,7 +38,7 @@
|
|||||||
# System state defaults (system-level configuration)
|
# System state defaults (system-level configuration)
|
||||||
system = {
|
system = {
|
||||||
# Theme (can differ from home for system-level theming)
|
# Theme (can differ from home for system-level theming)
|
||||||
theme = "nord";
|
theme = "summer-night";
|
||||||
|
|
||||||
# Timezone
|
# Timezone
|
||||||
timezone = "UTC";
|
timezone = "UTC";
|
||||||
@@ -50,18 +57,7 @@
|
|||||||
fingerprint = false;
|
fingerprint = false;
|
||||||
fido2 = false;
|
fido2 = false;
|
||||||
hybridGPU = 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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,62 @@ in
|
|||||||
@define-color accent #${palette.base0D};
|
@define-color accent #${palette.base0D};
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Per-palette kitty colors. features/apps/kitty/config/kitty.conf includes
|
||||||
|
# this file; without it the include silently failed and kitty stayed on
|
||||||
|
# default colors for every palette (Stylix's kitty target only kicks in
|
||||||
|
# when programs.kitty.enable is set, which the module doesn't use).
|
||||||
|
xdg.configFile."nomarchy/current/theme/kitty.conf".text = ''
|
||||||
|
background #${palette.base00}
|
||||||
|
foreground #${palette.base05}
|
||||||
|
cursor #${palette.base05}
|
||||||
|
selection_background #${palette.base02}
|
||||||
|
selection_foreground #${palette.base05}
|
||||||
|
color0 #${palette.base01}
|
||||||
|
color1 #${palette.base08}
|
||||||
|
color2 #${palette.base0B}
|
||||||
|
color3 #${palette.base0A}
|
||||||
|
color4 #${palette.base0D}
|
||||||
|
color5 #${palette.base0E}
|
||||||
|
color6 #${palette.base0C}
|
||||||
|
color7 #${palette.base04}
|
||||||
|
color8 #${palette.base03}
|
||||||
|
color9 #${palette.base08}
|
||||||
|
color10 #${palette.base0B}
|
||||||
|
color11 #${palette.base0A}
|
||||||
|
color12 #${palette.base0D}
|
||||||
|
color13 #${palette.base0E}
|
||||||
|
color14 #${palette.base0C}
|
||||||
|
color15 #${palette.base07}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Per-palette ghostty colors. features/apps/ghostty/config/config uses an
|
||||||
|
# optional include (?-prefix) of this file; without it the include was
|
||||||
|
# silently skipped and ghostty rendered with its built-in defaults across
|
||||||
|
# every palette. ghostty has no Stylix target.
|
||||||
|
xdg.configFile."nomarchy/current/theme/ghostty.conf".text = ''
|
||||||
|
background = ${palette.base00}
|
||||||
|
foreground = ${palette.base05}
|
||||||
|
cursor-color = ${palette.base05}
|
||||||
|
selection-background = ${palette.base02}
|
||||||
|
selection-foreground = ${palette.base05}
|
||||||
|
palette = 0=#${palette.base01}
|
||||||
|
palette = 1=#${palette.base08}
|
||||||
|
palette = 2=#${palette.base0B}
|
||||||
|
palette = 3=#${palette.base0A}
|
||||||
|
palette = 4=#${palette.base0D}
|
||||||
|
palette = 5=#${palette.base0E}
|
||||||
|
palette = 6=#${palette.base0C}
|
||||||
|
palette = 7=#${palette.base04}
|
||||||
|
palette = 8=#${palette.base03}
|
||||||
|
palette = 9=#${palette.base08}
|
||||||
|
palette = 10=#${palette.base0B}
|
||||||
|
palette = 11=#${palette.base0A}
|
||||||
|
palette = 12=#${palette.base0D}
|
||||||
|
palette = 13=#${palette.base0E}
|
||||||
|
palette = 14=#${palette.base0C}
|
||||||
|
palette = 15=#${palette.base07}
|
||||||
|
'';
|
||||||
|
|
||||||
# Ensure theme-specific hyprland config exists
|
# Ensure theme-specific hyprland config exists
|
||||||
# Lookup priority: palette apps/ > feature themes/ > nord fallback
|
# Lookup priority: palette apps/ > feature themes/ > nord fallback
|
||||||
xdg.configFile."nomarchy/current/theme/apps/hyprland.conf" = lib.mkIf (!hasHyprlandConf) {
|
xdg.configFile."nomarchy/current/theme/apps/hyprland.conf" = lib.mkIf (!hasHyprlandConf) {
|
||||||
@@ -83,6 +139,12 @@ in
|
|||||||
path = ../palettes;
|
path = ../palettes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# 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
|
# Nautilus python extensions
|
||||||
xdg.dataFile."nautilus-python/extensions/localsend.py".source = ../../core/home/config/nautilus-python/extensions/localsend.py;
|
xdg.dataFile."nautilus-python/extensions/localsend.py".source = ../../core/home/config/nautilus-python/extensions/localsend.py;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,31 +54,16 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
apps = {
|
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 {
|
btop = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Whether to load btop theme from active theme.";
|
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
|
for file in $out/bin/*; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
wrapProgram "$file" \
|
wrapProgram "$file" \
|
||||||
--prefix PATH : "$deps" \
|
--prefix PATH : "$deps"
|
||||||
--set NOMARCHY_PATH "/etc/nixos"
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ STATE_FILE="$STATE_DIR/state.json"
|
|||||||
mkdir -p "$STATE_DIR"
|
mkdir -p "$STATE_DIR"
|
||||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||||
|
|
||||||
THEME_NAME=$(jq -r '.theme // "nord"' "$STATE_FILE")
|
THEME_NAME=$(jq -r '.theme // "summer-night"' "$STATE_FILE")
|
||||||
|
|
||||||
# Resolve themes directory (Built-in from Nix store via Home Manager, or user extra)
|
# Resolve themes directory (Built-in from Nix store via Home Manager, or user extra)
|
||||||
if [ -d "$HOME/.config/nomarchy/themes/$THEME_NAME" ]; then
|
if [ -d "$HOME/.config/nomarchy/themes/$THEME_NAME" ]; then
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Sets the specified image as the current background
|
# Sets the specified image as the current background.
|
||||||
|
# Updates state.json so the choice survives the next rebuild — without
|
||||||
|
# that write, themes/engine/files.nix re-resolves the wallpaper from
|
||||||
|
# `nomarchy.wallpaper` on the next home-manager switch and silently
|
||||||
|
# falls back to the active theme's default background, undoing the
|
||||||
|
# user's pick.
|
||||||
|
|
||||||
if [[ -z $1 ]]; then
|
if [[ -z $1 ]]; then
|
||||||
echo "Usage: nomarchy-theme-bg-set <path-to-image>" >&2
|
echo "Usage: nomarchy-theme-bg-set <path-to-image>" >&2
|
||||||
@@ -9,7 +14,22 @@ if [[ -z $1 ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
BACKGROUND="$1"
|
BACKGROUND="$1"
|
||||||
CURRENT_BACKGROUND_LINK="$HOME/.config/nomarchy/current/background"
|
|
||||||
|
if [[ ! -f "$BACKGROUND" ]]; then
|
||||||
|
echo "Background image not found: $BACKGROUND" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
STATE_DIR="$HOME/.config/nomarchy"
|
||||||
|
STATE_FILE="$STATE_DIR/state.json"
|
||||||
|
CURRENT_BACKGROUND_LINK="$STATE_DIR/current/background"
|
||||||
|
|
||||||
|
mkdir -p "$STATE_DIR"
|
||||||
|
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||||
|
|
||||||
|
# Persist the choice for the next rebuild.
|
||||||
|
TMP_JSON=$(mktemp)
|
||||||
|
jq --arg wp "$BACKGROUND" '.wallpaper = $wp' "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
|
||||||
|
|
||||||
# Create symlink to the new background
|
# Create symlink to the new background
|
||||||
ln -nsf "$BACKGROUND" "$CURRENT_BACKGROUND_LINK"
|
ln -nsf "$BACKGROUND" "$CURRENT_BACKGROUND_LINK"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
{
|
{
|
||||||
find ~/.config/nomarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n'
|
find ~/.config/nomarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n' 2>/dev/null || true
|
||||||
find "$NOMARCHY_PATH/themes/palettes/" -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
|
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
|
} | sort -u | while read -r name; do
|
||||||
echo "$name" | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
|
echo "$name" | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ mkdir -p "$STATE_DIR"
|
|||||||
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
|
||||||
|
|
||||||
if [ ! -d "$THEMES_DIR/$THEME_NAME" ]; then
|
if [ ! -d "$THEMES_DIR/$THEME_NAME" ]; then
|
||||||
echo "Theme '$THEME_NAME' not found in $THEMES_DIR"
|
echo "Theme '$THEME_NAME' not found in $THEMES_DIR" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TMP_JSON=$(mktemp)
|
TMP_JSON=$(mktemp)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
TEMPLATES_DIR="$NOMARCHY_PATH/themes/templates"
|
TEMPLATES_DIR="$HOME/.local/share/nomarchy/templates"
|
||||||
USER_TEMPLATES_DIR="$HOME/.config/nomarchy/themes/templates"
|
USER_TEMPLATES_DIR="$HOME/.config/nomarchy/themes/templates"
|
||||||
NEXT_THEME_DIR="$HOME/.config/nomarchy/current/theme"
|
NEXT_THEME_DIR="$HOME/.config/nomarchy/current/theme"
|
||||||
COLORS_FILE="$NEXT_THEME_DIR/colors.toml"
|
COLORS_FILE="$NEXT_THEME_DIR/colors.toml"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
# Pre-realise every theme's Home Manager generation into the Nix store so
|
# Pre-realise every theme's Home Manager generation into the Nix store so
|
||||||
# future `nomarchy-theme-set` swaps are cache hits — no Stylix rebuild, no
|
# future `nomarchy-theme-set` swaps are cache hits — no Stylix rebuild, no
|
||||||
# downloads. Run once after install (the installer wires this up) and again
|
# downloads. Run once after install (the installer's final message prompts
|
||||||
# after adding or updating palettes.
|
# you to do so) and again after adding or updating palettes.
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,12 @@ in
|
|||||||
|
|
||||||
services.displayManager.defaultSession = lib.mkDefault "hyprland-uwsm";
|
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 = {
|
services.displayManager.autoLogin = {
|
||||||
enable = lib.mkDefault true;
|
enable = lib.mkDefault false;
|
||||||
user = lib.mkDefault "nomarchy";
|
user = lib.mkDefault "nomarchy";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
242,240,229
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
14,31,41
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
0,23,46
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
210,196,219
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# A port of forest night by sainnhe
|
|
||||||
# https://github.com/sainnhe/forest-night
|
|
||||||
|
|
||||||
font_family JetBrainsMono Nerd Font
|
|
||||||
font_size 12.0
|
|
||||||
|
|
||||||
foreground #323d43
|
|
||||||
background #fdf6e3
|
|
||||||
selection_foreground #e4e1cd
|
|
||||||
selection_background #d3dbc8
|
|
||||||
url_color #415c6d
|
|
||||||
cursor #7fbbb3
|
|
||||||
|
|
||||||
# black
|
|
||||||
color0 #4a555b
|
|
||||||
color8 #525c62
|
|
||||||
|
|
||||||
# red
|
|
||||||
color1 #e68183
|
|
||||||
color9 #e68183
|
|
||||||
|
|
||||||
# green
|
|
||||||
color2 #a7c080
|
|
||||||
color10 #a7c080
|
|
||||||
|
|
||||||
# yellow
|
|
||||||
color3 #dbbc7f
|
|
||||||
color11 #dbbc7f
|
|
||||||
|
|
||||||
# blue
|
|
||||||
color4 #7fbbb3
|
|
||||||
color12 #7fbbb3
|
|
||||||
|
|
||||||
# magenta
|
|
||||||
color5 #d699b6
|
|
||||||
color13 #d699b6
|
|
||||||
|
|
||||||
# cyan
|
|
||||||
color6 #83c092
|
|
||||||
color14 #83c092
|
|
||||||
|
|
||||||
# white
|
|
||||||
color7 #f3efda
|
|
||||||
color15 #f3efda
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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