diff --git a/aspects/ai.nix b/aspects/ai.nix deleted file mode 100644 index 6befeae..0000000 --- a/aspects/ai.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.ai = { inputs, pkgs, ... }: { - environment.systemPackages = - (with pkgs; [claude-desktop]) ++ - (with inputs.nix-ai-tools.packages.${pkgs.system}; [ - claude-code - claudebox - opencode - ]); - }; -} diff --git a/aspects/bluetooth.nix b/aspects/bluetooth.nix deleted file mode 100644 index 222bdf2..0000000 --- a/aspects/bluetooth.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.bluetooth = { config, lib, pkgs, ... }: { - hardware.bluetooth.enable = true; - }; -} diff --git a/aspects/cli/btop.nix b/aspects/cli/btop.nix deleted file mode 100644 index 09a815e..0000000 --- a/aspects/cli/btop.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-btop = { config, lib, pkgs, ... }: { - programs.btop = { - enable = true; - settings = { - theme_background = false; - proc_sorting = "cpu direct"; - update_ms = 500; - }; - }; - }; -} diff --git a/aspects/cli/comma.nix b/aspects/cli/comma.nix deleted file mode 100644 index b8e6c2a..0000000 --- a/aspects/cli/comma.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-comma = { config, lib, pkgs, inputs, ... }: { - imports = [ inputs.nix-index-database.homeModules.nix-index ]; - - programs.nix-index-database.comma.enable = true; - }; -} diff --git a/aspects/cli/direnv.nix b/aspects/cli/direnv.nix deleted file mode 100644 index 4399283..0000000 --- a/aspects/cli/direnv.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-direnv = { config, lib, pkgs, ... }: { - programs.direnv = { - enable = true; - nix-direnv.enable = true; - }; - }; -} diff --git a/aspects/cli/helix.nix b/aspects/cli/helix.nix deleted file mode 100644 index 1fa2baf..0000000 --- a/aspects/cli/helix.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-helix = { config, lib, pkgs, ... }: { - home.sessionVariables = { - EDITOR = "hx"; - }; - - programs.helix = { - enable = true; - settings = { - editor = { - file-picker.hidden = false; - idle-timeout = 0; - line-number = "relative"; - cursor-shape = { - normal = "underline"; - insert = "bar"; - select = "underline"; - }; - soft-wrap.enable = true; - auto-format = true; - indent-guides.render = true; - }; - keys.normal = { - space = { - o = "file_picker_in_current_buffer_directory"; - esc = [ - "collapse_selection" - "keep_primary_selection" - ]; - }; - }; - }; - languages = { - language = [ - { - name = "nix"; - auto-format = true; - formatter.command = "nixfmt"; - } - { - name = "typst"; - auto-format = true; - formatter.command = "typstyle -c 1000 -i"; - } - ]; - }; - }; - }; -} diff --git a/aspects/cli/hm-cli.nix b/aspects/cli/hm-cli.nix deleted file mode 100644 index acee59d..0000000 --- a/aspects/cli/hm-cli.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-base = { config, lib, pkgs, ... }: { - home = { - packages = with pkgs; [ hm-cli ]; - sessionVariables = { - HM_PATH = "/etc/nixos"; - }; - }; - }; -} diff --git a/aspects/cli/starship.nix b/aspects/cli/starship.nix deleted file mode 100644 index e9884a7..0000000 --- a/aspects/cli/starship.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-starship = { config, lib, pkgs, ... }: { - programs.starship = { - enable = true; - enableBashIntegration = true; - enableFishIntegration = true; - settings = { - add_newline = false; - format = '' - $hostname$directory$git_branch$git_status$nix_shell - [ ❯ ](bold green) - ''; - right_format = "$cmd_duration$character"; - hostname = { - ssh_symbol = "󰖟 "; - }; - character = { - error_symbol = "[](red)"; - success_symbol = "[󱐋](green)"; - }; - cmd_duration = { - format = "[󰄉 $duration ]($style)"; - style = "yellow"; - min_time = 500; - }; - git_branch = { - symbol = " "; - style = "purple"; - }; - git_status.style = "red"; - nix_shell = { - format = "via [$symbol$state]($style)"; - heuristic = true; - style = "blue"; - symbol = "󱄅 "; - }; - }; - }; - }; -} diff --git a/aspects/cli/tmux.nix b/aspects/cli/tmux.nix deleted file mode 100644 index 078a6aa..0000000 --- a/aspects/cli/tmux.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.cli-tmux = { config, lib, pkgs, ... }: { - programs.tmux = { - enable = true; - clock24 = true; - terminal = "xterm-256color"; - mouse = true; - keyMode = "vi"; - }; - }; -} diff --git a/aspects/common/boot.nix b/aspects/common/boot.nix deleted file mode 100644 index 109d6f2..0000000 --- a/aspects/common/boot.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-boot = { pkgs, ... }: { - boot = { - loader = { - timeout = 1; - efi.canTouchEfiVariables = true; - systemd-boot = { - enable = true; - editor = false; - consoleMode = "max"; - sortKey = "aa"; - netbootxyz = { - enable = true; - sortKey = "zz"; - }; - }; - }; - }; - }; -} diff --git a/aspects/common/console.nix b/aspects/common/console.nix deleted file mode 100644 index 6f6be9f..0000000 --- a/aspects/common/console.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-console = { ... }: { - console = { - useXkbConfig = true; - earlySetup = true; - }; - }; -} diff --git a/aspects/common/firewall.nix b/aspects/common/firewall.nix deleted file mode 100644 index af1a8f7..0000000 --- a/aspects/common/firewall.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-firewall = { ... }: { - networking = { - firewall.enable = true; - nftables.enable = true; - }; - }; -} diff --git a/aspects/common/locale.nix b/aspects/common/locale.nix deleted file mode 100644 index 2b91759..0000000 --- a/aspects/common/locale.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-locale = { ... }: { - time.timeZone = "America/Bahia"; - - i18n = { - defaultLocale = "en_US.UTF-8"; - extraLocaleSettings = { - LC_ADDRESS = "pt_BR.utf8"; - LC_COLLATE = "pt_BR.utf8"; - LC_IDENTIFICATION = "pt_BR.utf8"; - LC_MEASUREMENT = "pt_BR.utf8"; - LC_MONETARY = "pt_BR.utf8"; - LC_NAME = "pt_BR.utf8"; - LC_NUMERIC = "pt_BR.utf8"; - LC_PAPER = "pt_BR.utf8"; - LC_TELEPHONE = "pt_BR.utf8"; - LC_TIME = "en_IE.utf8"; - }; - }; - }; -} diff --git a/aspects/common/nix.nix b/aspects/common/nix.nix deleted file mode 100644 index 414c315..0000000 --- a/aspects/common/nix.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-nix = { inputs, ... }: { - imports = [ inputs.nixos-cli.nixosModules.nixos-cli ]; - - nix = { - settings = { - auto-optimise-store = true; - connect-timeout = 10; - log-lines = 25; - min-free = 128000000; - max-free = 1000000000; - trusted-users = [ "@wheel" ]; - }; - extraOptions = "experimental-features = nix-command flakes"; - gc = { - automatic = true; - options = "--delete-older-than 8d"; - }; - }; - - nixpkgs.config = { - allowUnfree = true; - enableParallelBuilding = true; - buildManPages = false; - buildDocs = false; - }; - - services.nixos-cli = { - enable = true; - config = { - use_nvd = true; - ignore_dirty_tree = true; - }; - }; - - system.stateVersion = "22.11"; - }; -} diff --git a/aspects/common/openssh.nix b/aspects/common/openssh.nix deleted file mode 100644 index c515d81..0000000 --- a/aspects/common/openssh.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-openssh = { ... }: { - services.openssh = { - enable = true; - settings.PermitRootLogin = "no"; - extraConfig = '' - PrintLastLog no - ''; - }; - }; -} diff --git a/aspects/common/programs.nix b/aspects/common/programs.nix deleted file mode 100644 index 7d12f09..0000000 --- a/aspects/common/programs.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-programs = - { lib, pkgs, ... }: - { - environment = { - systemPackages = with pkgs; [ - ### Dev Tools ### - git - ### System Utilities ### - btop - fastfetch - helix - nixos-firewall-tool - nvd - sysz - tmux - wget - yazi - ]; - shellAliases = { - cat = "${lib.getExe pkgs.bat} --paging=never --style=plain"; - ls = "${lib.getExe pkgs.eza} --git --icons --group-directories-first"; - tree = "ls --tree"; - }; - }; - - programs = { - command-not-found.enable = false; - fish = { - enable = true; - interactiveShellInit = '' - set fish_greeting - if set -q SSH_CONNECTION - export TERM=xterm-256color - clear - fastfetch - end - ''; - }; - }; - }; -} diff --git a/aspects/common/security.nix b/aspects/common/security.nix deleted file mode 100644 index 2ad04a0..0000000 --- a/aspects/common/security.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-security = - { ... }: - { - security.sudo = { - wheelNeedsPassword = false; - extraConfig = '' - Defaults lecture = never - ''; - }; - }; -} diff --git a/aspects/common/services.nix b/aspects/common/services.nix deleted file mode 100644 index befdbb9..0000000 --- a/aspects/common/services.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-services = { ... }: { - services = { - dbus.implementation = "broker"; - irqbalance.enable = true; - fstrim.enable = true; - }; - }; -} diff --git a/aspects/common/tailscale.nix b/aspects/common/tailscale.nix deleted file mode 100644 index 13eb82a..0000000 --- a/aspects/common/tailscale.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.common-tailscale = { ... }: { - services.tailscale = { - enable = true; - extraUpFlags = [ "--operator=user" ]; - }; - }; -} diff --git a/aspects/constants.nix b/aspects/constants.nix deleted file mode 100644 index 2d980e1..0000000 --- a/aspects/constants.nix +++ /dev/null @@ -1,131 +0,0 @@ -{ lib, config, ... }: - -let - # Host submodule type - hostType = lib.types.submodule { - options = { - lanIP = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "LAN IP address for the host"; - }; - tailscaleIP = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Tailscale IP address for the host"; - }; - }; - }; - - # Service submodule type - serviceType = lib.types.submodule { - options = { - name = lib.mkOption { - type = lib.types.str; - description = "Service name"; - }; - domain = lib.mkOption { - type = lib.types.str; - description = "Domain name for the service"; - }; - host = lib.mkOption { - type = lib.types.str; - description = "Host where the service runs"; - }; - public = lib.mkOption { - type = lib.types.bool; - default = false; - description = "Whether the service is publicly accessible"; - }; - lanIP = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "LAN IP address (inherited from host)"; - }; - tailscaleIP = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Tailscale IP address (inherited from host)"; - }; - }; - }; - - # Import shared data (also used by terranix) - sharedData = import ../data/services.nix; - - # Enrich services with host IP information - enrichServices = hosts: services: - map (svc: - let - hostInfo = hosts.${svc.host} or {}; - in - svc // { - lanIP = hostInfo.lanIP or null; - tailscaleIP = hostInfo.tailscaleIP or null; - } - ) services; - -in -{ - options.flake = { - hosts = lib.mkOption { - type = lib.types.attrsOf hostType; - default = {}; - description = "Host definitions with IP addresses"; - }; - - services = lib.mkOption { - type = lib.types.listOf serviceType; - default = []; - description = "Service definitions with enriched host information"; - }; - - lib = lib.mkOption { - type = lib.types.attrsOf lib.types.raw; - default = {}; - description = "Utility functions for flake configuration"; - }; - }; - - config.flake = { - hosts = sharedData.hosts; - - services = enrichServices config.flake.hosts sharedData.services; - - lib = { - # Nginx virtual host utilities - mkNginxVHosts = { domains }: - let - mkVHostConfig = domain: vhostConfig: - lib.recursiveUpdate { - useACMEHost = domain; - forceSSL = true; - kTLS = true; - } vhostConfig; - in - lib.mapAttrs mkVHostConfig domains; - - # Split DNS utilities for unbound - # Generates unbound view config from a list of DNS entries - mkSplitDNS = entries: - let - tailscaleData = map (e: ''"${e.domain}. IN A ${e.tailscaleIP}"'') entries; - lanData = map (e: ''"${e.domain}. IN A ${e.lanIP}"'') entries; - in - [ - { - name = "tailscale"; - view-first = true; - local-zone = ''"baduhai.dev." transparent''; - local-data = tailscaleData; - } - { - name = "lan"; - view-first = true; - local-zone = ''"baduhai.dev." transparent''; - local-data = lanData; - } - ]; - }; - }; -} diff --git a/aspects/desktop/boot.nix b/aspects/desktop/boot.nix deleted file mode 100644 index 48f879d..0000000 --- a/aspects/desktop/boot.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.desktop-boot = { config, lib, pkgs, ... }: { - boot = { - plymouth.enable = true; - initrd.systemd.enable = true; - loader.efi.efiSysMountPoint = "/boot/efi"; - kernelPackages = pkgs.linuxPackages_xanmod_latest; - extraModprobeConfig = '' - options bluetooth disable_ertm=1 - ''; - kernel.sysctl = { - "net.ipv4.tcp_mtu_probing" = 1; - }; - kernelParams = [ - "quiet" - "splash" - "i2c-dev" - "i2c-piix4" - "loglevel=3" - "udev.log_priority=3" - "rd.udev.log_level=3" - "rd.systemd.show_status=false" - ]; - }; - }; -} diff --git a/aspects/desktop/desktop.nix b/aspects/desktop/desktop.nix deleted file mode 100644 index f2298e7..0000000 --- a/aspects/desktop/desktop.nix +++ /dev/null @@ -1,292 +0,0 @@ -{ - inputs, - ... -}: -{ - flake.modules = { - nixos.desktop-desktop = { config, lib, pkgs, ... }: { - imports = [ - inputs.niri-flake.nixosModules.niri - inputs.nix-flatpak.nixosModules.nix-flatpak - ]; - - environment = { - sessionVariables = { - KDEHOME = "$XDG_CONFIG_HOME/kde4"; # Stops kde from placing a .kde4 folder in the home dir - NIXOS_OZONE_WL = "1"; # Forces chromium and most electron apps to run in wayland - }; - systemPackages = with pkgs; [ - ### Web ### - bitwarden-desktop - fragments - nextcloud-client - tor-browser - vesktop - inputs.zen-browser.packages."${system}".default - ### Office & Productivity ### - aspell - aspellDicts.de - aspellDicts.en - aspellDicts.en-computers - aspellDicts.pt_BR - papers - presenterm - rnote - ### Graphics & Design ### - gimp - inkscape - plasticity - ### System Utilities ### - adwaita-icon-theme - ghostty - gnome-disk-utility - junction - libfido2 - mission-center - nautilus - p7zip - rclone - toggleaudiosink - unrar - ### Media ### - decibels - loupe - obs-studio - showtime - ]; - }; - - services = { - pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - wireplumber.enable = true; - }; - greetd = { - enable = true; - settings = { - default_session = { - command = "${lib.getExe pkgs.tuigreet} --user-menu --time --remember --asterisks --cmd ${config.programs.niri.package}/bin/niri-session"; - user = "greeter"; - }; - } - // lib.optionalAttrs (config.networking.hostName == "io") { - initial_session = { - command = "${config.programs.niri.package}/bin/niri-session"; - user = "user"; - }; - }; - }; - flatpak = { - enable = true; - packages = [ - ### Office & Productivity ### - "com.collabora.Office" - ### Graphics & Design ### - "com.boxy_svg.BoxySVG" - rec { - appId = "io.github.softfever.OrcaSlicer"; - sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1"; - bundle = "${pkgs.fetchurl { - url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak"; - inherit sha256; - }}"; - } - ### System Utilities ### - "com.github.tchx84.Flatseal" - "com.rustdesk.RustDesk" - ]; - uninstallUnmanaged = true; - update.auto.enable = true; - }; - gvfs.enable = true; - }; - - security.rtkit.enable = true; # Needed for pipewire to acquire realtime priority - - users = { - users.greeter = { - isSystemUser = true; - group = "greeter"; - }; - groups.greeter = { }; - }; - - programs = { - niri = { - enable = true; - package = inputs.niri.packages.${pkgs.system}.niri; - }; - kdeconnect = { - enable = true; - package = pkgs.valent; - }; - dconf.enable = true; - appimage = { - enable = true; - binfmt = true; - }; - }; - - niri-flake.cache.enable = false; - - fonts = { - fontDir.enable = true; - packages = with pkgs; [ - corefonts - inter - nerd-fonts.fira-code - noto-fonts-cjk-sans - noto-fonts-color-emoji - roboto - ]; - }; - - xdg.portal = { - extraPortals = with pkgs; [ - xdg-desktop-portal-gnome - xdg-desktop-portal-gtk - ]; - config = { - common.default = "*"; - niri.default = [ - "gtk" - "gnome" - ]; - }; - }; - }; - - homeManager.desktop-desktop = { config, lib, pkgs, inputs, ... }: { - imports = [ inputs.vicinae.homeManagerModules.default ]; - - fonts.fontconfig.enable = true; - - home.packages = with pkgs; [ xwayland-satellite ]; - - services.vicinae = { - enable = true; - systemd = { - enable = true; - autoStart = true; - }; - }; - - programs = { - ghostty = { - enable = true; - settings = { - cursor-style = "block"; - shell-integration-features = "no-cursor"; - cursor-style-blink = false; - custom-shader = "${builtins.fetchurl { - url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl"; - sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41"; - }}"; - bell-features = ""; - gtk-titlebar-style = "tabs"; - keybind = [ "shift+enter=text:\\x1b\\r" ]; - }; - }; - - password-store = { - enable = true; - package = pkgs.pass-wayland; - }; - }; - - xdg = { - enable = true; - userDirs.enable = true; - mimeApps = { - enable = true; - defaultApplications = { - "text/html" = [ - "re.sonny.Junction.desktop" - "zen-browser.desktop" - "torbrowser.desktop" - ]; - "x-scheme-handler/http" = [ - "re.sonny.Junction.desktop" - "zen-browser.desktop" - "torbrowser.desktop" - ]; - "x-scheme-handler/https" = [ - "re.sonny.Junction.desktop" - "zen-browser.desktop" - "torbrowser.desktop" - ]; - "x-scheme-handler/about" = [ - "re.sonny.Junction.desktop" - "zen-browser.desktop" - "torbrowser.desktop" - ]; - "x-scheme-handler/unknown" = [ - "re.sonny.Junction.desktop" - "zen-browser.desktop" - "torbrowser.desktop" - ]; - "image/jpeg" = "org.gnome.Loupe.desktop"; - "image/png" = "org.gnome.Loupe.desktop"; - "image/gif" = "org.gnome.Loupe.desktop"; - "image/webp" = "org.gnome.Loupe.desktop"; - "image/bmp" = "org.gnome.Loupe.desktop"; - "image/svg+xml" = "org.gnome.Loupe.desktop"; - "image/tiff" = "org.gnome.Loupe.desktop"; - "video/mp4" = "io.bassi.Showtime.desktop"; - "video/x-matroska" = "io.bassi.Showtime.desktop"; - "video/webm" = "io.bassi.Showtime.desktop"; - "video/mpeg" = "io.bassi.Showtime.desktop"; - "video/x-msvideo" = "io.bassi.Showtime.desktop"; - "video/quicktime" = "io.bassi.Showtime.desktop"; - "video/x-flv" = "io.bassi.Showtime.desktop"; - "audio/mpeg" = "io.bassi.Showtime.desktop"; - "audio/flac" = "io.bassi.Showtime.desktop"; - "audio/ogg" = "io.bassi.Showtime.desktop"; - "audio/wav" = "io.bassi.Showtime.desktop"; - "audio/mp4" = "io.bassi.Showtime.desktop"; - "audio/x-opus+ogg" = "io.bassi.Showtime.desktop"; - "application/pdf" = [ - "org.gnome.Papers.desktop" - "zen-browser.desktop" - ]; - "text/plain" = "Helix.desktop"; - "text/markdown" = "Helix.desktop"; - "text/x-log" = "Helix.desktop"; - "application/x-shellscript" = "Helix.desktop"; - "application/vnd.openxmlformats-officedocument.wordprocessingml.document" = - "com.collabora.Office.desktop"; # DOCX - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" = - "com.collabora.Office.desktop"; # XLSX - "application/vnd.openxmlformats-officedocument.presentationml.presentation" = - "com.collabora.Office.desktop"; # PPTX - "application/vnd.oasis.opendocument.text" = "com.collabora.Office.desktop"; # ODT - "application/vnd.oasis.opendocument.spreadsheet" = "com.collabora.Office.desktop"; # ODS - "application/vnd.oasis.opendocument.presentation" = "com.collabora.Office.desktop"; # ODP - "application/msword" = "com.collabora.Office.desktop"; # DOC - "application/vnd.ms-excel" = "com.collabora.Office.desktop"; # XLS - "application/vnd.ms-powerpoint" = "com.collabora.Office.desktop"; # PPT - "application/zip" = "org.gnome.FileRoller.desktop"; - "application/x-tar" = "org.gnome.FileRoller.desktop"; - "application/x-compressed-tar" = "org.gnome.FileRoller.desktop"; - "application/x-bzip-compressed-tar" = "org.gnome.FileRoller.desktop"; - "application/x-xz-compressed-tar" = "org.gnome.FileRoller.desktop"; - "application/x-7z-compressed" = "org.gnome.FileRoller.desktop"; - "application/x-rar" = "org.gnome.FileRoller.desktop"; - "application/gzip" = "org.gnome.FileRoller.desktop"; - "application/x-bzip" = "org.gnome.FileRoller.desktop"; - "inode/directory" = "org.gnome.Nautilus.desktop"; - }; - }; - }; - - # Set Ghostty as default terminal - home.sessionVariables = { - TERMINAL = "ghostty"; - }; - }; - }; -} diff --git a/aspects/desktop/niri.nix b/aspects/desktop/niri.nix deleted file mode 100644 index 6458ab0..0000000 --- a/aspects/desktop/niri.nix +++ /dev/null @@ -1,220 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.desktop-niri = { config, lib, pkgs, inputs, hostname ? null, ... }: - let - isRotterdam = hostname == "rotterdam"; - in - { - imports = [ inputs.noctalia.homeModules.default ]; - - services.kanshi = { - enable = true; - settings = [ - { - profile.name = "default"; - profile.outputs = [ - { - criteria = "*"; - scale = 1.0; - } - ]; - } - ]; - }; - - home = { - packages = with pkgs; [ - xwayland-satellite - inputs.noctalia.packages.${pkgs.system}.default - ]; - sessionVariables.QT_QPA_PLATFORMTHEME = "gtk3"; - }; - - xdg.configFile."niri/config.kdl".text = '' - input { - keyboard { - xkb { - layout "us" - variant "altgr-intl" - } - } - touchpad { - tap - dwt - drag true - drag-lock - natural-scroll - accel-speed 0.2 - accel-profile "flat" - scroll-method "two-finger" - middle-emulation - } - mouse { - natural-scroll - accel-speed 0.2 - accel-profile "flat" - } - warp-mouse-to-focus mode="center-xy" - focus-follows-mouse - } - - layout { - gaps 8 - center-focused-column "never" - auto-center-when-space-available - preset-column-widths { - ${ - if isRotterdam then - '' - proportion 0.33333 - proportion 0.5 - proportion 0.66667 - '' - else - '' - proportion 0.5 - proportion 1.0 - '' - } - } - default-column-width { proportion ${if isRotterdam then "0.33333" else "0.5"}; } - focus-ring { - off - } - border { - width 4 - active-color "#ffc87f" - inactive-color "#505050" - urgent-color "#9b0000" - } - tab-indicator { - width 4 - gap 4 - place-within-column - } - } - - overview { - zoom 0.65 - } - - spawn-at-startup "noctalia-shell" "-d" - layer-rule { - match namespace="^noctalia-overview*" - place-within-backdrop true - } - - hotkey-overlay { - skip-at-startup - } - - prefer-no-csd - screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" - - animations { - slowdown 0.3 - } - - window-rule { - match app-id="zen" - default-column-width { proportion ${if isRotterdam then "0.5" else "1.0"}; } - } - - window-rule { - geometry-corner-radius 12 - clip-to-geometry true - } - - config-notification { - disable-failed - } - - binds { - Alt+Space repeat=false { spawn "vicinae" "toggle"; } - XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "increase"; } - XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "decrease"; } - XF86AudioMute allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "muteOutput"; } - XF86MonBrightnessUp allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "brightness" "increase"; } - XF86MonBrightnessDown allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "brightness" "decrease"; } - XF86AudioPlay allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "play-pause"; } - XF86AudioStop allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "stop"; } - XF86AudioPrev allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "previous"; } - XF86AudioNext allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "next"; } - Mod+V repeat=false { spawn "vicinae" "vicinae://extensions/vicinae/clipboard/history"; } - Mod+Shift+L repeat=false { spawn "noctalia-shell" "ipc" "call" "lockScreen" "lock"; } - Mod+Return { spawn "ghostty"; } - Ctrl+Alt+Shift+A allow-when-locked=true { spawn "toggleaudiosink"; } - Mod+W repeat=false { toggle-overview; } - Mod+Q { close-window; } - Alt+Shift+Q { close-window;} - Mod+Shift+Q { close-window; } - Alt+F4 { close-window; } - Mod+Left { focus-column-left; } - Mod+Down { focus-window-or-workspace-down; } - Mod+Up { focus-window-or-workspace-up; } - Mod+Right { focus-column-right; } - Mod+H { focus-column-left; } - Mod+L { focus-column-right; } - Mod+J { focus-window-or-workspace-down; } - Mod+K { focus-window-or-workspace-up; } - Mod+Ctrl+Left { move-column-left; } - Mod+Ctrl+Down { move-window-down-or-to-workspace-down; } - Mod+Ctrl+Up { move-window-up-or-to-workspace-up; } - Mod+Ctrl+Right { move-column-right; } - Mod+Ctrl+H { move-column-left; } - Mod+Ctrl+J { move-window-down-or-to-workspace-down; } - Mod+Ctrl+K { move-window-up-or-to-workspace-up; } - Mod+Ctrl+L { move-column-right; } - Mod+Home { focus-column-first; } - Mod+End { focus-column-last; } - Mod+Ctrl+Home { move-column-to-first; } - Mod+Ctrl+End { move-column-to-last; } - Mod+Alt+Left { focus-monitor-left; } - Mod+Alt+Down { focus-monitor-down; } - Mod+Alt+Up { focus-monitor-up; } - Mod+Alt+Right { focus-monitor-right; } - Mod+Alt+H { focus-monitor-left; } - Mod+Alt+J { focus-monitor-down; } - Mod+Alt+K { focus-monitor-up; } - Mod+Alt+L { focus-monitor-right; } - Mod+Alt+Ctrl+Left { move-column-to-monitor-left; } - Mod+Alt+Ctrl+Down { move-column-to-monitor-down; } - Mod+Alt+Ctrl+Up { move-column-to-monitor-up; } - Mod+Alt+Ctrl+Right { move-column-to-monitor-right; } - Mod+Alt+Ctrl+H { move-column-to-monitor-left; } - Mod+Alt+Ctrl+J { move-column-to-monitor-down; } - Mod+Alt+Ctrl+K { move-column-to-monitor-up; } - Mod+Alt+Ctrl+L { move-column-to-monitor-right; } - Mod+Ctrl+U { move-workspace-down; } - Mod+Ctrl+I { move-workspace-up; } - Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } - Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } - Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } - Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } - Mod+Shift+WheelScrollDown { focus-column-right; } - Mod+Shift+WheelScrollUp { focus-column-left; } - Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } - Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } - Mod+BracketLeft { consume-or-expel-window-left; } - Mod+BracketRight { consume-or-expel-window-right; } - Mod+Comma { consume-window-into-column; } - Mod+Period { expel-window-from-column; } - Mod+R { switch-preset-column-width; } - Mod+F { maximize-column; } - Mod+Ctrl+F { fullscreen-window; } - Mod+C { center-visible-columns; } - Mod+Ctrl+C { center-column; } - Mod+Space { toggle-window-floating; } - Mod+Ctrl+Space { switch-focus-between-floating-and-tiling; } - Mod+T { toggle-column-tabbed-display; } - Print { screenshot-screen; } - Mod+Print { screenshot; } - Ctrl+Print { screenshot-window; } - Mod+Backspace allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } - Mod+Alt+E { spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; } - Ctrl+Alt+Delete { spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; } - Mod+Ctrl+P { power-off-monitors; } - } - ''; - }; -} diff --git a/aspects/desktop/nix.nix b/aspects/desktop/nix.nix deleted file mode 100644 index a3aa421..0000000 --- a/aspects/desktop/nix.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ inputs, ... }: -{ - flake.modules.nixos.desktop-nix = { config, lib, pkgs, ... }: { - environment.etc."channels/nixpkgs".source = inputs.nixpkgs.outPath; - - nix = { - registry.nixpkgs.flake = inputs.nixpkgs; - nixPath = [ - "nixpkgs=${inputs.nixpkgs}" - "/nix/var/nix/profiles/per-user/root/channels" - ]; - }; - }; -} diff --git a/aspects/desktop/services.nix b/aspects/desktop/services.nix deleted file mode 100644 index 8ebbb6b..0000000 --- a/aspects/desktop/services.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.desktop-services = { config, lib, pkgs, ... }: { - services = { - printing.enable = true; - udev.packages = with pkgs; [ yubikey-personalization ]; - keyd = { - enable = true; - keyboards.all = { - ids = [ "*" ]; - settings.main.capslock = "overload(meta, esc)"; - }; - }; - }; - }; -} diff --git a/aspects/dev.nix b/aspects/dev.nix deleted file mode 100644 index cc84646..0000000 --- a/aspects/dev.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.dev = { config, lib, pkgs, ... }: { - environment.systemPackages = with pkgs; [ - android-tools - bat - lazygit - fd - fzf - glow - nixfmt - nix-init - nix-output-monitor - ripgrep - ]; - - users.users.user.extraGroups = [ "adbusers" ]; - }; -} diff --git a/aspects/ephemeral.nix b/aspects/ephemeral.nix deleted file mode 100644 index 724f931..0000000 --- a/aspects/ephemeral.nix +++ /dev/null @@ -1,136 +0,0 @@ -# Ephemeral root aspect - provides automatic btrfs root subvolume rollover -# Exports both a base module with options and a factory function for easy configuration -{ inputs, ... }: -{ - # Base module with options (for external flakes or direct use) - flake.modules.nixos.ephemeral = { lib, config, ... }: - let - cfg = config.ephemeral; - in - { - options.ephemeral = { - enable = lib.mkEnableOption "ephemeral root with automatic rollback"; - - rootDevice = lib.mkOption { - type = lib.types.str; - example = "/dev/mapper/cryptroot"; - description = "Device path for the root btrfs filesystem"; - }; - - rootSubvolume = lib.mkOption { - type = lib.types.str; - default = "@root"; - description = "Name of the root btrfs subvolume"; - }; - - oldRootRetentionDays = lib.mkOption { - type = lib.types.int; - default = 30; - description = "Number of days to keep old root snapshots before deletion"; - }; - }; - - config = lib.mkIf cfg.enable { - boot.initrd.systemd.services.recreate-root = { - description = "Rolling over and creating new filesystem root"; - requires = [ "initrd-root-device.target" ]; - after = [ - "local-fs-pre.target" - "initrd-root-device.target" - ]; - requiredBy = [ "initrd-root-fs.target" ]; - before = [ "sysroot.mount" ]; - unitConfig = { - AssertPathExists = "/etc/initrd-release"; - DefaultDependencies = false; - }; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = '' - set -euo pipefail - - mkdir /btrfs_tmp - if ! mount ${cfg.rootDevice} /btrfs_tmp; then - echo "ERROR: Failed to mount ${cfg.rootDevice}" - exit 1 - fi - - if [[ -e /btrfs_tmp/${cfg.rootSubvolume} ]]; then - mkdir -p /btrfs_tmp/old_roots - timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/${cfg.rootSubvolume})" "+%Y-%m-%-d_%H:%M:%S") - mv /btrfs_tmp/${cfg.rootSubvolume} "/btrfs_tmp/old_roots/$timestamp" - fi - - delete_subvolume_recursively() { - IFS=$'\n' - for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do - delete_subvolume_recursively "/btrfs_tmp/$i" - done - btrfs subvolume delete "$1" - } - - for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +${toString cfg.oldRootRetentionDays}); do - delete_subvolume_recursively "$i" - done - - if ! btrfs subvolume create /btrfs_tmp/${cfg.rootSubvolume}; then - echo "ERROR: Failed to create subvolume ${cfg.rootSubvolume}" - umount /btrfs_tmp - exit 1 - fi - - umount /btrfs_tmp - ''; - }; - }; - }; - - # Factory function that generates configured modules - flake.factory.ephemeral = - { rootDevice - , rootSubvolume ? "@root" - , retentionDays ? 30 - , persistentStoragePath ? "/persistent" - , persistentFiles ? [ - "/etc/machine-id" - "/etc/ssh/ssh_host_ed25519_key" - "/etc/ssh/ssh_host_ed25519_key.pub" - "/etc/ssh/ssh_host_rsa_key" - "/etc/ssh/ssh_host_rsa_key.pub" - ] - , persistentDirectories ? [ - "/etc/NetworkManager/system-connections" - "/etc/nixos" - "/var/lib/bluetooth" - "/var/lib/flatpak" - "/var/lib/lxd" - "/var/lib/nixos" - "/var/lib/systemd/coredump" - "/var/lib/systemd/timers" - "/var/lib/tailscale" - "/var/log" - ] - }: - { ... }: { - imports = [ - inputs.impermanence.nixosModules.impermanence - inputs.self.modules.nixos.ephemeral - ]; - - ephemeral = { - enable = true; - inherit rootDevice rootSubvolume; - oldRootRetentionDays = retentionDays; - }; - - fileSystems."/persistent".neededForBoot = true; - - environment.persistence.main = { - inherit persistentStoragePath; - files = persistentFiles; - directories = persistentDirectories; - }; - }; -} diff --git a/aspects/fwupd.nix b/aspects/fwupd.nix deleted file mode 100644 index 746f1d0..0000000 --- a/aspects/fwupd.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.fwupd = { config, lib, pkgs, ... }: { - services.fwupd.enable = true; - }; -} diff --git a/aspects/gaming/flatpak.nix b/aspects/gaming/flatpak.nix deleted file mode 100644 index ad50c7c..0000000 --- a/aspects/gaming/flatpak.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.gaming-flatpak = { pkgs, ... }: { - services.flatpak.packages = [ - "com.github.k4zmu2a.spacecadetpinball" - "com.steamgriddb.SGDBoop" - "io.github.Foldex.AdwSteamGtk" - "io.itch.itch" - "io.mrarm.mcpelauncher" - "net.retrodeck.retrodeck" - "org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/25.08" - rec { - appId = "com.hypixel.HytaleLauncher"; - sha256 = "01307s44bklc1ldcigcn9n4lm8hf8q793v9fv7w4w04xd5zyh4rv"; - bundle = "${pkgs.fetchurl { - url = "https://launcher.hytale.com/builds/release/linux/amd64/hytale-launcher-latest.flatpak"; - inherit sha256; - }}"; - } - ]; - }; -} diff --git a/aspects/gaming/hardware.nix b/aspects/gaming/hardware.nix deleted file mode 100644 index f1bd75b..0000000 --- a/aspects/gaming/hardware.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.gaming-hardware = { ... }: { - hardware = { - xpadneo.enable = true; - steam-hardware.enable = true; # Allow steam client to manage controllers - graphics.enable32Bit = true; # For OpenGL games - }; - }; -} diff --git a/aspects/gaming/launchers.nix b/aspects/gaming/launchers.nix deleted file mode 100644 index 5684f9f..0000000 --- a/aspects/gaming/launchers.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.gaming-launchers = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ - clonehero - heroic - prismlauncher - ]; - }; -} diff --git a/aspects/gaming/mangohud.nix b/aspects/gaming/mangohud.nix deleted file mode 100644 index 7f83644..0000000 --- a/aspects/gaming/mangohud.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ ... }: - -{ - flake.modules = { - nixos.gaming-mangohud = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ - mangohud - ]; - }; - - homeManager.gaming-mangohud = { config, ... }: { - programs.mangohud = { - enable = true; - enableSessionWide = true; - settings = { - position = "top-left"; - fps = true; - frametime = false; - frame_timing = false; - gpu_stats = true; - gpu_temp = true; - gpu_power = true; - cpu_stats = true; - cpu_temp = true; - cpu_power = true; - ram = true; - vram = true; - gamemode = false; - vkbasalt = false; - version = false; - engine_version = false; - vulkan_driver = false; - wine = false; - time = false; - fps_sampling_period = 500; - toggle_hud = "Shift_L+F12"; - toggle_logging = "Ctrl_L+F2"; - output_folder = "${config.home.homeDirectory}/.local/share/mangohud"; - }; - }; - }; - }; -} diff --git a/aspects/gaming/steam.nix b/aspects/gaming/steam.nix deleted file mode 100644 index e0ab9a8..0000000 --- a/aspects/gaming/steam.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.gaming-steam = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ - steam-run - ]; - - programs = { - steam = { - enable = true; - extraCompatPackages = [ pkgs.proton-ge-bin ]; - }; - gamemode.enable = true; - }; - }; -} diff --git a/aspects/hosts/alexandria.nix b/aspects/hosts/alexandria.nix deleted file mode 100644 index 28c333e..0000000 --- a/aspects/hosts/alexandria.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ inputs, self, ... }: -{ - flake.nixosConfigurations.alexandria = inputs.nixpkgs-stable.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = { inherit inputs; }; - modules = [ - inputs.agenix.nixosModules.default - { networking.hostName = "alexandria"; } - { - nixpkgs.overlays = [ - inputs.agenix.overlays.default - inputs.self.overlays.default - ]; - } - - # Common aspects (always included) - inputs.self.modules.nixos.common-boot - inputs.self.modules.nixos.common-console - inputs.self.modules.nixos.common-firewall - inputs.self.modules.nixos.common-locale - inputs.self.modules.nixos.common-nix - inputs.self.modules.nixos.common-openssh - inputs.self.modules.nixos.common-programs - inputs.self.modules.nixos.common-security - inputs.self.modules.nixos.common-services - inputs.self.modules.nixos.common-tailscale - - # User aspects - inputs.self.modules.nixos.user - inputs.self.modules.nixos.root - - # Server aspects - inputs.self.modules.nixos.server-boot - inputs.self.modules.nixos.server-nix - inputs.self.modules.nixos.server-tailscale - - # Other aspects based on tags - inputs.self.modules.nixos.fwupd - - # Host-specific files (from _alexandria/) - ./_alexandria/hardware-configuration.nix - ./_alexandria/jellyfin.nix - ./_alexandria/kanidm.nix - ./_alexandria/nextcloud.nix - ./_alexandria/nginx.nix - ./_alexandria/unbound.nix - ./_alexandria/vaultwarden.nix - ]; - }; -} diff --git a/aspects/hosts/io.nix b/aspects/hosts/io.nix deleted file mode 100644 index c6c3dbf..0000000 --- a/aspects/hosts/io.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ inputs, self, ... }: -{ - flake.nixosConfigurations.io = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = { inherit inputs; }; - modules = [ - inputs.agenix.nixosModules.default - { networking.hostName = "io"; } - { - nixpkgs.overlays = [ - inputs.agenix.overlays.default - inputs.self.overlays.default - ]; - } - - # Common aspects (always included) - inputs.self.modules.nixos.common-boot - inputs.self.modules.nixos.common-console - inputs.self.modules.nixos.common-firewall - inputs.self.modules.nixos.common-locale - inputs.self.modules.nixos.common-nix - inputs.self.modules.nixos.common-openssh - inputs.self.modules.nixos.common-programs - inputs.self.modules.nixos.common-security - inputs.self.modules.nixos.common-services - inputs.self.modules.nixos.common-tailscale - - # User aspects - inputs.self.modules.nixos.user - inputs.self.modules.nixos.root - - # Desktop aspects - inputs.self.modules.nixos.desktop-boot - inputs.self.modules.nixos.desktop-desktop - inputs.self.modules.nixos.desktop-nix - inputs.self.modules.nixos.desktop-services - - # Other aspects based on tags - inputs.self.modules.nixos.ai - inputs.self.modules.nixos.bluetooth - inputs.self.modules.nixos.dev - inputs.self.modules.nixos.libvirtd - inputs.self.modules.nixos.networkmanager - inputs.self.modules.nixos.podman - - # Factory-generated ephemeral module - (inputs.self.factory.ephemeral { - rootDevice = "/dev/mapper/cryptroot"; - }) - - # Host-specific files (from _io/) - ./_io/hardware-configuration.nix - ./_io/disko.nix - ./_io/boot.nix - ./_io/programs.nix - ./_io/services.nix - ]; - }; -} diff --git a/aspects/hosts/rotterdam.nix b/aspects/hosts/rotterdam.nix deleted file mode 100644 index 76ffbb0..0000000 --- a/aspects/hosts/rotterdam.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ inputs, ... }: -{ - flake.nixosConfigurations.rotterdam = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = { inherit inputs; }; - modules = [ - inputs.agenix.nixosModules.default - { networking.hostName = "rotterdam"; } - { - nixpkgs.overlays = [ - inputs.agenix.overlays.default - inputs.self.overlays.default - ]; - } - - # Common aspects (always included) - inputs.self.modules.nixos.common-boot - inputs.self.modules.nixos.common-console - inputs.self.modules.nixos.common-firewall - inputs.self.modules.nixos.common-locale - inputs.self.modules.nixos.common-nix - inputs.self.modules.nixos.common-openssh - inputs.self.modules.nixos.common-programs - inputs.self.modules.nixos.common-security - inputs.self.modules.nixos.common-services - inputs.self.modules.nixos.common-tailscale - - # User aspects - inputs.self.modules.nixos.user - inputs.self.modules.nixos.root - - # Desktop aspects - inputs.self.modules.nixos.desktop-boot - inputs.self.modules.nixos.desktop-desktop - inputs.self.modules.nixos.desktop-nix - inputs.self.modules.nixos.desktop-services - - # Other aspects based on tags - inputs.self.modules.nixos.ai - inputs.self.modules.nixos.bluetooth - inputs.self.modules.nixos.dev - inputs.self.modules.nixos.fwupd - inputs.self.modules.nixos.gaming-steam - inputs.self.modules.nixos.gaming-hardware - inputs.self.modules.nixos.gaming-flatpak - inputs.self.modules.nixos.gaming-launchers - inputs.self.modules.nixos.libvirtd - inputs.self.modules.nixos.networkmanager - inputs.self.modules.nixos.podman - - # Factory-generated ephemeral module - (inputs.self.factory.ephemeral { - rootDevice = "/dev/mapper/cryptroot"; - }) - - # Host-specific files (from _rotterdam/) - ./_rotterdam/hardware-configuration.nix - ./_rotterdam/boot.nix - ./_rotterdam/hardware.nix - ./_rotterdam/programs.nix - ./_rotterdam/services.nix - ]; - }; -} diff --git a/aspects/hosts/trantor.nix b/aspects/hosts/trantor.nix deleted file mode 100644 index 3de68a9..0000000 --- a/aspects/hosts/trantor.nix +++ /dev/null @@ -1,54 +0,0 @@ -{ inputs, self, ... }: -{ - flake.nixosConfigurations.trantor = inputs.nixpkgs-stable.lib.nixosSystem { - system = "aarch64-linux"; - specialArgs = { inherit inputs; }; - modules = [ - inputs.agenix.nixosModules.default - { networking.hostName = "trantor"; } - { - nixpkgs.overlays = [ - inputs.agenix.overlays.default - inputs.self.overlays.default - ]; - } - - # Common aspects (always included) - inputs.self.modules.nixos.common-boot - inputs.self.modules.nixos.common-console - inputs.self.modules.nixos.common-firewall - inputs.self.modules.nixos.common-locale - inputs.self.modules.nixos.common-nix - inputs.self.modules.nixos.common-openssh - inputs.self.modules.nixos.common-programs - inputs.self.modules.nixos.common-security - inputs.self.modules.nixos.common-services - inputs.self.modules.nixos.common-tailscale - - # User aspects - inputs.self.modules.nixos.user - inputs.self.modules.nixos.root - - # Server aspects - inputs.self.modules.nixos.server-boot - inputs.self.modules.nixos.server-nix - inputs.self.modules.nixos.server-tailscale - - # Factory-generated ephemeral module - (inputs.self.factory.ephemeral { - rootDevice = "/dev/disk/by-id/scsi-360b207ed25d84372a95d1ecf842f8e20-part2"; - }) - - # Host-specific files (from _trantor/) - ./_trantor/hardware-configuration.nix - ./_trantor/disko.nix - ./_trantor/boot.nix - ./_trantor/fail2ban.nix - ./_trantor/forgejo.nix - ./_trantor/networking.nix - ./_trantor/nginx.nix - ./_trantor/openssh.nix - ./_trantor/unbound.nix - ]; - }; -} diff --git a/aspects/libvirtd.nix b/aspects/libvirtd.nix deleted file mode 100644 index 6487999..0000000 --- a/aspects/libvirtd.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.libvirtd = { config, lib, pkgs, ... }: { - virtualisation = { - libvirtd.enable = true; - spiceUSBRedirection.enable = true; - }; - - programs.virt-manager.enable = true; - - networking.firewall.trustedInterfaces = [ "virbr0" ]; - - users.users.user.extraGroups = [ - "libvirt" - "libvirtd" - ]; - }; -} diff --git a/aspects/networkmanager.nix b/aspects/networkmanager.nix deleted file mode 100644 index 74c9260..0000000 --- a/aspects/networkmanager.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.networkmanager = { config, lib, pkgs, ... }: { - networking.networkmanager = { - enable = true; - wifi.backend = "iwd"; - }; - - users.users.user.extraGroups = [ "networkmanager" ]; - }; -} diff --git a/aspects/podman.nix b/aspects/podman.nix deleted file mode 100644 index 6afa327..0000000 --- a/aspects/podman.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ ... }: -{ - flake.modules.nixos.podman = - { - config, - lib, - pkgs, - ... - }: - { - virtualisation.podman = { - enable = true; - autoPrune.enable = true; - extraPackages = [ pkgs.podman-compose ]; - }; - - security.unprivilegedUsernsClone = true; # Needed for rootless podman - - systemd = { - services.podman-auto-update.enable = true; - timers.podman-auto-update.enable = true; - }; - }; -} diff --git a/aspects/programs/graphics.nix b/aspects/programs/graphics.nix deleted file mode 100644 index 4b7a16b..0000000 --- a/aspects/programs/graphics.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.programs-graphics = - { pkgs, ... }: - { - environment.systemPackages = with pkgs; [ - gimp - inkscape - plasticity - ]; - - services.flatpak.packages = [ - "com.boxy_svg.BoxySVG" - rec { - appId = "io.github.softfever.OrcaSlicer"; - sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1"; - bundle = "${pkgs.fetchurl { - url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak"; - inherit sha256; - }}"; - } - ]; - }; -} diff --git a/aspects/programs/media.nix b/aspects/programs/media.nix deleted file mode 100644 index 7daaa87..0000000 --- a/aspects/programs/media.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ ... }: - -{ - flake.modules = { - nixos.programs-media = - { pkgs, ... }: - { - environment.systemPackages = with pkgs; [ - decibels - loupe - obs-studio - showtime - ]; - }; - - homeManager.programs-media = - { pkgs, ... }: - { - programs.obs-studio = { - enable = true; - plugins = with pkgs.obs-studio-plugins; [ - obs-vkcapture - obs-backgroundremoval - obs-pipewire-audio-capture - ]; - }; - }; - }; -} diff --git a/aspects/programs/office.nix b/aspects/programs/office.nix deleted file mode 100644 index c3349f3..0000000 --- a/aspects/programs/office.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.programs-office = - { pkgs, ... }: - { - environment.systemPackages = with pkgs; [ - aspell - aspellDicts.de - aspellDicts.en - aspellDicts.en-computers - aspellDicts.pt_BR - papers - presenterm - rnote - ]; - - services.flatpak.packages = [ - "com.collabora.Office" - ]; - }; -} diff --git a/aspects/programs/utilities.nix b/aspects/programs/utilities.nix deleted file mode 100644 index 4a207af..0000000 --- a/aspects/programs/utilities.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ ... }: - -{ - flake.modules = { - nixos.programs-utilities = - { pkgs, ... }: - { - environment.systemPackages = with pkgs; [ - ghostty - gnome-disk-utility - mission-center - nautilus - p7zip - rclone - unrar - # Desktop Integration - adwaita-icon-theme - junction - libfido2 - toggleaudiosink - # Xwayland Support - xwayland-satellite - ]; - - services.flatpak.packages = [ - "com.github.tchx84.Flatseal" - "com.rustdesk.RustDesk" - ]; - }; - - homeManager.programs-utilities = - { pkgs, ... }: - { - programs = { - ghostty = { - enable = true; - settings = { - cursor-style = "block"; - shell-integration-features = "no-cursor"; - cursor-style-blink = false; - custom-shader = "${builtins.fetchurl { - url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl"; - sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41"; - }}"; - bell-features = ""; - gtk-titlebar-style = "tabs"; - keybind = [ "shift+enter=text:\\x1b\\r" ]; - }; - }; - - password-store = { - enable = true; - package = pkgs.pass-wayland; - }; - }; - - home.sessionVariables = { - TERMINAL = "ghostty"; - }; - }; - }; -} diff --git a/aspects/programs/web.nix b/aspects/programs/web.nix deleted file mode 100644 index a11ca57..0000000 --- a/aspects/programs/web.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.programs-web = - { - inputs, - pkgs, - system, - ... - }: - { - environment.systemPackages = with pkgs; [ - inputs.zen-browser.packages."${system}".default - bitwarden-desktop - fragments - nextcloud-client - tor-browser - vesktop - ]; - }; -} diff --git a/aspects/server/boot.nix b/aspects/server/boot.nix deleted file mode 100644 index ff5ef25..0000000 --- a/aspects/server/boot.nix +++ /dev/null @@ -1,7 +0,0 @@ -# aspects/server/boot.nix -{ ... }: -{ - flake.modules.nixos.server-boot = { config, lib, pkgs, ... }: { - boot.kernelPackages = pkgs.linuxPackages_hardened; - }; -} diff --git a/aspects/server/nix.nix b/aspects/server/nix.nix deleted file mode 100644 index 84bec67..0000000 --- a/aspects/server/nix.nix +++ /dev/null @@ -1,15 +0,0 @@ -# aspects/server/nix.nix -{ inputs, ... }: -{ - flake.modules.nixos.server-nix = { config, lib, pkgs, ... }: { - environment.etc."channels/nixpkgs".source = inputs.nixpkgs-stable.outPath; - - nix = { - registry.nixpkgs.flake = inputs.nixpkgs-stable; - nixPath = [ - "nixpkgs=/etc/channels/nixpkgs" - "/nix/var/nix/profiles/per-user/root/channels" - ]; - }; - }; -} diff --git a/aspects/server/tailscale.nix b/aspects/server/tailscale.nix deleted file mode 100644 index 5a48799..0000000 --- a/aspects/server/tailscale.nix +++ /dev/null @@ -1,15 +0,0 @@ -# aspects/server/tailscale.nix -{ ... }: -{ - flake.modules.nixos.server-tailscale = { config, lib, pkgs, ... }: { - services.tailscale = { - extraSetFlags = [ "--advertise-exit-node" ]; - useRoutingFeatures = "server"; - }; - - boot.kernel.sysctl = { - "net.ipv4.ip_forward" = 1; - "net.ipv6.conf.all.forwarding" = 1; - }; - }; -} diff --git a/aspects/shell/bash.nix b/aspects/shell/bash.nix deleted file mode 100644 index 3ec7237..0000000 --- a/aspects/shell/bash.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.shell-bash = { config, lib, pkgs, ... }: { - programs.bash = { - enable = true; - historyFile = "~/.cache/bash_history"; - }; - }; -} diff --git a/aspects/shell/fish.nix b/aspects/shell/fish.nix deleted file mode 100644 index e2ae9cf..0000000 --- a/aspects/shell/fish.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ ... }: -{ - flake.modules.homeManager.shell-fish = { config, lib, pkgs, ... }: { - programs.fish = { - enable = true; - interactiveShellInit = '' - set fish_greeting - ${lib.getExe pkgs.nix-your-shell} fish | source - ''; - loginShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source"; - plugins = [ - { - name = "bang-bang"; - src = pkgs.fetchFromGitHub { - owner = "oh-my-fish"; - repo = "plugin-bang-bang"; - rev = "f969c618301163273d0a03d002614d9a81952c1e"; - sha256 = "sha256-A8ydBX4LORk+nutjHurqNNWFmW6LIiBPQcxS3x4nbeQ="; - }; - } - { - name = "z"; - src = pkgs.fetchFromGitHub { - owner = "jethrokuan"; - repo = "z"; - rev = "067e867debee59aee231e789fc4631f80fa5788e"; - sha256 = "sha256-emmjTsqt8bdI5qpx1bAzhVACkg0MNB/uffaRjjeuFxU="; - }; - } - ]; - }; - }; -} diff --git a/aspects/stylix.nix b/aspects/stylix.nix deleted file mode 100644 index ec3fd42..0000000 --- a/aspects/stylix.nix +++ /dev/null @@ -1,80 +0,0 @@ -{ ... }: -{ - flake.modules = { - nixos.stylix = - { inputs, ... }: - { - imports = [ inputs.stylix.nixosModules.stylix ]; - }; - - homeManager.stylix = - { - config, - inputs, - pkgs, - ... - }: - { - imports = [ - inputs.stylix.homeModules.stylix - inputs.zen-browser.homeModules.beta - ]; - - stylix = { - enable = true; - polarity = "dark"; - base16Scheme = "${pkgs.base16-schemes}/share/themes/tokyodark.yaml"; - cursor = { - package = pkgs.kdePackages.breeze; - name = "breeze_cursors"; - size = 24; - }; - icons = { - enable = true; - package = pkgs.morewaita-icon-theme; - light = "MoreWaita"; - dark = "MoreWaita"; - }; - opacity = { - applications = 1.0; - desktop = 1.0; - popups = config.stylix.opacity.desktop; - terminal = 1.0; - }; - fonts = { - serif = { - package = pkgs.source-serif; - name = "Source Serif 4 Display"; - }; - sansSerif = { - package = pkgs.inter; - name = "Inter"; - }; - monospace = { - package = pkgs.nerd-fonts.fira-code; - name = "FiraCode Nerd Font"; - }; - emoji = { - package = pkgs.noto-fonts-color-emoji; - name = "Noto Color Emoji"; - }; - sizes = { - applications = 10; - desktop = config.stylix.fonts.sizes.applications; - popups = config.stylix.fonts.sizes.applications; - terminal = 12; - }; - }; - targets.zen-browser = { - enable = true; - profileNames = [ "william" ]; - }; - }; - - programs.zen-browser = { - enable = true; - profiles.william = { }; - }; - }; - }; -} diff --git a/aspects/users/root.nix b/aspects/users/root.nix deleted file mode 100644 index ff04c56..0000000 --- a/aspects/users/root.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ ... }: - -{ - flake.modules.nixos.root = - { pkgs, ... }: - { - users.users.root = { - shell = pkgs.fish; - hashedPassword = "!"; - }; - }; -} diff --git a/aspects/users/user.nix b/aspects/users/user.nix deleted file mode 100644 index ad1b8ca..0000000 --- a/aspects/users/user.nix +++ /dev/null @@ -1,118 +0,0 @@ -{ inputs, self, ... }: - -{ - flake = { - modules.nixos.user = - { pkgs, ... }: - { - users.users.user = { - isNormalUser = true; - shell = pkgs.fish; - extraGroups = [ - "networkmanager" - "wheel" - ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" - ]; - hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0"; - }; - }; - - homeConfigurations = { - "user@rotterdam" = inputs.home-manager.lib.homeManagerConfiguration { - pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; - extraSpecialArgs = { - inherit inputs; - hostname = "rotterdam"; - }; - modules = [ - { nixpkgs.overlays = [ inputs.self.overlays.default ]; } - - # CLI aspects (common module included) - inputs.self.modules.homeManager.cli-base - inputs.self.modules.homeManager.cli-btop - inputs.self.modules.homeManager.cli-comma - inputs.self.modules.homeManager.cli-direnv - inputs.self.modules.homeManager.cli-helix - inputs.self.modules.homeManager.cli-starship - inputs.self.modules.homeManager.cli-tmux - - # Shell - inputs.self.modules.homeManager.shell-fish - inputs.self.modules.homeManager.shell-bash - - # Desktop - inputs.self.modules.homeManager.desktop-desktop - inputs.self.modules.homeManager.desktop-niri - - # Gaming - inputs.self.modules.homeManager.gaming-mangohud - - # Programs - inputs.self.modules.homeManager.programs-media # for obs-studio - - # Stylix - inputs.self.modules.homeManager.stylix - - # User-specific (from _user/) - ./_user/git.nix - - # Home configuration - { - home = { - username = "user"; - homeDirectory = "/home/user"; - stateVersion = "22.05"; - }; - } - ]; - }; - - "user@io" = inputs.home-manager.lib.homeManagerConfiguration { - pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; - extraSpecialArgs = { - inherit inputs; - hostname = "io"; - }; - modules = [ - { nixpkgs.overlays = [ inputs.self.overlays.default ]; } - - # CLI aspects (common module included) - inputs.self.modules.homeManager.cli-base - inputs.self.modules.homeManager.cli-btop - inputs.self.modules.homeManager.cli-comma - inputs.self.modules.homeManager.cli-direnv - inputs.self.modules.homeManager.cli-helix - inputs.self.modules.homeManager.cli-starship - inputs.self.modules.homeManager.cli-tmux - - # Shell - inputs.self.modules.homeManager.shell-fish - inputs.self.modules.homeManager.shell-bash - - # Desktop - inputs.self.modules.homeManager.desktop-desktop - inputs.self.modules.homeManager.desktop-niri - - # Stylix - inputs.self.modules.homeManager.stylix - - # User-specific (from _user/) - ./_user/git.nix - - # Home configuration - { - home = { - username = "user"; - homeDirectory = "/home/user"; - stateVersion = "22.05"; - }; - } - ]; - }; - }; - }; -} diff --git a/deploy.nix b/deploy.nix new file mode 100644 index 0000000..187c92f --- /dev/null +++ b/deploy.nix @@ -0,0 +1,48 @@ +{ inputs, self, ... }: +{ + flake.deploy = { + remoteBuild = true; + nodes = { + alexandria = { + hostname = "alexandria"; + profiles.system = { + sshUser = "user"; + path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.alexandria; + user = "root"; + }; + }; + + trantor = { + hostname = "trantor"; + profiles.system = { + sshUser = "user"; + path = inputs.deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.trantor; + user = "root"; + }; + }; + + io = { + hostname = "io"; + profiles = { + system = { + sshUser = "user"; + path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.io; + user = "root"; + remoteBuild = false; + }; + user = { + sshUser = "user"; + path = inputs.deploy-rs.lib.x86_64-linux.activate.home-manager self.homeConfigurations."user@io"; + user = "user"; + remoteBuild = false; + }; + }; + }; + }; + }; + perSystem = + { system, ... }: + { + checks = inputs.deploy-rs.lib.${system}.deployChecks self.deploy; + }; +} diff --git a/shells/default.nix b/devShells.nix similarity index 92% rename from shells/default.nix rename to devShells.nix index a7cda20..1c93cf3 100644 --- a/shells/default.nix +++ b/devShells.nix @@ -7,6 +7,7 @@ devShells.default = pkgs.mkShell { packages = with pkgs; [ inputs.agenix.packages.${system}.default + deploy-rs nil nixfmt ]; diff --git a/flake.lock b/flake.lock index 806550a..b5b63cf 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1770165109, - "narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=", + "lastModified": 1762618334, + "narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=", "owner": "ryantm", "repo": "agenix", - "rev": "b027ee29d959fda4b60b57566d64c98a202e0feb", + "rev": "fcdea223397448d35d9b31f798479227e80183f6", "type": "github" }, "original": { @@ -97,14 +97,14 @@ "nix-ai-tools", "nixpkgs" ], - "systems": "systems_2" + "systems": "systems_3" }, "locked": { - "lastModified": 1769353768, - "narHash": "sha256-zI+7cbMI4wMIR57jMjDSEsVb3grapTnURDxxJPYFIW0=", + "lastModified": 1767386128, + "narHash": "sha256-BJDu7dIMauO2nYRSL4aI8wDNtEm2KOb7lDKP3hxdrpo=", "owner": "numtide", "repo": "blueprint", - "rev": "c7da5c70ad1c9b60b6f5d4f674fbe205d48d8f6c", + "rev": "0ed984d51a3031065925ab08812a5434f40b93d4", "type": "github" }, "original": { @@ -135,16 +135,36 @@ "type": "github" } }, - "disko": { + "deploy-rs": { "inputs": { - "nixpkgs": "nixpkgs" + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs", + "utils": "utils" }, "locked": { - "lastModified": 1769524058, - "narHash": "sha256-zygdD6X1PcVNR2PsyK4ptzrVEiAdbMqLos7utrMDEWE=", + "lastModified": 1766051518, + "narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=", + "owner": "serokell", + "repo": "deploy-rs", + "rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "deploy-rs", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1768923567, + "narHash": "sha256-GVJ0jKsyXLuBzRMXCDY6D5J8wVdwP1DuQmmvYL/Vw/Q=", "owner": "nix-community", "repo": "disko", - "rev": "71a3fc97d80881e91710fe721f1158d3b96ae14d", + "rev": "00395d188e3594a1507f214a2f15d4ce5c07cb28", "type": "github" }, "original": { @@ -170,6 +190,22 @@ } }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1767039857, @@ -185,7 +221,7 @@ "type": "github" } }, - "flake-compat_2": { + "flake-compat_3": { "flake": false, "locked": { "lastModified": 1747046372, @@ -206,11 +242,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1769996383, - "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "lastModified": 1768135262, + "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", "type": "github" }, "original": { @@ -342,11 +378,11 @@ ] }, "locked": { - "lastModified": 1770915843, - "narHash": "sha256-ZwU5wXKNqpOQvjNz6aBp1j5peiBZow1++6pLnk5VAhs=", + "lastModified": 1768927746, + "narHash": "sha256-zyMpWHqcpKVmRc1W2NEK7DAuyVJZV62Jdjqudg70b1k=", "owner": "nix-community", "repo": "home-manager", - "rev": "6a1f7101d2c3ee87d485a87880d73b4665c6a4bd", + "rev": "63a87808f5f9b6e4195a1d33f6ea25d23f4aa0df", "type": "github" }, "original": { @@ -385,11 +421,11 @@ ] }, "locked": { - "lastModified": 1769872935, - "narHash": "sha256-07HMIGQ/WJeAQJooA7Kkg1SDKxhAiV6eodvOwTX6WKI=", + "lastModified": 1768434960, + "narHash": "sha256-cJbFn17oyg6qAraLr+NVeNJrXsrzJdrudkzI4H2iTcg=", "owner": "nix-community", "repo": "home-manager", - "rev": "f4ad5068ee8e89e4a7c2e963e10dd35cd77b37b7", + "rev": "b4d88c9ac42ae1a745283f6547701da43b6e9f9b", "type": "github" }, "original": { @@ -401,14 +437,14 @@ "impermanence": { "inputs": { "home-manager": "home-manager_3", - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1769548169, - "narHash": "sha256-03+JxvzmfwRu+5JafM0DLbxgHttOQZkUtDWBmeUkN8Y=", + "lastModified": 1768835187, + "narHash": "sha256-6nY0ixjGjPQCL+/sUC1B1MRiO1LOI3AkRSIywm3i3bE=", "owner": "nix-community", "repo": "impermanence", - "rev": "7b1d382faf603b6d264f58627330f9faa5cba149", + "rev": "0d633a69480bb3a3e2f18c080d34a8fa81da6395", "type": "github" }, "original": { @@ -417,24 +453,9 @@ "type": "github" } }, - "import-tree": { - "locked": { - "lastModified": 1763762820, - "narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=", - "owner": "vic", - "repo": "import-tree", - "rev": "3c23749d8013ec6daa1d7255057590e9ca726646", - "type": "github" - }, - "original": { - "owner": "vic", - "repo": "import-tree", - "type": "github" - } - }, "niri": { "inputs": { - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_4", "rust-overlay": "rust-overlay" }, "locked": { @@ -456,17 +477,17 @@ "inputs": { "niri-stable": "niri-stable", "niri-unstable": "niri-unstable", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs_5", "nixpkgs-stable": "nixpkgs-stable", "xwayland-satellite-stable": "xwayland-satellite-stable", "xwayland-satellite-unstable": "xwayland-satellite-unstable" }, "locked": { - "lastModified": 1770844822, - "narHash": "sha256-QgJZ+W6YE6nAzO/m7ezamAzr9DTflIEXRozMivL0+hc=", + "lastModified": 1768877436, + "narHash": "sha256-ct4qxmFJeJbaJKiOnXOZmRmVmk7TpT+lohuTgTr+kYQ=", "owner": "sodiboo", "repo": "niri-flake", - "rev": "7634add8bf2dd225d04f535de4bd0ee60982f367", + "rev": "6581f5458309233622c1b73c8902dcaea7be16eb", "type": "github" }, "original": { @@ -495,11 +516,11 @@ "niri-unstable": { "flake": false, "locked": { - "lastModified": 1770735554, - "narHash": "sha256-8GzUa8bCyQ688jYW2waXrOqetTr7oV8UPTO2He+5Hsg=", + "lastModified": 1768678265, + "narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=", "owner": "YaLTeR", "repo": "niri", - "rev": "41b5de87692b8262fbdbff7faab93f04ff0be453", + "rev": "d7184a04b904e07113f4623610775ae78d32394c", "type": "github" }, "original": { @@ -511,15 +532,15 @@ "nix-ai-tools": { "inputs": { "blueprint": "blueprint", - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_6", "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1770907059, - "narHash": "sha256-HQXK2CXAhBuTBw99Ip018Vp9MMAPfJVywgRrkwMUgMc=", + "lastModified": 1768922080, + "narHash": "sha256-gFoGvnW2YDWsxKD56kdiXbhh9vBPAU3yusssbXF0UMo=", "owner": "numtide", "repo": "llm-agents.nix", - "rev": "266d4d8a55eef6dd23cd0adced301053d8fc23c9", + "rev": "78f3fdc13ef903475aa5bfc0f85eeefaa36af837", "type": "github" }, "original": { @@ -551,11 +572,11 @@ ] }, "locked": { - "lastModified": 1770315571, - "narHash": "sha256-hy0gcAgAcxrnSWKGuNO+Ob0x6jQ2xkR6hoaR0qJBHYs=", + "lastModified": 1765267181, + "narHash": "sha256-d3NBA9zEtBu2JFMnTBqWj7Tmi7R5OikoU2ycrdhQEws=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "2684bb8080a6f2ca5f9d494de5ef875bc1c4ecdb", + "rev": "82befcf7dc77c909b0f2a09f5da910ec95c5b78f", "type": "github" }, "original": { @@ -566,17 +587,17 @@ }, "nixos-cli": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": "flake-compat_2", "flake-parts": "flake-parts_2", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_7", "optnix": "optnix" }, "locked": { - "lastModified": 1770862985, - "narHash": "sha256-TFRhwVzPg3ly388J3CYYvjrma/dWjsBVpNE437bWeHk=", + "lastModified": 1768778579, + "narHash": "sha256-6w1Mhg6+46LlaheCa1O/jIk02ukerZ7DdUf9GlQVGxc=", "owner": "nix-community", "repo": "nixos-cli", - "rev": "9a2e97e8832b211df22c5cb21a55ebf1c3eb2be1", + "rev": "5e79001c7a8b556c3c61d4ef38f0f0fa1187ee90", "type": "github" }, "original": { @@ -587,11 +608,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1769330179, - "narHash": "sha256-yxgb4AmkVHY5OOBrC79Vv6EVd4QZEotqv+6jcvA212M=", + "lastModified": 1743014863, + "narHash": "sha256-jAIUqsiN2r3hCuHji80U7NNEafpIMBXiwKlSrjWMlpg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "48698d12cc10555a4f3e3222d9c669b884a49dfe", + "rev": "bd3bac8bfb542dbde7ffffb6987a1a1f9d41699f", "type": "github" }, "original": { @@ -603,11 +624,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1769909678, - "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "72716169fe93074c333e8d0173151350670b824c", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", "type": "github" }, "original": { @@ -633,11 +654,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1770770419, - "narHash": "sha256-iKZMkr6Cm9JzWlRYW/VPoL0A9jVKtZYiU4zSrVeetIs=", + "lastModified": 1768773494, + "narHash": "sha256-XsM7GP3jHlephymxhDE+/TKKO1Q16phz/vQiLBGhpF4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6c5e707c6b5339359a9a9e215c5e66d6d802fd7a", + "rev": "77ef7a29d276c6d8303aece3444d61118ef71ac2", "type": "github" }, "original": { @@ -649,11 +670,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1770770419, - "narHash": "sha256-iKZMkr6Cm9JzWlRYW/VPoL0A9jVKtZYiU4zSrVeetIs=", + "lastModified": 1768773494, + "narHash": "sha256-XsM7GP3jHlephymxhDE+/TKKO1Q16phz/vQiLBGhpF4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6c5e707c6b5339359a9a9e215c5e66d6d802fd7a", + "rev": "77ef7a29d276c6d8303aece3444d61118ef71ac2", "type": "github" }, "original": { @@ -664,150 +685,6 @@ } }, "nixpkgs_10": { - "locked": { - "lastModified": 1762111121, - "narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_11": { - "locked": { - "lastModified": 1769461804, - "narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1768564909, - "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1757967192, - "narHash": "sha256-/aA9A/OBmnuOMgwfzdsXRusqzUpd8rQnQY8jtrHK+To=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "0d7c15863b251a7a50265e57c1dca1a7add2e291", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1770562336, - "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1770843696, - "narHash": "sha256-LovWTGDwXhkfCOmbgLVA10bvsi/P8eDDpRudgk68HA8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "2343bbb58f99267223bc2aac4fc9ea301a155a16", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1767151656, - "narHash": "sha256-ujL2AoYBnJBN262HD95yer7QYUmYp5kFZGYbyCCKxq8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "f665af0cdb70ed27e1bd8f9fdfecaf451260fc55", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_7": { - "locked": { - "lastModified": 1759070547, - "narHash": "sha256-JVZl8NaVRYb0+381nl7LvPE+A774/dRpif01FKLrYFQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "647e5c14cbd5067f44ac86b74f014962df460840", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_8": { - "locked": { - "lastModified": 1770562336, - "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_9": { "locked": { "lastModified": 1767767207, "narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=", @@ -823,6 +700,166 @@ "type": "github" } }, + "nixpkgs_11": { + "locked": { + "lastModified": 1762111121, + "narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_12": { + "locked": { + "lastModified": 1768127708, + "narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1768661221, + "narHash": "sha256-MJwOjrIISfOpdI9x4C+5WFQXvHtOuj5mqLZ4TMEtk1M=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3327b113f2ef698d380df83fbccefad7e83d7769", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1757967192, + "narHash": "sha256-/aA9A/OBmnuOMgwfzdsXRusqzUpd8rQnQY8jtrHK+To=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0d7c15863b251a7a50265e57c1dca1a7add2e291", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1768783163, + "narHash": "sha256-tLj4KcRDLakrlpvboTJDKsrp6z2XLwyQ4Zmo+w8KsY4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "bde09022887110deb780067364a0818e89258968", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1767151656, + "narHash": "sha256-ujL2AoYBnJBN262HD95yer7QYUmYp5kFZGYbyCCKxq8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f665af0cdb70ed27e1bd8f9fdfecaf451260fc55", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1759070547, + "narHash": "sha256-JVZl8NaVRYb0+381nl7LvPE+A774/dRpif01FKLrYFQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "647e5c14cbd5067f44ac86b74f014962df460840", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_9": { + "locked": { + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "noctalia": { "inputs": { "nixpkgs": [ @@ -830,11 +867,11 @@ ] }, "locked": { - "lastModified": 1770922006, - "narHash": "sha256-xg40mnp5KKBepACmvlPzmn5iPyUBxktfv50saSVUn0M=", + "lastModified": 1768924718, + "narHash": "sha256-T4H/VMjGwBuHEIrPYWfXQ73XV0foCuFGgH7k3SNSJDo=", "owner": "noctalia-dev", "repo": "noctalia-shell", - "rev": "d87364964948b9d691f8363f85a5e23bee154df9", + "rev": "1ef5c0eb307e8a4f30dfa6bcc75cf90ae8c6af46", "type": "github" }, "original": { @@ -870,8 +907,8 @@ }, "optnix": { "inputs": { - "flake-compat": "flake-compat_2", - "nixpkgs": "nixpkgs_7" + "flake-compat": "flake-compat_3", + "nixpkgs": "nixpkgs_8" }, "locked": { "lastModified": 1765418479, @@ -890,18 +927,18 @@ "root": { "inputs": { "agenix": "agenix", + "deploy-rs": "deploy-rs", "disko": "disko", "flake-parts": "flake-parts", "home-manager": "home-manager_2", "impermanence": "impermanence", - "import-tree": "import-tree", "niri": "niri", "niri-flake": "niri-flake", "nix-ai-tools": "nix-ai-tools", "nix-flatpak": "nix-flatpak", "nix-index-database": "nix-index-database", "nixos-cli": "nixos-cli", - "nixpkgs": "nixpkgs_8", + "nixpkgs": "nixpkgs_9", "nixpkgs-stable": "nixpkgs-stable_2", "noctalia": "noctalia", "stylix": "stylix", @@ -940,9 +977,9 @@ "firefox-gnome-theme": "firefox-gnome-theme", "flake-parts": "flake-parts_3", "gnome-shell": "gnome-shell", - "nixpkgs": "nixpkgs_9", + "nixpkgs": "nixpkgs_10", "nur": "nur", - "systems": "systems_3", + "systems": "systems_4", "tinted-foot": "tinted-foot", "tinted-kitty": "tinted-kitty", "tinted-schemes": "tinted-schemes", @@ -950,11 +987,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1770914701, - "narHash": "sha256-QHFYyngohNhih4w+3IqQty5DV+p1txsx1kkk6XJWar8=", + "lastModified": 1768744881, + "narHash": "sha256-3+h7OxqfrPIB/tRsiZXWE9sCbTm7NQN5Ie428p+S6BA=", "owner": "danth", "repo": "stylix", - "rev": "db03fed72e5ca02be34e1d24789345a943329738", + "rev": "06684f00cfbee14da96fd4307b966884de272d3a", "type": "github" }, "original": { @@ -1038,13 +1075,28 @@ "type": "github" } }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "terranix": { "inputs": { "flake-parts": "flake-parts_4", "nixpkgs": [ "nixpkgs" ], - "systems": "systems_4" + "systems": "systems_5" }, "locked": { "lastModified": 1762472226, @@ -1149,11 +1201,11 @@ ] }, "locked": { - "lastModified": 1770228511, - "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", + "lastModified": 1768158989, + "narHash": "sha256-67vyT1+xClLldnumAzCTBvU0jLZ1YBcf4vANRWP3+Ak=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", + "rev": "e96d59dff5c0d7fddb9d113ba108f03c3ef99eca", "type": "github" }, "original": { @@ -1162,17 +1214,35 @@ "type": "github" } }, - "vicinae": { + "utils": { "inputs": { - "nixpkgs": "nixpkgs_10", - "systems": "systems_5" + "systems": "systems_2" }, "locked": { - "lastModified": 1770912475, - "narHash": "sha256-21lurBRyHgJbVD3E0/i7Fhxi4rBUxyznGfKpdGVtEdc=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "vicinae": { + "inputs": { + "nixpkgs": "nixpkgs_11", + "systems": "systems_6" + }, + "locked": { + "lastModified": 1768856963, + "narHash": "sha256-u5bWDuwk6oieTnvm1YjNotcYK8iJSddH5+S68+X4TSc=", "owner": "vicinaehq", "repo": "vicinae", - "rev": "0c70267ab7e07d7972012fcf8ae58808a32a2e86", + "rev": "934bc0ad47be6dbd6498a0dac655c4613fd0ab27", "type": "github" }, "original": { @@ -1201,11 +1271,11 @@ "xwayland-satellite-unstable": { "flake": false, "locked": { - "lastModified": 1770583271, - "narHash": "sha256-Q75S8cEqJoZ92s1y4zArvk2U1ayAy2E4SaF7gbNXkYQ=", + "lastModified": 1768765571, + "narHash": "sha256-C1JbyJ3ftogmN3vmLNfyPtnJw2wY64TiUTIhFtk1Leg=", "owner": "Supreeeme", "repo": "xwayland-satellite", - "rev": "86f5bd5d867ad6e120935dfe825f6b903ebbeddd", + "rev": "ed1cef792b4def3321ff9ab5479df09609f17a69", "type": "github" }, "original": { @@ -1217,14 +1287,14 @@ "zen-browser": { "inputs": { "home-manager": "home-manager_4", - "nixpkgs": "nixpkgs_11" + "nixpkgs": "nixpkgs_12" }, "locked": { - "lastModified": 1770919290, - "narHash": "sha256-iJ9c0ZewfRRYUflaEOj43n5TWaB6Ezygn2UA/ZHGQJA=", + "lastModified": 1768919538, + "narHash": "sha256-w10iy/aqd5LtD78NDWWG+eKGzkb+cGhAAo7PVciLbWE=", "owner": "0xc000022070", "repo": "zen-browser-flake", - "rev": "0078cf2d5e81eb56a9356d51f2738f7141194de1", + "rev": "37149a5b77e8fd2b5332e8cec9edf39ca5b8e8bc", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 6026fa3..20210f2 100644 --- a/flake.nix +++ b/flake.nix @@ -2,61 +2,61 @@ description = "My nix hosts"; inputs = { - # nix tools flake-parts.url = "github:hercules-ci/flake-parts"; - import-tree.url = "github:vic/import-tree"; - # nixos/hm nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11"; + home-manager = { url = "github:nix-community/home-manager/master"; inputs.nixpkgs.follows = "nixpkgs"; }; - # nixos/hm functionality modules agenix = { url = "github:ryantm/agenix"; inputs.nixpkgs.follows = "nixpkgs-stable"; }; - disko.url = "github:nix-community/disko"; - impermanence.url = "github:nix-community/impermanence"; - nixos-cli.url = "github:nix-community/nixos-cli"; - nix-flatpak.url = "github:gmodena/nix-flatpak/main"; - stylix.url = "github:danth/stylix"; - # nixos/hm program modules - niri-flake.url = "github:sodiboo/niri-flake"; - nix-ai-tools.url = "github:numtide/llm-agents.nix"; - nix-index-database = { - url = "github:nix-community/nix-index-database"; - inputs.nixpkgs.follows = "nixpkgs"; - }; + disko.url = "github:nix-community/disko"; + noctalia = { url = "github:noctalia-dev/noctalia-shell"; inputs.nixpkgs.follows = "nixpkgs"; }; - vicinae.url = "github:vicinaehq/vicinae"; + + stylix.url = "github:danth/stylix"; + + nixos-cli.url = "github:nix-community/nixos-cli"; + + nix-flatpak.url = "github:gmodena/nix-flatpak/main"; + zen-browser.url = "github:0xc000022070/zen-browser-flake"; - # stand-alone tools + impermanence.url = "github:nix-community/impermanence"; + + deploy-rs.url = "github:serokell/deploy-rs"; + + niri-flake.url = "github:sodiboo/niri-flake"; + + niri.url = "github:baduhai/niri/auto-center-when-space-available"; + + nix-index-database = { + url = "github:nix-community/nix-index-database"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + terranix = { url = "github:terranix/terranix"; inputs.nixpkgs.follows = "nixpkgs"; }; - # others - niri.url = "github:baduhai/niri/auto-center-when-space-available"; + nix-ai-tools.url = "github:numtide/llm-agents.nix"; + + vicinae.url = "github:vicinaehq/vicinae"; }; outputs = - inputs@{ flake-parts, import-tree, ... }: - let - aspectsModules = import-tree ./aspects; - packagesModules = import-tree ./packages; - shellsModules = import-tree ./shells; - terranixModules = import-tree ./terranix; - in + inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" @@ -64,12 +64,14 @@ ]; imports = [ - flake-parts.flakeModules.modules - inputs.terranix.flakeModule - ] - ++ aspectsModules.imports - ++ packagesModules.imports - ++ shellsModules.imports - ++ terranixModules.imports; + ./deploy.nix + ./devShells.nix + ./homeConfigurations.nix + ./nixosConfigurations.nix + ./nixosModules.nix + ./overlays.nix + ./packages.nix + ./terranixConfigurations.nix + ]; }; } diff --git a/homeConfigurations.nix b/homeConfigurations.nix new file mode 100644 index 0000000..296abfa --- /dev/null +++ b/homeConfigurations.nix @@ -0,0 +1,43 @@ +{ inputs, ... }: + +let + lib = inputs.nixpkgs.lib; + utils = import ./utils.nix { inherit inputs lib; }; + inherit (utils) mkHome; +in + +{ + flake.homeConfigurations = { + "user@rotterdam" = mkHome { + username = "user"; + hostname = "rotterdam"; + tags = [ + "desktop" + "btop" + "comma" + "direnv" + "gaming" + "helix" + "obs-studio" + "starship" + "stylix" + "tmux" + ]; + }; + + "user@io" = mkHome { + username = "user"; + hostname = "io"; + tags = [ + "desktop" + "btop" + "comma" + "direnv" + "helix" + "starship" + "stylix" + "tmux" + ]; + }; + }; +} diff --git a/aspects/hosts/_alexandria/hardware-configuration.nix b/hosts/alexandria/hardware-configuration.nix similarity index 100% rename from aspects/hosts/_alexandria/hardware-configuration.nix rename to hosts/alexandria/hardware-configuration.nix diff --git a/aspects/hosts/_alexandria/jellyfin.nix b/hosts/alexandria/jellyfin.nix similarity index 73% rename from aspects/hosts/_alexandria/jellyfin.nix rename to hosts/alexandria/jellyfin.nix index 0b024bd..6ceac09 100644 --- a/aspects/hosts/_alexandria/jellyfin.nix +++ b/hosts/alexandria/jellyfin.nix @@ -1,6 +1,7 @@ { lib, inputs, ... }: let - mkNginxVHosts = inputs.self.lib.mkNginxVHosts; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts; in { services.jellyfin = { diff --git a/aspects/hosts/_alexandria/kanidm.nix b/hosts/alexandria/kanidm.nix similarity index 95% rename from aspects/hosts/_alexandria/kanidm.nix rename to hosts/alexandria/kanidm.nix index 35e08c8..eaaa9b9 100644 --- a/aspects/hosts/_alexandria/kanidm.nix +++ b/hosts/alexandria/kanidm.nix @@ -7,7 +7,8 @@ }: let - mkNginxVHosts = inputs.self.lib.mkNginxVHosts; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts; kanidmCertDir = "/var/lib/kanidm/certs"; in diff --git a/aspects/hosts/_alexandria/nextcloud.nix b/hosts/alexandria/nextcloud.nix similarity index 91% rename from aspects/hosts/_alexandria/nextcloud.nix rename to hosts/alexandria/nextcloud.nix index c4a9669..c449cce 100644 --- a/aspects/hosts/_alexandria/nextcloud.nix +++ b/hosts/alexandria/nextcloud.nix @@ -7,7 +7,8 @@ }: let - mkNginxVHosts = inputs.self.lib.mkNginxVHosts; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts; in { @@ -83,12 +84,12 @@ in age.secrets = { "nextcloud-secrets.json" = { - file = ../../../secrets/nextcloud-secrets.json.age; + file = ../../secrets/nextcloud-secrets.json.age; owner = "nextcloud"; group = "nextcloud"; }; nextcloud-adminpass = { - file = ../../../secrets/nextcloud-adminpass.age; + file = ../../secrets/nextcloud-adminpass.age; owner = "nextcloud"; group = "nextcloud"; }; diff --git a/aspects/hosts/_alexandria/nginx.nix b/hosts/alexandria/nginx.nix similarity index 88% rename from aspects/hosts/_alexandria/nginx.nix rename to hosts/alexandria/nginx.nix index 26a7ba1..274f645 100644 --- a/aspects/hosts/_alexandria/nginx.nix +++ b/hosts/alexandria/nginx.nix @@ -6,7 +6,8 @@ }: let - services = inputs.self.services; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts services; # Get all unique domains from shared services that have LAN IPs (served by this host) localDomains = lib.unique (map (s: s.domain) (lib.filter (s: s.host == "alexandria") services)); @@ -51,7 +52,7 @@ in ]; age.secrets.cloudflare = { - file = ../../../secrets/cloudflare.age; + file = ../../secrets/cloudflare.age; owner = "nginx"; group = "nginx"; }; diff --git a/aspects/hosts/_alexandria/unbound.nix b/hosts/alexandria/unbound.nix similarity index 91% rename from aspects/hosts/_alexandria/unbound.nix rename to hosts/alexandria/unbound.nix index 07c8850..31363aa 100644 --- a/aspects/hosts/_alexandria/unbound.nix +++ b/hosts/alexandria/unbound.nix @@ -1,7 +1,7 @@ { inputs, lib, ... }: let - services = inputs.self.services; + utils = import ../../utils.nix { inherit inputs lib; }; in { @@ -35,7 +35,7 @@ in # LAN-only DNS records local-zone = ''"baduhai.dev." transparent''; local-data = map (e: ''"${e.domain}. IN A ${e.lanIP}"'') - (lib.filter (e: e.lanIP != null) services); + (lib.filter (e: e ? lanIP) utils.services); }; forward-zone = [ diff --git a/aspects/hosts/_alexandria/vaultwarden.nix b/hosts/alexandria/vaultwarden.nix similarity index 84% rename from aspects/hosts/_alexandria/vaultwarden.nix rename to hosts/alexandria/vaultwarden.nix index 8577b2d..2335ee0 100644 --- a/aspects/hosts/_alexandria/vaultwarden.nix +++ b/hosts/alexandria/vaultwarden.nix @@ -5,7 +5,8 @@ ... }: let - mkNginxVHosts = inputs.self.lib.mkNginxVHosts; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts; in { services.vaultwarden = { diff --git a/aspects/hosts/_io/boot.nix b/hosts/io/boot.nix similarity index 100% rename from aspects/hosts/_io/boot.nix rename to hosts/io/boot.nix diff --git a/aspects/hosts/_io/disko.nix b/hosts/io/disko.nix similarity index 100% rename from aspects/hosts/_io/disko.nix rename to hosts/io/disko.nix diff --git a/aspects/hosts/_io/hardware-configuration.nix b/hosts/io/hardware-configuration.nix similarity index 100% rename from aspects/hosts/_io/hardware-configuration.nix rename to hosts/io/hardware-configuration.nix diff --git a/aspects/hosts/_io/programs.nix b/hosts/io/programs.nix similarity index 100% rename from aspects/hosts/_io/programs.nix rename to hosts/io/programs.nix diff --git a/aspects/hosts/_io/services.nix b/hosts/io/services.nix similarity index 100% rename from aspects/hosts/_io/services.nix rename to hosts/io/services.nix diff --git a/hosts/modules/ai.nix b/hosts/modules/ai.nix new file mode 100644 index 0000000..b80ac38 --- /dev/null +++ b/hosts/modules/ai.nix @@ -0,0 +1,11 @@ +{ inputs, pkgs, ... }: + +{ + environment.systemPackages = + (with pkgs; [claude-desktop]) ++ + (with inputs.nix-ai-tools.packages.${pkgs.system}; [ + claude-code + claudebox + opencode + ]); +} diff --git a/hosts/modules/bluetooth.nix b/hosts/modules/bluetooth.nix new file mode 100644 index 0000000..fb6a06a --- /dev/null +++ b/hosts/modules/bluetooth.nix @@ -0,0 +1,5 @@ +{ ... }: + +{ + hardware.bluetooth.enable = true; +} diff --git a/hosts/modules/common/boot.nix b/hosts/modules/common/boot.nix new file mode 100644 index 0000000..fbba278 --- /dev/null +++ b/hosts/modules/common/boot.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: + +{ + boot = { + loader = { + timeout = 1; + efi.canTouchEfiVariables = true; + systemd-boot = { + enable = true; + editor = false; + consoleMode = "max"; + sortKey = "aa"; + netbootxyz = { + enable = true; + sortKey = "zz"; + }; + }; + }; + }; +} diff --git a/hosts/modules/common/console.nix b/hosts/modules/common/console.nix new file mode 100644 index 0000000..9cb99d4 --- /dev/null +++ b/hosts/modules/common/console.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + console = { + useXkbConfig = true; + earlySetup = true; + }; +} diff --git a/hosts/modules/common/firewall.nix b/hosts/modules/common/firewall.nix new file mode 100644 index 0000000..910e803 --- /dev/null +++ b/hosts/modules/common/firewall.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + networking = { + firewall.enable = true; + nftables.enable = true; + }; +} diff --git a/hosts/modules/common/locale.nix b/hosts/modules/common/locale.nix new file mode 100644 index 0000000..1171a32 --- /dev/null +++ b/hosts/modules/common/locale.nix @@ -0,0 +1,21 @@ +{ ... }: + +{ + time.timeZone = "America/Bahia"; + + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "pt_BR.utf8"; + LC_COLLATE = "pt_BR.utf8"; + LC_IDENTIFICATION = "pt_BR.utf8"; + LC_MEASUREMENT = "pt_BR.utf8"; + LC_MONETARY = "pt_BR.utf8"; + LC_NAME = "pt_BR.utf8"; + LC_NUMERIC = "pt_BR.utf8"; + LC_PAPER = "pt_BR.utf8"; + LC_TELEPHONE = "pt_BR.utf8"; + LC_TIME = "en_IE.utf8"; + }; + }; +} diff --git a/hosts/modules/common/nix.nix b/hosts/modules/common/nix.nix new file mode 100644 index 0000000..5ef9c4c --- /dev/null +++ b/hosts/modules/common/nix.nix @@ -0,0 +1,38 @@ +{ inputs, ... }: + +{ + imports = [ inputs.nixos-cli.nixosModules.nixos-cli ]; + + nix = { + settings = { + auto-optimise-store = true; + connect-timeout = 10; + log-lines = 25; + min-free = 128000000; + max-free = 1000000000; + trusted-users = [ "@wheel" ]; + }; + extraOptions = "experimental-features = nix-command flakes"; + gc = { + automatic = true; + options = "--delete-older-than 8d"; + }; + }; + + nixpkgs.config = { + allowUnfree = true; + enableParallelBuilding = true; + buildManPages = false; + buildDocs = false; + }; + + services.nixos-cli = { + enable = true; + config = { + use_nvd = true; + ignore_dirty_tree = true; + }; + }; + + system.stateVersion = "22.11"; +} diff --git a/hosts/modules/common/openssh.nix b/hosts/modules/common/openssh.nix new file mode 100644 index 0000000..df70bdd --- /dev/null +++ b/hosts/modules/common/openssh.nix @@ -0,0 +1,11 @@ +{ ... }: + +{ + services.openssh = { + enable = true; + settings.PermitRootLogin = "no"; + extraConfig = '' + PrintLastLog no + ''; + }; +} diff --git a/hosts/modules/common/programs.nix b/hosts/modules/common/programs.nix new file mode 100644 index 0000000..fd10953 --- /dev/null +++ b/hosts/modules/common/programs.nix @@ -0,0 +1,40 @@ +{ lib, pkgs, ... }: + +{ + environment = { + systemPackages = with pkgs; [ + ### Dev Tools ### + git + ### System Utilities ### + btop + fastfetch + helix + nixos-firewall-tool + nvd + sysz + tmux + wget + yazi + ]; + shellAliases = { + cat = "${lib.getExe pkgs.bat} --paging=never --style=plain"; + ls = "${lib.getExe pkgs.eza} --icons --group-directories-first"; + tree = "ls --tree"; + }; + }; + + programs = { + command-not-found.enable = false; + fish = { + enable = true; + interactiveShellInit = '' + set fish_greeting + if set -q SSH_CONNECTION + export TERM=xterm-256color + clear + fastfetch + end + ''; + }; + }; +} diff --git a/hosts/modules/common/security.nix b/hosts/modules/common/security.nix new file mode 100644 index 0000000..33d4953 --- /dev/null +++ b/hosts/modules/common/security.nix @@ -0,0 +1,13 @@ +{ ... }: + +{ + security = { + unprivilegedUsernsClone = true; # Needed for rootless podman + sudo = { + wheelNeedsPassword = false; + extraConfig = '' + Defaults lecture = never + ''; + }; + }; +} diff --git a/hosts/modules/common/services.nix b/hosts/modules/common/services.nix new file mode 100644 index 0000000..89ac527 --- /dev/null +++ b/hosts/modules/common/services.nix @@ -0,0 +1,9 @@ +{ ... }: + +{ + services = { + dbus.implementation = "broker"; + irqbalance.enable = true; + fstrim.enable = true; + }; +} diff --git a/hosts/modules/common/tailscale.nix b/hosts/modules/common/tailscale.nix new file mode 100644 index 0000000..98bea97 --- /dev/null +++ b/hosts/modules/common/tailscale.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + services.tailscale = { + enable = true; + extraUpFlags = [ "--operator=user" ]; + }; +} diff --git a/hosts/modules/common/users.nix b/hosts/modules/common/users.nix new file mode 100644 index 0000000..7dd6490 --- /dev/null +++ b/hosts/modules/common/users.nix @@ -0,0 +1,24 @@ +{ pkgs, ... }: + +{ + users.users = { + user = { + isNormalUser = true; + shell = pkgs.fish; + extraGroups = [ + "networkmanager" + "wheel" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" + ]; + hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0"; + }; + root = { + shell = pkgs.fish; + hashedPassword = "!"; + }; + }; +} diff --git a/hosts/modules/desktop/boot.nix b/hosts/modules/desktop/boot.nix new file mode 100644 index 0000000..0ac4847 --- /dev/null +++ b/hosts/modules/desktop/boot.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: + +{ + boot = { + plymouth.enable = true; + initrd.systemd.enable = true; + loader.efi.efiSysMountPoint = "/boot/efi"; + kernelPackages = pkgs.linuxPackages_xanmod_latest; + extraModprobeConfig = '' + options bluetooth disable_ertm=1 + ''; + kernel.sysctl = { + "net.ipv4.tcp_mtu_probing" = 1; + }; + kernelParams = [ + "quiet" + "splash" + "i2c-dev" + "i2c-piix4" + "loglevel=3" + "udev.log_priority=3" + "rd.udev.log_level=3" + "rd.systemd.show_status=false" + ]; + }; +} diff --git a/hosts/modules/desktop/desktop.nix b/hosts/modules/desktop/desktop.nix new file mode 100644 index 0000000..7510c02 --- /dev/null +++ b/hosts/modules/desktop/desktop.nix @@ -0,0 +1,163 @@ +{ + config, + inputs, + lib, + pkgs, + ... +}: + +{ + imports = [ + inputs.niri-flake.nixosModules.niri + inputs.nix-flatpak.nixosModules.nix-flatpak + ]; + + environment = { + sessionVariables = { + KDEHOME = "$XDG_CONFIG_HOME/kde4"; # Stops kde from placing a .kde4 folder in the home dir + NIXOS_OZONE_WL = "1"; # Forces chromium and most electron apps to run in wayland + }; + systemPackages = with pkgs; [ + ### Web ### + bitwarden-desktop + fragments + nextcloud-client + tor-browser + vesktop + inputs.zen-browser.packages."${system}".default + ### Office & Productivity ### + aspell + aspellDicts.de + aspellDicts.en + aspellDicts.en-computers + aspellDicts.pt_BR + papers + presenterm + rnote + ### Graphics & Design ### + gimp + inkscape + plasticity + ### System Utilities ### + adwaita-icon-theme + ghostty + gnome-disk-utility + junction + libfido2 + mission-center + nautilus + p7zip + rclone + toggleaudiosink + unrar + ### Media ### + decibels + loupe + obs-studio + showtime + ]; + }; + + services = { + pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber.enable = true; + }; + greetd = { + enable = true; + settings = { + default_session = { + command = "${lib.getExe pkgs.tuigreet} --user-menu --time --remember --asterisks --cmd ${config.programs.niri.package}/bin/niri-session"; + user = "greeter"; + }; + } + // lib.optionalAttrs (config.networking.hostName == "io") { + initial_session = { + command = "${config.programs.niri.package}/bin/niri-session"; + user = "user"; + }; + }; + }; + flatpak = { + enable = true; + packages = [ + ### Office & Productivity ### + "com.collabora.Office" + ### Graphics & Design ### + "com.boxy_svg.BoxySVG" + rec { + appId = "io.github.softfever.OrcaSlicer"; + sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1"; + bundle = "${pkgs.fetchurl { + url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak"; + inherit sha256; + }}"; + } + ### System Utilities ### + "com.github.tchx84.Flatseal" + "com.rustdesk.RustDesk" + ]; + uninstallUnmanaged = true; + update.auto.enable = true; + }; + gvfs.enable = true; + }; + + security.rtkit.enable = true; # Needed for pipewire to acquire realtime priority + + users = { + users.greeter = { + isSystemUser = true; + group = "greeter"; + }; + groups.greeter = { }; + }; + + programs = { + niri = { + enable = true; + package = inputs.niri.packages.${pkgs.system}.niri; + }; + kdeconnect = { + enable = true; + package = pkgs.valent; + }; + dconf.enable = true; + appimage = { + enable = true; + binfmt = true; + }; + }; + + niri-flake.cache.enable = false; + + fonts = { + fontDir.enable = true; + packages = with pkgs; [ + corefonts + inter + nerd-fonts.fira-code + noto-fonts-cjk-sans + noto-fonts-color-emoji + roboto + ]; + }; + + xdg.portal = { + extraPortals = with pkgs; [ + xdg-desktop-portal-gnome + xdg-desktop-portal-gtk + ]; + config = { + common.default = "*"; + niri.default = [ + "gtk" + "gnome" + ]; + }; + }; +} diff --git a/hosts/modules/desktop/nix.nix b/hosts/modules/desktop/nix.nix new file mode 100644 index 0000000..54a3549 --- /dev/null +++ b/hosts/modules/desktop/nix.nix @@ -0,0 +1,13 @@ +{ inputs, ... }: + +{ + environment.etc."channels/nixpkgs".source = inputs.nixpkgs.outPath; + + nix = { + registry.nixpkgs.flake = inputs.nixpkgs; + nixPath = [ + "nixpkgs=${inputs.nixpkgs}" + "/nix/var/nix/profiles/per-user/root/channels" + ]; + }; +} diff --git a/hosts/modules/desktop/services.nix b/hosts/modules/desktop/services.nix new file mode 100644 index 0000000..66b78f1 --- /dev/null +++ b/hosts/modules/desktop/services.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: + +{ + services = { + printing.enable = true; + udev.packages = with pkgs; [ yubikey-personalization ]; + keyd = { + enable = true; + keyboards.all = { + ids = [ "*" ]; + settings.main.capslock = "overload(meta, esc)"; + }; + }; + }; +} diff --git a/hosts/modules/dev.nix b/hosts/modules/dev.nix new file mode 100644 index 0000000..d9c31f7 --- /dev/null +++ b/hosts/modules/dev.nix @@ -0,0 +1,18 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + android-tools + bat + lazygit + fd + fzf + glow + nixfmt + nix-init + nix-output-monitor + ripgrep + ]; + + users.users.user.extraGroups = [ "adbusers" ]; +} diff --git a/hosts/modules/ephemeral.nix b/hosts/modules/ephemeral.nix new file mode 100644 index 0000000..e962a89 --- /dev/null +++ b/hosts/modules/ephemeral.nix @@ -0,0 +1,43 @@ +{ config, inputs, ... }: + +{ + imports = [ + inputs.impermanence.nixosModules.impermanence + inputs.self.nixosModules.ephemeral + ]; + + ephemeral = { + enable = true; + rootDevice = + if config.networking.hostName == "trantor" then + "/dev/disk/by-id/scsi-360b207ed25d84372a95d1ecf842f8e20-part2" + else + "/dev/mapper/cryptroot"; + rootSubvolume = "@root"; + }; + + fileSystems."/persistent".neededForBoot = true; + + environment.persistence.main = { + persistentStoragePath = "/persistent"; + files = [ + "/etc/machine-id" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + directories = [ + "/etc/NetworkManager/system-connections" + "/etc/nixos" + "/var/lib/bluetooth" + "/var/lib/flatpak" + "/var/lib/lxd" + "/var/lib/nixos" + "/var/lib/systemd/coredump" + "/var/lib/systemd/timers" + "/var/lib/tailscale" + "/var/log" + ]; + }; +} diff --git a/hosts/modules/fwupd.nix b/hosts/modules/fwupd.nix new file mode 100644 index 0000000..52dc13e --- /dev/null +++ b/hosts/modules/fwupd.nix @@ -0,0 +1,5 @@ +{ ... }: + +{ + services.fwupd.enable = true; +} diff --git a/hosts/modules/gaming.nix b/hosts/modules/gaming.nix new file mode 100644 index 0000000..0f00fe3 --- /dev/null +++ b/hosts/modules/gaming.nix @@ -0,0 +1,43 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + clonehero + heroic + mangohud + prismlauncher + steam-run + ]; + + programs = { + steam = { + enable = true; + extraCompatPackages = [ pkgs.proton-ge-bin ]; + }; + gamemode.enable = true; + }; + + hardware = { + xpadneo.enable = true; + steam-hardware.enable = true; # Allow steam client to manage controllers + graphics.enable32Bit = true; # For OpenGL games + }; + + services.flatpak.packages = [ + "com.github.k4zmu2a.spacecadetpinball" + "com.steamgriddb.SGDBoop" + "io.github.Foldex.AdwSteamGtk" + "io.itch.itch" + "io.mrarm.mcpelauncher" + "net.retrodeck.retrodeck" + "org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/25.08" + rec { + appId = "com.hypixel.HytaleLauncher"; + sha256 = "01307s44bklc1ldcigcn9n4lm8hf8q793v9fv7w4w04xd5zyh4rv"; + bundle = "${pkgs.fetchurl { + url = "https://launcher.hytale.com/builds/release/linux/amd64/hytale-launcher-latest.flatpak"; + inherit sha256; + }}"; + } + ]; +} diff --git a/hosts/modules/libvirtd.nix b/hosts/modules/libvirtd.nix new file mode 100644 index 0000000..6bd154f --- /dev/null +++ b/hosts/modules/libvirtd.nix @@ -0,0 +1,17 @@ +{ ... }: + +{ + virtualisation = { + libvirtd.enable = true; + spiceUSBRedirection.enable = true; + }; + + programs.virt-manager.enable = true; + + networking.firewall.trustedInterfaces = [ "virbr0" ]; + + users.users.user.extraGroups = [ + "libvirt" + "libvirtd" + ]; +} diff --git a/hosts/modules/networkmanager.nix b/hosts/modules/networkmanager.nix new file mode 100644 index 0000000..7634116 --- /dev/null +++ b/hosts/modules/networkmanager.nix @@ -0,0 +1,10 @@ +{ ... }: + +{ + networking.networkmanager = { + enable = true; + wifi.backend = "iwd"; + }; + + users.users.user.extraGroups = [ "networkmanager" ]; +} diff --git a/hosts/modules/podman.nix b/hosts/modules/podman.nix new file mode 100644 index 0000000..99018cc --- /dev/null +++ b/hosts/modules/podman.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: + +{ + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + extraPackages = [ pkgs.podman-compose ]; + }; + + systemd = { + services.podman-auto-update.enable = true; + timers.podman-auto-update.enable = true; + }; +} diff --git a/hosts/modules/server/boot.nix b/hosts/modules/server/boot.nix new file mode 100644 index 0000000..5d6e482 --- /dev/null +++ b/hosts/modules/server/boot.nix @@ -0,0 +1,5 @@ +{ pkgs, ... }: + +{ + boot.kernelPackages = pkgs.linuxPackages_hardened; +} diff --git a/hosts/modules/server/nix.nix b/hosts/modules/server/nix.nix new file mode 100644 index 0000000..af57cae --- /dev/null +++ b/hosts/modules/server/nix.nix @@ -0,0 +1,13 @@ +{ inputs, ... }: + +{ + environment.etc."channels/nixpkgs".source = inputs.nixpkgs-stable.outPath; + + nix = { + registry.nixpkgs.flake = inputs.nixpkgs-stable; + nixPath = [ + "nixpkgs=/etc/channels/nixpkgs" + "/nix/var/nix/profiles/per-user/root/channels" + ]; + }; +} diff --git a/hosts/modules/server/tailscale.nix b/hosts/modules/server/tailscale.nix new file mode 100644 index 0000000..1f105ba --- /dev/null +++ b/hosts/modules/server/tailscale.nix @@ -0,0 +1,13 @@ +{ ... }: + +{ + services.tailscale = { + extraSetFlags = [ "--advertise-exit-node" ]; + useRoutingFeatures = "server"; + }; + + boot.kernel.sysctl = { + "net.ipv4.ip_forward" = 1; + "net.ipv6.conf.all.forwarding" = 1; + }; +} diff --git a/aspects/hosts/_rotterdam/boot.nix b/hosts/rotterdam/boot.nix similarity index 100% rename from aspects/hosts/_rotterdam/boot.nix rename to hosts/rotterdam/boot.nix diff --git a/aspects/hosts/_rotterdam/hardware-configuration.nix b/hosts/rotterdam/hardware-configuration.nix similarity index 100% rename from aspects/hosts/_rotterdam/hardware-configuration.nix rename to hosts/rotterdam/hardware-configuration.nix diff --git a/aspects/hosts/_rotterdam/hardware.nix b/hosts/rotterdam/hardware.nix similarity index 100% rename from aspects/hosts/_rotterdam/hardware.nix rename to hosts/rotterdam/hardware.nix diff --git a/aspects/hosts/_rotterdam/programs.nix b/hosts/rotterdam/programs.nix similarity index 100% rename from aspects/hosts/_rotterdam/programs.nix rename to hosts/rotterdam/programs.nix diff --git a/aspects/hosts/_rotterdam/services.nix b/hosts/rotterdam/services.nix similarity index 100% rename from aspects/hosts/_rotterdam/services.nix rename to hosts/rotterdam/services.nix diff --git a/aspects/hosts/_trantor/boot.nix b/hosts/trantor/boot.nix similarity index 100% rename from aspects/hosts/_trantor/boot.nix rename to hosts/trantor/boot.nix diff --git a/aspects/hosts/_trantor/disko.nix b/hosts/trantor/disko.nix similarity index 100% rename from aspects/hosts/_trantor/disko.nix rename to hosts/trantor/disko.nix diff --git a/aspects/hosts/_trantor/fail2ban.nix b/hosts/trantor/fail2ban.nix similarity index 100% rename from aspects/hosts/_trantor/fail2ban.nix rename to hosts/trantor/fail2ban.nix diff --git a/aspects/hosts/_trantor/forgejo.nix b/hosts/trantor/forgejo.nix similarity index 95% rename from aspects/hosts/_trantor/forgejo.nix rename to hosts/trantor/forgejo.nix index 1112622..fdfa64a 100644 --- a/aspects/hosts/_trantor/forgejo.nix +++ b/hosts/trantor/forgejo.nix @@ -6,7 +6,8 @@ }: let - mkNginxVHosts = inputs.self.lib.mkNginxVHosts; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts; in { diff --git a/aspects/hosts/_trantor/hardware-configuration.nix b/hosts/trantor/hardware-configuration.nix similarity index 100% rename from aspects/hosts/_trantor/hardware-configuration.nix rename to hosts/trantor/hardware-configuration.nix diff --git a/aspects/hosts/_trantor/networking.nix b/hosts/trantor/networking.nix similarity index 100% rename from aspects/hosts/_trantor/networking.nix rename to hosts/trantor/networking.nix diff --git a/aspects/hosts/_trantor/nginx.nix b/hosts/trantor/nginx.nix similarity index 88% rename from aspects/hosts/_trantor/nginx.nix rename to hosts/trantor/nginx.nix index 5522e24..56eed7c 100644 --- a/aspects/hosts/_trantor/nginx.nix +++ b/hosts/trantor/nginx.nix @@ -6,7 +6,8 @@ }: let - services = inputs.self.services; + utils = import ../../utils.nix { inherit inputs lib; }; + inherit (utils) mkNginxVHosts services; # Get all unique domains from shared services on trantor (host = "trantor") localDomains = lib.unique ( @@ -53,7 +54,7 @@ in ]; age.secrets.cloudflare = { - file = ../../../secrets/cloudflare.age; + file = ../../secrets/cloudflare.age; owner = "nginx"; group = "nginx"; }; diff --git a/aspects/hosts/_trantor/openssh.nix b/hosts/trantor/openssh.nix similarity index 100% rename from aspects/hosts/_trantor/openssh.nix rename to hosts/trantor/openssh.nix diff --git a/aspects/hosts/_trantor/unbound.nix b/hosts/trantor/unbound.nix similarity index 93% rename from aspects/hosts/_trantor/unbound.nix rename to hosts/trantor/unbound.nix index 9f84228..46808c6 100644 --- a/aspects/hosts/_trantor/unbound.nix +++ b/hosts/trantor/unbound.nix @@ -1,7 +1,7 @@ { inputs, lib, ... }: let - services = inputs.self.services; + utils = import ../../utils.nix { inherit inputs lib; }; in { @@ -35,7 +35,7 @@ in # Tailnet DNS records from shared services local-zone = ''"baduhai.dev." transparent''; - local-data = map (e: ''"${e.domain}. IN A ${e.tailscaleIP}"'') services; + local-data = map (e: ''"${e.domain}. IN A ${e.tailscaleIP}"'') utils.services; }; forward-zone = [ diff --git a/modules/ephemeral.nix b/modules/ephemeral.nix new file mode 100644 index 0000000..7403aac --- /dev/null +++ b/modules/ephemeral.nix @@ -0,0 +1,84 @@ +{ lib, config, ... }: + +let + cfg = config.ephemeral; +in +{ + options.ephemeral = { + enable = lib.mkEnableOption "ephemeral root with automatic rollback"; + + rootDevice = lib.mkOption { + type = lib.types.str; + example = "/dev/mapper/cryptroot"; + description = "Device path for the root btrfs filesystem"; + }; + + rootSubvolume = lib.mkOption { + type = lib.types.str; + example = "@root"; + description = "Name of the root btrfs subvolume"; + }; + + oldRootRetentionDays = lib.mkOption { + type = lib.types.int; + default = 30; + description = "Number of days to keep old root snapshots before deletion"; + }; + }; + + config = lib.mkIf cfg.enable { + boot.initrd.systemd.services.recreate-root = { + description = "Rolling over and creating new filesystem root"; + requires = [ "initrd-root-device.target" ]; + after = [ + "local-fs-pre.target" + "initrd-root-device.target" + ]; + requiredBy = [ "initrd-root-fs.target" ]; + before = [ "sysroot.mount" ]; + unitConfig = { + AssertPathExists = "/etc/initrd-release"; + DefaultDependencies = false; + }; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + set -euo pipefail + + mkdir /btrfs_tmp + if ! mount ${cfg.rootDevice} /btrfs_tmp; then + echo "ERROR: Failed to mount ${cfg.rootDevice}" + exit 1 + fi + + if [[ -e /btrfs_tmp/${cfg.rootSubvolume} ]]; then + mkdir -p /btrfs_tmp/old_roots + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/${cfg.rootSubvolume})" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/${cfg.rootSubvolume} "/btrfs_tmp/old_roots/$timestamp" + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } + + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +${toString cfg.oldRootRetentionDays}); do + delete_subvolume_recursively "$i" + done + + if ! btrfs subvolume create /btrfs_tmp/${cfg.rootSubvolume}; then + echo "ERROR: Failed to create subvolume ${cfg.rootSubvolume}" + umount /btrfs_tmp + exit 1 + fi + + umount /btrfs_tmp + ''; + }; + }; +} diff --git a/nixosConfigurations.nix b/nixosConfigurations.nix new file mode 100644 index 0000000..8367438 --- /dev/null +++ b/nixosConfigurations.nix @@ -0,0 +1,56 @@ +{ inputs, ... }: +let + lib = inputs.nixpkgs.lib; + utils = import ./utils.nix { inherit inputs lib; }; + inherit (utils) mkHost; +in +{ + flake.nixosConfigurations = { + rotterdam = mkHost { + hostname = "rotterdam"; + tags = [ + "desktop" + "ai" + "bluetooth" + "dev" + "ephemeral" + "fwupd" + "gaming" + "libvirtd" + "networkmanager" + "podman" + ]; + }; + + io = mkHost { + hostname = "io"; + tags = [ + "desktop" + "ai" + "bluetooth" + "dev" + "ephemeral" + "libvirtd" + "networkmanager" + "podman" + ]; + }; + + alexandria = mkHost { + hostname = "alexandria"; + tags = [ + "server" + "fwupd" + ]; + }; + + trantor = mkHost { + hostname = "trantor"; + system = "aarch64-linux"; + tags = [ + "server" + "ephemeral" + ]; + }; + }; +} diff --git a/nixosModules.nix b/nixosModules.nix new file mode 100644 index 0000000..5fd416b --- /dev/null +++ b/nixosModules.nix @@ -0,0 +1,7 @@ +{ ... }: + +{ + flake.nixosModules = { + ephemeral = import ./modules/ephemeral.nix; + }; +} diff --git a/overlays.nix b/overlays.nix new file mode 100644 index 0000000..b8f807f --- /dev/null +++ b/overlays.nix @@ -0,0 +1,14 @@ +{ inputs, ... }: + +{ + flake.overlays = { + default = final: prev: { + base16-schemes = inputs.self.packages.${final.system}.base16-schemes; + claude-desktop = inputs.self.packages.${final.system}.claude-desktop; + fastfetch = inputs.self.packages.${final.system}.fastfetch; + hm-cli = inputs.self.packages.${final.system}.hm-cli; + kwrite = inputs.self.packages.${final.system}.kwrite; + toggleaudiosink = inputs.self.packages.${final.system}.toggleaudiosink; + }; + }; +} diff --git a/packages.nix b/packages.nix new file mode 100644 index 0000000..bf0319e --- /dev/null +++ b/packages.nix @@ -0,0 +1,22 @@ +{ inputs, ... }: + +{ + perSystem = + { system, ... }: + let + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + in + { + packages = { + base16-schemes = pkgs.callPackage ./packages/base16-schemes.nix { }; + claude-desktop = pkgs.callPackage ./packages/claude-desktop.nix { }; + fastfetch = pkgs.callPackage ./packages/fastfetch.nix { }; + hm-cli = pkgs.callPackage ./packages/hm-cli.nix { }; + kwrite = pkgs.callPackage ./packages/kwrite.nix { }; + toggleaudiosink = pkgs.callPackage ./packages/toggleaudiosink.nix { }; + }; + }; +} diff --git a/packages/base16-schemes.nix b/packages/base16-schemes.nix index fbb1341..ffd6c04 100644 --- a/packages/base16-schemes.nix +++ b/packages/base16-schemes.nix @@ -1,35 +1,32 @@ -{ ... }: - { - perSystem = - { pkgs, ... }: - { - packages.base16-schemes = pkgs.stdenv.mkDerivation (finalAttrs: { - pname = "base16-schemes"; - version = "0-unstable-2025-06-04"; + lib, + stdenv, + fetchFromGitHub, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "base16-schemes"; + version = "0-unstable-2025-06-04"; - src = pkgs.fetchFromGitHub { - owner = "tinted-theming"; - repo = "schemes"; - rev = "317a5e10c35825a6c905d912e480dfe8e71c7559"; - hash = "sha256-d4km8W7w2zCUEmPAPUoLk1NlYrGODuVa3P7St+UrqkM="; - }; + src = fetchFromGitHub { + owner = "tinted-theming"; + repo = "schemes"; + rev = "317a5e10c35825a6c905d912e480dfe8e71c7559"; + hash = "sha256-d4km8W7w2zCUEmPAPUoLk1NlYrGODuVa3P7St+UrqkM="; + }; - installPhase = '' - runHook preInstall + installPhase = '' + runHook preInstall - mkdir -p $out/share/themes/ - install base16/*.yaml $out/share/themes/ + mkdir -p $out/share/themes/ + install base16/*.yaml $out/share/themes/ - runHook postInstall - ''; + runHook postInstall + ''; - meta = { - description = "All the color schemes for use in base16 packages"; - homepage = "https://github.com/tinted-theming/schemes"; - maintainers = [ pkgs.lib.maintainers.DamienCassou ]; - license = pkgs.lib.licenses.mit; - }; - }); - }; -} + meta = { + description = "All the color schemes for use in base16 packages"; + homepage = "https://github.com/tinted-theming/schemes"; + maintainers = [ lib.maintainers.DamienCassou ]; + license = lib.licenses.mit; + }; +}) diff --git a/packages/claude-desktop.nix b/packages/claude-desktop.nix index e93f3af..e72fc37 100644 --- a/packages/claude-desktop.nix +++ b/packages/claude-desktop.nix @@ -1,215 +1,221 @@ -{ inputs, ... }: - { - perSystem = - { system, ... }: - let - pkgs = import inputs.nixpkgs { - inherit system; - config.allowUnfree = true; - }; + lib, + stdenv, + fetchurl, + makeWrapper, + makeDesktopItem, + copyDesktopItems, + p7zip, + unzip, + electron, + nodejs, + asar, + graphicsmagick, +}: - pname = "claude-desktop"; - version = "1.0.1768"; +let + pname = "claude-desktop"; + version = "1.0.1768"; # Updated based on extracted nupkg - srcs.x86_64-linux = pkgs.fetchurl { - url = "https://downloads.claude.ai/releases/win32/x64/1.0.1768/Claude-67d01376d0e9d08b328455f6db9e63b0d603506a.exe"; - hash = "sha256-x76Qav38ya3ObpWIq3dDowo79LgvVquMfaZeH8M1LUk=;"; - }; + srcs.x86_64-linux = fetchurl { + url = "https://downloads.claude.ai/releases/win32/x64/1.0.1768/Claude-67d01376d0e9d08b328455f6db9e63b0d603506a.exe"; + hash = "sha256-x76Qav38ya3ObpWIq3dDowo79LgvVquMfaZeH8M1LUk=;"; + }; - src = - srcs.${pkgs.stdenv.hostPlatform.system} or (throw "Unsupported system: ${pkgs.stdenv.hostPlatform.system}"); + src = + srcs.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}"); - claudeNativeStub = '' - // Stub implementation of claude-native using KeyboardKey enum values - const KeyboardKey = { - Backspace: 43, Tab: 280, Enter: 261, Shift: 272, Control: 61, Alt: 40, - CapsLock: 56, Escape: 85, Space: 276, PageUp: 251, PageDown: 250, - End: 83, Home: 154, LeftArrow: 175, UpArrow: 282, RightArrow: 262, - DownArrow: 81, Delete: 79, Meta: 187 - }; - Object.freeze(KeyboardKey); - module.exports = { - getWindowsVersion: () => "10.0.0", - setWindowEffect: () => {}, - removeWindowEffect: () => {}, - getIsMaximized: () => false, - flashFrame: () => {}, - clearFlashFrame: () => {}, - showNotification: () => {}, - setProgressBar: () => {}, - clearProgressBar: () => {}, - setOverlayIcon: () => {}, - clearOverlayIcon: () => {}, - KeyboardKey - }; - ''; - in - { - packages.claude-desktop = pkgs.stdenv.mkDerivation rec { - inherit pname version src; - - nativeBuildInputs = with pkgs; [ - makeWrapper - copyDesktopItems - p7zip - unzip - nodejs - graphicsmagick - ]; - - buildInputs = [ pkgs.electron ]; - - desktopItems = [ - (pkgs.makeDesktopItem { - name = "claude-desktop"; - desktopName = "Claude"; - comment = "AI assistant from Anthropic"; - exec = "claude-desktop %u"; - icon = "claude-desktop"; - categories = [ - "Network" - "Chat" - "Office" - ]; - mimeTypes = [ "x-scheme-handler/claude" ]; - startupNotify = true; - startupWMClass = "Claude"; - }) - ]; - - unpackPhase = '' - runHook preUnpack - - # Extract the Windows installer - use -y to auto-overwrite - 7z x -y $src -o./extracted - - # The installer contains a NuGet package - if [ -f ./extracted/AnthropicClaude-*-full.nupkg ]; then - echo "Found NuGet package, extracting..." - # NuGet packages are just zip files - unzip -q ./extracted/AnthropicClaude-*-full.nupkg -d ./nupkg - - # Extract app.asar to modify it - if [ -f ./nupkg/lib/net45/resources/app.asar ]; then - echo "Extracting app.asar..." - ${pkgs.asar}/bin/asar extract ./nupkg/lib/net45/resources/app.asar ./app - - # Also copy the unpacked resources - if [ -d ./nupkg/lib/net45/resources/app.asar.unpacked ]; then - cp -r ./nupkg/lib/net45/resources/app.asar.unpacked/* ./app/ - fi - - # Copy additional resources - mkdir -p ./app/resources - mkdir -p ./app/resources/i18n - cp ./nupkg/lib/net45/resources/Tray* ./app/resources/ || true - cp ./nupkg/lib/net45/resources/*-*.json ./app/resources/i18n/ || true - fi - else - echo "NuGet package not found" - ls -la ./extracted/ - exit 1 - fi - - runHook postUnpack - ''; - - buildPhase = '' - runHook preBuild - - # Replace the Windows-specific claude-native module with a stub - if [ -d ./app/node_modules/claude-native ]; then - echo "Replacing claude-native module with Linux stub..." - rm -rf ./app/node_modules/claude-native/*.node - cat > ./app/node_modules/claude-native/index.js << 'EOF' - ${claudeNativeStub} - EOF - fi - - # Fix the title bar detection (from aaddrick script) - echo "Fixing title bar detection..." - SEARCH_BASE="./app/.vite/renderer/main_window/assets" - if [ -d "$SEARCH_BASE" ]; then - TARGET_FILE=$(find "$SEARCH_BASE" -type f -name "MainWindowPage-*.js" | head -1) - if [ -n "$TARGET_FILE" ]; then - echo "Found target file: $TARGET_FILE" - # Replace patterns like 'if(!VAR1 && VAR2)' with 'if(VAR1 && VAR2)' - sed -i -E 's/if\(!([a-zA-Z]+)[[:space:]]*&&[[:space:]]*([a-zA-Z]+)\)/if(\1 \&\& \2)/g' "$TARGET_FILE" - echo "Title bar fix applied" - fi - fi - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - - mkdir -p $out/lib/claude-desktop - - # Repack the modified app as app.asar - cd ./app - ${pkgs.asar}/bin/asar pack . ../app.asar - cd .. - - # Copy resources - mkdir -p $out/lib/claude-desktop/resources - cp ./app.asar $out/lib/claude-desktop/resources/ - - # Create app.asar.unpacked directory with the stub - mkdir -p $out/lib/claude-desktop/resources/app.asar.unpacked/node_modules/claude-native - cat > $out/lib/claude-desktop/resources/app.asar.unpacked/node_modules/claude-native/index.js << 'EOF' - ${claudeNativeStub} - EOF - - # Copy other resources - if [ -d ./nupkg/lib/net45/resources ]; then - cp ./nupkg/lib/net45/resources/*.png $out/lib/claude-desktop/resources/ 2>/dev/null || true - cp ./nupkg/lib/net45/resources/*.ico $out/lib/claude-desktop/resources/ 2>/dev/null || true - cp ./nupkg/lib/net45/resources/*.json $out/lib/claude-desktop/resources/ 2>/dev/null || true - fi - - # Create wrapper script - makeWrapper ${pkgs.electron}/bin/electron $out/bin/claude-desktop \ - --add-flags "$out/lib/claude-desktop/resources/app.asar" \ - --set DISABLE_AUTOUPDATER 1 \ - --set NODE_ENV production - - # Extract and install icons in multiple sizes - if [ -f ./extracted/setupIcon.ico ]; then - echo "Converting and installing icons..." - # Count frames in the ICO file and extract each one - frame_count=$(gm identify ./extracted/setupIcon.ico | wc -l) - for i in $(seq 0 $((frame_count - 1))); do - gm convert "./extracted/setupIcon.ico[$i]" "./extracted/setupIcon-$i.png" 2>/dev/null || true - done - - # Loop through converted icons and install them by size - for img in ./extracted/setupIcon-*.png; do - if [ -f "$img" ]; then - size=$(gm identify -format "%wx%h" "$img") - # Skip smallest icons (16x16 and 32x32) as they're too low quality - if [ "$size" != "16x16" ] && [ "$size" != "32x32" ]; then - mkdir -p "$out/share/icons/hicolor/$size/apps" - cp "$img" "$out/share/icons/hicolor/$size/apps/claude-desktop.png" - fi - fi - done - fi - - runHook postInstall - ''; - - meta = with pkgs.lib; { - description = "Claude Desktop - AI assistant from Anthropic"; - homepage = "https://claude.ai"; - license = licenses.unfree; - sourceProvenance = with sourceTypes; [ binaryNativeCode ]; - maintainers = [ ]; - platforms = [ "x86_64-linux" ]; - mainProgram = "claude-desktop"; - }; - }; + # Stub implementation for claude-native module + claudeNativeStub = '' + // Stub implementation of claude-native using KeyboardKey enum values + const KeyboardKey = { + Backspace: 43, Tab: 280, Enter: 261, Shift: 272, Control: 61, Alt: 40, + CapsLock: 56, Escape: 85, Space: 276, PageUp: 251, PageDown: 250, + End: 83, Home: 154, LeftArrow: 175, UpArrow: 282, RightArrow: 262, + DownArrow: 81, Delete: 79, Meta: 187 }; + Object.freeze(KeyboardKey); + module.exports = { + getWindowsVersion: () => "10.0.0", + setWindowEffect: () => {}, + removeWindowEffect: () => {}, + getIsMaximized: () => false, + flashFrame: () => {}, + clearFlashFrame: () => {}, + showNotification: () => {}, + setProgressBar: () => {}, + clearProgressBar: () => {}, + setOverlayIcon: () => {}, + clearOverlayIcon: () => {}, + KeyboardKey + }; + ''; + +in +stdenv.mkDerivation rec { + inherit pname version src; + + nativeBuildInputs = [ + makeWrapper + copyDesktopItems + p7zip + unzip + nodejs + graphicsmagick + ]; + + buildInputs = [ + electron + ]; + + desktopItems = [ + (makeDesktopItem { + name = "claude-desktop"; + desktopName = "Claude"; + comment = "AI assistant from Anthropic"; + exec = "claude-desktop %u"; + icon = "claude-desktop"; + categories = [ + "Network" + "Chat" + "Office" + ]; + mimeTypes = [ "x-scheme-handler/claude" ]; + startupNotify = true; + startupWMClass = "Claude"; + }) + ]; + + unpackPhase = '' + runHook preUnpack + + # Extract the Windows installer - use -y to auto-overwrite + 7z x -y $src -o./extracted + + # The installer contains a NuGet package + if [ -f ./extracted/AnthropicClaude-*-full.nupkg ]; then + echo "Found NuGet package, extracting..." + # NuGet packages are just zip files + unzip -q ./extracted/AnthropicClaude-*-full.nupkg -d ./nupkg + + # Extract app.asar to modify it + if [ -f ./nupkg/lib/net45/resources/app.asar ]; then + echo "Extracting app.asar..." + ${asar}/bin/asar extract ./nupkg/lib/net45/resources/app.asar ./app + + # Also copy the unpacked resources + if [ -d ./nupkg/lib/net45/resources/app.asar.unpacked ]; then + cp -r ./nupkg/lib/net45/resources/app.asar.unpacked/* ./app/ + fi + + # Copy additional resources + mkdir -p ./app/resources + mkdir -p ./app/resources/i18n + cp ./nupkg/lib/net45/resources/Tray* ./app/resources/ || true + cp ./nupkg/lib/net45/resources/*-*.json ./app/resources/i18n/ || true + fi + else + echo "NuGet package not found" + ls -la ./extracted/ + exit 1 + fi + + runHook postUnpack + ''; + + buildPhase = '' + runHook preBuild + + # Replace the Windows-specific claude-native module with a stub + if [ -d ./app/node_modules/claude-native ]; then + echo "Replacing claude-native module with Linux stub..." + rm -rf ./app/node_modules/claude-native/*.node + cat > ./app/node_modules/claude-native/index.js << 'EOF' + ${claudeNativeStub} + EOF + fi + + # Fix the title bar detection (from aaddrick script) + echo "Fixing title bar detection..." + SEARCH_BASE="./app/.vite/renderer/main_window/assets" + if [ -d "$SEARCH_BASE" ]; then + TARGET_FILE=$(find "$SEARCH_BASE" -type f -name "MainWindowPage-*.js" | head -1) + if [ -n "$TARGET_FILE" ]; then + echo "Found target file: $TARGET_FILE" + # Replace patterns like 'if(!VAR1 && VAR2)' with 'if(VAR1 && VAR2)' + sed -i -E 's/if\(!([a-zA-Z]+)[[:space:]]*&&[[:space:]]*([a-zA-Z]+)\)/if(\1 \&\& \2)/g' "$TARGET_FILE" + echo "Title bar fix applied" + fi + fi + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/lib/claude-desktop + + # Repack the modified app as app.asar + cd ./app + ${asar}/bin/asar pack . ../app.asar + cd .. + + # Copy resources + mkdir -p $out/lib/claude-desktop/resources + cp ./app.asar $out/lib/claude-desktop/resources/ + + # Create app.asar.unpacked directory with the stub + mkdir -p $out/lib/claude-desktop/resources/app.asar.unpacked/node_modules/claude-native + cat > $out/lib/claude-desktop/resources/app.asar.unpacked/node_modules/claude-native/index.js << 'EOF' + ${claudeNativeStub} + EOF + + # Copy other resources + if [ -d ./nupkg/lib/net45/resources ]; then + cp ./nupkg/lib/net45/resources/*.png $out/lib/claude-desktop/resources/ 2>/dev/null || true + cp ./nupkg/lib/net45/resources/*.ico $out/lib/claude-desktop/resources/ 2>/dev/null || true + cp ./nupkg/lib/net45/resources/*.json $out/lib/claude-desktop/resources/ 2>/dev/null || true + fi + + # Create wrapper script + makeWrapper ${electron}/bin/electron $out/bin/claude-desktop \ + --add-flags "$out/lib/claude-desktop/resources/app.asar" \ + --set DISABLE_AUTOUPDATER 1 \ + --set NODE_ENV production + + # Extract and install icons in multiple sizes + if [ -f ./extracted/setupIcon.ico ]; then + echo "Converting and installing icons..." + # Count frames in the ICO file and extract each one + frame_count=$(gm identify ./extracted/setupIcon.ico | wc -l) + for i in $(seq 0 $((frame_count - 1))); do + gm convert "./extracted/setupIcon.ico[$i]" "./extracted/setupIcon-$i.png" 2>/dev/null || true + done + + # Loop through converted icons and install them by size + for img in ./extracted/setupIcon-*.png; do + if [ -f "$img" ]; then + size=$(gm identify -format "%wx%h" "$img") + # Skip smallest icons (16x16 and 32x32) as they're too low quality + if [ "$size" != "16x16" ] && [ "$size" != "32x32" ]; then + mkdir -p "$out/share/icons/hicolor/$size/apps" + cp "$img" "$out/share/icons/hicolor/$size/apps/claude-desktop.png" + fi + fi + done + fi + + runHook postInstall + ''; + + meta = with lib; { + description = "Claude Desktop - AI assistant from Anthropic"; + homepage = "https://claude.ai"; + license = licenses.unfree; + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; + maintainers = with maintainers; [ ]; + platforms = [ "x86_64-linux" ]; + mainProgram = "claude-desktop"; + }; } diff --git a/packages/fastfetch.nix b/packages/fastfetch.nix index aa8d616..fa8e0ea 100644 --- a/packages/fastfetch.nix +++ b/packages/fastfetch.nix @@ -1,84 +1,81 @@ -{ ... }: - { - perSystem = - { pkgs, lib, ... }: - let - fastfetch-logo = pkgs.fetchurl { - url = "https://discourse.nixos.org/uploads/default/original/3X/3/6/36954e6d6aa32c8b00f50ca43f142d898c1ff535.png"; - hash = "sha256-aLHz8jSAFocrn+Pb4vRq0wtkYFJpBpZRevd+VoZC/PQ="; - }; + lib, + pkgs ? import { }, +}: - fastfetch-config = pkgs.writeText "fastfetch-config.json" ( - builtins.toJSON { - "$schema" = "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"; - modules = [ - "title" - "separator" - { - type = "os"; - keyWidth = 9; - } - { - type = "kernel"; - keyWidth = 9; - } - { - type = "uptime"; - keyWidth = 9; - } - { - type = "shell"; - keyWidth = 9; - } - "break" - { - type = "cpu"; - keyWidth = 11; - } - { - type = "memory"; - keyWidth = 11; - } - { - type = "swap"; - keyWidth = 11; - } - { - type = "disk"; - folders = "/"; - keyWidth = 11; - } - { - type = "command"; - key = "Systemd"; - keyWidth = 11; - text = "echo \"$(systemctl list-units --state=failed --no-legend | wc -l) failed units, $(systemctl list-jobs --no-legend | wc -l) queued jobs\""; - } - "break" - { - type = "command"; - key = "Public IP"; - keyWidth = 15; - text = "curl -s -4 ifconfig.me 2>/dev/null || echo 'N/A'"; - } - { - type = "command"; - key = "Tailscale IP"; - keyWidth = 15; - text = "tailscale ip -4 2>/dev/null || echo 'N/A'"; - } - { - type = "command"; - key = "Local IP"; - keyWidth = 15; - text = "ip -4 addr show scope global | grep inet | head -n1 | awk '{print $2}' | cut -d/ -f1"; - } - ]; +let + fastfetch-logo = pkgs.fetchurl { + url = "https://discourse.nixos.org/uploads/default/original/3X/3/6/36954e6d6aa32c8b00f50ca43f142d898c1ff535.png"; + hash = "sha256-aLHz8jSAFocrn+Pb4vRq0wtkYFJpBpZRevd+VoZC/PQ="; + }; + + fastfetch-config = pkgs.writeText "fastfetch-config.json" ( + builtins.toJSON { + "$schema" = "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"; + modules = [ + "title" + "separator" + { + type = "os"; + keyWidth = 9; } - ); - in - { - packages.fastfetch = pkgs.writeShellScriptBin "fastfetch" ''exec ${lib.getExe pkgs.fastfetch} --config ${fastfetch-config} --logo-type kitty --logo ${fastfetch-logo} --logo-padding-right 1 --logo-width 36 "$@" ''; - }; -} + { + type = "kernel"; + keyWidth = 9; + } + { + type = "uptime"; + keyWidth = 9; + } + { + type = "shell"; + keyWidth = 9; + } + "break" + { + type = "cpu"; + keyWidth = 11; + } + { + type = "memory"; + keyWidth = 11; + } + { + type = "swap"; + keyWidth = 11; + } + { + type = "disk"; + folders = "/"; + keyWidth = 11; + } + { + type = "command"; + key = "Systemd"; + keyWidth = 11; + text = "echo \"$(systemctl list-units --state=failed --no-legend | wc -l) failed units, $(systemctl list-jobs --no-legend | wc -l) queued jobs\""; + } + "break" + { + type = "command"; + key = "Public IP"; + keyWidth = 15; + text = "curl -s -4 ifconfig.me 2>/dev/null || echo 'N/A'"; + } + { + type = "command"; + key = "Tailscale IP"; + keyWidth = 15; + text = "tailscale ip -4 2>/dev/null || echo 'N/A'"; + } + { + type = "command"; + key = "Local IP"; + keyWidth = 15; + text = "ip -4 addr show scope global | grep inet | head -n1 | awk '{print $2}' | cut -d/ -f1"; + } + ]; + } + ); +in +pkgs.writeShellScriptBin "fastfetch" ''exec ${lib.getExe pkgs.fastfetch} --config ${fastfetch-config} --logo-type kitty --logo ${fastfetch-logo} --logo-padding-right 1 --logo-width 36 "$@" '' diff --git a/packages/hm-cli.nix b/packages/hm-cli.nix index 94dae66..f6034ea 100644 --- a/packages/hm-cli.nix +++ b/packages/hm-cli.nix @@ -1,109 +1,105 @@ -{ ... }: - { - perSystem = - { pkgs, ... }: - { - packages.hm-cli = pkgs.writeShellScriptBin "hm" '' - set -e + pkgs ? import { }, +}: - HM="${pkgs.lib.getExe pkgs.home-manager}" - FLAKE_PATH="''${HM_PATH:-$HOME/.config/home-manager}" - FLAKE_OUTPUT="''${HM_USER:-$(whoami)@$(hostname)}" +pkgs.writeShellScriptBin "hm" '' + set -e - show_usage() { - cat < [args] + HM="${pkgs.lib.getExe pkgs.home-manager}" + FLAKE_PATH="''${HM_PATH:-$HOME/.config/home-manager}" + FLAKE_OUTPUT="''${HM_USER:-$(whoami)@$(hostname)}" - Commands: - apply Switch to a new generation - generation list List all generations - generation delete ID... Delete specified generation(s) - generation rollback Rollback to the previous generation - generation switch ID Switch to the specified generation - generation cleanup Delete all but the current generation + show_usage() { + cat < [args] - Environment Variables: - HM_PATH Override default flake path (~/.config/home-manager) - Currently set to "''${HM_PATH:-}" - HM_USER Override default user output ("$(whoami)@$(hostname)") - Currently set to "''${HM_USER:-}" - EOF - } + Commands: + apply Switch to a new generation + generation list List all generations + generation delete ID... Delete specified generation(s) + generation rollback Rollback to the previous generation + generation switch ID Switch to the specified generation + generation cleanup Delete all but the current generation - if [[ $# -eq 0 ]]; then + Environment Variables: + HM_PATH Override default flake path (~/.config/home-manager) + Currently set to "''${HM_PATH:-}" + HM_USER Override default user output ("$(whoami)@$(hostname)") + Currently set to "''${HM_USER:-}" + EOF + } + + if [[ $# -eq 0 ]]; then + show_usage + exit 1 + fi + + case "$1" in + apply) + "$HM" switch --flake "$FLAKE_PATH#$FLAKE_OUTPUT" -b bkp + ;; + generation) + if [[ $# -lt 2 ]]; then + echo "Error: generation command requires a subcommand" show_usage exit 1 fi - case "$1" in - apply) - "$HM" switch --flake "$FLAKE_PATH#$FLAKE_OUTPUT" -b bkp + case "$2" in + list) + "$HM" generations ;; - generation) - if [[ $# -lt 2 ]]; then - echo "Error: generation command requires a subcommand" - show_usage + delete) + if [[ $# -lt 3 ]]; then + echo "Error: delete requires at least one generation ID" exit 1 fi - - case "$2" in - list) - "$HM" generations - ;; - delete) - if [[ $# -lt 3 ]]; then - echo "Error: delete requires at least one generation ID" - exit 1 - fi - shift 2 - "$HM" remove-generations "$@" - ;; - rollback) - PREV_GEN=$("$HM" generations | \ - sed -n 's/^[[:space:]]*id \([0-9]\+\).*/\1/p' | \ - head -n 2 | tail -n 1) - if [[ -z "$PREV_GEN" ]]; then - echo "Error: could not determine previous generation (possibly only one generation exists)" - exit 1 - fi - "$HM" switch --flake "$FLAKE_PATH" --switch-generation "$PREV_GEN" -b bkp - ;; - switch) - if [[ $# -ne 3 ]]; then - echo "Error: switch requires exactly one generation ID" - exit 1 - fi - "$HM" switch --flake "$FLAKE_PATH" --switch-generation "$3" -b bkp - ;; - cleanup) - CURRENT_GEN=$("$HM" generations | sed -n 's/^.*id \([0-9]\+\) .* (current)$/\1/p') - if [[ -z "$CURRENT_GEN" ]]; then - echo "Error: could not determine current generation" - exit 1 - fi - OLD_GENS=$("$HM" generations | sed -n 's/^.*id \([0-9]\+\) .*/\1/p' | grep -v "^$CURRENT_GEN$") - if [[ -z "$OLD_GENS" ]]; then - echo "No old generations to delete" - else - echo "Deleting generations: $(echo $OLD_GENS | tr '\n' ' ')" - echo "$OLD_GENS" | xargs "$HM" remove-generations - echo "Cleanup complete. Current generation $CURRENT_GEN preserved." - fi - ;; - *) - echo "Error: unknown generation subcommand '$2'" - show_usage - exit 1 - ;; - esac + shift 2 + "$HM" remove-generations "$@" + ;; + rollback) + PREV_GEN=$("$HM" generations | \ + sed -n 's/^[[:space:]]*id \([0-9]\+\).*/\1/p' | \ + head -n 2 | tail -n 1) + if [[ -z "$PREV_GEN" ]]; then + echo "Error: could not determine previous generation (possibly only one generation exists)" + exit 1 + fi + "$HM" switch --flake "$FLAKE_PATH" --switch-generation "$PREV_GEN" -b bkp + ;; + switch) + if [[ $# -ne 3 ]]; then + echo "Error: switch requires exactly one generation ID" + exit 1 + fi + "$HM" switch --flake "$FLAKE_PATH" --switch-generation "$3" -b bkp + ;; + cleanup) + CURRENT_GEN=$("$HM" generations | sed -n 's/^.*id \([0-9]\+\) .* (current)$/\1/p') + if [[ -z "$CURRENT_GEN" ]]; then + echo "Error: could not determine current generation" + exit 1 + fi + OLD_GENS=$("$HM" generations | sed -n 's/^.*id \([0-9]\+\) .*/\1/p' | grep -v "^$CURRENT_GEN$") + if [[ -z "$OLD_GENS" ]]; then + echo "No old generations to delete" + else + echo "Deleting generations: $(echo $OLD_GENS | tr '\n' ' ')" + echo "$OLD_GENS" | xargs "$HM" remove-generations + echo "Cleanup complete. Current generation $CURRENT_GEN preserved." + fi ;; *) - echo "Error: unknown command '$1'" + echo "Error: unknown generation subcommand '$2'" show_usage exit 1 ;; esac - ''; - }; -} + ;; + *) + echo "Error: unknown command '$1'" + show_usage + exit 1 + ;; + esac +'' diff --git a/packages/kwrite.nix b/packages/kwrite.nix index 67ce69e..14ebce1 100644 --- a/packages/kwrite.nix +++ b/packages/kwrite.nix @@ -1,21 +1,15 @@ -{ ... }: +{ pkgs }: -{ - perSystem = - { pkgs, ... }: - { - packages.kwrite = pkgs.symlinkJoin { - name = "kwrite"; - paths = [ pkgs.kdePackages.kate ]; - postBuild = '' - rm -rf $out/bin/kate \ - $out/bin/.kate-wrapped \ - $out/share/applications/org.kde.kate.desktop \ - $out/share/man \ - $out/share/icons/hicolor/*/apps/kate.png \ - $out/share/icons/hicolor/scalable/apps/kate.svg \ - $out/share/appdata/org.kde.kate.appdata.xml - ''; - }; - }; +pkgs.symlinkJoin { + name = "kwrite"; + paths = [ pkgs.kdePackages.kate ]; + postBuild = '' + rm -rf $out/bin/kate \ + $out/bin/.kate-wrapped \ + $out/share/applications/org.kde.kate.desktop \ + $out/share/man \ + $out/share/icons/hicolor/*/apps/kate.png \ + $out/share/icons/hicolor/scalable/apps/kate.svg \ + $out/share/appdata/org.kde.kate.appdata.xml + ''; } diff --git a/packages/overlays.nix b/packages/overlays.nix deleted file mode 100644 index a36ed60..0000000 --- a/packages/overlays.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ inputs, ... }: - -let - packageDir = builtins.readDir ./.; - - # Filter to .nix files, excluding overlays.nix - isPackageFile = name: - name != "overlays.nix" && builtins.match ".*\\.nix$" name != null; - - # Extract package name from filename (e.g., "foo-bar.nix" -> "foo-bar") - toPackageName = filename: - builtins.head (builtins.match "(.+)\\.nix$" filename); - - packageNames = map toPackageName (builtins.filter isPackageFile (builtins.attrNames packageDir)); -in -{ - flake.overlays.default = final: prev: - builtins.listToAttrs (map (name: { - inherit name; - value = inputs.self.packages.${final.system}.${name}; - }) packageNames); -} diff --git a/packages/toggleaudiosink.nix b/packages/toggleaudiosink.nix index 22e0d44..623346f 100644 --- a/packages/toggleaudiosink.nix +++ b/packages/toggleaudiosink.nix @@ -1,52 +1,48 @@ -{ ... }: - { - perSystem = - { pkgs, ... }: - { - packages.toggleaudiosink = pkgs.writeShellScriptBin "toggleaudiosink" '' - #!/usr/bin/env bash + pkgs ? import { }, +}: - sound_server="pipewire" +pkgs.writeShellScriptBin "toggleaudiosink" '' + #!/usr/bin/env bash - # Grab a count of how many audio sinks we have - sink_count=$(${pkgs.pulseaudio}/bin/pactl list sinks | grep -c "Sink #[[:digit:]]") - # Create an array of the actual sink IDs - sinks=() - mapfile -t sinks < <(${pkgs.pulseaudio}/bin/pactl list sinks | grep 'Sink #[[:digit:]]' | sed -n -e 's/.*Sink #\([[:digit:]]\)/\1/p') - # Get the ID of the active sink - active_sink_name=$(${pkgs.pulseaudio}/bin/pactl info | grep 'Default Sink:' | sed -n -e 's/.*Default Sink:[[:space:]]\+\(.*\)/\1/p') - active_sink=$(${pkgs.pulseaudio}/bin/pactl list sinks | grep -B 2 "$active_sink_name" | sed -n -e 's/Sink #\([[:digit:]]\)/\1/p' | head -n 1) + sound_server="pipewire" - # Get the ID of the last sink in the array - final_sink=''${sinks[$((sink_count - 1))]} + # Grab a count of how many audio sinks we have + sink_count=$(${pkgs.pulseaudio}/bin/pactl list sinks | grep -c "Sink #[[:digit:]]") + # Create an array of the actual sink IDs + sinks=() + mapfile -t sinks < <(${pkgs.pulseaudio}/bin/pactl list sinks | grep 'Sink #[[:digit:]]' | sed -n -e 's/.*Sink #\([[:digit:]]\)/\1/p') + # Get the ID of the active sink + active_sink_name=$(${pkgs.pulseaudio}/bin/pactl info | grep 'Default Sink:' | sed -n -e 's/.*Default Sink:[[:space:]]\+\(.*\)/\1/p') + active_sink=$(${pkgs.pulseaudio}/bin/pactl list sinks | grep -B 2 "$active_sink_name" | sed -n -e 's/Sink #\([[:digit:]]\)/\1/p' | head -n 1) - # Find the index of the active sink - for index in "''${!sinks[@]}"; do - if [[ "''${sinks[$index]}" == "$active_sink" ]]; then - active_sink_index=$index - fi - done + # Get the ID of the last sink in the array + final_sink=''${sinks[$((sink_count - 1))]} - # Default to the first sink in the list - next_sink=''${sinks[0]} - next_sink_index=0 + # Find the index of the active sink + for index in "''${!sinks[@]}"; do + if [[ "''${sinks[$index]}" == "$active_sink" ]]; then + active_sink_index=$index + fi + done - # If we're not at the end of the list, move up the list - if [[ $active_sink -ne $final_sink ]]; then - next_sink_index=$((active_sink_index + 1)) - next_sink=''${sinks[$next_sink_index]} - fi + # Default to the first sink in the list + next_sink=''${sinks[0]} + next_sink_index=0 - # Change the default sink - # Get the name of the next sink - next_sink_name=$(${pkgs.pulseaudio}/bin/pactl list sinks | grep -C 2 "Sink #$next_sink" | sed -n -e 's/.*Name:[[:space:]]\+\(.*\)/\1/p' | head -n 1) - ${pkgs.pulseaudio}/bin/pactl set-default-sink "$next_sink_name" + # If we're not at the end of the list, move up the list + if [[ $active_sink -ne $final_sink ]]; then + next_sink_index=$((active_sink_index + 1)) + next_sink=''${sinks[$next_sink_index]} + fi - # Move all inputs to the new sink - for app in $(${pkgs.pulseaudio}/bin/pactl list sink-inputs | sed -n -e 's/.*Sink Input #\([[:digit:]]\)/\1/p'); do - ${pkgs.pulseaudio}/bin/pactl "move-sink-input $app $next_sink" - done - ''; - }; -} + # Change the default sink + # Get the name of the next sink + next_sink_name=$(${pkgs.pulseaudio}/bin/pactl list sinks | grep -C 2 "Sink #$next_sink" | sed -n -e 's/.*Name:[[:space:]]\+\(.*\)/\1/p' | head -n 1) + ${pkgs.pulseaudio}/bin/pactl set-default-sink "$next_sink_name" + + # Move all inputs to the new sink + for app in $(${pkgs.pulseaudio}/bin/pactl list sink-inputs | sed -n -e 's/.*Sink Input #\([[:digit:]]\)/\1/p'); do + ${pkgs.pulseaudio}/bin/pactl "move-sink-input $app $next_sink" + done +'' diff --git a/data/services.nix b/shared/services.nix similarity index 83% rename from data/services.nix rename to shared/services.nix index ae7395c..1173b3b 100644 --- a/data/services.nix +++ b/shared/services.nix @@ -1,6 +1,6 @@ -# Shared service and host definitions -# This file can be imported directly (unlike aspects which use flake-parts) +# Shared service definitions for cross-host configuration { + # Host IP definitions hosts = { alexandria = { lanIP = "192.168.15.142"; @@ -11,6 +11,7 @@ }; }; + # Service definitions - IPs are inherited from host services = [ { name = "kanidm"; diff --git a/terranix/baduhai.dev.nix b/terranix/baduhai.dev.nix deleted file mode 100644 index cea9f22..0000000 --- a/terranix/baduhai.dev.nix +++ /dev/null @@ -1,113 +0,0 @@ -# Required environment variables: -# CLOUDFLARE_API_TOKEN - API token with "Edit zone DNS" permissions -# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage -# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage - -{ ... }: - -{ - perSystem = - { pkgs, ... }: - { - terranix.terranixConfigurations.cloudflare-baduhaidev = { - terraformWrapper.package = pkgs.opentofu; - modules = [ - ( - { config, lib, ... }: - - let - sharedData = import ../data/services.nix; - # Enrich services with host IPs - services = map ( - svc: - let - hostInfo = sharedData.hosts.${svc.host} or { }; - in - svc - // { - lanIP = hostInfo.lanIP or null; - tailscaleIP = hostInfo.tailscaleIP or null; - } - ) sharedData.services; - - # Helper to extract subdomain from full domain (e.g., "git.baduhai.dev" -> "git") - getSubdomain = domain: lib.head (lib.splitString "." domain); - - # Generate DNS records for services - # Public services point to trantor's public IP - # Private services point to their tailscale IP - mkServiceRecords = lib.listToAttrs ( - lib.imap0 ( - i: svc: - let - subdomain = getSubdomain svc.domain; - targetIP = - if svc.public or false then - config.data.terraform_remote_state.trantor "outputs.instance_public_ip" - else - svc.tailscaleIP; - in - { - name = "service_${toString i}"; - value = { - zone_id = config.variable.zone_id.default; - name = subdomain; - type = "A"; - content = targetIP; - proxied = false; - ttl = 3600; - }; - } - ) services - ); - in - - { - terraform.required_providers.cloudflare = { - source = "cloudflare/cloudflare"; - version = "~> 5.0"; - }; - - terraform.backend.s3 = { - bucket = "terraform-state"; - key = "cloudflare/baduhai.dev.tfstate"; - region = "auto"; - endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; - skip_credentials_validation = true; - skip_metadata_api_check = true; - skip_region_validation = true; - skip_requesting_account_id = true; - use_path_style = true; - }; - - variable = { - zone_id = { - default = "c63a8332fdddc4a8e5612ddc54557044"; - type = "string"; - }; - }; - - data = { - terraform_remote_state.trantor = { - backend = "s3"; - config = { - bucket = "terraform-state"; - key = "oci/trantor.tfstate"; - region = "auto"; - endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; - skip_credentials_validation = true; - skip_metadata_api_check = true; - skip_region_validation = true; - skip_requesting_account_id = true; - use_path_style = true; - }; - }; - }; - - resource.cloudflare_dns_record = mkServiceRecords; - } - ) - ]; - }; - }; -} diff --git a/terranix/cloudflare/baduhai.dev.nix b/terranix/cloudflare/baduhai.dev.nix new file mode 100644 index 0000000..1b456f3 --- /dev/null +++ b/terranix/cloudflare/baduhai.dev.nix @@ -0,0 +1,86 @@ +# Required environment variables: +# CLOUDFLARE_API_TOKEN - API token with "Edit zone DNS" permissions +# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage +# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage + +{ config, lib, ... }: + +let + inherit (import ../../shared/services.nix) services; + + # Helper to extract subdomain from full domain (e.g., "git.baduhai.dev" -> "git") + getSubdomain = domain: lib.head (lib.splitString "." domain); + + # Generate DNS records for services + # Public services point to trantor's public IP + # Private services point to their tailscale IP + mkServiceRecords = lib.listToAttrs ( + lib.imap0 ( + i: svc: + let + subdomain = getSubdomain svc.domain; + targetIP = + if svc.public or false then + config.data.terraform_remote_state.trantor "outputs.instance_public_ip" + else + svc.tailscaleIP; + in + { + name = "service_${toString i}"; + value = { + zone_id = config.variable.zone_id.default; + name = subdomain; + type = "A"; + content = targetIP; + proxied = false; + ttl = 3600; + }; + } + ) services + ); +in + +{ + terraform.required_providers.cloudflare = { + source = "cloudflare/cloudflare"; + version = "~> 5.0"; + }; + + terraform.backend.s3 = { + bucket = "terraform-state"; + key = "cloudflare/baduhai.dev.tfstate"; + region = "auto"; + endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; + skip_credentials_validation = true; + skip_metadata_api_check = true; + skip_region_validation = true; + skip_requesting_account_id = true; + use_path_style = true; + }; + + variable = { + zone_id = { + default = "c63a8332fdddc4a8e5612ddc54557044"; + type = "string"; + }; + }; + + data = { + terraform_remote_state.trantor = { + backend = "s3"; + config = { + bucket = "terraform-state"; + key = "oci/trantor.tfstate"; + region = "auto"; + endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; + skip_credentials_validation = true; + skip_metadata_api_check = true; + skip_region_validation = true; + skip_requesting_account_id = true; + use_path_style = true; + }; + }; + }; + + resource.cloudflare_dns_record = mkServiceRecords; +} diff --git a/terranix/cloudflare/kernelpanic.space.nix b/terranix/cloudflare/kernelpanic.space.nix new file mode 100644 index 0000000..e69de29 diff --git a/terranix/kernelpanic.space.nix b/terranix/kernelpanic.space.nix deleted file mode 100644 index 01e5c08..0000000 --- a/terranix/kernelpanic.space.nix +++ /dev/null @@ -1,17 +0,0 @@ -# Cloudflare kernelpanic.space configuration placeholder -{ ... }: - -{ - perSystem = - { pkgs, ... }: - { - terranix.terranixConfigurations.cloudflare-kernelpanicspace = { - terraformWrapper.package = pkgs.opentofu; - modules = [ - ({ config, ... }: { - # Terraform config goes here - }) - ]; - }; - }; -} diff --git a/terranix/oci/terminus.nix b/terranix/oci/terminus.nix new file mode 100644 index 0000000..e69de29 diff --git a/terranix/oci/trantor.nix b/terranix/oci/trantor.nix new file mode 100644 index 0000000..170ad04 --- /dev/null +++ b/terranix/oci/trantor.nix @@ -0,0 +1,258 @@ +# Required environment variables: +# instead of OCI variables, ~/.oci/config may also be used +# OCI_TENANCY_OCID - Oracle tenancy OCID (or use TF_VAR_* to override variables) +# OCI_USER_OCID - Oracle user OCID +# OCI_FINGERPRINT - API key fingerprint +# OCI_PRIVATE_KEY_PATH - Path to OCI API private key +# AWS variables are required +# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage +# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage + +{ config, ... }: + +{ + terraform.required_providers.oci = { + source = "oracle/oci"; + version = "~> 7.0"; + }; + + provider.oci.region = "sa-saopaulo-1"; + + terraform.backend.s3 = { + bucket = "terraform-state"; + key = "oci/trantor.tfstate"; + region = "auto"; + endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; + skip_credentials_validation = true; + skip_metadata_api_check = true; + skip_region_validation = true; + skip_requesting_account_id = true; + use_path_style = true; + }; + + variable = { + tenancy_ocid = { + default = "ocid1.tenancy.oc1..aaaaaaaap3vfdz4piygqza6e6zqunbcuso43ddqfo3ydmpmnomidyghh7rvq"; + type = "string"; + }; + + compartment_name = { + default = "trantor"; + type = "string"; + }; + + vcn_cidr = { + default = "10.0.0.0/24"; + type = "string"; + }; + + instance_name = { + default = "trantor"; + type = "string"; + }; + + ssh_public_keys = { + default = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" + ]; + type = "list(string)"; + }; + }; + + data = { + oci_identity_availability_domains.ads = { + compartment_id = config.variable.tenancy_ocid.default; + }; + + oci_core_images.ubuntu_arm = { + compartment_id = config.variable.tenancy_ocid.default; + operating_system = "Canonical Ubuntu"; + operating_system_version = "24.04"; + shape = "VM.Standard.A1.Flex"; + sort_by = "TIMECREATED"; + sort_order = "DESC"; + }; + }; + + resource = { + oci_identity_compartment.trantor = { + compartment_id = config.variable.tenancy_ocid.default; + description = "trantor infrastructure compartment"; + name = config.variable.compartment_name.default; + }; + + oci_core_vcn.vcn = { + compartment_id = config.resource.oci_identity_compartment.trantor "id"; + cidr_blocks = [ config.variable.vcn_cidr.default ]; + display_name = "trantor-vcn"; + dns_label = "trantor"; + }; + + oci_core_internet_gateway.ig = { + compartment_id = config.resource.oci_identity_compartment.trantor "id"; + vcn_id = config.resource.oci_core_vcn.vcn "id"; + display_name = "trantor-ig"; + enabled = true; + }; + + oci_core_route_table.rt = { + compartment_id = config.resource.oci_identity_compartment.trantor "id"; + vcn_id = config.resource.oci_core_vcn.vcn "id"; + display_name = "trantor-rt"; + + route_rules = [ + { + network_entity_id = config.resource.oci_core_internet_gateway.ig "id"; + destination = "0.0.0.0/0"; + destination_type = "CIDR_BLOCK"; + } + ]; + }; + + oci_core_security_list.sl = { + compartment_id = config.resource.oci_identity_compartment.trantor "id"; + vcn_id = config.resource.oci_core_vcn.vcn "id"; + display_name = "trantor-sl"; + + egress_security_rules = [ + { + destination = "0.0.0.0/0"; + protocol = "all"; + stateless = false; + } + ]; + + ingress_security_rules = [ + { + protocol = "6"; # TCP + source = "0.0.0.0/0"; + stateless = false; + tcp_options = { + min = 22; + max = 22; + }; + } + { + protocol = "6"; # TCP + source = "0.0.0.0/0"; + stateless = false; + tcp_options = { + min = 80; + max = 80; + }; + } + { + protocol = "6"; # TCP + source = "0.0.0.0/0"; + stateless = false; + tcp_options = { + min = 443; + max = 443; + }; + } + { + protocol = "6"; # TCP + source = "0.0.0.0/0"; + stateless = false; + tcp_options = { + min = 25565; + max = 25565; + }; + } + { + protocol = "6"; # TCP + source = "0.0.0.0/0"; + stateless = false; + tcp_options = { + min = 19132; + max = 19133; + }; + } + { + protocol = "17"; # UDP + source = "0.0.0.0/0"; + stateless = false; + udp_options = { + min = 19132; + max = 19133; + }; + } + ]; + }; + + oci_core_subnet.subnet = { + compartment_id = config.resource.oci_identity_compartment.trantor "id"; + vcn_id = config.resource.oci_core_vcn.vcn "id"; + cidr_block = config.variable.vcn_cidr.default; + display_name = "trantor-subnet"; + dns_label = "subnet"; + route_table_id = config.resource.oci_core_route_table.rt "id"; + security_list_ids = [ (config.resource.oci_core_security_list.sl "id") ]; + prohibit_public_ip_on_vnic = false; + }; + + oci_core_instance.trantor = { + availability_domain = config.data.oci_identity_availability_domains.ads "availability_domains[0].name"; + compartment_id = config.resource.oci_identity_compartment.trantor "id"; + display_name = config.variable.instance_name.default; + shape = "VM.Standard.A1.Flex"; + + shape_config = { + ocpus = 2; + memory_in_gbs = 12; + }; + + source_details = { + source_type = "image"; + source_id = config.data.oci_core_images.ubuntu_arm "images[0].id"; + boot_volume_size_in_gbs = 100; + }; + + create_vnic_details = { + subnet_id = config.resource.oci_core_subnet.subnet "id"; + display_name = "trantor-vnic"; + assign_public_ip = true; + hostname_label = config.variable.instance_name.default; + }; + + metadata = { + ssh_authorized_keys = builtins.concatStringsSep "\n" config.variable.ssh_public_keys.default; + }; + + preserve_boot_volume = false; + }; + + oci_budget_budget.trantor_budget = { + compartment_id = config.variable.tenancy_ocid.default; + targets = [ (config.resource.oci_identity_compartment.trantor "id") ]; + amount = 1; + reset_period = "MONTHLY"; + display_name = "trantor-budget"; + description = "Monthly budget for trantor compartment"; + target_type = "COMPARTMENT"; + }; + + oci_budget_alert_rule.daily_spend_alert = { + budget_id = config.resource.oci_budget_budget.trantor_budget "id"; + type = "ACTUAL"; + threshold = 5; + threshold_type = "PERCENTAGE"; + display_name = "daily-spend-alert"; + recipients = "baduhai@proton.me"; + description = "Alert when daily spending exceeds $0.05"; + message = "Daily spending has exceeded $0.05 in the trantor compartment"; + }; + }; + + output = { + compartment_id = { + value = config.resource.oci_identity_compartment.trantor "id"; + }; + + instance_public_ip = { + value = config.resource.oci_core_instance.trantor "public_ip"; + }; + }; +} diff --git a/terranix/tailnet.nix b/terranix/tailnet.nix deleted file mode 100644 index 4e01ab9..0000000 --- a/terranix/tailnet.nix +++ /dev/null @@ -1,57 +0,0 @@ -# Required environment variables: -# TAILSCALE_API_KEY - Tailscale API key with appropriate permissions -# TAILSCALE_TAILNET - Your tailnet name (e.g., "user@example.com" or "example.org.github") -# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage -# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage - -{ ... }: - -{ - perSystem = - { pkgs, ... }: - { - terranix.terranixConfigurations.tailscale-tailnet = { - terraformWrapper.package = pkgs.opentofu; - modules = [ - ( - { config, ... }: - { - terraform.required_providers.tailscale = { - source = "tailscale/tailscale"; - version = "~> 0.17"; - }; - - terraform.backend.s3 = { - bucket = "terraform-state"; - key = "tailscale/tailnet.tfstate"; - region = "auto"; - endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; - skip_credentials_validation = true; - skip_metadata_api_check = true; - skip_region_validation = true; - skip_requesting_account_id = true; - use_path_style = true; - }; - - variable = { - trantor_tailscale_ip = { - default = "100.108.5.90"; - type = "string"; - }; - }; - - resource = { - tailscale_dns_nameservers.global = { - nameservers = [ - config.variable.trantor_tailscale_ip.default - "1.1.1.1" - "1.0.0.1" - ]; - }; - }; - } - ) - ]; - }; - }; -} diff --git a/terranix/tailscale/tailnet.nix b/terranix/tailscale/tailnet.nix new file mode 100644 index 0000000..929e79b --- /dev/null +++ b/terranix/tailscale/tailnet.nix @@ -0,0 +1,43 @@ +# Required environment variables: +# TAILSCALE_API_KEY - Tailscale API key with appropriate permissions +# TAILSCALE_TAILNET - Your tailnet name (e.g., "user@example.com" or "example.org.github") +# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage +# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage + +{ config, ... }: + +{ + terraform.required_providers.tailscale = { + source = "tailscale/tailscale"; + version = "~> 0.17"; + }; + + terraform.backend.s3 = { + bucket = "terraform-state"; + key = "tailscale/tailnet.tfstate"; + region = "auto"; + endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; + skip_credentials_validation = true; + skip_metadata_api_check = true; + skip_region_validation = true; + skip_requesting_account_id = true; + use_path_style = true; + }; + + variable = { + trantor_tailscale_ip = { + default = "100.108.5.90"; + type = "string"; + }; + }; + + resource = { + tailscale_dns_nameservers.global = { + nameservers = [ + config.variable.trantor_tailscale_ip.default + "1.1.1.1" + "1.0.0.1" + ]; + }; + }; +} diff --git a/terranix/terminus.nix b/terranix/terminus.nix deleted file mode 100644 index 7a0fa5b..0000000 --- a/terranix/terminus.nix +++ /dev/null @@ -1,17 +0,0 @@ -# OCI Terminus configuration placeholder -{ ... }: - -{ - perSystem = - { pkgs, ... }: - { - terranix.terranixConfigurations.oci-terminus = { - terraformWrapper.package = pkgs.opentofu; - modules = [ - ({ config, ... }: { - # Terraform config goes here - }) - ]; - }; - }; -} diff --git a/terranix/trantor.nix b/terranix/trantor.nix deleted file mode 100644 index 5f19e22..0000000 --- a/terranix/trantor.nix +++ /dev/null @@ -1,272 +0,0 @@ -# Required environment variables: -# instead of OCI variables, ~/.oci/config may also be used -# OCI_TENANCY_OCID - Oracle tenancy OCID (or use TF_VAR_* to override variables) -# OCI_USER_OCID - Oracle user OCID -# OCI_FINGERPRINT - API key fingerprint -# OCI_PRIVATE_KEY_PATH - Path to OCI API private key -# AWS variables are required -# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage -# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage - -{ ... }: - -{ - perSystem = - { pkgs, ... }: - { - terranix.terranixConfigurations.oci-trantor = { - terraformWrapper.package = pkgs.opentofu; - modules = [ - ( - { config, ... }: - { - terraform.required_providers.oci = { - source = "oracle/oci"; - version = "~> 7.0"; - }; - - provider.oci.region = "sa-saopaulo-1"; - - terraform.backend.s3 = { - bucket = "terraform-state"; - key = "oci/trantor.tfstate"; - region = "auto"; - endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com"; - skip_credentials_validation = true; - skip_metadata_api_check = true; - skip_region_validation = true; - skip_requesting_account_id = true; - use_path_style = true; - }; - - variable = { - tenancy_ocid = { - default = "ocid1.tenancy.oc1..aaaaaaaap3vfdz4piygqza6e6zqunbcuso43ddqfo3ydmpmnomidyghh7rvq"; - type = "string"; - }; - - compartment_name = { - default = "trantor"; - type = "string"; - }; - - vcn_cidr = { - default = "10.0.0.0/24"; - type = "string"; - }; - - instance_name = { - default = "trantor"; - type = "string"; - }; - - ssh_public_keys = { - default = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" - ]; - type = "list(string)"; - }; - }; - - data = { - oci_identity_availability_domains.ads = { - compartment_id = config.variable.tenancy_ocid.default; - }; - - oci_core_images.ubuntu_arm = { - compartment_id = config.variable.tenancy_ocid.default; - operating_system = "Canonical Ubuntu"; - operating_system_version = "24.04"; - shape = "VM.Standard.A1.Flex"; - sort_by = "TIMECREATED"; - sort_order = "DESC"; - }; - }; - - resource = { - oci_identity_compartment.trantor = { - compartment_id = config.variable.tenancy_ocid.default; - description = "trantor infrastructure compartment"; - name = config.variable.compartment_name.default; - }; - - oci_core_vcn.vcn = { - compartment_id = config.resource.oci_identity_compartment.trantor "id"; - cidr_blocks = [ config.variable.vcn_cidr.default ]; - display_name = "trantor-vcn"; - dns_label = "trantor"; - }; - - oci_core_internet_gateway.ig = { - compartment_id = config.resource.oci_identity_compartment.trantor "id"; - vcn_id = config.resource.oci_core_vcn.vcn "id"; - display_name = "trantor-ig"; - enabled = true; - }; - - oci_core_route_table.rt = { - compartment_id = config.resource.oci_identity_compartment.trantor "id"; - vcn_id = config.resource.oci_core_vcn.vcn "id"; - display_name = "trantor-rt"; - - route_rules = [ - { - network_entity_id = config.resource.oci_core_internet_gateway.ig "id"; - destination = "0.0.0.0/0"; - destination_type = "CIDR_BLOCK"; - } - ]; - }; - - oci_core_security_list.sl = { - compartment_id = config.resource.oci_identity_compartment.trantor "id"; - vcn_id = config.resource.oci_core_vcn.vcn "id"; - display_name = "trantor-sl"; - - egress_security_rules = [ - { - destination = "0.0.0.0/0"; - protocol = "all"; - stateless = false; - } - ]; - - ingress_security_rules = [ - { - protocol = "6"; # TCP - source = "0.0.0.0/0"; - stateless = false; - tcp_options = { - min = 22; - max = 22; - }; - } - { - protocol = "6"; # TCP - source = "0.0.0.0/0"; - stateless = false; - tcp_options = { - min = 80; - max = 80; - }; - } - { - protocol = "6"; # TCP - source = "0.0.0.0/0"; - stateless = false; - tcp_options = { - min = 443; - max = 443; - }; - } - { - protocol = "6"; # TCP - source = "0.0.0.0/0"; - stateless = false; - tcp_options = { - min = 25565; - max = 25565; - }; - } - { - protocol = "6"; # TCP - source = "0.0.0.0/0"; - stateless = false; - tcp_options = { - min = 19132; - max = 19133; - }; - } - { - protocol = "17"; # UDP - source = "0.0.0.0/0"; - stateless = false; - udp_options = { - min = 19132; - max = 19133; - }; - } - ]; - }; - - oci_core_subnet.subnet = { - compartment_id = config.resource.oci_identity_compartment.trantor "id"; - vcn_id = config.resource.oci_core_vcn.vcn "id"; - cidr_block = config.variable.vcn_cidr.default; - display_name = "trantor-subnet"; - dns_label = "subnet"; - route_table_id = config.resource.oci_core_route_table.rt "id"; - security_list_ids = [ (config.resource.oci_core_security_list.sl "id") ]; - prohibit_public_ip_on_vnic = false; - }; - - oci_core_instance.trantor = { - availability_domain = config.data.oci_identity_availability_domains.ads "availability_domains[0].name"; - compartment_id = config.resource.oci_identity_compartment.trantor "id"; - display_name = config.variable.instance_name.default; - shape = "VM.Standard.A1.Flex"; - - shape_config = { - ocpus = 2; - memory_in_gbs = 12; - }; - - source_details = { - source_type = "image"; - source_id = config.data.oci_core_images.ubuntu_arm "images[0].id"; - boot_volume_size_in_gbs = 100; - }; - - create_vnic_details = { - subnet_id = config.resource.oci_core_subnet.subnet "id"; - display_name = "trantor-vnic"; - assign_public_ip = true; - hostname_label = config.variable.instance_name.default; - }; - - metadata = { - ssh_authorized_keys = builtins.concatStringsSep "\n" config.variable.ssh_public_keys.default; - }; - - preserve_boot_volume = false; - }; - - oci_budget_budget.trantor_budget = { - compartment_id = config.variable.tenancy_ocid.default; - targets = [ (config.resource.oci_identity_compartment.trantor "id") ]; - amount = 1; - reset_period = "MONTHLY"; - display_name = "trantor-budget"; - description = "Monthly budget for trantor compartment"; - target_type = "COMPARTMENT"; - }; - - oci_budget_alert_rule.daily_spend_alert = { - budget_id = config.resource.oci_budget_budget.trantor_budget "id"; - type = "ACTUAL"; - threshold = 5; - threshold_type = "PERCENTAGE"; - display_name = "daily-spend-alert"; - recipients = "baduhai@proton.me"; - description = "Alert when daily spending exceeds $0.05"; - message = "Daily spending has exceeded $0.05 in the trantor compartment"; - }; - }; - - output = { - compartment_id = { - value = config.resource.oci_identity_compartment.trantor "id"; - }; - - instance_public_ip = { - value = config.resource.oci_core_instance.trantor "public_ip"; - }; - }; - } - ) - ]; - }; - }; -} diff --git a/terranixConfigurations.nix b/terranixConfigurations.nix new file mode 100644 index 0000000..12c90d1 --- /dev/null +++ b/terranixConfigurations.nix @@ -0,0 +1,27 @@ +{ inputs, ... }: + +{ + imports = [ + inputs.terranix.flakeModule + ]; + + perSystem = + { pkgs, ... }: + + { + terranix.terranixConfigurations = { + oci-trantor = { + modules = [ ./terranix/oci/trantor.nix ]; + terraformWrapper.package = pkgs.opentofu; + }; + cloudflare-baduhaidev = { + modules = [ ./terranix/cloudflare/baduhai.dev.nix ]; + terraformWrapper.package = pkgs.opentofu; + }; + tailscale-tailnet = { + modules = [ ./terranix/tailscale/tailnet.nix ]; + terraformWrapper.package = pkgs.opentofu; + }; + }; + }; +} diff --git a/users/modules/btop.nix b/users/modules/btop.nix new file mode 100644 index 0000000..c19c4bb --- /dev/null +++ b/users/modules/btop.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: + +{ + programs.btop = { + enable = true; + settings = { + theme_background = false; + proc_sorting = "cpu direct"; + update_ms = 500; + }; + }; +} \ No newline at end of file diff --git a/users/modules/comma.nix b/users/modules/comma.nix new file mode 100644 index 0000000..0aad530 --- /dev/null +++ b/users/modules/comma.nix @@ -0,0 +1,7 @@ +{ inputs, ... }: + +{ + imports = [ inputs.nix-index-database.homeModules.nix-index ]; + + programs.nix-index-database.comma.enable = true; +} diff --git a/users/modules/common/bash.nix b/users/modules/common/bash.nix new file mode 100644 index 0000000..a5a0823 --- /dev/null +++ b/users/modules/common/bash.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: + +{ + programs.bash = { + enable = true; + historyFile = "~/.cache/bash_history"; + }; +} \ No newline at end of file diff --git a/users/modules/common/fish.nix b/users/modules/common/fish.nix new file mode 100644 index 0000000..c753297 --- /dev/null +++ b/users/modules/common/fish.nix @@ -0,0 +1,32 @@ +{ pkgs, lib, ... }: + +{ + programs.fish = { + enable = true; + interactiveShellInit = '' + set fish_greeting + ${lib.getExe pkgs.nix-your-shell} fish | source + ''; + loginShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source"; + plugins = [ + { + name = "bang-bang"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "plugin-bang-bang"; + rev = "f969c618301163273d0a03d002614d9a81952c1e"; + sha256 = "sha256-A8ydBX4LORk+nutjHurqNNWFmW6LIiBPQcxS3x4nbeQ="; + }; + } + { + name = "z"; + src = pkgs.fetchFromGitHub { + owner = "jethrokuan"; + repo = "z"; + rev = "067e867debee59aee231e789fc4631f80fa5788e"; + sha256 = "sha256-emmjTsqt8bdI5qpx1bAzhVACkg0MNB/uffaRjjeuFxU="; + }; + } + ]; + }; +} diff --git a/users/modules/common/hm-cli.nix b/users/modules/common/hm-cli.nix new file mode 100644 index 0000000..d2ed715 --- /dev/null +++ b/users/modules/common/hm-cli.nix @@ -0,0 +1,10 @@ +{ pkgs, ... }: + +{ + home = { + packages = with pkgs; [ hm-cli ]; + sessionVariables = { + HM_PATH = "/etc/nixos"; + }; + }; +} diff --git a/users/modules/desktop/desktop.nix b/users/modules/desktop/desktop.nix new file mode 100644 index 0000000..fd3d306 --- /dev/null +++ b/users/modules/desktop/desktop.nix @@ -0,0 +1,134 @@ +{ + inputs, + pkgs, + ... +}: + +{ + imports = [ inputs.vicinae.homeManagerModules.default ]; + + fonts.fontconfig.enable = true; + + home.packages = with pkgs; [ xwayland-satellite ]; + + services.vicinae = { + enable = true; + systemd = { + enable = true; + autoStart = true; + }; + }; + + programs = { + ghostty = { + enable = true; + settings = { + cursor-style = "block"; + shell-integration-features = "no-cursor"; + cursor-style-blink = false; + custom-shader = "${builtins.fetchurl { + url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl"; + sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41"; + }}"; + bell-features = ""; + gtk-titlebar-style = "tabs"; + keybind = [ "shift+enter=text:\\x1b\\r" ]; + }; + }; + + password-store = { + enable = true; + package = pkgs.pass-wayland; + }; + }; + + xdg = { + enable = true; + userDirs.enable = true; + mimeApps = { + enable = true; + defaultApplications = { + "text/html" = [ + "re.sonny.Junction.desktop" + "zen-browser.desktop" + "torbrowser.desktop" + ]; + "x-scheme-handler/http" = [ + "re.sonny.Junction.desktop" + "zen-browser.desktop" + "torbrowser.desktop" + ]; + "x-scheme-handler/https" = [ + "re.sonny.Junction.desktop" + "zen-browser.desktop" + "torbrowser.desktop" + ]; + "x-scheme-handler/about" = [ + "re.sonny.Junction.desktop" + "zen-browser.desktop" + "torbrowser.desktop" + ]; + "x-scheme-handler/unknown" = [ + "re.sonny.Junction.desktop" + "zen-browser.desktop" + "torbrowser.desktop" + ]; + "image/jpeg" = "org.gnome.Loupe.desktop"; + "image/png" = "org.gnome.Loupe.desktop"; + "image/gif" = "org.gnome.Loupe.desktop"; + "image/webp" = "org.gnome.Loupe.desktop"; + "image/bmp" = "org.gnome.Loupe.desktop"; + "image/svg+xml" = "org.gnome.Loupe.desktop"; + "image/tiff" = "org.gnome.Loupe.desktop"; + "video/mp4" = "io.bassi.Showtime.desktop"; + "video/x-matroska" = "io.bassi.Showtime.desktop"; + "video/webm" = "io.bassi.Showtime.desktop"; + "video/mpeg" = "io.bassi.Showtime.desktop"; + "video/x-msvideo" = "io.bassi.Showtime.desktop"; + "video/quicktime" = "io.bassi.Showtime.desktop"; + "video/x-flv" = "io.bassi.Showtime.desktop"; + "audio/mpeg" = "io.bassi.Showtime.desktop"; + "audio/flac" = "io.bassi.Showtime.desktop"; + "audio/ogg" = "io.bassi.Showtime.desktop"; + "audio/wav" = "io.bassi.Showtime.desktop"; + "audio/mp4" = "io.bassi.Showtime.desktop"; + "audio/x-opus+ogg" = "io.bassi.Showtime.desktop"; + "application/pdf" = [ + "org.gnome.Papers.desktop" + "zen-browser.desktop" + ]; + "text/plain" = "Helix.desktop"; + "text/markdown" = "Helix.desktop"; + "text/x-log" = "Helix.desktop"; + "application/x-shellscript" = "Helix.desktop"; + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" = + "com.collabora.Office.desktop"; # DOCX + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" = + "com.collabora.Office.desktop"; # XLSX + "application/vnd.openxmlformats-officedocument.presentationml.presentation" = + "com.collabora.Office.desktop"; # PPTX + "application/vnd.oasis.opendocument.text" = "com.collabora.Office.desktop"; # ODT + "application/vnd.oasis.opendocument.spreadsheet" = "com.collabora.Office.desktop"; # ODS + "application/vnd.oasis.opendocument.presentation" = "com.collabora.Office.desktop"; # ODP + "application/msword" = "com.collabora.Office.desktop"; # DOC + "application/vnd.ms-excel" = "com.collabora.Office.desktop"; # XLS + "application/vnd.ms-powerpoint" = "com.collabora.Office.desktop"; # PPT + "application/zip" = "org.gnome.FileRoller.desktop"; + "application/x-tar" = "org.gnome.FileRoller.desktop"; + "application/x-compressed-tar" = "org.gnome.FileRoller.desktop"; + "application/x-bzip-compressed-tar" = "org.gnome.FileRoller.desktop"; + "application/x-xz-compressed-tar" = "org.gnome.FileRoller.desktop"; + "application/x-7z-compressed" = "org.gnome.FileRoller.desktop"; + "application/x-rar" = "org.gnome.FileRoller.desktop"; + "application/gzip" = "org.gnome.FileRoller.desktop"; + "application/x-bzip" = "org.gnome.FileRoller.desktop"; + "inode/directory" = "org.gnome.Nautilus.desktop"; + }; + }; + }; + + # Set Ghostty as default terminal + home.sessionVariables = { + TERMINAL = "ghostty"; + }; +} diff --git a/users/modules/desktop/niri.nix b/users/modules/desktop/niri.nix new file mode 100644 index 0000000..58a7aaf --- /dev/null +++ b/users/modules/desktop/niri.nix @@ -0,0 +1,225 @@ +{ + inputs, + lib, + pkgs, + hostname ? null, + ... +}: + +let + isRotterdam = hostname == "rotterdam"; +in + +{ + imports = [ inputs.noctalia.homeModules.default ]; + + services.kanshi = { + enable = true; + settings = [ + { + profile.name = "default"; + profile.outputs = [ + { + criteria = "*"; + scale = 1.0; + } + ]; + } + ]; + }; + + home = { + packages = with pkgs; [ + xwayland-satellite + inputs.noctalia.packages.${pkgs.system}.default + ]; + sessionVariables.QT_QPA_PLATFORMTHEME = "gtk3"; + }; + + xdg.configFile."niri/config.kdl".text = '' + input { + keyboard { + xkb { + layout "us" + variant "altgr-intl" + } + } + touchpad { + tap + dwt + drag true + drag-lock + natural-scroll + accel-speed 0.2 + accel-profile "flat" + scroll-method "two-finger" + middle-emulation + } + mouse { + natural-scroll + accel-speed 0.2 + accel-profile "flat" + } + warp-mouse-to-focus mode="center-xy" + focus-follows-mouse + } + + layout { + gaps 8 + center-focused-column "never" + auto-center-when-space-available + preset-column-widths { + ${ + if isRotterdam then + '' + proportion 0.33333 + proportion 0.5 + proportion 0.66667 + '' + else + '' + proportion 0.5 + proportion 1.0 + '' + } + } + default-column-width { proportion ${if isRotterdam then "0.33333" else "0.5"}; } + focus-ring { + off + } + border { + width 4 + active-color "#ffc87f" + inactive-color "#505050" + urgent-color "#9b0000" + } + tab-indicator { + width 4 + gap 4 + place-within-column + } + } + + overview { + zoom 0.65 + } + + spawn-at-startup "noctalia-shell" "-d" + layer-rule { + match namespace="^noctalia-overview*" + place-within-backdrop true + } + + hotkey-overlay { + skip-at-startup + } + + prefer-no-csd + screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" + + animations { + slowdown 0.3 + } + + window-rule { + match app-id="zen" + default-column-width { proportion ${if isRotterdam then "0.5" else "1.0"}; } + } + + window-rule { + geometry-corner-radius 12 + clip-to-geometry true + } + + config-notification { + disable-failed + } + + binds { + Alt+Space repeat=false { spawn "vicinae" "toggle"; } + XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "increase"; } + XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "decrease"; } + XF86AudioMute allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "muteOutput"; } + XF86MonBrightnessUp allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "brightness" "increase"; } + XF86MonBrightnessDown allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "brightness" "decrease"; } + XF86AudioPlay allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "play-pause"; } + XF86AudioStop allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "stop"; } + XF86AudioPrev allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "previous"; } + XF86AudioNext allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "next"; } + Mod+V repeat=false { spawn "vicinae" "vicinae://extensions/vicinae/clipboard/history"; } + Mod+Shift+L repeat=false { spawn "noctalia-shell" "ipc" "call" "lockScreen" "lock"; } + Mod+Return { spawn "ghostty"; } + Ctrl+Alt+Shift+A allow-when-locked=true { spawn "toggleaudiosink"; } + Mod+W repeat=false { toggle-overview; } + Mod+Q { close-window; } + Alt+Shift+Q { close-window;} + Mod+Shift+Q { close-window; } + Alt+F4 { close-window; } + Mod+Left { focus-column-left; } + Mod+Down { focus-window-or-workspace-down; } + Mod+Up { focus-window-or-workspace-up; } + Mod+Right { focus-column-right; } + Mod+H { focus-column-left; } + Mod+L { focus-column-right; } + Mod+J { focus-window-or-workspace-down; } + Mod+K { focus-window-or-workspace-up; } + Mod+Ctrl+Left { move-column-left; } + Mod+Ctrl+Down { move-window-down-or-to-workspace-down; } + Mod+Ctrl+Up { move-window-up-or-to-workspace-up; } + Mod+Ctrl+Right { move-column-right; } + Mod+Ctrl+H { move-column-left; } + Mod+Ctrl+J { move-window-down-or-to-workspace-down; } + Mod+Ctrl+K { move-window-up-or-to-workspace-up; } + Mod+Ctrl+L { move-column-right; } + Mod+Home { focus-column-first; } + Mod+End { focus-column-last; } + Mod+Ctrl+Home { move-column-to-first; } + Mod+Ctrl+End { move-column-to-last; } + Mod+Alt+Left { focus-monitor-left; } + Mod+Alt+Down { focus-monitor-down; } + Mod+Alt+Up { focus-monitor-up; } + Mod+Alt+Right { focus-monitor-right; } + Mod+Alt+H { focus-monitor-left; } + Mod+Alt+J { focus-monitor-down; } + Mod+Alt+K { focus-monitor-up; } + Mod+Alt+L { focus-monitor-right; } + Mod+Alt+Ctrl+Left { move-column-to-monitor-left; } + Mod+Alt+Ctrl+Down { move-column-to-monitor-down; } + Mod+Alt+Ctrl+Up { move-column-to-monitor-up; } + Mod+Alt+Ctrl+Right { move-column-to-monitor-right; } + Mod+Alt+Ctrl+H { move-column-to-monitor-left; } + Mod+Alt+Ctrl+J { move-column-to-monitor-down; } + Mod+Alt+Ctrl+K { move-column-to-monitor-up; } + Mod+Alt+Ctrl+L { move-column-to-monitor-right; } + Mod+Ctrl+U { move-workspace-down; } + Mod+Ctrl+I { move-workspace-up; } + Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } + Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } + Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } + Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } + Mod+Shift+WheelScrollDown { focus-column-right; } + Mod+Shift+WheelScrollUp { focus-column-left; } + Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } + Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } + Mod+BracketLeft { consume-or-expel-window-left; } + Mod+BracketRight { consume-or-expel-window-right; } + Mod+Comma { consume-window-into-column; } + Mod+Period { expel-window-from-column; } + Mod+R { switch-preset-column-width; } + Mod+F { maximize-column; } + Mod+Ctrl+F { fullscreen-window; } + Mod+C { center-visible-columns; } + Mod+Ctrl+C { center-column; } + Mod+Space { toggle-window-floating; } + Mod+Ctrl+Space { switch-focus-between-floating-and-tiling; } + Mod+T { toggle-column-tabbed-display; } + Print { screenshot-screen; } + Mod+Print { screenshot; } + Ctrl+Print { screenshot-window; } + Mod+Backspace allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } + Mod+Alt+E { spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; } + Ctrl+Alt+Delete { spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; } + Mod+Ctrl+P { power-off-monitors; } + } + ''; +} diff --git a/users/modules/direnv.nix b/users/modules/direnv.nix new file mode 100644 index 0000000..c91d0af --- /dev/null +++ b/users/modules/direnv.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: + +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; +} \ No newline at end of file diff --git a/users/modules/gaming.nix b/users/modules/gaming.nix new file mode 100644 index 0000000..48825ab --- /dev/null +++ b/users/modules/gaming.nix @@ -0,0 +1,33 @@ +{ config, ... }: + +{ + programs.mangohud = { + enable = true; + enableSessionWide = true; + settings = { + position = "top-left"; + fps = true; + frametime = false; + frame_timing = false; + gpu_stats = true; + gpu_temp = true; + gpu_power = true; + cpu_stats = true; + cpu_temp = true; + cpu_power = true; + ram = true; + vram = true; + gamemode = false; + vkbasalt = false; + version = false; + engine_version = false; + vulkan_driver = false; + wine = false; + time = false; + fps_sampling_period = 500; + toggle_hud = "Shift_L+F12"; + toggle_logging = "Ctrl_L+F2"; + output_folder = "${config.home.homeDirectory}/.local/share/mangohud"; + }; + }; +} diff --git a/users/modules/helix.nix b/users/modules/helix.nix new file mode 100644 index 0000000..a72ead3 --- /dev/null +++ b/users/modules/helix.nix @@ -0,0 +1,49 @@ +{ pkgs, ... }: + +{ + home.sessionVariables = { + EDITOR = "hx"; + }; + + programs.helix = { + enable = true; + settings = { + editor = { + file-picker.hidden = false; + idle-timeout = 0; + line-number = "relative"; + cursor-shape = { + normal = "underline"; + insert = "bar"; + select = "underline"; + }; + soft-wrap.enable = true; + auto-format = true; + indent-guides.render = true; + }; + keys.normal = { + space = { + o = "file_picker_in_current_buffer_directory"; + esc = [ + "collapse_selection" + "keep_primary_selection" + ]; + }; + }; + }; + languages = { + language = [ + { + name = "nix"; + auto-format = true; + formatter.command = "nixfmt"; + } + { + name = "typst"; + auto-format = true; + formatter.command = "typstyle -c 1000 -i"; + } + ]; + }; + }; +} diff --git a/users/modules/obs-studio.nix b/users/modules/obs-studio.nix new file mode 100644 index 0000000..67e3b8b --- /dev/null +++ b/users/modules/obs-studio.nix @@ -0,0 +1,13 @@ +{ pkgs, ... }: + +{ + programs.obs-studio = { + enable = true; + plugins = [ + pkgs.obs-studio-plugins.obs-vkcapture + pkgs.obs-studio-plugins.obs-backgroundremoval + pkgs.obs-studio-plugins.obs-pipewire-audio-capture + ]; + }; + +} diff --git a/users/modules/starship.nix b/users/modules/starship.nix new file mode 100644 index 0000000..c836c51 --- /dev/null +++ b/users/modules/starship.nix @@ -0,0 +1,40 @@ +{ pkgs, ... }: + +{ + programs.starship = { + enable = true; + enableBashIntegration = true; + enableFishIntegration = true; + settings = { + add_newline = false; + format = '' + $hostname$directory$git_branch$git_status$nix_shell + [ ❯ ](bold green) + ''; + right_format = "$cmd_duration$character"; + hostname = { + ssh_symbol = "󰖟 "; + }; + character = { + error_symbol = "[](red)"; + success_symbol = "[󱐋](green)"; + }; + cmd_duration = { + format = "[󰄉 $duration ]($style)"; + style = "yellow"; + min_time = 500; + }; + git_branch = { + symbol = " "; + style = "purple"; + }; + git_status.style = "red"; + nix_shell = { + format = "via [$symbol$state]($style)"; + heuristic = true; + style = "blue"; + symbol = "󱄅 "; + }; + }; + }; +} diff --git a/users/modules/stylix.nix b/users/modules/stylix.nix new file mode 100644 index 0000000..6b34e43 --- /dev/null +++ b/users/modules/stylix.nix @@ -0,0 +1,69 @@ +{ + config, + inputs, + pkgs, + ... +}: + +{ + imports = [ + inputs.stylix.homeModules.stylix + inputs.zen-browser.homeModules.beta + ]; + + stylix = { + enable = true; + polarity = "dark"; + base16Scheme = "${pkgs.base16-schemes}/share/themes/tokyodark.yaml"; + cursor = { + package = pkgs.kdePackages.breeze; + name = "breeze_cursors"; + size = 24; + }; + icons = { + enable = true; + package = pkgs.morewaita-icon-theme; + light = "MoreWaita"; + dark = "MoreWaita"; + }; + opacity = { + applications = 1.0; + desktop = 1.0; + popups = config.stylix.opacity.desktop; + terminal = 1.0; + }; + fonts = { + serif = { + package = pkgs.source-serif; + name = "Source Serif 4 Display"; + }; + sansSerif = { + package = pkgs.inter; + name = "Inter"; + }; + monospace = { + package = pkgs.nerd-fonts.fira-code; + name = "FiraCode Nerd Font"; + }; + emoji = { + package = pkgs.noto-fonts-color-emoji; + name = "Noto Color Emoji"; + }; + sizes = { + applications = 10; + desktop = config.stylix.fonts.sizes.applications; + popups = config.stylix.fonts.sizes.applications; + terminal = 12; + }; + }; + targets.zen-browser = { + enable = true; + profileNames = [ "william" ]; + }; + }; + + programs.zen-browser = { + enable = true; + profiles.william = { }; + }; +} diff --git a/users/modules/tmux.nix b/users/modules/tmux.nix new file mode 100644 index 0000000..4268e7a --- /dev/null +++ b/users/modules/tmux.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: + +{ + programs.tmux = { + enable = true; + clock24 = true; + terminal = "xterm-256color"; + mouse = true; + keyMode = "vi"; + }; +} \ No newline at end of file diff --git a/aspects/users/_user/git.nix b/users/user/git.nix similarity index 100% rename from aspects/users/_user/git.nix rename to users/user/git.nix diff --git a/utils.nix b/utils.nix new file mode 100644 index 0000000..e65837c --- /dev/null +++ b/utils.nix @@ -0,0 +1,233 @@ +{ inputs, lib }: + +let + inherit (inputs) + self + nixpkgs + nixpkgs-stable + home-manager + agenix + ; + + # Import shared service definitions + sharedServices = import ./shared/services.nix; + + # Enrich services with host IP information + enrichedServices = builtins.map (svc: + let + hostInfo = sharedServices.hosts.${svc.host} or {}; + in + svc // lib.optionalAttrs (hostInfo ? lanIP) { inherit (hostInfo) lanIP; } + // lib.optionalAttrs (hostInfo ? tailscaleIP) { inherit (hostInfo) tailscaleIP; } + ) sharedServices.services; +in + +{ + # Re-export enriched services and hosts for use in host configs + services = enrichedServices; + inherit (sharedServices) hosts; + # Tag-based host configuration system + mkHost = + { + hostname, + tags ? [ ], + system ? "x86_64-linux", + extraModules ? [ ], + }: + let + # Validate that server and desktop tags are mutually exclusive + hasServer = builtins.elem "server" tags; + hasDesktop = builtins.elem "desktop" tags; + + # Always include "common" tag implicitly + allTags = + if hasServer && hasDesktop then + throw "Error: 'server' and 'desktop' tags are mutually exclusive for host '${hostname}'" + else + [ "common" ] ++ tags; + + # Choose nixpkgs based on server tag + pkgs = if builtins.elem "server" allTags then nixpkgs-stable else nixpkgs; + + # Tag-specific modules: each tag can be either: + # 1. A file: hosts/modules/${tag}.nix + # 2. A directory: hosts/modules/${tag}/*.nix (all .nix files imported) + tagModuleFiles = builtins.concatMap ( + tag: + let + filePath = ./hosts/modules/${tag}.nix; + dirPath = ./hosts/modules/${tag}; + in + # Check if it's a file first + if builtins.pathExists filePath then + [ filePath ] + # Then check if it's a directory + else if builtins.pathExists dirPath then + let + entries = builtins.readDir dirPath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name + ) entries; + in + map (name: dirPath + "/${name}") (builtins.attrNames nixFiles) + else + [ ] + ) allTags; + + # Automatically import all .nix files from hosts/${hostname}/ + hostModulePath = ./hosts/${hostname}; + hostModuleFiles = + if builtins.pathExists hostModulePath then + let + entries = builtins.readDir hostModulePath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name && name != "${hostname}.nix" + ) entries; + in + map (name: hostModulePath + "/${name}") (builtins.attrNames nixFiles) + else + [ ]; + + # Combine all modules + allModules = [ + agenix.nixosModules.default + { + networking.hostName = hostname; + nix.nixPath = [ "nixos-config=${self.outPath}/nixosConfigurations/${hostname}" ]; + nixpkgs.overlays = [ + agenix.overlays.default + self.overlays.default + ]; + } + ] + ++ tagModuleFiles + ++ hostModuleFiles + ++ extraModules; + in + pkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs; + hostTags = allTags; + }; + modules = allModules; + }; + + # Tag-based user configuration system + mkHome = + { + username, + hostname ? null, + homeDirectory ? "/home/${username}", + tags ? [ ], + extraModules ? [ ], + }: + let + pkgs = nixpkgs.legacyPackages.x86_64-linux; + + # Always include "common" tag implicitly + allTags = [ "common" ] ++ tags; + + # Tag-specific modules: each tag maps to users/modules/${tag}.nix if it exists + tagModuleFiles = builtins.concatMap ( + tag: + let + filePath = ./users/modules/${tag}.nix; + dirPath = ./users/modules/${tag}; + in + # Check if it's a file first + if builtins.pathExists filePath then + [ filePath ] + # Then check if it's a directory + else if builtins.pathExists dirPath then + let + entries = builtins.readDir dirPath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name + ) entries; + in + map (name: dirPath + "/${name}") (builtins.attrNames nixFiles) + else + [ ] + ) allTags; + + # Automatically import all .nix files from users/${username}/ + userModulePath = ./users/${username}; + userModuleFiles = + if builtins.pathExists userModulePath then + let + entries = builtins.readDir userModulePath; + nixFiles = pkgs.lib.filterAttrs ( + name: type: type == "regular" && pkgs.lib.hasSuffix ".nix" name + ) entries; + in + map (name: userModulePath + "/${name}") (builtins.attrNames nixFiles) + else + [ ]; + + # Combine all modules + allModules = [ + { + home = { + inherit username homeDirectory; + stateVersion = "22.05"; + }; + } + ] + ++ tagModuleFiles + ++ userModuleFiles + ++ extraModules; + in + home-manager.lib.homeManagerConfiguration { + inherit pkgs; + extraSpecialArgs = { + inherit inputs hostname; + userTags = allTags; + }; + modules = allModules ++ [ + { + nixpkgs.overlays = [ self.overlays.default ]; + } + ]; + }; + + # Nginx virtual host utilities + mkNginxVHosts = + { domains }: + let + # Extract domain name and apply it as useACMEHost + mkVHostConfig = domain: config: + lib.recursiveUpdate { + useACMEHost = domain; + forceSSL = true; + kTLS = true; + } config; + in + lib.mapAttrs mkVHostConfig domains; + + # Split DNS utilities for unbound + # Generates unbound view config from a list of DNS entries + mkSplitDNS = + entries: + let + # Generate local-data entries for all domains + tailscaleData = map (e: ''"${e.domain}. IN A ${e.tailscaleIP}"'') entries; + lanData = map (e: ''"${e.domain}. IN A ${e.lanIP}"'') entries; + in + [ + # Single Tailscale view with all domains + { + name = "tailscale"; + view-first = true; + local-zone = ''"baduhai.dev." transparent''; + local-data = tailscaleData; + } + # Single LAN view with all domains + { + name = "lan"; + view-first = true; + local-zone = ''"baduhai.dev." transparent''; + local-data = lanData; + } + ]; +}