This is currently broken so don't use this commit for building.
I'm not sure if I'll use the .mod.nix approach or just go with flake-file
tbh. Not really keen on the appearance of it.
MQT74AV47PUYNCX27OMFK6BFN7PP4DX46JAACN2EPRYXUXV7EL3AC WD33BD7BJRIZYCBPRECY4VFPSJNY65FFXVWN2FUE5ZHBJA7LUX6QC 3JJNSJEGODVFHBIC2AOLOB3JZSFPPQBENWFLKHTSOGH7YGVW6GTQC VS6GXDU54DGMQJW7OCOZZCVEGE6F5SWXTW7NCDJUH67JN5MQQESQC 5G7WRBMWKG6DMCOHE6WQHTYZACUHO2UPBZRWN72CFH7P45NN5E7QC HWCVAVGHMRTGNMV7WXWM6XB6KMMZQCMZQXWHQV4MPKXZOCAOGXKAC RTBMBSBABSGTRICJ4AWBKWO3JJHBRKV6FGOMYPDD7X6SS6X35ZIQC VTPA57TTA3C4RUCTOAO6HYOKGBKGBDSWMJMWA7CWSCFAAV7GMEJQC ZBZAKBTWMFRBVZ66JMLA22M3JRULPIH7G7OBU2AT3AHHEA3E4KOQC NC7UU7NY53VETOZLU2DEE34J2DA2SLQXD6LZM3XIHT6SKB6EPKKQC RVV2KSCIXFU4HLXELZV67QDRTKG7OU6FZHFMPYO6HN6ISXPALX6QC TGXVRQU53E3KY7XVAXCIZIKSJMHQXMK4QKWZQ7UJHRFEFGZEAAKQC 4SBHPC3PZB66O3Y6UU2IZDF5Y5XJCD7WV4QTOVAGUSY5FT3VPZGQC B25Y6ZESZM3UB3G7F2QCANOQN6FH5O4A5G7SFUJ5LLWWR7DZNHDQC 4NRVIEMX33UUJASFFO4JXHNPN3EY3VB7K2FZXJVQGZMCAKEMXGYQC XPKDQGFUFF4BT32ODPEJRZGBEOGZVDRAEN2EOWU7DBIN2QQX6KUAC KOXYNEPMHOWPUOUDAIDAVC2ZPUCLFGN23BM6QJ4UIDGVN73SUO7AC KE4A6XYYKVBEVCWG4TPFRAO5EYJHCJB25VWNXB2NZNXNEPSDKH6QC ISKRPSY5MU5XKIV7FTBDYDPRKV6ONINH2SDIXY7QDGTXNCYN7YFQC {config.flake.modules.nixosModules.virtualisation ={virtualisation.docker.rootless = {enable = true;setSocketVariable = true; # Doesn't seem to work?};# We can do this instead.environment.sessionVariables = {DOCKER_HOST = "unix:///run/user/1000/docker.sock";};};}
{ lib, inputs, ... }:letinherit (lib) const;# Extend nixpkgs.lib with nix-darwin.lib, then our custom lib.lib' = inputs.os.lib.extend (const <| const <| inputs.os-darwin.lib);libCustom = lib'.extend <| import ../lib inputs;in{# Add yuzu-dendritic to the flake outputsconfig.flake.nixosConfigurations.yuzu-dendritic =libCustom.mkNixos "x86_64-linux" "yuzu-dendritic";}
{config.flake.modules.nixosModules.zram-swap ={zramSwap.enable = true;};}
{config.flake.modules.homeModules.zoxide ={programs.zoxide = {enable = true;flags = [ "--cmd cd" ];integrations.nushell.enable = true;};};}
{config.flake.modules.homeModules.yubikey ={ pkgs, ... }:letpackages = [pkgs.yubikey-personalizationpkgs.yubioath-flutterpkgs.age-plugin-yubikey];in{inherit packages;};config.flake.modules.nixosModules.yubikey ={ pkgs, ... }:{services.udev.packages = [pkgs.yubikey-personalization];security.pam.services = {login = {u2fAuth = true;enableGnomeKeyring = true;};sudo.u2fAuth = true;su.u2fAuth = true;sshd.u2fAuth = true;};services.pcscd.enable = true;programs.yubikey-manager.enable = true;programs.yubikey-touch-detector = {enable = true;libnotify = true;};};config.flake.modules.darwinModules.yubikey ={ pkgs, ... }:{services.udev.packages = [pkgs.yubikey-personalization];security.pam.services = {login = {u2fAuth = true;enableGnomeKeyring = true;};sudo.u2fAuth = true;su.u2fAuth = true;sshd.u2fAuth = true;};services.pcscd.enable = true;programs.yubikey-manager.enable = true;programs.yubikey-touch-detector = {enable = true;libnotify = true;};};}
{config.flake.modules.nixosModules.xdg-portal ={ pkgs, ... }:{xdg.portal = {enable = true;config = {common.default = "*";# [1/2] Niri screensharing fixes.niri.default = "*";niri."org.freedesktop.impl.portal.ScreenCast" = [ "gnome" ];};extraPortals = [# [2/2] Niri screensharing fixes.pkgs.xdg-desktop-portal-gnome];};environment.systemPackages = [pkgs.xdg-utils];environment.sessionVariables = {# Hint Electron apps to use Wayland.NIXOS_OZONE_WL = "1";XDG_CURRENT_DESKTOP = "niri";XDG_SESSION_TYPE = "wayland";XDG_SESSION_DESKTOP = "niri";};};}
{config.flake.modules.nixosModules.waybar = {programs.waybar.enable = true;};config.flake.modules.homeModules.waybar ={ config, ... }:letinherit (config) theme;in{xdg.config.files."waybar/config.jsonc".text =# jsonc''{"layer": "top","height": ${toString theme.margin.big},"margin-top": ${toString theme.margin.normal},"margin-left": ${toString theme.margin.normal},"margin-right": ${toString theme.margin.normal},"modules-left": ["niri/workspaces"],"modules-center": ["niri/window"],"modules-right": ["tray","pulseaudio","cpu","memory","disk","custom/gpu","battery","clock"],"niri/workspaces": {"current-only": true,"format": "{index}"},"niri/window": {"max-length": 50,"separate-outputs": true,"rewrite": {"(.*) (—|-) (Zen Browser|Brave)": " $1","(.*) - Discord": " $1","(.*) — nu": " $1"}},"tray": {"reverse-direction": true,"spacing": 5},"pulseaudio": {"format": "{format_source} {icon} {volume}%","format-muted": "{format_source} ","format-source": "","format-source-muted": "","format-icons": {"default": ["", "", ""]},"on-click": "pwvucontrol","on-click-right": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle","tooltip": true,"tooltip-format": "Volume: {volume}%\nClick: Open audio manager\nRight-click: Mute toggle"},"cpu": {"format": " {usage}%","tooltip": true,"tooltip-format": "CPU Usage: {usage}%\nLoad: {load}","interval": 2,"on-click": "kitty btop","states": {"warning": 70,"critical": 90}},"memory": {"format": " {used:0.1f}G/{total:0.1f}G","tooltip": true,"tooltip-format": "Memory: {used:0.1f}G/{total:0.1f}G ({percentage}%)\nAvailable: {avail:0.1f}G","interval": 2,"on-click": "kitty btop","states": {"warning": 70,"critical": 90}},"disk": {"format": " {percentage_used}%","path": "/","tooltip": true,"tooltip-format": "Disk: {used}/{total} ({percentage_used}%)\nAvailable: {free}","interval": 300,"states": {"warning": 70,"critical": 90}},"custom/gpu": {"exec": "bash -c 'if command -v nvidia-smi >/dev/null; then nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits | head -1; elif command -v radeontop >/dev/null; then radeontop -d - -l 1 | grep -o \"gpu [0-9]*\" | cut -d\" \" -f2; else echo \"N/A\"; fi'","format": " {}%","interval": 5,"tooltip": true,"tooltip-format": "GPU Usage: {}%\nClick: Open system monitor","on-click": "kitty btop","states": {"warning": 70,"critical": 90}},"battery": {"format": "{icon} {capacity}%","format-charging": " {capacity}%","format-plugged": " {capacity}%","format-icons": ["", "", "", "", "","", "", "", "", ""],"tooltip": true,"tooltip-format": "Battery: {capacity}%\nTime: {time}\nHealth: {health}%","states": {"warning": 30,"critical": 15}},"clock": {"interval": 1,"format": " {:%Y-%m-%d | %H:%M:%S}","tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"}}'';xdg.config.files."waybar/style.css".text =with theme.withHash; # css''* {border: none;border-radius: 0;font-family: "${theme.font.sans.name}";font-size: ${toString theme.font.size.small}px;margin: 0;padding: 0;}#waybar {background:linear-gradient(rgba(${builtins.concatStringsSep ", " (map toString theme.withRgb.base00)}, ${toString theme.opacity.verylow}), rgba(${builtins.concatStringsSep ", " (map toString theme.withRgb.base00)}, ${toString theme.opacity.verylow})) padding-box,linear-gradient(225deg, ${base0B}, ${base09}) border-box;color: ${base07};border: ${toString (theme.border.small)}px solid transparent;border-radius: ${toString (theme.radius.big)}px;}#window {color: ${base07};}#workspaces button {padding: 0 ${toString theme.padding.normal}px;border: ${toString (theme.border.small)}px solid transparent;border-radius: ${toString theme.radius.normal}px;}#workspaces button.empty {color: ${base03};}#workspaces button.active {color: ${base07};background: rgba(${builtins.concatStringsSep ", " (map toString theme.withRgb.base00)}, 0.45) padding-box;}#tray, #pulseaudio, #cpu, #memory, #disk, #battery, #clock, #custom-gpu {margin: 0;margin-left: ${toString theme.margin.normal}px;padding: 0 ${toString theme.padding.normal}px;color: ${base07}; /* Use highest contrast text */}#cpu, #memory, #disk, #custom-gpu {min-width: 36px;}#battery.critical:not(.charging) {animation-name: blink;animation-duration: ${toString theme.duration.s.short}s;animation-timing-function: linear;animation-iteration-count: infinite;animation-direction: alternate;color: ${base08};}#cpu.warning, #memory.warning, #disk.warning {color: ${base0A};}#cpu.critical, #memory.critical, #disk.critical, #custom-gpu.critical {color: ${base08};animation-name: blink;animation-duration: ${toString theme.duration.s.normal}s;animation-timing-function: linear;animation-iteration-count: infinite;animation-direction: alternate;}#cpu.warning, #memory.warning, #disk.warning, #custom-gpu.warning {color: ${base0A};}@keyframes blink {to {color: ${base05};}}'';};}
{ pkgs, keys, config, lib, self, inputs, ... }: letinherit (lib) mkIf types;in {options.customUsersHjem = {enable = lib.mkEnableOption "hjem users (for dendritic hosts)";passwordFile = lib.mkOption {type = types.path;example = "/run/agenix/password";description = "Path to the password secret file";};primaryUserExtraGroups = lib.mkOption {type = with types; listOf str;default = [ "wheel" ];example = [ "wheel" "networkmanager" "docker" ];description = "Extra groups for jam";};};config = mkIf config.customUsersHjem.enable {age.secrets.password.rekeyFile = config.customUsersHjem.passwordFile;# Pass arguments to hjem moduleshjem.specialArgs = {inherit inputs;theme = config.theme;isDesktop = config.type == "desktop";isServer = config.type == "server";isGaming = config.isGaming or false;secrets = builtins.mapAttrs (name: secret: secret) config.age.secrets;};# Propagate all homeModules to all hjem users# Append modules to make theme and other NixOS values available as config optionshome.extraModules = builtins.attrValues self.modules.homeModules ++ [# First, define the options({ lib, ... }: {options.theme = lib.mkOption {type = lib.types.attrs;default = { };description = "Theme configuration from NixOS";};options.isDesktop = lib.mkOption {type = lib.types.bool;default = false;description = "Whether this is a desktop system";};options.isServer = lib.mkOption {type = lib.types.bool;default = false;description = "Whether this is a server system";};options.isGaming = lib.mkOption {type = lib.types.bool;default = false;description = "Whether this is a gaming system";};})# Then, set them from the NixOS config (via specialArgs)({ lib, theme, isDesktop, isServer, isGaming, ... }: {config.theme = theme;config.isDesktop = isDesktop;config.isServer = isServer;config.isGaming = isGaming;})];users.users = {root = {shell = pkgs.nushell;hashedPasswordFile = config.age.secrets.password.path;openssh.authorizedKeys.keys = keys.admins;};jam = {description = "Jam";isNormalUser = true;shell = pkgs.nushell;hashedPasswordFile = config.age.secrets.password.path;openssh.authorizedKeys.keys = keys.admins;extraGroups = config.customUsersHjem.primaryUserExtraGroups;};};hjem.users = {root = {user = "root";directory = "/home/root";};jam = {user = "jam";directory = "/home/jam";};};};}
{config.flake.modules.nixosModules.unfree ={ config, lib, ... }:letinherit (lib.lists) elem;inherit (lib.options) mkOption;inherit (lib.types) listOf str;in{options.unfree.allowedPackageNames = mkOption {type = listOf str;default = [ ];description = "List of unfree package names to allow";example = ["discord""vscode"];};config.nixpkgs.config.allowUnfreePredicate =pkg: elem (lib.getName pkg) config.unfree.allowedPackageNames;};config.flake.modules.darwinModules.unfree ={ config, lib, ... }:letinherit (lib.lists) elem;inherit (lib.options) mkOption;inherit (lib.types) listOf str;in{options.unfree.allowedPackageNames = mkOption {type = listOf str;default = [ ];description = "List of unfree package names to allow";example = ["discord""vscode"];};config.nixpkgs.config.allowUnfreePredicate =pkg: elem (lib.getName pkg) config.unfree.allowedPackageNames;};}
{config.flake.modules.nixosModules.thunar ={ pkgs, ... }:{# TODO: Might need desktop entry?environment.systemPackages = [pkgs.thunarpkgs.tumbler];};}
{ config, lib, pkgs, ... }: letinherit (lib) mkIf;set-wallpaper = pkgs.writeTextFile {name = "set-wallpaper";text = ''#!/usr/bin/env nudef main [url_or_path: string] {if ($url_or_path | str starts-with "http") {let wallpaper_dir = $"($env.HOME)/wallpapers"mkdir $wallpaper_dir# Extract filename from URLlet filename = ($url_or_path | url parse | get path | path basename)let wallpaper_file = $"($wallpaper_dir)/($filename)"if ($wallpaper_file | path exists) {print $"Wallpaper already exists: ($wallpaper_file)"^${pkgs.swww}/bin/swww img $wallpaper_file o+e>| ignoreprint "Using existing wallpaper"return}print $"Downloading wallpaper to ($wallpaper_file)..."try {${pkgs.curl}/bin/curl -L -o $wallpaper_file $url_or_path^${pkgs.swww}/bin/swww img $wallpaper_file o+e>| ignoreprint $"Wallpaper downloaded and set: ($wallpaper_file)"} catch {print "Failed to download wallpaper"exit 1}} else {^${pkgs.swww}/bin/swww img $url_or_path o+e>| ignore}}'';executable = true;destination = "/bin/set-wallpaper";};pick-wallpaper = pkgs.writeTextFile {name = "pick-wallpaper";text = /* nu */ ''#!/usr/bin/env nudef main [] {let wallpaper_dir = $"($env.HOME)/wallpapers"mkdir $wallpaper_dirlet wallpapers = (ls $wallpaper_dir | where type == file | where name =~ '\.(jpg|png|jpeg|webp|gif)$')if ($wallpapers | is-empty) {print $"No wallpapers found in ($wallpaper_dir)"exit 1}# Use fzf with chafa for previewlet selected = ($wallpapers| get name| str join "\n"| ^${pkgs.fzf}/bin/fzf --preview $"${pkgs.chafa}/bin/chafa --size 40x20 {}" --preview-window=right:50% --prompt="Select wallpaper: ")if not ($selected | is-empty) {^${pkgs.swww}/bin/swww img $selected o+e>| ignoreprint $"Wallpaper set: (($selected | path basename))"# Regenerate pywal colors if using pywal schemelet theme_config = try {open $"($env.HOME)/nixos/modules/theme/theme.json"} catch {{ mode: "light", scheme: "pywal" }}let using_pywal = $theme_config.scheme == "pywal"if $using_pywal {print "Regenerating pywal colors..."let is_dark = $theme_config.mode == "dark"try {# Clear pywal cache to force regeneration^rm -rf ~/.cache/wal# Build args: start with base, then append mode-specific oneslet base_args = ["-n" "--backend" "wal" "-i" $selected]let mode_args = if $is_dark {["--saturate" "0.5"]} else {["--saturate" "0.75" "-l"]}^${pkgs.pywal}/bin/wal ...($base_args | append $mode_args) err> /dev/null^cp ~/.cache/wal/colors.json $"($env.HOME)/nixos/modules/theme/pywal-colors.json"print "Colors regenerated!"try {^rebuild --quiet} catch { |e|print "Failed to rebuild."}print "Rebuilt system to apply colors."} catch { |e|print $"Warning: Failed to regenerate colors: ($e.msg)"}}}}'';executable = true;destination = "/bin/pick-wallpaper";};save-wallpaper = pkgs.writeTextFile {name = "save-wallpaper";text = ''#!/usr/bin/env nudef main [url: string] {if not ($url | str starts-with "http") {print "Error: Please provide a valid URL"exit 1}let wallpaper_dir = $"($env.HOME)/wallpapers"mkdir $wallpaper_dir# Extract filename from URLlet filename = ($url | url parse | get path | path basename)let wallpaper_file = $"($wallpaper_dir)/($filename)"if ($wallpaper_file | path exists) {print $"Wallpaper already exists: ($wallpaper_file)"return}print $"Downloading wallpaper to ($wallpaper_file)..."try {${pkgs.curl}/bin/curl -L -o $wallpaper_file $urlprint $"Wallpaper saved: ($wallpaper_file)"} catch {print "Failed to download wallpaper"exit 1}}'';executable = true;destination = "/bin/save-wallpaper";};in {environment.systemPackages = [pkgs.swwwpkgs.chafa # Terminal image viewer for previews.set-wallpaperpick-wallpapersave-wallpaper];# home-manager.sharedModules = [{# # Desktop entry for fuzzel.# xdg.desktopEntries.pick-wallpaper = {# name = "Pick Wallpaper";# icon = "preferences-desktop-wallpaper";# exec = "pick-wallpaper";# terminal = true;# };# }];}
{ pkgs, config, lib, ... }: letinherit (lib) mkIf;themeToggleScript = pkgs.writeScriptBin "tt" /* nu */ ''#!${pkgs.nushell}/bin/nudef print-notify [message: string, progress: int = -1] {print $"(ansi purple)[Theme Switcher](ansi rst) ($message)"let is_error = ($message | str downcase | str contains "error")let urgency = if $is_error { "critical" } else { "normal" }let timeout = 5000let args = if $progress >= 0 and $progress < 100 {["--hint" $"int:value:($progress)"]} else {[]}^${pkgs.libnotify}/bin/notify-send ...$args --urgency=($urgency) --expire-time=($timeout) "Theme Switcher" $"($message)"}def generate-pywal-colors [wallpaper: string, is_dark: bool] {# Clear pywal cache to force regeneration.^${pkgs.coreutils}/bin/rm -rf ~/.cache/wal# Build args: start with base args, then append mode-specific ones.let base_args = ["-n" "--backend" "wal" "-i" $wallpaper]let mode_args = if $is_dark {["--saturate" "0.5"]} else {["--saturate" "0.75" "-l"]}^${pkgs.pywal}/bin/wal ...($base_args | append $mode_args) err> /dev/null^${pkgs.coreutils}/bin/cp ~/.cache/wal/colors.json $"($env.HOME)/nixos/modules/theme/pywal-colors.json"}def toggle-theme [theme?: string] {# Determine current theme and scheme from theme.json file.let theme_config = try {open $"($env.HOME)/nixos/modules/theme/theme.json"} catch {{ mode: "light", scheme: "pywal" }}let current_theme = $theme_config.modelet using_pywal = $theme_config.scheme == "pywal"# Use provided theme or error if not provided.let new_theme = if $theme != null {if $theme in ["light", "dark"] {$theme} else {print-notify $"Invalid theme: '($theme)'. Use 'light' or 'dark'."return}} else {print-notify "Theme argument required. Use 'light' or 'dark'."return}print-notify $"Switching to ($new_theme) theme."# If using pywal, regenerate colors from current wallpaper.if $using_pywal {print-notify "Regenerating pywal colors..." 20let wallpaper = try {^${pkgs.swww}/bin/swww query | lines | first | parse "{monitor}: image: {path}" | get path.0} catch {null}if $wallpaper != null and ($wallpaper | path exists) {try {generate-pywal-colors $wallpaper ($new_theme == "dark")print-notify $"Regenerated ($new_theme) mode pywal colors." 30} catch { |e|print-notify $"Warning: Failed to regenerate pywal colors: ($e.msg)" 30}} else {print-notify "Warning: Could not detect current wallpaper" 30}}# Update environment and persist to theme.json.print-notify "Updating theme configuration..." 40$env.THEME_MODE = $new_themelet theme_json = $"($env.HOME)/nixos/modules/theme/theme.json"{ mode: $new_theme, scheme: $theme_config.scheme } | to json | save $theme_json --forceprint-notify $"($new_theme | str capitalize) mode activated." 50# Rebuild configuration to apply themes.print-notify $"Rebuilding configuration to apply ($new_theme) theme." 75try {^rebuild --quiet} catch { |e|print-notify "Error: Rebuild failed, run manually in a terminal."exit 1}print-notify $"Switch to the ($new_theme) theme completed!" 100}def switch-scheme [scheme: string] {# Validate scheme.if $scheme not-in ["pywal", "gruvbox"] {print-notify $"Invalid scheme: '($scheme)'. Use 'pywal' or 'gruvbox'."return}print-notify $"Switching to ($scheme) color scheme."# Get current theme configuration from theme.json file.let theme_config = try {open $"($env.HOME)/nixos/modules/theme/theme.json"} catch {{ mode: "light", scheme: "pywal" }}# If switching to pywal, generate colors from current wallpaper.if $scheme == "pywal" {print-notify "Generating pywal colors from current wallpaper..." 25let is_dark = $theme_config.mode == "dark"let wallpaper = try {^${pkgs.swww}/bin/swww query | lines | first | parse "{monitor}: image: {path}" | get path.0} catch {null}if $wallpaper != null and ($wallpaper | path exists) {try {generate-pywal-colors $wallpaper $is_darkprint-notify "Generated pywal colors." 50} catch { |e|print-notify $"Warning: Failed to generate colors: ($e.msg)" 50}} else {print-notify "Warning: Could not detect current wallpaper" 50}}# Update environment and persist to theme.json.$env.THEME_SCHEME = $schemelet theme_json = $"($env.HOME)/nixos/modules/theme/theme.json"{ mode: $theme_config.mode, scheme: $scheme } | to json | save $theme_json --forceprint $"Updated THEME_SCHEME to ($scheme)"# Rebuild configuration to apply new scheme.print-notify $"Rebuilding configuration to apply ($scheme) scheme..." 75try {^rebuild --quiet} catch { |e|print-notify "Error: Rebuild failed, run manually in a terminal."exit 1}print-notify $"Switch to ($scheme) scheme completed!" 100}# Main tt command - handles both light/dark and scheme switching.def --wrapped main [arg?: string # Theme mode (dark/light) or color scheme (pywal/gruvbox)....rest: string # Arbitrary arguments.]: nothing -> nothing {if $arg == null {print "Usage: tt <dark|light|pywal|gruvbox>"return}match $arg {"dark" | "light" => { toggle-theme $arg }"pywal" | "gruvbox" => { switch-scheme $arg }_ => { print $"Invalid option: '($arg)'. Use: dark, light, pywal, or gruvbox." }}}'';in {environment.systemPackages = mkIf config.useTheme [themeToggleScript];}
{ pkgs, config, ... }:letinherit (config.theme) is_dark;themes = {alacritty.dark = "gruvbox_material_hard_dark";alacritty.light = "gruvbox_material_hard_light";ghostty.dark = "Gruvbox Dark Hard";ghostty.light = "Gruvbox Light Hard";rio.dark = "gruvbox-dark-hard";rio.light = "gruvbox-light-hard";zellij.dark = "gruvbox-dark";zellij.light = "gruvbox-light";starship.dark = "dark_theme";starship.light = "light_theme";vivid.dark = "gruvbox-dark";vivid.light = "gruvbox-light";nushell.dark = "dark-theme";nushell.light = "light-theme";helix.dark = "gruvbox_dark_hard";helix.light = "gruvbox_light_hard";gtk.dark = {name = "Gruvbox-Dark";package = pkgs.gruvbox-gtk-theme;};gtk.light = {name = "Adwaita";package = pkgs.gnome-themes-extra;};qt.dark = {name = "adwaita-dark";platformTheme = "adwaita";};qt.light = {name = "adwaita";platformTheme = "adwaita";};icons.dark = {name = "Gruvbox-Plus-Dark";package = pkgs.gruvbox-plus-icons;};icons.light = {name = "Papirus-Light";package = pkgs.papirus-icon-theme;};};# Helper for the current theme.get_theme = program: if is_dark then themes.${program}.dark else themes.${program}.light;in{config.theme = {icons = get_theme "icons";# Program-specific theme names.alacritty = get_theme "alacritty";ghostty = get_theme "ghostty";rio = get_theme "rio";zellij = get_theme "zellij";starship = get_theme "starship";vivid = get_theme "vivid";nushell = get_theme "nushell";helix = get_theme "helix";gtk = get_theme "gtk";qt = get_theme "qt";# Expose raw theme definitions for flexibility.themes = themes;};}
{"mode": "dark","scheme": "gruvbox"}
{"wallpaper": "/home/jam/wallpapers/044.jpg","alpha": "100","special": {"background": "#211b29","foreground": "#f2ece1","cursor": "#f2ece1"},"colors": {"color0": "#211b29","color1": "#c145ba","color2": "#d37d7d","color3": "#deb49c","color4": "#e7d2b8","color5": "#e1a5c5","color6": "#ebcec3","color7": "#f2ece1","color8": "#a9a59d","color9": "#c145ba","color10": "#d37d7d","color11": "#deb49c","color12": "#e7d2b8","color13": "#e1a5c5","color14": "#ebcec3","color15": "#f2ece1"}}
{ config, pkgs, lib, ... }: letinherit (lib) mkIf;in{config.theme.font = {size.small = 12;size.term = 12;size.normal = 16;size.big = 20;# mono.name = "JetBrainsMono Nerd Font Mono";# mono.family = "JetBrainsMono Nerd Font";# mono.package = pkgs.nerd-fonts.jetbrains-mono;# mono.name = "Fira Code Nerd Font Mono";# mono.family = "Fira Code Nerd Font";# mono.package = pkgs.nerd-fonts.fira-code;# mono.name = "Hasklug Nerd Font Mono";# mono.family = "Hasklug Nerd Font";# mono.package = pkgs.nerd-fonts.hasklug;# mono.name = "Iosevka Nerd Font Mono";# mono.family = "Iosevka Nerd Font";# mono.package = pkgs.nerd-fonts.iosevka;# mono.name = "Cascadia Code NF";# mono.family = "Cascadia Code";# mono.package = pkgs.cascadia-code;# mono.name = "Hack Nerd Font Mono";# mono.family = "Hack Nerd Font";# mono.package = pkgs.nerd-fonts.hack;mono.name = "Maple Mono NF";mono.family = "Maple Mono";mono.package = pkgs.maple-mono.NF;sans.name = "Lexend";sans.family = "Lexend";sans.package = pkgs.lexend;};# Virtual console for login.config.console = {earlySetup = true;font = "Lat2-Terminus16";packages = [ pkgs.terminus_font ];};config.fonts.fontconfig.enable = mkIf (!config.useTheme) true;config.fonts.packages = mkIf config.useTheme [config.theme.font.mono.packageconfig.theme.font.sans.package# Fallback for emojis and icons.pkgs.noto-fontspkgs.noto-fonts-cjk-sanspkgs.noto-fonts-lgc-pluspkgs.noto-fonts-color-emoji];}
{ lib, config, ... }:letinherit (lib) mkOption types mkIf;in{imports = lib.collectNix ./.|> lib.remove ./default.nix;# Define theme as a top-level option that all modules can access via config.theme.options.theme = mkOption {type = types.attrs;default = {};description = "Global theme configuration";};options.useTheme = lib.mkEnableOption "use theming";config = mkIf config.useTheme {theme = {# Shared design system.radius = {small = 2;normal = 4;big = 6;verybig = 8;};border = {small = 2;normal = 4;big = 6;};margin = {small = 4;normal = 8;big = 32;};padding = {small = 4;normal = 8;};opacity = {opaque = 1.00;veryhigh = 0.99;high = 0.97;medium = 0.94;low = 0.90;verylow = 0.80;};duration = {s = {short = 0.5;normal = 1.0;long = 1.5;};ms = {short = 150;normal = 200;long = 300;};};};# home-manager.sharedModules = mkIf config.isDesktopNotWsl [# (homeArgs: {# programs.pywal = enabled;# xdg.desktopEntries.dark-mode = {# name = "Dark Mode";# icon = "preferences-color-symbolic";# exec = ''tt dark'';# terminal = false;# };# xdg.desktopEntries.light-mode = {# name = "Light Mode";# icon = "preferences-color-symbolic";# exec = ''tt light'';# terminal = false;# };# xdg.desktopEntries.pywal-mode = {# name = "Pywal Mode";# icon = "preferences-color-symbolic";# exec = ''tt pywal'';# terminal = false;# };# xdg.desktopEntries.gruvbox-mode = {# name = "Gruvbox Mode";# icon = "preferences-color-symbolic";# exec = ''tt gruvbox'';# terminal = false;# };# })# ];};}
{ lib, self, ... }:let# Global theme configuration - use `tt dark`/`tt light` to switch light/dark.# Use `tt pywal`/`tt gruvbox` to switch color scheme.# Both are controlled via theme.json file that gets updated by theme commands.themeConfig = builtins.fromJSON (builtins.readFile ./theme.json);is_dark = themeConfig.mode == "dark";color_scheme = themeConfig.scheme;# Pywal colors cache - single file updated when theme changes.# Stored in flake directory so Nix can access it (Nix can't read ~/.cache).pywal_cache = ./pywal-colors.json;# Parse pywal colors and convert to base16 format.# Pywal provides: background, foreground, color0-15.parse_pywal_colors = json: letcolors = builtins.fromJSON json;strip_hash = s: builtins.substring 1 6 s;in {base00 = strip_hash colors.colors.color0; # Background 0.base01 = strip_hash colors.colors.color1; # Background 1.base02 = strip_hash colors.colors.color2; # Background 2.base03 = strip_hash colors.colors.color3; # Background 3.base04 = strip_hash colors.colors.color4; # Foreground 3.base05 = strip_hash colors.colors.color5; # Foreground 2.base06 = strip_hash colors.colors.color6; # Foreground 1.base07 = strip_hash colors.colors.color7; # Foreground 0.base08 = strip_hash colors.colors.color8; # Main colour 1.base09 = strip_hash colors.colors.color9; # Main colour 2.base0A = strip_hash colors.colors.color10; # Main colour 3.base0B = strip_hash colors.colors.color11; # Main colour 4.base0C = strip_hash colors.colors.color12; # Main colour 5.base0D = strip_hash colors.colors.color13; # Main colour 6.base0E = strip_hash colors.colors.color14; # Main colour 7.base0F = strip_hash colors.colors.color15; # Main colour 8.};# Read pywal colors if cache exists and scheme is pywal.pywal_colors_raw = if builtins.pathExists pywal_cachethen builtins.readFile pywal_cacheelse null;pywal_colors = if pywal_colors_raw != nullthen parse_pywal_colors pywal_colors_rawelse gruvbox_colors.dark; # Fallback to gruvbox dark.# Gruvbox hard Base16 color definitions.gruvbox_colors = {dark = {base00 = "1d2021"; # Background.base01 = "3c3836"; # Background 1.base02 = "504945"; # Background 2.base03 = "665c54"; # Background 3.base04 = "bdae93"; # Foreground 2.base05 = "d5c4a1"; # Foreground 1.base06 = "ebdbb2"; # Foreground 0.base07 = "fbf1c7"; # Foreground.base08 = "fb4934"; # Red.base09 = "fe8019"; # Orange.base0A = "fabd2f"; # Yellow.base0B = "b8bb26"; # Green.base0C = "8ec07c"; # Aqua.base0D = "83a598"; # Blue.base0E = "d3869b"; # Purple.base0F = "d65d0e"; # Brown.};light = {base00 = "f9f5d7"; # Background.base01 = "ebdbb2"; # Background 1.base02 = "d5c4a1"; # Background 2.base03 = "bdae93"; # Background 3.base04 = "665c54"; # Foreground 2.base05 = "504945"; # Foreground 1.base06 = "3c3836"; # Foreground 0.base07 = "282828"; # Foreground.base08 = "9d0006"; # Red.base09 = "af3a03"; # Orange.base0A = "b57614"; # Yellow.base0B = "79740e"; # Green.base0C = "427b58"; # Aqua.base0D = "076678"; # Blue.base0E = "8f3f71"; # Purple.base0F = "d65d0e"; # Brown.};};# Current color scheme (two-dimensional: scheme + light/dark).# NOTE: pywal colors are pre-generated in the correct mode (light/dark) by tt command.colors = if color_scheme == "pywal"then pywal_colorselse (if is_dark then gruvbox_colors.dark else gruvbox_colors.light);variant = if is_dark then "dark" else "light";# Convert hex to RGB array helper for colors.hexToRgb = hex: letr = lib.fromHexString (builtins.substring 0 2 hex);g = lib.fromHexString (builtins.substring 2 2 hex);b = lib.fromHexString (builtins.substring 4 2 hex);in [ r g b ];in{config.theme = {inherit# Core theme state.is_darkcolor_schemevariant# Base16 color scheme.colors;# Color helpers with prefixes.withHash = lib.mapAttrs (name: value: "#${value}") colors;with0x = lib.mapAttrs (name: value: "0x${value}") colors;withRgb = lib.mapAttrs (name: value: hexToRgb value) colors;};}
{config.flake.modules.nixosModules.tailscale =letinterface = "ts0";domains = [ "taild29fec.ts.net" ];in{services.resolved.domains = domains;services.tailscale = {enable = true;useRoutingFeatures = "both";interfaceName = interface;};};config.flake.modules.darwinModules.tailscale =letinterface = "ts0";domains = [ "taild29fec.ts.net" ];in{services.resolved.domains = domains;services.tailscale = {enable = true;useRoutingFeatures = "both";interfaceName = interface;};};}
{config.flake.modules.nixosModules.sudo ={ config, lib, ... }:letinherit (lib) mkIf;in{security.sudo-rs = {enable = true;execWheelOnly = true;extraConfig = # sudo''Defaults pwfeedbackDefaults !lectureDefaults env_keep+="DISPLAY EDITOR PATH"${lib.optionalString config.isServer # sudo''Defaults timestamp_timeout = 0''}'';wheelNeedsPassword = mkIf (config.type != "desktop") false;};};config.flake.modules.darwinModules.sudo = {security.pam.services.sudo_local = {enable = true;touchIdAuth = true;};};}
{config.flake.modules.nixosModules.settings ={ pkgs, ... }:{networking.networkmanager = {enable = true;wifi.powersave = false;};users.users.jam.extraGroups = [ "networkmanager" ];# Bluetooth support.hardware.bluetooth = {enable = true;powerOnBoot = true;};services.blueman.enable = true;environment.systemPackages = [pkgs.lshw # Hardware info.pkgs.usbutils # USB device info.pkgs.pciutils # PCI device info.];# Network managerprograms.nm-applet.enable = true;};}
{config.flake.modules.homeModules.rust ={ pkgs, lib, config, inputs, ... }:letinherit (lib.modules) mkIf;inherit (lib.strings) makeLibraryPath;inherit (pkgs.stdenv) hostPlatform;in{environment.sessionVariables = {CARGO_NET_GIT_FETCH_WITH_CLI = "true";LIBRARY_PATH = mkIf hostPlatform.isDarwin <| makeLibraryPath [ pkgs.libiconv ];};packages = [# [1/2] For Forgejo Action runners.pkgs.cargo-binstallpkgs.cargo-nextestpkgs.dioxus-cli]++ lib.optionals config.isDesktop [(inputs.fenix.packages.${pkgs.stdenv.hostPlatform.system}.complete.withComponents [ # Nightly."cargo""clippy""miri""rustc""rust-analyzer""rustfmt""rust-std""rust-src"])pkgs.cargo-carefulpkgs.cargo-denypkgs.cargo-generatepkgs.cargo-machetepkgs.cargo-workspacespkgs.cargo-outdatedpkgs.kondo]++ lib.optionals config.isServer [# [2/2] For Forgejo Action runners.(inputs.fenix.packages.${pkgs.stdenv.hostPlatform.system}.complete.withComponents [ # Nightly."cargo""clippy""miri""rustc""rustfmt""rust-std""rust-src"])];};}
{config.flake.modules.homeModules.ripgrep ={ lib, pkgs, ... }:letinherit (lib.meta) getExe;package = pkgs.ripgrep;in{environment.sessionVariables = {RIPGREP_CONFIG_PATH = "/home/jam/.config/ripgrep/ripgreprc";};packages = [ package ];xdg.config.files."ripgrep/ripgreprc".text =''--line-number--smart-case'';};}
{ pkgs, config, lib, ... }: letinherit (lib) mkIf;rebuildScript = pkgs.writeScriptBin "rebuild" /* nu */ ''#!${pkgs.nushell}/bin/nudef print-notify [message: string, progress: int = -1] {print $"(ansi purple)[Rebuilder](ansi rst) ($message)"let is_error = ($message | str downcase | str contains "error")let urgency = if $is_error { "critical" } else { "normal" }let timeout = 5000let args = if $progress >= 0 and $progress < 100 {["--hint" $"int:value:($progress)"]} else {[]}^${pkgs.libnotify}/bin/notify-send ...$args --urgency=($urgency) --expire-time=($timeout) "Rebuilder" $"($message)"}def --wrapped main [host: string = "" # The host to build.--remote # Deploy to remote host using --target-host.--rollback # Rollback.--quiet (-q) # Run without output (for theme toggling).--try_attempts (-t): int = 0 # How many times to try the same rebuild....arguments # Extra arguments to pass to rebuild commands.]: nothing -> nothing {let host = if ($host | is-not-empty) {if $host != (hostname) and not $remote {if not $quiet { print-notify $"Error: Building local configuration for hostname that does not match the local machine." }exit 1}$host} else if $remote {if not $quiet { print-notify "Error: Hostname not specified for remote deployment." }exit 1} else {(hostname)}# Build locally (always).let os = (uname | get kernel-name)let config_path = if $os == "Darwin" { "/Users/jam/nixos" } else { "/home/jam/nixos" }# nh os/darwin switch [flake_path] --hostname [host] -- [nix_args]let base_args = ["switch"$config_path"--hostname" yuzu-dendritic # TODO: Change back to $host."--accept-flake-config" # Avoid asking for y/n approval for all settings."--fallback" # Build locally if substituters fail.] | append $arguments# Add target-host for remote deployments.let final_args = if $remote {$base_args | append ["--target-host" $"root@($host)"]} else {$base_args}let command = if $rollback {"rollback"} else {if $os == "Darwin" { "darwin" } else { "os" }}let final_args = if $rollback {[$host] | append $arguments} else {$final_args}# Execute final command.let action = if $remote { $"Deploying to: ($host)" } else { "Building locally:" }let platform = if $os == "Darwin" { "Darwin" } else { "NixOS" }if not $quiet { print-notify $"($action) ($platform). Configuration for: ($host)." 50 }if $remote {for attempts in 1..($try_attempts + 1) {try {NH_BYPASS_ROOT_CHECK=true NH_NO_CHECKS=true nh $command ...$final_argsbreak} catch { |e|if $attempts < $try_attempts {print-notify $"First attempt failed, retrying... (attempt ($attempts) of ($try_attempts))"} else {print-notify $"Error: Rebuild failed after ($try_attempts) attempts, run manually in a terminal."exit 1}}}} else {for attempts in 1..($try_attempts + 1) {try {sudo NH_BYPASS_ROOT_CHECK=true NH_NO_CHECKS=true nh $command ...$final_argsbreak} catch { |e|if $attempts < $try_attempts {print-notify $"First attempt failed, retrying... (attempt ($attempts) of ($try_attempts))"} else {print-notify $"Error: Rebuild failed after ($try_attempts) attempts, run manually in a terminal."exit 1}}}}if $rollback {if not $quiet { print-notify $"Rollback for ($host) succeeded." 100 }} else {if not $quiet { print-notify $"Rebuild for ($host) succeeded." 100 }}}'';in {# home-manager.sharedModules = mkIf config.isDesktopNotWsl [{# xdg.desktopEntries.rebuild = {# name = "Rebuild";# icon = "system-run";# exec = ''rebuild'';# terminal = false;# };# xdg.desktopEntries.rebuild-plum = {# name = "Rebuild plum";# icon = "system-run";# exec = ''rebuild --remote plum'';# terminal = false;# };# xdg.desktopEntries.rebuild-kiwi = {# name = "Rebuild kiwi";# icon = "system-run";# exec = ''rebuild --remote kiwi'';# terminal = false;# };# xdg.desktopEntries.rollback = {# name = "Rollback";# icon = "folder";# exec = ''rebuild rollback'';# terminal = false;# };# }];environment.systemPackages = [rebuildScript];}
{config.flake.modules.nixosModules.qt ={ config, ... }:letinherit (config) theme;in{qt = {enable = true;style = theme.qt.name;};};}
{config.flake.modules.nixosModules.power-menu ={ pkgs, config, ... }:letpower-menu = pkgs.writeShellScriptBin "power-menu" ''choice=$(echo -e "Shutdown\nReboot\nSleep\nHibernate\nLock" | ${pkgs.fuzzel}/bin/fuzzel --dmenu --prompt "Power: ")case "$choice" in"Shutdown")systemctl poweroff;;"Reboot")systemctl reboot;;"Sleep")hyprlock --quiet & systemctl suspend;;"Hibernate")hyprlock --quiet & systemctl hibernate;;"Lock")hyprlock --quiet --grace 60;;*)exit 1;;esac'';in /* mkIf config.isDesktopNotWsl */ {environment.systemPackages = [power-menu];};}
letcommonPackages ={ pkgs, ... }:[pkgs.ast-greppkgs.commapkgs.curlpkgs.forgejo-clipkgs.hyperfinepkgs.moreutilspkgs.nodejspkgs.opensslpkgs.pvpkgs.rsyncpkgs.tokeipkgs.treepkgs.turso-clipkgs.typospkgs.uutils-coreutils-noprefixpkgs.sqldpkgs.sqlitepkgs.wrkpkgs.xh];darwinPackages ={ pkgs, ... }:[pkgs.raycastpkgs.karabiner-elements];linuxPackages ={ pkgs, ... }:[pkgs.gccpkgs.gnumakepkgs.wget];in{config.flake.modules.nixosModules.packages ={ pkgs, ... }:{environment.systemPackages = commonPackages pkgs ++ linuxPackages pkgs;};config.flake.modules.nixosModules.packages-extra-desktop ={ pkgs, ... }:{environment.systemPackages = [pkgs.bitwarden-clipkgs.denopkgs.dockerpkgs.docker-composepkgs.exercismpkgs.moonpkgs.pnpmpkgs.protopkgs.bitwarden-desktoppkgs.bravepkgs.obs-studiopkgs.thunderbirdpkgs.wasistlos];};config.flake.modules.nixosModules.packages-extra-wsl ={ pkgs, ... }:{environment.systemPackages = [pkgs.bitwarden-clipkgs.denopkgs.dockerpkgs.docker-composepkgs.exercismpkgs.moonpkgs.pnpmpkgs.proto];};config.flake.modules.darwinModules.packages ={ pkgs, ... }:{environment.systemPackages = commonPackages pkgs ++ darwinPackages pkgs;};}
{config.flake.modules.homeModules.nushell ={ pkgs, config, lib, ... }:letinherit (lib.strings) readFile;in{programs.nushell = {enable = true;aliases = {m = "moon";mp = "mprocs";ko = "kondo";td = "hx ${config.directory}/notes/todo.md";notes = "hx ${config.directory}/notes";random = "hx ${config.directory}/notes/random.md";rm = "rm --recursive --verbose";cp = "cp --recursive --verbose --progress";mv = "mv --verbose";mk = "mkdir";tree = "eza --tree --git-ignore --group-directories-first";swarm = "mprocs claude claude claude claude claude";fj = "fj --host https://git.plumj.am";oops = "nix run nixpkgs#sqlite -- ${config.directory}/.config/nushell/history.sqlite3 'DELETE FROM history WHERE rowid IN (SELECT rowid FROM history ORDER BY rowid DESC LIMIT 5);'";};extraConfig =# nu''$env.config.edit_mode = "vi"$env.config.buffer_editor = "hx"$env.config.show_banner = false$env.config.footer_mode = "auto"$env.config.recursion_limit = 100$env.config.error_style = "fancy"$env.config.completions.algorithm = "substring"$env.config.completions.sort = "smart"$env.config.completions.case_sensitive = false$env.config.completions.quick = true$env.config.completions.partial = true$env.config.completions.use_ls_colors = true$env.config.ls.use_ls_colors = true$env.config.ls.clickable_links = true$env.config.rm.always_trash = false$env.config.table.mode = "compact"$env.config.table.index_mode = "always"$env.config.table.show_empty = true$env.config.table.trim.methodology = "wrapping"$env.config.table.trim.wrapping_try_keep_words = true$env.config.table.trim.truncating_suffix = "..."$env.config.history.file_format = "sqlite"$env.config.history.max_size = 10000000$env.config.history.sync_on_enter = true$env.config.cursor_shape.emacs = "block"$env.config.cursor_shape.vi_insert = "line"$env.config.cursor_shape.vi_normal = "block"$env.config.float_precision = 2$env.config.use_ansi_coloring = "auto"$env.config.explore.help_banner = true$env.config.explore.exit_esc = true$env.config.explore.command_bar_text = "#C4C9C6"$env.config.explore.highlight.bg = "yellow"$env.config.explore.highlight.fg = "black"$env.config.explore.table.split_line = "#404040"$env.config.explore.table.cursor = true$env.config.explore.table.line_index = true$env.config.explore.table.line_shift = true$env.config.explore.table.line_head_top = true$env.config.explore.table.line_head_bottom = true$env.config.explore.table.show_head = true$env.config.explore.table.show_index = true$env.config.explore.config.cursor_color.bg = "yellow"$env.config.explore.config.cursor_color.fg = "black"$env.config.keybindings = [{name: quit_shellmodifier: controlkeycode: char_dmode: emacsevent: null}{name: quit_shellmodifier: controlkeycode: char_dmode: vi_insertevent: null}{name: quit_shellmodifier: controlkeycode: char_dmode: vi_normalevent: null}]$env.config.hooks.env_change.PWD = [{ |before, after| zellij-update-tabname }]$env.config.hooks.display_output = {if (term size).columns >= 100 { tee { table --expand | print } } | try { if $in != null { $env.last = $in } }}$env.config.hooks.pre_prompt = [{if not (which direnv | is-empty) {direnv export json | from json | default {} | load-env$env.PATH = ($env.PATH | split row (char env_sep))}}]${readFile ./nushell.menus.nu}${readFile ./nushell.functions.nu}'';envFile = with config.theme.withHash;#nu''use std/config ${config.theme.nushell}$env.config.color_config = (${config.theme.nushell})$env.CARAPACE_BRIDGES = "zsh,fish,bash,inshellisense,clap"$env.LS_COLORS = (${pkgs.vivid}/bin/vivid generate ${config.theme.vivid})let theme_json = $"($env.HOME)/nixos/modules/theme/theme.json"if ($theme_json | path exists) {let theme = (open $theme_json)$env.THEME_MODE = $theme.mode$env.THEME_SCHEME = $theme.scheme} else {$env.THEME_MODE = "${config.theme.variant}"$env.THEME_SCHEME = "${config.theme.color_scheme}"}# Custom Nushell prompt.def prompt [--transient]: nothing -> string {let exit_code = $env.LAST_EXIT_CODElet status = if not ($exit_code == 0) or $transient {$"(ansi '${base0D}')┫(ansi rst)(if $exit_code == 0 { ansi '${base0D}' } else { ansi '${base08}' })($exit_code)(ansi rst)(ansi '${base0D}')┣(ansi rst)"} else {$"(ansi '${base0D}')━(ansi rst)"}let host = if ($env.SSH_CONNECTION? | is-not-empty) {$" (ansi '${base0B}')(hostname)(ansi rst)"} else { "" }let jj_root = try {jj workspace root err> /dev/null} catch { "" }let pwd = pwd | path expandlet dir = if ($jj_root | is-not-empty) {let subpath = $pwd | path relative-to $jj_rootlet subpath = if ($subpath | is-not-empty) {$"(ansi '${base0E}') ⟶ (ansi rst)(ansi '${base0B}')($subpath)(ansi rst)"}$"($jj_root | path basename)($subpath)"} else {let pwd = if ($pwd | str starts-with $env.HOME) {"~" | path join ($pwd | path relative-to $env.HOME)} else { $pwd }$pwd}let directory = $"(ansi '${base0A}')($dir)(ansi rst)"let jj_info = if (which jj | is-not-empty) {try {let jj_output = (^jj --quiet --color always --ignore-working-copy log --no-graph --revisions @ --template 'separate(" ",bookmarks.join(", "),if(empty, label("empty", "(empty)")),coalesce(surround("\"", "\"",if(description.first_line().substr(0, 22).starts_with(description.first_line()),description.first_line().substr(0, 22),description.first_line().substr(0, 21) ++ "…")),label(if(empty, "empty"), "")),change_id.shortest(),commit_id.shortest(),if(conflict, label("conflict", "(conflict)")),if(divergent, label("divergent prefix", "(divergent)")),if(hidden, label("hidden prefix", "(hidden)")),if(immutable, label("immutable", "(immutable)")),)' err> /dev/null | str trim)if ($jj_output | is-not-empty) {$" ($jj_output)"} else { "" }} catch { "" }} else { "" }let ms = ($env.CMD_DURATION_MS | into int)let duration = if $transient or $ms > 1000 {let secs = $ms / 1000 | math floorif $transient and $ms < 1000 {$" (ansi '${base0A}')($ms)ms"} else {$" (ansi '${base0A}')($secs)s"}} else { "" }let bar = $"(ansi '${base0D}')(ansi attr_bold)━(ansi rst)"let prompt_line = [(char nl)$bar$status$bar$host" "$directory" "(if ($jj_info | is-not-empty) {[$"(ansi '${base0D}')━┫(ansi rst)"$jj_info$" (ansi '${base0D}')┣━(ansi rst)"] | str join} else {[$bar$bar$bar] | str join})$duration(char nl)] | str join$prompt_line}$env.PROMPT_COMMAND = { || prompt }$env.PROMPT_COMMAND_RIGHT = ""$env.TRANSIENT_PROMPT_COMMAND = { || prompt --transient }$env.TRANSIENT_PROMPT_COMMAND_RIGHT = ""$env.PROMPT_INDICATOR = " "$env.PROMPT_INDICATOR_VI_NORMAL = $env.PROMPT_INDICATOR$env.PROMPT_INDICATOR_VI_INSERT = $env.PROMPT_INDICATOR$env.PROMPT_MULTILINE_INDICATOR = $env.PROMPT_INDICATOR$env.TRANSIENT_PROMPT_INDICATOR = $env.PROMPT_INDICATOR$env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = $env.PROMPT_INDICATOR$env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = $env.PROMPT_INDICATOR$env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = $env.PROMPT_INDICATOR'';};};}
# menus$env.config.menus = [{name: completion_menuonly_buffer_difference: falsemarker: "| "type: {layout: idemin_completion_width: 0max_completion_width: 150max_completion_height: 25padding: 0border: falsecursor_offset: 0description_mode: "prefer_right"min_description_width: 0max_description_width: 50max_description_height: 10description_offset: 1correct_cursor_pos: true}style: {text: greenselected_text: green_reversedescription_text: yellowmatch_text: { attr: u }selected_match_text: { attr: ur }}}{name: history_menuonly_buffer_difference: truemarker: "? "type: {layout: listpage_size: 10}style: {text: greenselected_text: green_reverse}}{name: help_menuonly_buffer_difference: truemarker: "? "type: {layout: descriptioncolumns: 4col_width: 20col_padding: 2selection_rows: 4description_rows: 10}style: {text: greenselected_text: green_reversedescription_text: yellow}}{name: commands_menuonly_buffer_difference: falsemarker: "# "type: {layout: columnarcolumns: 4col_width: 20col_padding: 2}style: {text: greenselected_text: green_reversedescription_text: yellow}source: { |buffer, position|$nu.scope.commands| where name =~ $buffer| each { |it| {value: $it.name description: $it.usage} }}}{name: vars_menuonly_buffer_difference: truemarker: "# "type: {layout: listpage_size: 10}style: {text: greenselected_text: green_reversedescription_text: yellow}source: { |buffer, position|$nu.scope.vars| where name =~ $buffer| sort-by name| each { |it| {value: $it.name description: $it.type} }}}{name: commands_with_descriptiononly_buffer_difference: truemarker: "# "type: {layout: descriptioncolumns: 4col_width: 20col_padding: 2selection_rows: 4description_rows: 10}style: {text: greenselected_text: green_reversedescription_text: yellow}source: { |buffer, position|$nu.scope.commands| where name =~ $buffer| each { |it| {value: $it.name description: $it.usage} }}}]
def zellij-update-tabname [] {if ("ZELLIJ" in $env) {let tab_name = if ((pwd) == $env.HOME) {"~"} else {(pwd | path parse | get stem)};zellij action rename-tab $tab_name;}}def "cargo search" [query: string, --limit=10] {^cargo search $query --limit $limit| lines| each {|line| if ($line | str contains "#") {$line | parse --regex '(?P<name>.+) = "(?P<version>.+)" +# (?P<description>.+)'} else {$line | parse --regex '(?P<name>.+) = "(?P<version>.+)"'}}| flatten}def "cargo update-all" [--force] {cargo install --list| parse "{package} v{version}:"| get package| each {|p|if $force {cargo install --locked --force $p} else {cargo install --locked $p}}}def pwd [] {$env.PWD | str replace $nu.home-path '~'}def "git summary" [--count (-n): int = 999999] {try {git log $"--pretty=%h»¦«%aN»¦«%s»¦«%aD" $"-($count)"| lines| split column "»¦«" sha1 committer desc merged_at| histogram committer merger| sort-by merger| reverse| table -i 1 # start index from 1} catch {print "Error: Make sure you're in a git repository"}}
{config.flake.modules.nixosModules.nix-ld ={programs.nix-ld.enable = true;};}
{config.flake.modules.homeModules.niri ={ inputs, pkgs, config, lib, theme, ... }:letinherit (lib) genAttrs const merge;cfg = config // {inherit theme;};in{programs.nushell.aliases.ns = "niri-session";rum.desktops.niri = {enable = true;package = inputs.niri.packages.${pkgs.stdenv.hostPlatform.system}.niri-unstable;config = ''window-rule {match app-id=r#"^*$"#opacity ${toString cfg.theme.opacity.opaque}draw-border-with-background falseclip-to-geometry truegeometry-corner-radius ${toString (cfg.theme.radius.big * 1.0)}}window-rule {match app-id=r#"^(zen-.*|org\.qutebrowser\.qutebrowser|brave-browser)$"#opacity ${toString cfg.theme.opacity.opaque}}window-rule {match title=r#"^.*YouTube|Picture-in-Picture.*"#opacity ${toString cfg.theme.opacity.opaque}}window-rule {match app-id=r#"kitty"#}window-rule {match app-id=r#"^steam_app_*"#opacity ${toString cfg.theme.opacity.opaque}open-fullscreen trueborder {off}focus-ring {off}shadow {off}geometry-corner-radius 0clip-to-geometry false}layer-rule {match namespace=r#"waybar|notifications|launcher"#shadow {oncolor "#${toString cfg.theme.colors.base09}33"draw-behind-window truesoftness 15offset x=0 y=0}}layer-rule {match namespace=r#"waybar"#opacity ${toString cfg.theme.opacity.opaque}}layer-rule {match namespace=r#"notifications|launcher"#opacity ${toString cfg.theme.opacity.opaque}}input {focus-follows-mousewarp-mouse-to-focusdisable-power-key-handlingmouse {accel-profile "flat"left-handed}touchpad {accel-profile "flat"left-handed}trackball {accel-profile "flat"left-handed}trackpoint {accel-profile "flat"left-handed}}layout {always-center-single-column trueempty-workspace-above-first truegaps ${toString cfg.theme.margin.normal}preset-column-widths {proportion 0.20proportion 0.25proportion 0.33proportion 0.50proportion 0.66proportion 0.75proportion 0.80}preset-window-heights {proportion 0.50proportion 0.66proportion 1.00}border {onwidth ${toString cfg.theme.border.big}active-gradient from="${cfg.theme.colors.base0B}" to="${cfg.theme.colors.base09}" angle=45inactive-color "#${cfg.theme.colors.base00}"urgent-color "#${cfg.theme.colors.base08}"}shadow {oncolor "#${toString cfg.theme.colors.base09}DD"draw-behind-window falsesoftness 10offset x=0 y=0}focus-ring {off}}animations {slowdown 2.25window-open {curve "ease-out-cubic"duration-ms ${toString cfg.theme.duration.ms.normal}}window-close {curve "ease-out-expo"duration-ms ${toString cfg.theme.duration.ms.short}}window-movement {spring damping-ratio=1.0 stiffness=800 epsilon=0.0001}window-resize {spring damping-ratio=1.0 stiffness=1200 epsilon=0.0001}}cursor {hide-when-typing}hotkey-overlay {skip-at-startup}gestures {hot-corners {off}}screenshot-path "/home/jam/Pictures/Screenshots/screenshot_%Y-%m-%d_%H-%M-%S.png"'';binds = {"Mod+slash".action = "show-hotkey-overlay";"Mod+Shift+slash".action = "show-hotkey-overlay";"Mod+Q" = {action = "close-window";parameters.repeat = false;};"Mod+Tab" = {action = "toggle-overview";parameters.repeat = false;};"Mod+1".action = "focus-workspace 1";"Mod+2".action = "focus-workspace 2";"Mod+3".action = "focus-workspace 3";"Mod+4".action = "focus-workspace 4";"Mod+5".action = "focus-workspace 5";"Mod+6".action = "focus-workspace 6";"Mod+7".action = "focus-workspace 7";"Mod+8".action = "focus-workspace 8";"Mod+Ctrl+H".action = "focus-monitor-left";"Mod+Ctrl+L".action = "focus-monitor-right";"Mod+F".action = "expand-column-to-available-width";"Mod+Shift+F".action = "maximize-column";"Mod+Shift+C".action = "center-visible-columns";"Mod+Shift+T".action = "toggle-window-floating";"Mod+Shift+Ctrl+T".action = "switch-focus-between-floating-and-tiling";"Mod+W".action = "toggle-column-tabbed-display";"Mod+R".action = "switch-preset-window-width";"Mod+Shift+R".action = "switch-preset-window-height";"Mod+Minus".action = "set-column-width \"-10%\"";"Mod+Equal".action = "set-column-width \"+10%\"";"Mod+Shift+Minus".action = "set-window-height \"-10%\"";"Mod+Shift+Equal".action = "set-window-height \"+10%\"";"Mod+H".action = "focus-column-or-monitor-left";"Mod+L".action = "focus-column-or-monitor-right";"Mod+J".action = "focus-workspace-down";"Mod+K".action = "focus-workspace-up";"Mod+Shift+H".action = "move-column-left-or-to-monitor-left";"Mod+Shift+L".action = "move-column-right-or-to-monitor-right";"Mod+Shift+J".action = "move-window-down-or-to-workspace-down";"Mod+Shift+K".action = "move-window-up-or-to-workspace-up";"Mod+Comma".action = "consume-window-into-column";"Mod+Period".action = "expel-window-from-column";"Mod+Shift+Comma".action = "consume-or-expel-window-left";"Mod+Shift+Period".action = "consume-or-expel-window-right";"Ctrl+Backspace".spawn = [ "fuzzel" ];"Mod+Shift+P".spawn = [ "power-menu" ];"Mod+T".spawn = [ "process-monitor" ];"Mod+P".spawn = [ "process-killer" ];"Mod+D".spawn = [ "todo-scratchpad" ];"Mod+S".spawn = [ "random-scratchpad" ];"Mod+C".spawn = [ "nu -c cliphist list | fuzzel --dmenu | cliphist decode | wl-copy" ];};spawn-at-startup = [[ "waybar" ][ "swww-daemon" ][ "mako" ]];};};config.flake.modules.nixosModules.niri ={ pkgs, ... }:{environment.systemPackages = [ pkgs.xwayland-satellite ];# TODO: Add desktop entries.# xdg.desktopEntries.screenshot = {# name = "Screenshot";# icon = "camera-web";# exec = "niri msg action screenshot";# terminal = false;# };# xdg.desktopEntries.screenshot-window = {# name = "Screenshot Window";# icon = "camera-web";# exec = "niri msg action screenshot-window --write-to-disk";# terminal = false;# };};}
{config.flake.modules.homeModules.nh ={ pkgs, ... }:letpackages = [pkgs.nhpkgs.nix-output-monitor];in{inherit packages;};}
{ inputs, lib, ... }:letinherit (builtins) pathExists readDir;inherit (lib)filterAttrshasSuffixmapAttrs'nameValuePairremoveSuffix;newHostsDir = ../new-hosts;hasNewHosts = pathExists newHostsDir;# Read all .host.nix files from new-hosts directorynewHostsFiles =if hasNewHoststhenreadDir newHostsDir|> filterAttrs (name: type: type == "regular" && hasSuffix ".host.nix" name)|> mapAttrs' (name: _value:nameValuePair (removeSuffix ".host.nix" name) (import (newHostsDir + "/${name}") { inherit lib inputs; }))else { };in{# Each .host.nix file should return a flake-parts module that sets config.flake.*imports = builtins.attrValues newHostsFiles;}
{config.flake.modules.homeModules.mprocs ={ pkgs, lib, config, ... }:letinherit (lib) mkIf;package = pkgs.mprocs;inmkIf config.isDesktop {packages = [ package ];xdg.config.files."mprocs/mprocs.yaml".text = # yaml''hide_keymap_window = true;proc_list_width = 18;keymap_procs = {<C-j>:c: batchcmds:- { c: next-proc }- { c: focus-term }<C-k>:c: batchcmds:- { c: prev-proc }- { c: focus-term }}keymap_term:<C-j>:c: batchcmds:- { c: focus-procs }- { c: next-proc }- { c: focus-term }<C-k>:c: batchcmds:- { c: focus-procs }- { c: prev-proc }- { c: focus-term }'';};}
{config.flake.modules.nixosModules.mouse ={ lib, config, ... }:letinherit (lib) mkIf;in mkIf config.isDesktop {services.libinput = {enable = true;mouse.leftHanded = true;touchpad.leftHanded = true;};};}
{config.flake.modules.nixosModules.locale ={time.timeZone = "Europe/Warsaw";i18n.defaultLocale = "en_US.UTF-8";};}
{ pkgs, config, lib, ... }:{options.linux-kernel = {enableZen = lib.mkEnableOption "linux_zen kernel";};config ={boot.kernelPackages =if config.linux-kernel.enableZen thenpkgs.linuxKernel.packages.linux_zenelsepkgs.linuxPackages_latest;# Credits from me:# - https://github.com/RGBCube/ncc/blob/c5714110d951f57e66d5ee47a244c0a93f3406a1/modules/linux/kernel.nix# From RGBCube:# - https://github.com/NotAShelf/nyx/blob/main/modules/core/common/system/security/kernel.nix# - "hsslister" user - raf (NotAShelf) - "I actually forgot the dudes GitHub"boot.kernel.sysctl = {# The Magic SysRq key is a key combo that allows users connected to the# system console of a Linux kernel to perform some low-level commands.# Disable it, since we don't need it, and is a potential security concern."kernel.sysrq" = 0;# Hide kptrs even for processes with CAP_SYSLOG.# Also prevents printing kernel pointers."kernel.kptr_restrict" = 2;# Disable bpf() JIT (to eliminate spray attacks)."net.core.bpf_jit_enable" = false;# Disable ftrace debugging."kernel.ftrace_enabled" = false;# Avoid kernel memory address exposures via dmesg (this value can also be set by CONFIG_SECURITY_DMESG_RESTRICT)."kernel.dmesg_restrict" = 1;# Prevent unintentional fifo writes."fs.protected_fifos" = 2;# Prevent unintended writes to already-created files."fs.protected_regular" = 2;# Disable SUID binary dump."fs.suid_dumpable" = 0;# Disallow profiling at all levels without CAP_SYS_ADMIN."kernel.perf_event_paranoid" = 3;# Require CAP_BPF to use bpf."kernel.unprvileged_bpf_disabled" = 1;};# https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.htmlboot.kernelParams = [# Make stack-based attacks on the kernel harder."randomize_kstack_offset=on"# Controls the behavior of vsyscalls. This has been defaulted to none back in 2016 - break really old binaries for security."vsyscall=none"# Reduce most of the exposure of a heap attack to a single cache."slab_nomerge"# Only allow signed modules."module.sig_enforce=1"# Blocks access to all kernel memory, even preventing administrators from being able to inspect and probe the kernel."lockdown=confidentiality"# Enable buddy allocator free poisoning."page_poison=1"# Performance improvement for direct-mapped memory-side-cache utilization, reduces the predictability of page allocations."page_alloc.shuffle=1"# Disable sysrq keys. sysrq is seful for debugging, but also insecure."sysrq_always_enabled=0"# Ignore access time (atime) updates on files, except when they coincide with updates to the ctime or mtime."rootflags=noatime"# Linux security modules."lsm=landlock,lockdown,yama,integrity,apparmor,bpf,tomoyo,selinux"# Prevent the kernel from blanking plymouth out of the fb."fbcon=nodefer"];boot.blacklistedKernelModules = [# Obscure network protocols."af_802154" # IEEE 802.15.4"appletalk" # Appletalk"atm" # ATM"ax25" # Amatuer X.25"can" # Controller Area Network"dccp" # Datagram Congestion Control Protocol"decnet" # DECnet"econet" # Econet"ipx" # Internetwork Packet Exchange"n-hdlc" # High-level Data Link Control"netrom" # NetRom"p8022" # IEEE 802.3"p8023" # Novell raw IEEE 802.3"psnap" # SubnetworkAccess Protocol"rds" # Reliable Datagram Sockets"rose" # ROSE"sctp" # Stream Control Transmission Protocol"tipc" # Transparent Inter-Process Communication"x25" # X.25# Old or rare or insufficiently audited filesystems."adfs" # Active Directory Federation Services"affs" # Amiga Fast File System"befs" # "Be File System""bfs" # BFS, used by SCO UnixWare OS for the /stand slice"cifs" # Common Internet File System"cramfs" # compressed ROM/RAM file system"efs" # Extent File System"erofs" # Enhanced Read-Only File System"exofs" # EXtended Object File System"f2fs" # Flash-Friendly File System"freevxfs" # Veritas filesystem driver"gfs2" # Global File System 2"hfs" # Hierarchical File System (Macintosh)"hfsplus" # Same as above, but with extended attributes."hpfs" # High Performance File System (used by OS/2)"jffs2" # Journalling Flash File System (v2)"jfs" # Journaled File System - only useful for VMWare sessions"ksmbd" # SMB3 Kernel Server"minix" # minix fs - used by the minix OS"nfs" # Network File System"nfsv3" # Network File System (v3)"nfsv4" # Network File System (v4)"nilfs2" # New Implementation of a Log-structured File System"omfs" # Optimized MPEG Filesystem"qnx4" # Extent-based file system used by the QNX4 OS."qnx6" # Extent-based file system used by the QNX6 OS."squashfs" # compressed read-only file system (used by live CDs)"sysv" # implements all of Xenix FS, SystemV/386 FS and Coherent FS."udf" # https://docs.kernel.org/5.15/filesystems/udf.html"vivid" # Virtual Video Test Driver (unnecessary)# Disable Thunderbolt and FireWire to prevent DMA attacks"firewire-core""thunderbolt"];};}
{config.flake.modules.homeModules.kitty ={ lib, config, ... }:letinherit (lib) mkIf;inmkIf config.isDesktop {programs.kitty = {enable = true;settings = with config.theme.withHash; {font_family = config.theme.font.mono.name;font_size = config.theme.font.size.term;allow_remote_control = true;confirm_os_window_close = 0;scrollback_lines = 100000;scrollback_pager = "bat --chop-long-lines";mouse_hide_wait = 0;enable_audio_bell = false;strip_trailing_spaces = "always";# Performancerepaint_delay = 1;input_delay = 1;sync_to_monitor = false;hide_window_decorations = true;window_padding_width = config.theme.padding.small;window_border_width = "0pt";cursor = base05;cursor_text_color = base00;background = base00;foreground = base05;active_tab_background = base00;active_tab_foreground = base05;inactive_tab_background = base01;inactive_tab_foreground = base05;selection_background = base02;selection_foreground = base00;url_color = base0D;color0 = base00;color1 = base08;color2 = base0B;color3 = base0A;color4 = base0D;color5 = base0E;color6 = base0C;color7 = base05;color8 = base03;color9 = base08;color10 = base0B;color11 = base0A;color12 = base0D;color13 = base0E;color14 = base0C;color15 = base07;color16 = base09;color17 = base0F;color18 = base01;color19 = base02;color20 = base04;color21 = base06;};};};}
{config.flake.modules.nixosModules.keyboard ={ pkgs, ... }:{environment.systemPackages = [ pkgs.vial ];# Udev rule for Vial keyboard accessservices.udev.extraRules = ''# Universal Vial rule.KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{serial}=="*vial:f64c2b3c*", MODE="0660", GROUP="users", TAG+="uaccess", TAG+="udev-acl"# Specific rule for Corne v4.KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="4653", ATTRS{idProduct}=="0004", MODE="0660", GROUP="users", TAG+="uaccess", TAG+="udev-acl"'';};}
{config.flake.modules.homeModules.jq ={ pkgs, ... }:letpackage = pkgs.jq;in{packages = [ package ];};}
{config.flake.modules.nixosModules.immutable-users ={users.mutableUsers = false;};}
{config.flake.modules.nixosModules.hyprpicker ={ pkgs, ... }:{environment.systemPackages = [pkgs.hyprpicker];# TODO# xdg.desktopEntries.hyprpicker = {# name = "Colour Picker";# icon = "image-x-generic";# exec = "hyprpicker --format=hex --autocopy";# terminal = false;# };};}
{config.flake.modules.homeModules.hyprlock ={ config, lib, ... }:letinherit (lib) mkIf;yuzuMonitor = # mkIf (config.networking.hostName == "yuzu")"DP-2";in{programs.hyprlock = {enable = true;settings = {font-name = "${config.theme.font.sans.name} ${toString config.theme.font.size.small}";general = {hide_cursor = true;ignore_empty_input = true;immediate_render = true;};animations.enabled = false;background = [{color = "rgba(0,0,0,1.0)";path = "screenshot";brightness = 0.4;blur_passes = 3;}];input-field = [{size = "400, 50";position = "0, -80";monitor = yuzuMonitor;font_family = config.theme.font.mono.family;fade_on_empty = false;}];label = [{monitor = yuzuMonitor;text = ''cmd[update:18000000] echo "<b> "$(date +'%A, %-d %B %Y')" </b>"'';font_size = 24;font_family = config.theme.font.mono.family;position = "0, -150";halign = "center";valign = "top";}{monitor = yuzuMonitor;text = ''cmd[update:1000] echo "<b><big> $(date +"%H:%M:%S") </big></b>"'';font_size = 64;font_family = config.theme.font.mono.family;position = "0, 0";halign = "center";valign = "center";}{monitor = yuzuMonitor;text = "$USER";font_size = 16;font_family = config.theme.font.mono.family;position = "0, 100";halign = "center";valign = "bottom";}{monitor = yuzuMonitor;text = ''cmd[update:1000] echo "<b> Uptime: $(cat /proc/uptime | awk '{printf "%.0f", $1}' | awk '{days=int($1/86400); hours=int(($1%86400)/3600); minutes=int(($1%3600)/60); seconds=$1%60; printf "%dd %dh %dm %ds", days, hours, minutes, seconds}') </b>"'';font_size = 12;font_family = config.theme.font.mono.family;position = "0, -200";halign = "center";valign = "center";}];};};};}
rawHosts = readDir ../hosts|> mapAttrs' (name: _value: nameValuePair (removeSuffix ".nix" name) (import (../hosts + "/${name}") libCustom));
rawHosts =readDir ../hosts|> mapAttrs' (name: _value: nameValuePair (removeSuffix ".nix" name) (import (../hosts + "/${name}") libCustom));
|> groupBy ({ value, ... }:if value ? class && value.class == "nixos" then"nixosConfigurations"else"darwinConfigurations")|> mapAttrs (const (hosts:hosts|> map ({ name, value }: nameValuePair name value.config)|> listToAttrs));
|> groupBy ({ value, ... }:if value ? class && value.class == "nixos" then "nixosConfigurations" else "darwinConfigurations")|> mapAttrs (const (hosts: hosts |> map ({ name, value }: nameValuePair name value.config) |> listToAttrs));
agenix-rekey = inputs.agenix-rekey.configure {userFlake = inputs.self;nixosConfigurations = hostsByType.nixosConfigurations;};};
agenix-rekey = inputs.agenix-rekey.configure {userFlake = inputs.self;nixosConfigurations = hostsByType.nixosConfigurations;};}];
{ self, inputs, ... }:{config.flake.modules.homeModules.home ={ config, lib, pkgs, ... }:letinherit (lib.modules) mkAliasOptionModule;inherit (lib.options) mkOption;inherit (lib.types) bool;in{imports = [(mkAliasOptionModule [ "programs" ] [ "rum" "programs" ])(mkAliasOptionModule [ "desktops" ] [ "rum" "desktops" ])(mkAliasOptionModule [ "misc" ] [ "rum" "misc" ])];config = {xdg.cache.directory = "${config.directory}/.cache";xdg.config.directory = "${config.directory}/.config";xdg.data.directory = "${config.directory}/.local/share";xdg.state.directory = "${config.directory}/.local/state";};};config.flake.modules.nixosModules.home ={ lib, self, ... }:letinherit (lib.modules) mkAliasOptionModule;in{imports = [(mkAliasOptionModule [ "home" ] [ "hjem" ])];# Note: home.extraModules is set by users-hjem.nix to all homeModules# Note: inputs.home.nixosModules.default is already included in mkNixos'};config.flake.modules.darwinModules.home ={ lib, ... }:letinherit (lib.lists) singleton;inherit (lib.modules) mkAliasOptionModule;in{imports = [inputs.home.darwinModules.default(mkAliasOptionModule [ "home" ] [ "hjem" ]){ home.extraModules = singleton self.modules.homeModules.home; }];};}
{ inputs, ... }:{config.flake.modules.homeModules.home-module ={imports = [ inputs.home-modules.hjemModules.hjem-rum ];};}
{config.flake.modules.homeModules.helix ={ inputs, lib, config, pkgs, ... }:letinherit (lib)constgenAttrsmkIfelemmapAttrsoptionalAttrsattrValuesmerge;yaziPickerScript = pkgs.writeShellScript "yazi-picker.sh" ''#!/usr/bin/env bashpaths=$(yazi "$2" --chooser-file=/dev/stdout | while read -r; do printf "%q " "$REPLY"; done)if [[ -n "$paths" ]]; thenzellij action toggle-floating-paneszellij action write 27 # send <Escape> keyzellij action write-chars ":$1 $paths"zellij action write 13 # send <Enter> keyelsezellij action toggle-floating-panesfi'';package = inputs.helix.packages.${pkgs.stdenv.hostPlatform.system}.helix; # `.helix` follows the master branch.in{programs.helix = {enable = true;inherit package;settings.theme =if config.theme.color_scheme == "pywal" then "base16_custom" else config.theme.helix;# Pywal output doesn't have gradients like base16 needs.# So it's necessary to override a few colours.# Also added overrides for diagnostic colours which don't work well from Pywal.themes.base16_custom = {inherits = "base16_default";"comment".fg = if config.theme.is_dark then "#909090" else "#C0C0C0";# Selections.}// genAttrs [ "ui.selection" "ui.selection.primary" ] (const {bg = if config.theme.is_dark then "#707070" else "#E0E0E0";})# Cursorline and popups.//genAttrs [ "ui.cursorline.primary" "ui.cursorline.secondary" "ui.popup" "ui.popup.info" ](const {bg = if config.theme.is_dark then "#404040" else "#F0F0F0";})# Info.//genAttrs [ "hint" "info" "diagnostic" "diagnostic.hint" "diagnostic.info" "diagnostic.unnecessary" ](const {fg = if config.theme.is_dark then "#2B83A6" else "#3A8C9A"; # Muted teal.})# Warnings.// genAttrs [ "warning" "diagnostic.warning" "diagnostic.deprecated" ] (const {fg = if config.theme.is_dark then "#B58900" else "#9D8740"; # Muted yellow.})# Errors.// genAttrs [ "error" "diagnostic.error" ] (const {fg = if config.theme.is_dark then "#9D0006" else "#8F3F71"; # Muted red/brown.});settings.editor = {bufferline = "multiple";completion-timeout = 5;completion-replace = true;color-modes = true;cursorline = true;file-picker.hidden = false;idle-timeout = 0;shell = ["nu""--commands"];trim-trailing-whitespace = true;true-color = true;lsp.display-inlay-hints = true;inline-diagnostics.cursor-line = "hint";# Nightly options:word-completion.trigger-length = 3;# rainbow-brackets = true;};settings.editor.cursor-shape = {normal = "block";select = "underline";insert = "bar";};settings.editor.indent-guides = {character = "▏";render = true;};settings.editor.whitespace = {characters.tab = "→";render.tab = "all";};settings.keys =merge {normal."C-y" =":sh zellij run -n Yazi -c -f -x 10%% -y 10%% --width 80%% --height 80%% -- ${yaziPickerScript} open ...%{buffer_name}";}<| genAttrs [ "normal" "select" ] (const {D = "extend_to_line_end";});languages.language =letdenoFmtLanguages ={astro = "astro";css = "css";html = "html";javascript = "js";json = "json";jsonc = "jsonc";jsx = "jsx";markdown = "md";scss = "scss";svelte = "svelte";tsx = "tsx";typescript = "ts";vue = "vue";yaml = "yaml";}|> mapAttrs (name: extension:{inherit name;auto-format = true;formatter.command = "deno";formatter.args = ["fmt""--use-tabs""--no-semicolons""--indent-width""4""--unstable-component""--ext"extension"-"];}//optionalAttrs(elem name ["javascript""jsx""typescript""tsx"]){language-servers = ["deno""typos"];})|> attrValues;indenoFmtLanguages++ [{name = "rust";auto-format = true;language-servers = [{name = "rust-analyzer";except-features = [ "inlay-hints" ];}"typos"];indent = {tab-width = 3;unit = " ";};}{name = "nix";auto-format = false;formatter.command = "nix fmt";language-servers = ["nixd""typos"];}{name = "toml";auto-format = true;formatter.command = "taplo";formatter.args = ["fmt""--option""align_entries=true""--option""column_width=100""--option""compact_arrays=false""--option""reorder_inline_tables=true""--option""reorder_keys=true""-"];language-servers = ["taplo""typos"];}{name = "markdown";auto-format = true;language-servers = ["marksman""typos"];}{name = "just";auto-format = true;formatter.command = "just-formatter";language-servers = ["just-lsp""typos"];}# I can't get this working right now.# {# name = "rust";# debugger.name = "lldb-dap";# debugger.transport = "stdio";# debugger.command = "lldb-dap";# debugger.templates = [{# name = "binary";# request = "launch";# args.program = "{0}";# completion = [{# name = "binary";# completion = "filename";# }];# }];# }];languages.language-server = mkIf config.isDesktop {typos.command = "typos-lsp";deno = {command = "deno";args = [ "lsp" ];config.javascript = {enable = true;lint = true;unstable = true;suggest.imports.hosts."https://deno.land" = true;inlayHints.enumMemberValues.enabled = true;inlayHints.functionLikeReturnTypes.enabled = true;inlayHints.parameterNames.enabled = "all";inlayHints.parameterTypes.enabled = true;inlayHints.propertyDeclarationTypes.enabled = true;inlayHints.variableTypes.enabled = true;};};rust-analyzer = {except-features = [ "inlay-hints" ];config = {cargo.features = "all";check.command = "clippy";completion.callable.snippets = "add_parentheses";};};};};programs.nushell.aliases = {nvim = "echo 'no more neovim, use hx'";nv = "echo 'no more neovim, use hx'";vim = "echo 'no more vim, use hx'";v = "echo 'no more vim, use hx'";h = "hx";e = "hx"; # editor};packages = mkIf config.isDesktop [# Rust# rust-analyzer is in modules/common/rust.nixpkgs.lldb# Assemblerpkgs.asm-lsp# TypeScript etc.pkgs.deno# Nixpkgs.nixdpkgs.nixfmt# YAMLpkgs.yaml-language-server# JSONpkgs.vscode-json-languageserver# TOMLpkgs.taplo# Sveltepkgs.svelte-language-server# Markdownpkgs.marksmanpkgs.mdformat# Justpkgs.just-lsppkgs.just-formatter# Haskellpkgs.fourmolupkgs.haskell-language-server# Typospkgs.typos-lsp];};}
{config.flake.modules.homeModules.gtk ={ config, ... }:letpackages = [ config.theme.gtk.package ];in{rum.misc.gtk = {inherit packages;enable = true;settings = {application-prefers-dark-theme = true;font-name = "${config.theme.font.sans.name} ${toString config.theme.font.size.small}";theme-name = config.theme.gtk.name;icon-theme-name = config.theme.icons.name;};};};config.flake.modules.nixosModules.gtk ={programs.dconf.enable = true;};}
{config.flake.modules.nixosModules.graphics ={ config, ... }:{hardware.graphics = {enable = true;enable32Bit = true; # Required for Steam and 32-bit applications.};# For Wayland.services.xserver.videoDrivers = [ "nvidia" ];hardware.nvidia = {# Enable modesetting (required for Wayland).modesetting.enable = true;# For sleep handling.powerManagement.enable = true;powerManagement.finegrained = false;# Use open source kernel modules (recommended for RTX/GTX 16xx+).open = true;# Enable nvidia-settings menu.nvidiaSettings = true;package = config.boot.kernelPackages.nvidiaPackages.beta;};# Environment variables for NVIDIA on Wayland.environment.sessionVariables = {GBM_BACKEND = "nvidia-drm";__GLX_VENDOR_LIBRARY_NAME = "nvidia";WLR_NO_HARDWARE_CURSORS = "1"; # Cursor fix.};boot.kernelModules = [ "nvidia" "nvidia_modeset" "nvidia_uvm" "nvidia_drm" ];};}
{config.flake.modules.hjem.git ={ lib, ... }:letinherit (lib) mkDefault;in{rum.programs.git = {enable = true;integrations.difftastic.enable = true;ignore = # .gitignore''.claude/mprocs.log'';# TODO: commit signingsettings = {user.name = "PlumJam";user.email = "git@plumj.am";init.defaultBranch = "master";log.date = "iso";column.ui = "auto";commit.verbose = true;status.branch = true;status.showStash = true;status.showUntrackedFiles = "all";push.autoSetupRemote = true;pull.rebase = true;rebase.autoStash = true;rebase.missingCommitsCheck = "warn";rebase.updateRefs = true;rerere.enabled = true;fetch.fsckObjects = true;receive.fsckObjects = true;transfer.fsckObjects = true;branch.sort = "-committerdate";tag.sort = "-taggerdate";core.compression = 9;core.preloadindex = true;# TODO# core.editor = config.environment.variables.EDITOR;core.longpaths = true;diff.algorithm = "histogram";diff.colorMoved = "default";merge.conflictStyle = mkDefault "zdiff3";commit.gpgSign = true;tag.gpgSign = true;gpg.format = "ssh";credential.helper = # .gitconfig''"!gh auth git-credential""cache --timeout 21600" # 6 hours"oauth""oauth -device"'';core.sshCommand = "ssh -i ~/.ssh/id";url."ssh://git@github.com/".insteadOf = "gh:";};};};}
{config.flake.modules.homeModules.git ={ lib, ... }:letinherit (lib) mkDefault;in{programs.git = {enable = true;integrations.difftastic.enable = true;ignore = # .gitignore''.claude/mprocs.log'';# TODO: commit signingsettings = {user.name = "PlumJam";user.email = "git@plumj.am";init.defaultBranch = "master";log.date = "iso";column.ui = "auto";commit.verbose = true;status.branch = true;status.showStash = true;status.showUntrackedFiles = "all";push.autoSetupRemote = true;pull.rebase = true;rebase.autoStash = true;rebase.missingCommitsCheck = "warn";rebase.updateRefs = true;rerere.enabled = true;fetch.fsckObjects = true;receive.fsckObjects = true;transfer.fsckObjects = true;branch.sort = "-committerdate";tag.sort = "-taggerdate";core.compression = 9;core.preloadindex = true;# TODO# core.editor = config.environment.variables.EDITOR;core.longpaths = true;diff.algorithm = "histogram";diff.colorMoved = "default";merge.conflictStyle = mkDefault "zdiff3";commit.gpgSign = true;tag.gpgSign = true;gpg.format = "ssh";credential.helper = # .gitconfig''"!gh auth git-credential""cache --timeout 21600" # 6 hours"oauth""oauth -device"'';core.sshCommand = "ssh -i ~/.ssh/id";url."ssh://git@github.com/".insteadOf = "gh:";};};};}
{config.flake.modules.homeModules.gammastep ={ pkgs, ... }:letpackages = [pkgs.gammasteppkgs.geoclue2];in {inherit packages;programs.gammastep = {enable = true;settings.general = {location-provider = "geoclue2";temp-day = 4500;temp-night = 3500;};};};}
{config.flake.modules.nixosModules.games ={ pkgs, ... }:letpackages = [pkgs.steampkgs.gamemodepkgs.protontrickspkgs.winetricks];in {environment.systemPackages = packages;# Hardware acceleration and 32-bit graphics support.hardware.graphics = {enable = true;enable32Bit = true; # Required for Steam and 32-bit games};# Audio settings for gamingsecurity.rtkit.enable = true; # For low-latency audio# TODO: fix# xdg.desktopEntries.overwatch = {# name = "Overwatch";# icon = "com.valvesoftware.Steam";# exec = "steam steam://rungameid/2357570";# terminal = false;# };};}
{config.flake.modules.homeModules.fzf ={ pkgs, ... }:letpackage = pkgs.fzf;in{packages = [ package ];};}
{config.flake.modules.homeModules.fuzzel ={ config, ... }:{programs.fuzzel = with config.theme; {enable = true;settings.main = {icon-theme = icons.name;font = "${font.sans.name}:size=${toString font.size.small}";layer = "overlay";prompt = ''"❯ "'';terminal = "kitty";# output = mkIf (config.networking.hostName == "yuzu") "DP-1";horizontal-pad = padding.normal;vertical-pad = padding.normal;};settings.colors = {background = colors.base00 + "FF";text = colors.base07 + "FF";match = colors.base0A + "FF";selection = colors.base0A + "88"; # Lower opacity.selection-text = colors.base07 + "FF";selection-match = colors.base08 + "FF";border = colors.base0A + "FF";};settings.border = {radius = radius.verybig;width = border.small;};};};}
{ lib, ... }:{options.flake.modules = lib.mkOption {type = lib.types.attrsOf (lib.types.attrsOf lib.types.deferredModule);default = { };};}
{config.flake.modules.homeModules.fd ={ pkgs, ... }:letpackage = pkgs.fd;in{packages = [ package ];};}
{config.flake.modules.homeModules.eza ={ pkgs, ... }:letpackage = pkgs.eza;in{programs.nushell.aliases = {ls = "eza";sl = "eza";ll = "eza -la";la = "eza -a";lsa = "eza -a";lsl = "eza -l -a";};packages = [ package ];};}
{config.flake.modules.homeModules.env ={ pkgs, ... }:{environment.sessionVariables = {EDITOR = "hx";SHELL = "${pkgs.nushell}/bin/nu";TERMINAL = "zellij";TERM_PROGRAM = "zellij";};# TODO: Add sessionPath equivalent in hjem?# home-manager.sharedModules = [{# home.sessionPath = [# "$HOME/.local/bin"# "$HOME/.cargo/bin"# "$HOME/.bun/bin"# ];# }];};}
{config.flake.modules.homeModules.direnv ={programs.direnv = {enable = true;integrations = {nushell.enable = true;nix-direnv.enable = true;};};};}
{config.flake.modules.nixosModules.cursor ={ pkgs, ... }:letpackage = pkgs.bibata-cursors;in{environment.systemPackages = [ package ];environment.sessionVariables = {XCURSOR_THEME = "Bibata-Modern-Classic";XCURSOR_SIZE = "24";};};}
{config.flake.modules.homeModules.bun ={ pkgs, lib, config, ... }:letinherit (lib) mkIf;package = pkgs.bun;inmkIf config.isDesktop {packages = [ package ];};}
{config.flake.modules.homeModules.btop ={ pkgs, ... }:letpackage = pkgs.btop;in{packages = [ package ];};}
{config.flake.modules.nixosModules.boot ={boot.tmp.cleanOnBoot = true;boot.loader.grub = {efiSupport = true;efiInstallAsRemovable = true;};};}
{config.flake.modules.homeModules.bat ={ lib, pkgs, ... }:letinherit (lib.meta) getExe;exe = getExe pkgs.bat;package = pkgs.bat;less = pkgs.less;in{environment.sessionVariables = {MANPAGER = "${exe} --plain";PAGER = "${exe} --plain";};programs.nushell.aliases = {cat = "${exe} --pager=${less} --quit-if-one-screen --RAW-CONTROL-CHARS";less = "${exe} --plain";};packages = [ package ];};}
{config.flake.modules.homeModules.bacon ={ pkgs, ... }:letpackage = pkgs.bacon;in{packages = [ package ];};}
{config.flake.modules.nixosModules.audio ={ pkgs, ... }:{services.pipewire = {enable = true;audio.enable = true;pulse.enable = true;jack.enable = true;alsa = {enable = true;support32Bit = true;};};security.rtkit.enable = true;# Disable built-in audio. Only use NVIDIA audio output.boot.extraModprobeConfig = ''options snd_hda_intel enable=0,1'';environment.systemPackages = [pkgs.helvum # PipeWire patchbay GUI.pkgs.pwvucontrol # PipeWire volume control.pkgs.pulsemixer # Terminal-based audio mixer.];};}
{config.flake.modules.homeModules.bat ={ lib, pkgs, config, inputs, secrets, ... }:letinherit (lib) mkIf;claudeCodePackage = pkgs.symlinkJoin {name = "claude-code-wrapped";paths = [ inputs.claude-code.packages.${pkgs.stdenv.hostPlatform.system}.default ];buildInputs = [ pkgs.makeWrapper ];postBuild = # sh''wrapProgram $out/bin/claude \--run 'export ANTHROPIC_AUTH_TOKEN=$(cat ${secrets.z-ai-key.path})''';};packages = mkIf config.isDesktop [pkgs.codexpkgs.gemini-cli# pkgs.qwen-codepkgs.python3pkgs.uv# claude-code sandboxing deps.pkgs.socatpkgs.bubblewrapclaudeCodePackage];in{inherit packages;# TODO: Add claude-code and opencode config files.programs.nushell.aliases = {claude = "claude --continue --fork-session";codex = "codex resume --ask-for-approval untrusted";oc = "opencode --continue";};# Create hooks with home-manager to avoid permissions issues.files.".claude/hooks/format-files" = {text = # nu''#!/usr/bin/env nulet json_input = (^cat)let file_path = ""if (which jq | is-empty) { exit 2 }let $file_path = ($json_input | from json | get tool_input.file_path)if ($file_path | is-empty) { exit 2 }let extension = ($file_path | path parse | get extension)let command = match ($extension | str trim) {"rs" if (which cargo | is-not-empty) => { ["rustfmt" $file_path] }"toml" if (which taplo | is-not-empty) => { ["taplo" "fmt" $file_path] }_ => {print "This file extension is not covered by this script"exit 0}}^$command.0 ...($command | skip 1)'';executable = true;};# Statusline script.files.".claude/scripts/statusline.py" = {text = # py''#!/usr/bin/env python3"""PlumJam's Claude Code Statusline<https://git.plumj.am/plumjam/nixos/src/branch/master/modules/common/ai.nix>"""import jsonimport sysimport osimport reimport timedef parse_context_from_transcript(transcript_path):if not transcript_path or not os.path.exists(transcript_path):return Nonetry:with open(transcript_path, 'r', encoding='utf-8', errors='replace') as f:lines = f.readlines()# Check last 15 lines for context information.recent_lines = lines[-15:] if len(lines) > 15 else linesfor line in reversed(recent_lines):try:data = json.loads(line.strip())# Method 1: Parse usage tokens from assistant messages.if data.get('type') == 'assistant':message = data.get('message', {})usage = message.get('usage', {})if usage:input_tokens = usage.get('input_tokens', 0)cache_read = usage.get('cache_read_input_tokens', 0)cache_creation = usage.get('cache_creation_input_tokens', 0)# Estimate context usage (assume 200k).total_tokens = input_tokens + cache_read + cache_creationif total_tokens > 0:percent_used = min(100, (total_tokens / 200000) * 100)return {'percent': percent_used,'tokens': total_tokens,'method': 'usage'}# Method 2: Parse system context warnings.elif data.get('type') == 'system_message':content = data.get('content', "")# "Context left until auto-compact: X%"match = re.search(r'Context left until auto-compact: (\d+)%', content)if match:percent_left = int(match.group(1))return {'percent': 100 - percent_left,'warning': 'auto-compact','method': 'system'}# "Context low (X% remaining)"match = re.search(r'Context low \((\d+)% remaining\)', content)if match:percent_left = int(match.group(1))return {'percent': 100 - percent_left,'warning': 'low','method': 'system'}except (json.JSONDecodeError, KeyError, ValueError):continuereturn Noneexcept (FileNotFoundError, PermissionError):return Nonedef get_context_display(context_info):if not context_info:return f"\033[38;5;109m━┫ ┣━ 0%\033[0m"percent = context_info.get('percent', 0)warning = context_info.get('warning')# Create progress bar.segments = 10filled = int((percent / 100) * segments)bar = "█" * filled + " " * (segments - filled)return f"\033[38;5;109m━┫ [{bar}] ┣━{percent:.0f}%\033[0m"def get_directory_display(workspace_data):current_dir = workspace_data.get('current_dir', "")project_dir = workspace_data.get('project_dir', "")if current_dir and project_dir:if current_dir.startswith(project_dir):rel_path = current_dir[len(project_dir):].lstrip('/')return rel_path or os.path.basename(project_dir)else:return os.path.basename(current_dir)elif project_dir:return os.path.basename(project_dir)elif current_dir:return os.path.basename(current_dir)else:return "unknown"def get_session_duration(duration_ms):if duration_ms > 0:minutes = duration_ms / 60000if minutes < 1:return f"{duration_ms//1000}s"else:return f"{minutes:.0f}m"return ""def main():try:# Read JSON input from claude-code.data = json.load(sys.stdin)model_name = data.get('model', {}).get('display_name', 'Claude')workspace = data.get('workspace', {})transcript_path = data.get('transcript_path', "")cost_data = data.get('cost', {})thinking_enabled = os.environ.get('THINKING_ENABLED', "").lower() in ('true', '1', 'yes')context_info = parse_context_from_transcript(transcript_path)context_display = get_context_display(context_info)directory = get_directory_display(workspace)duration_ms = cost_data.get('total_duration_ms', 0)session_duration = get_session_duration(duration_ms)thinking_indicator = " \033[38;5;172m|\033[0m \033[38;5;142mTHINKING\033[0m " if thinking_enabled else " "# Combine all components in the correct format.status_line = f"\033[38;5;142m[{model_name}]\033[0m \033[38;5;214m{directory}\033[0m{thinking_indicator}{context_display}"if session_duration:status_line += f" \033[38;5;172m|\033[0m \033[38;5;214m{session_duration}\033[0m"print(status_line)except Exception as e:# Fallback display on any error.print("error")if __name__ == "__main__":main()'';};# Helper script to add MCPs.files.".claude/claude-mcps.sh" = {text = # bash''#!/usr/bin/env bash# Run this once to add the MCP servers that need API keysclaude mcp add -s user -t http context7 https://mcp.context7.com/mcp --header "CONTEXT7_API_KEY: $(cat ${secrets.context7Key.path})"claude mcp add -s user -t http web-reader https://api.z.ai/api/mcp/web_reader/mcp --header "Authorization: Bearer $(cat ${secrets.z-ai-key.path})"claude mcp add -s user -t http web-search-prime https://api.z.ai/api/mcp/web_search_prime/mcp --header "Authorization: Bearer $(cat ${secrets.z-ai-key.path})"claude mcp add -s user -t http zread https://api.z.ai/api/mcp/zread/mcp --header "Authorization: Bearer your_api_key"'';executable = true;};};}
inputs: self: super: letinherit (super) mkDefault;in {# Dendritic pattern helpers for building NixOS/Darwin configurations# These use modules defined in flake.modules.* (from dendritic-style host definitions)# Note: These use hjem, NOT home-manager# mkNixos: Looks up module from flake.modules.nixos.${name}mkNixos = system: name:inputs.os.lib.nixosSystem {specialArgs = inputs // {inherit inputs;lib = self;self = inputs.self;keys = inputs.self.keys;};modules = [inputs.self.flake.modules.nixos.${name}{ nixpkgs.hostPlatform = mkDefault system; }{nixpkgs.overlays =lethasOverlay = i: i ? overlays && i.overlays ? default && i.overlays.default != { };inmap (i: i.overlays.default) (builtins.filter hasOverlay (builtins.attrValues inputs));}inputs.home.nixosModules.defaultinputs.agenix.nixosModules.defaultinputs.agenix-rekey.nixosModules.default];};# mkNixos': Takes module directly (useful when defining module inline)mkNixos' = system: name: module:inputs.os.lib.nixosSystem {specialArgs = inputs // {inherit inputs;lib = self;self = inputs.self;keys = inputs.self.keys;};modules = [module{ nixpkgs.hostPlatform = mkDefault system; }{nixpkgs.overlays =lethasOverlay = i: i ? overlays && i.overlays ? default && i.overlays.default != { };inmap (i: i.overlays.default) (builtins.filter hasOverlay (builtins.attrValues inputs));}inputs.home.nixosModules.defaultinputs.agenix.nixosModules.defaultinputs.agenix-rekey.nixosModules.default];};mkDarwin = system: name:inputs.os-darwin.lib.darwinSystem {specialArgs = inputs // {inherit inputs;lib = self;self = inputs.self;keys = inputs.self.keys;};modules = [inputs.self.flake.modules.darwin.${name}{ nixpkgs.hostPlatform = mkDefault system; }];};}