Commit Diff


commit - acfbca07aa18e85b11311cb4d924e71e8d576faf
commit + 8b67385501cc720d0a0b99f9ba857205e748d043
blob - /dev/null
blob + b2be92b7db01b7bfebb8e0aabd2f546906ff651a (mode 644)
--- /dev/null
+++ .gitignore
@@ -0,0 +1 @@
+result
blob - d1c05ea4ecb149cb14f4f896efe52ce769d62123
blob + aa36675e477fc08c61deff55fdf3213935c246b3
--- flake.lock
+++ flake.lock
@@ -164,11 +164,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1784351324,
-        "narHash": "sha256-By+kuRJZRqs2TuXgtR8vJ8cTKWXw33YG/Yollu5cO1U=",
+        "lastModified": 1784489491,
+        "narHash": "sha256-j9maqjx1T8+ljAVntAdSI5hSGCm77QNZz64JF1rJNu0=",
         "owner": "nix-community",
         "repo": "home-manager",
-        "rev": "460108009ca1ff69ca2ff19079ca2c838d6e3080",
+        "rev": "3139deb8cafbe73b39b24451255b2fdd3426077e",
         "type": "github"
       },
       "original": {
@@ -206,11 +206,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1783864904,
-        "narHash": "sha256-BQxN5UMg9FOevAsgBRwPxfxlh51Puj+dNn/8Dsi3sPM=",
+        "lastModified": 1784440659,
+        "narHash": "sha256-Q5kNLlWngt7TaIIZoxDKWMHjiSaNRVqr70FqWCRRfr4=",
         "owner": "nix-community",
         "repo": "nix-index-database",
-        "rev": "1111b9bc836afb7e31a7014e8d1272de9b1c917d",
+        "rev": "4f8d52a3598b0dc7db7a5e7b419e3edd9d1ecfdb",
         "type": "github"
       },
       "original": {
@@ -234,11 +234,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1784347607,
-        "narHash": "sha256-VI5cdo27nEZ3m1SlgB8RvBbrqFUO2/dUgrrLWe407oA=",
+        "lastModified": 1784494590,
+        "narHash": "sha256-Gn7vGw9aIyoJy7GkNbsHXvSkvXeNLoP9ZiK1RtS/0M8=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "31cd72fdba8fa052e437ce7e6879c4fe62def10f",
+        "rev": "472e4428b5aee60be7ac35c03662ebb36c901edd",
         "type": "github"
       },
       "original": {
@@ -279,7 +279,8 @@
         "home-manager": "home-manager",
         "nix-index-database": "nix-index-database",
         "nixpkgs": "nixpkgs_2",
-        "ragenix": "ragenix"
+        "ragenix": "ragenix",
+        "shirts": "shirts"
       }
     },
     "rust-overlay": {
@@ -303,6 +304,26 @@
         "type": "github"
       }
     },
+    "shirts": {
+      "inputs": {
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1784453219,
+        "narHash": "sha256-tTwhiMFuQ9C2ICynU1RrHbKSYPmVRJPnyhQmWCiv4fc=",
+        "owner": "~mtmn",
+        "repo": "shirts",
+        "rev": "d6db010862981845406e9b19d7f3dd5f123d22ca",
+        "type": "sourcehut"
+      },
+      "original": {
+        "owner": "~mtmn",
+        "repo": "shirts",
+        "type": "sourcehut"
+      }
+    },
     "systems": {
       "locked": {
         "lastModified": 1681028828,
blob - 68d8aeea614d810fed7f717fcc397595bd71a08e
blob + 7142ff72c84589551c8c52c4608b5014901cdfe6
--- flake.nix
+++ flake.nix
@@ -28,6 +28,11 @@
       url = "sourcehut:~mtmn/corpus";
       inputs.nixpkgs.follows = "nixpkgs";
     };
+
+    shirts = {
+      url = "sourcehut:~mtmn/shirts";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
   };
 
   outputs = {
@@ -44,78 +49,88 @@
     specialArgs = {
       inherit inputs self configData;
     };
-
-    nixosConfigurations = lib.mapAttrs (hostName: host: let
-      hostDir = ./hosts/${hostName};
-      username = host.username or defaultUsername;
-    in
-      lib.nixosSystem {
-        specialArgs = specialArgs // {inherit username;};
-        modules =
-          [
-            {nixpkgs.hostPlatform = host.system;}
-            inputs.ragenix.nixosModules.default
-            (hostDir + "/configuration.nix")
-          ]
-          ++ (lib.attrValues self.nixosModules)
-          ++ lib.optionals (host.disko or false) (
-            [disko.nixosModules.disko]
-            ++ lib.optional (builtins.pathExists (hostDir + "/disk-config.nix")) (hostDir + "/disk-config.nix")
-          );
-      })
-    (lib.filterAttrs (_: host: host.nixos or false) configData.hosts);
-
-    homeConfigurations = lib.concatMapAttrs (userName: user:
-      lib.mapAttrs' (hostName: _: let
-        host = configData.hosts.${hostName};
-        username = host.username or userName;
-        homeDirectory =
-          if lib.hasInfix "darwin" host.system
-          then "/Users/${username}"
-          else "/home/${username}";
-        hostDir = host.hostDir or hostName;
+  in
+    assert lib.assertMsg
+    (lib.all
+      (userName: lib.all (hostName: lib.hasAttr hostName configData.hosts) (lib.attrNames configData.users.${userName}.configs))
+      (lib.attrNames configData.users))
+    "home-manager user configs reference unknown hosts";
+    assert lib.assertMsg
+    (lib.all
+      (hostName: builtins.pathExists (./hosts + "/${hostName}/configuration.nix"))
+      (lib.attrNames (lib.filterAttrs (_: host: host.nixos or false) configData.hosts)))
+    "NixOS hosts must have a hosts/<name>/configuration.nix file"; let
+      nixosConfigurations = lib.mapAttrs (hostName: host: let
+        hostDir = ./hosts/${hostName};
+        username = host.username or defaultUsername;
       in
-        lib.nameValuePair "${username}@${hostName}" (
-          home-manager.lib.homeManagerConfiguration {
-            pkgs = nixpkgs.legacyPackages.${host.system};
-            extraSpecialArgs = specialArgs // {inherit username homeDirectory;};
-            modules = [
-              ./home.nix
-              ./hosts/${hostDir}
-            ];
-          }
-        ))
-      user.configs)
-    configData.users;
-  in {
-    inherit nixosConfigurations homeConfigurations configData;
+        lib.nixosSystem {
+          specialArgs = specialArgs // {inherit username;};
+          modules =
+            [
+              {nixpkgs.hostPlatform = host.system;}
+              inputs.ragenix.nixosModules.default
+              (hostDir + "/configuration.nix")
+            ]
+            ++ (lib.attrValues self.nixosModules)
+            ++ lib.optionals (host.disko or false) (
+              [disko.nixosModules.disko]
+              ++ lib.optional (builtins.pathExists (hostDir + "/disk-config.nix")) (hostDir + "/disk-config.nix")
+            );
+        })
+      (lib.filterAttrs (_: host: host.nixos or false) configData.hosts);
 
-    nixosModules =
-      lib.mapAttrs' (
-        filename: _:
-          lib.nameValuePair
-          (lib.removeSuffix ".nix" filename)
-          (import ./modules/services/${filename})
-      ) (lib.filterAttrs (
-        n: t:
-          (t == "regular" && lib.hasSuffix ".nix" n)
-          || (t == "directory" && builtins.pathExists ./modules/services/${n}/default.nix)
-      ) (builtins.readDir ./modules/services))
-      // {
-        base = import ./modules/nixos/base.nix;
-        haravara = import ./lib/haravara.nix;
-      };
+      homeConfigurations = lib.concatMapAttrs (userName: user:
+        lib.mapAttrs' (hostName: _: let
+          host = configData.hosts.${hostName};
+          username = host.username or userName;
+          homeDirectory =
+            if lib.hasInfix "darwin" host.system
+            then "/Users/${username}"
+            else "/home/${username}";
+          hostDir = host.hostDir or hostName;
+        in
+          lib.nameValuePair "${username}@${hostName}" (
+            home-manager.lib.homeManagerConfiguration {
+              pkgs = nixpkgs.legacyPackages.${host.system};
+              extraSpecialArgs = specialArgs // {inherit username homeDirectory;};
+              modules = [
+                ./home.nix
+                ./hosts/${hostDir}
+              ];
+            }
+          ))
+        user.configs)
+      configData.users;
+    in {
+      inherit nixosConfigurations homeConfigurations configData;
 
-    devShells.x86_64-linux.default = let
-      pkgs = nixpkgs.legacyPackages.x86_64-linux;
-    in
-      pkgs.mkShell {
-        packages = [
-          pkgs.nh
-          pkgs.dix
-          pkgs.nvd
-          pkgs.npins
-        ];
-      };
-  };
+      nixosModules =
+        lib.mapAttrs' (
+          filename: _:
+            lib.nameValuePair
+            (lib.removeSuffix ".nix" filename)
+            (import ./modules/services/${filename})
+        ) (lib.filterAttrs (
+          n: t:
+            (t == "regular" && lib.hasSuffix ".nix" n)
+            || (t == "directory" && builtins.pathExists ./modules/services/${n}/default.nix)
+        ) (builtins.readDir ./modules/services))
+        // {
+          base = import ./modules/nixos/base.nix;
+          haravara = import ./lib/haravara.nix;
+        };
+
+      devShells.x86_64-linux.default = let
+        pkgs = nixpkgs.legacyPackages.x86_64-linux;
+      in
+        pkgs.mkShell {
+          packages = [
+            pkgs.nh
+            pkgs.dix
+            pkgs.nvd
+            pkgs.npins
+          ];
+        };
+    };
 }
blob - a29eb3bc94eae330455bd567ead0f40fad2b6630
blob + 65721dc8713796a0ec95c46e555f19f57b846bfe
Binary files hosts/nixaran/configuration.nix and hosts/nixaran/configuration.nix differ
blob - 20c976027bef8f02d6350b2853dd61fd84c3111d (mode 644)
blob + /dev/null
Binary files hosts/nixaran/flake.nix and /dev/null differ
blob - 0962dbb88127843dcfe6ca33028c4436ef486e52
blob + 1cecb4b0beab7cccba7e2cf7d22ffd0a9e78f87a
--- hosts/void/default.nix
+++ hosts/void/default.nix
@@ -179,6 +179,7 @@
     gui = [
       picard
       xnviewmp
+      tigervnc
     ];
 
     llm = [
blob - a0c3ff11bbff023d7e504aa5315c8fd65e2992c9
blob + 6e4a9ceb89ec2acebb197f3929104ae39eeec61c
--- hosts/void/overlays/config/fnott/fnott.ini
+++ hosts/void/overlays/config/fnott/fnott.ini
@@ -8,25 +8,25 @@ selection-helper=dmenu
 selection-helper-uses-null-separator=no
 
 layer=top
-background=0d1612ff
-border-color=7fdbcaff
+background=000000ff
+border-color=646464ff
 border-radius=4
 border-size=1
 
 title-font=Fragment Mono:size=12
-title-color=d6deebff
+title-color=ffffffff
 title-format=
 
 summary-font=Fragment Mono:size=12
-summary-color=d6deebff
+summary-color=f4f4f4ff
 summary-format=<b>%s</b>
 
 body-font=Fragment Mono:size=12
-body-color=d6deebff
+body-color=f4f4f4ff
 body-format=%b
 
 progress-bar-height=2
-progress-color=7fdbcaff
+progress-color=79a8ffff
 progress-style=bar
 
 max-timeout=0
@@ -34,16 +34,16 @@ default-timeout=0
 idle-timeout=0
 
 [low]
-background=0d1612ff
-border-color=7fdbcaff
-title-color=637777ff
-summary-color=637777ff
-body-color=637777ff
+background=000000ff
+border-color=646464ff
+title-color=989898ff
+summary-color=989898ff
+body-color=989898ff
 
 [normal]
-background=0d1612ff
-border-color=7fdbcaff
+background=000000ff
+border-color=646464ff
 
 [critical]
-background=1a0d0dff
-border-color=7fdbcaff
+background=000000ff
+border-color=646464ff
blob - eda899aaed935f2e62101fc168ae1b8c15408521
blob + cc7891f9f7b0f580bb811bad4ab8026c45db8b5b
Binary files hosts/void/overlays/config/magdalena/config.json.nix and hosts/void/overlays/config/magdalena/config.json.nix differ
blob - 48b410ec42d1892bf13c48b3cdb3537815a2fc7b
blob + 79c8e13c12030278eedd76937ec320c59474f848
--- hosts/void/overlays/config/river/init
+++ hosts/void/overlays/config/river/init
@@ -7,13 +7,13 @@ alt="Mod4"
 term="foot"
 wobsock="$XDG_RUNTIME_DIR/wob.sock"
 
-dmenu_args="-vi -fn 'Ttyp0 OTB:size=10' -l 10 -h 20 -nb '#0d1612' -nf '#d6deeb' -sb '#1d3b2e' -sf '#d6deeb' -nhb '#0d1612' -nhf '#7fdbca'"
+dmenu_args="-vi -fn 'Ttyp0 OTB:size=10' -l 10 -h 20 -nb '#000000' -nf '#ffffff' -sb '#303030' -sf '#ffffff' -nhb '#000000' -nhf '#79a8ff'"
 
 rivertile -view-padding 0 -outer-padding 0 -main-ratio 0.50 &
 
-riverctl background-color "0x0d1612"
-riverctl border-color-focused "0x7fdbca"
-riverctl border-color-unfocused "0x1d3b2e"
+riverctl background-color "0x000000"
+riverctl border-color-focused "0x79a8ff"
+riverctl border-color-unfocused "0x646464"
 riverctl border-width 1
 
 riverctl set-repeat 50 300
blob - 6a2f079b98e3124be0e28fa0b2f4656103e1ecd3
blob + fca92b8056201ce8c7858366cb6baa4b1ff4a382
--- hosts/void/overlays/config/shepherd/init.d/emacs-daemon.scm
+++ hosts/void/overlays/config/shepherd/init.d/emacs-daemon.scm
@@ -1,3 +1,9 @@
 ;; -*- mode: scheme; -*-
 (use-modules (helpers))
-(exec-service 'emacs-daemon '("emacs" "--fg-daemon"))
+
+;; Force truecolor for terminal Emacs frames created by emacsclient.
+;; TERM is left at whatever Shepherd inherited; COLORTERM is set explicitly.
+(exec-service 'emacs-daemon
+              '("emacs" "--fg-daemon")
+              #:environment
+              '("COLORTERM=truecolor"))
blob - f59b1094920f2a35b7c1f8cdd9067e4cb245d259
blob + 6ca6012ed6f63d8410f2bd78812a66b8d42588b7
--- hosts/void/overlays/config/shepherd/init.d/swaybg.scm
+++ hosts/void/overlays/config/shepherd/init.d/swaybg.scm
@@ -1,6 +1,6 @@
 ;; -*- mode: scheme; -*-
 (use-modules (helpers))
 (exec-service 'swaybg
-              (list "swaybg" "-m" "fill" "-c" "#0d1612"
+              (list "swaybg" "-m" "fill" "-c" "#000000"
                     "-i" (string-append (getenv "HOME")
-                                        "/misc/random/wallpapers/curtains.jpg")))
+                                        "/misc/random/wallpapers/15.jpg")))
blob - fd3e230e7707b463e219c26632648ab3fd3c7983
blob + d8d117f928533d98257c8620dc1d8a2ee55811c5
--- hosts/void/overlays/config/shepherd/modules/helpers.scm
+++ hosts/void/overlays/config/shepherd/modules/helpers.scm
@@ -4,12 +4,31 @@
 (define-module (helpers)
   #:use-module (shepherd service)
   #:use-module (shepherd support)
+  #:use-module (srfi srfi-13)
   #:export (exec-service))
 
+(define (environment-with-overrides base overrides)
+  "Return BASE (a list of \"KEY=VALUE\" strings) with OVERRIDES applied.
+Each override must be a \"KEY=VALUE\" string; if the key already exists in
+BASE, the old entry is replaced."
+  (let loop ((remaining overrides)
+             (result base))
+    (if (null? remaining)
+        result
+        (let* ((override (car remaining))
+               (split (string-index override #\=))
+               (key (substring override 0 split))
+               (prefix (string-append key "=")))
+          (loop (cdr remaining)
+                (cons override
+                      (filter (lambda (entry)
+                                (not (string-prefix? prefix entry)))
+                              result)))))))
+
 ;; Register and start NAME running COMMAND (program + args).  Idempotent:
 ;; an existing service by that name is replaced, so re-running the file via
 ;; `herd load' reloads it in place.
-(define* (exec-service name command #:key (respawn? #t))
+(define* (exec-service name command #:key (respawn? #t) (environment '()))
   (let ((old (lookup-service name)))
     (when old
       (stop-service old)
@@ -19,7 +38,11 @@
                       #:start (make-forkexec-constructor
                                command
                                #:log-file (string-append %user-log-dir "/"
-                                                         (symbol->string name) ".log"))
+                                                         (symbol->string name) ".log")
+                               #:environment-variables
+                               (environment-with-overrides
+                                (default-environment-variables)
+                                environment))
                       #:stop (make-kill-destructor)
                       #:respawn? respawn?)))
     (register-services (list svc))
blob - f2be2514060f7351e3be6c73f3ad6b58c515d9fa
blob + 1dc4e37f552453c23701ff7b916620675cef0761
--- hosts/void/overlays/config/volare/config
+++ hosts/void/overlays/config/volare/config
@@ -5,14 +5,14 @@ set $term foot
 set $menu dmenu_run $dmenu_args
 
 set $wobsock $XDG_RUNTIME_DIR/wob.sock
-set $dmenu_args -vi -fn 'Ttyp0 OTB:size=10' -l 10 -h 20 -nb '#0d1612' -nf '#d6deeb' -sb '#1d3b2e' -sf '#d6deeb' -nhb '#0d1612' -nhf '#7fdbca'
+set $dmenu_args -vi -fn 'Ttyp0 OTB:size=10' -l 10 -h 20 -nb '#000000' -nf '#ffffff' -sb '#303030' -sf '#ffffff' -nhb '#000000' -nhf '#79a8ff'
 
 default_border pixel 1
 default_floating_border pixel 1
 
-client.focused          "#7fdbca" "#1d3b2e" "#d6deeb" "#7fdbca" "#7fdbca"
-client.focused_inactive "#1d3b2e" "#0d1612" "#d6deeb" "#1d3b2e" "#1d3b2e"
-client.unfocused        "#1d3b2e" "#0d1612" "#d6deeb" "#1d3b2e" "#1d3b2e"
+client.focused          "#79a8ff" "#303030" "#ffffff" "#79a8ff" "#79a8ff"
+client.focused_inactive "#646464" "#1e1e1e" "#f4f4f4" "#646464" "#646464"
+client.unfocused        "#646464" "#000000" "#989898" "#646464" "#646464"
 
 input type:keyboard {
     repeat_rate 50
@@ -50,6 +50,7 @@ mouse_warping none
 
     bindsym $mod+Shift+o exec todomenu $dmenu_args
     bindsym $alt+Shift+d exec clipmenu $dmenu_args
+    bindsym $mod+Shift+d exec clipmenu $dmenu_args
     bindsym $alt+Shift+l exec langmenu $dmenu_args
     bindsym $alt+Shift+h exec huemenu $dmenu_args
     bindsym $mod+Shift+m exec plsmenu $dmenu_args
@@ -66,6 +67,9 @@ mouse_warping none
     bindsym $mod+Tab focus tab right
     bindsym $mod+Shift+Tab focus tab left
 
+    bindsym $mod+Shift+Left move tab left
+    bindsym $mod+Shift+Right move tab right
+
     bindsym $mod+Left focus left
     bindsym $mod+Down focus down
     bindsym $mod+Up focus up
@@ -128,8 +132,8 @@ mouse_warping none
 
     bindsym $mod+shift+h splith
     bindsym $mod+shift+v splitv
+    bindsym $mod+shift+n split none
 
-    bindsym $mod+shift+s split none
     bindsym $mod+q fullscreen
 
     bindsym $mod+Shift+space floating toggle
@@ -165,10 +169,10 @@ bar {
     status_command while true; do echo "$(plants) $(date '+%Y-%m-%d %H:%M') $(cat /sys/class/power_supply/BAT*/capacity 2>/dev/null)%"; sleep 30; done
 
     colors {
-        statusline #d6deeb
-        background #0d1612
-        focused_workspace #7fdbca #1d3b2e #d6deeb
-        active_workspace #1d3b2e #0d1612 #d6deeb
-        inactive_workspace #0d1612 #0d1612 #637777
+        statusline #ffffff
+        background #000000
+        focused_workspace #79a8ff #303030 #ffffff
+        active_workspace #646464 #1e1e1e #f4f4f4
+        inactive_workspace #646464 #000000 #989898
     }
 }
blob - 9c9fb16a86bc06b51b3b4558b8862818203c62b7
blob + a392d3e9564cf5644eb53c2d350ace62867547ff
Binary files hosts/work/overlays/bin/nota and hosts/work/overlays/bin/nota differ
blob - b73a19a70edbc9e013f870f505e9e46f955e66ed
blob + 28d8fcab6bbf38c1f7e75510c3e5654e62b00f7f
Binary files hosts/work/overlays/config/ghostty/config and hosts/work/overlays/config/ghostty/config differ
blob - 387f20b979f296dd4d7adb38298f93be12afafb7
blob + 3d8c9f82fb2f20c743283563a50cc828f1d11ca4
Binary files hosts/work/overlays/config/magdalena/config.json.nix and hosts/work/overlays/config/magdalena/config.json.nix differ
blob - 14db549588f70b6b7d111ae078e3d80b49653172
blob + 8759dab5ff3522627354eab6d51332bc4a5c13e8
Binary files hosts/work/overlays/home/tmux.conf and hosts/work/overlays/home/tmux.conf differ
blob - /dev/null
blob + 190287f3bc7dbdb4fcc2ca0535608a72f6fe6701 (mode 644)
--- /dev/null
+++ lib/mk-overlay.nix
@@ -0,0 +1,62 @@
+{
+  config,
+  lib,
+  inputs,
+}: let
+  date = inputs.self.lastModifiedDate or "19700101000000";
+  year = lib.substring 0 4 date;
+  monthNum = lib.substring 4 2 date;
+  month = lib.elemAt [
+    "january"
+    "february"
+    "march"
+    "april"
+    "may"
+    "june"
+    "july"
+    "august"
+    "september"
+    "october"
+    "november"
+    "december"
+  ] (lib.toInt (lib.removePrefix "0" monthNum) - 1);
+
+  tmplArgs = {
+    inherit year month;
+    homeDir = config.home.homeDirectory;
+  };
+
+  mkMapping = path: prefix: let
+    go = dir: rel:
+      lib.foldl' (a: b: a // b) {} (
+        lib.mapAttrsToList (name: type: let
+          newRel =
+            if rel == ""
+            then name
+            else "${rel}/${name}";
+          newPath = dir + "/${name}";
+        in
+          if type == "directory"
+          then go newPath newRel
+          else let
+            isNix = lib.hasSuffix ".nix" name;
+            target = prefix + (lib.removeSuffix ".nix" newRel);
+          in {
+            ${target} =
+              if isNix
+              then {
+                text = import newPath tmplArgs;
+                force = true;
+              }
+              else {
+                source = newPath;
+                force = true;
+              };
+          })
+        (builtins.readDir dir)
+      );
+  in
+    go path "";
+in {
+  inherit tmplArgs mkMapping;
+}
blob - a9d012aa66514845ebf63cbc533cb722329de889
blob + 9116936954c86c99d7e09fb875557415d3fa5218
--- modules/mixins/core/default.nix
+++ modules/mixins/core/default.nix
@@ -1,19 +1,14 @@
-{
-  pkgs,
-  lib,
-  ...
-}: {
-  home.packages = lib.concatLists (lib.attrValues (with pkgs; {
-    nix = [
-      nh
-      nvd
-      comma
-      npins
-      nixfmt
-      statix
-      deadnix
-      ragenix
-      alejandra
-    ];
-  }));
+{pkgs, ...}: {
+  home.packages = with pkgs; [
+    nh
+    nvd
+    comma
+    npins
+    nixfmt
+    statix
+    deadnix
+    ragenix
+    alejandra
+    manix
+  ];
 }
blob - 177e8547b44e6b05da54f87db78a9b1ffdbe6bc7 (mode 644)
blob + /dev/null
--- modules/mixins/default.nix
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  imports = [
-    ./dotfiles
-  ];
-}
blob - 0d0db0d8c28a80c69103590c209e00f4841352c9
blob + c3b58b1920aac4b0daf1edc0a667961dbefae738
--- modules/mixins/dotfiles/bin/pinentry-bemenu
+++ modules/mixins/dotfiles/bin/pinentry-bemenu
@@ -1,4 +1,4 @@
 #!/bin/bash
-BEMENU_OPTS="--fn 'Ttyp0 OTB' '#1d2021' --tf '#fabd2f' \
-    --nb '#1d2021' --nf '#ebdbb2' --hb '#458588' --hf '#1d2021'" \
+BEMENU_OPTS="--fn 'Ttyp0 OTB' '#000000' --tf '#ffffff' \
+    --nb '#000000' --nf '#ffffff' --hb '#79a8ff' --hf '#000000'" \
 	/usr/sbin/pinentry-bemenu "$@"
blob - e7b314c9d3123c683743a63ed75b869de4b14228
blob + bb4523ebea0df2a0255b036dbd94c4cffd6a53f3
--- modules/mixins/dotfiles/config/aerc/stylesets/mine
+++ modules/mixins/dotfiles/config/aerc/stylesets/mine
@@ -1,61 +1,61 @@
 *.default=true
 *.normal=true
-*.fg = #d6deeb
-*.selected.bg = #1d3b2e
-*.selected.fg = #d6deeb
-title.bg=#1d3b2e
-title.fg=#d6deeb
+*.fg = #ffffff
+*.selected.bg = #303030
+*.selected.fg = #ffffff
+title.bg=#303030
+title.fg=#ffffff
 title.bold=true
 header.bold=true
-header.fg=#7fdbca
-header.bg=#13281e
-border.bg=#13281e
-border.fg=#13281e
-tab.selected.fg=#d6deeb
-tab.selected.bg=#1d3b2e
+header.fg=#79a8ff
+header.bg=#1e1e1e
+border.bg=#1e1e1e
+border.fg=#646464
+tab.selected.fg=#ffffff
+tab.selected.bg=#303030
 tab.selected.bold=true
-dirlist*.selected.bg=#1d3b2e
-dirlist*.selected.fg=#d6deeb
+dirlist*.selected.bg=#303030
+dirlist*.selected.fg=#ffffff
 dirlist*.selected.bold=false
 *error.bold=true
-*error.fg=#ef5350
-*warning.fg=#ecc48d
-*success.fg=#22da6e
-statusline_*.bg=#13281e
-statusline_*.fg=#d6deeb
-statusline_error.fg=#ef5350
-msglist_unread.fg=#c792ea
+*error.fg=#ff5f59
+*warning.fg=#c0965b
+*success.fg=#44bc44
+statusline_*.bg=#1e1e1e
+statusline_*.fg=#ffffff
+statusline_error.fg=#ff5f59
+msglist_unread.fg=#feacd0
 msglist_unread.bold=true
-msglist_read.fg=#a7b9d0
-msglist_deleted.fg=#13281e
-msglist_*.selected.bg=#1d3b2e
-msglist_marked.fg=#22da6e
-msglist_marked.selected.fg=#d6deeb
-msglist_marked.bg=#ecc48d
-msglist_marked.selected.bg=#c792ea
+msglist_read.fg=#989898
+msglist_deleted.fg=#1e1e1e
+msglist_*.selected.bg=#303030
+msglist_marked.fg=#44bc44
+msglist_marked.selected.fg=#ffffff
+msglist_marked.bg=#c0965b
+msglist_marked.selected.bg=#f78fe7
 completion_pill.reverse=false
 selector_focused.bold=false
-selector_focused.bg=#1d3b2e
-selector_focused.fg=#d6deeb
+selector_focused.bg=#303030
+selector_focused.fg=#ffffff
 selector_chooser.bold=false
-selector_chooser.bg=#1d3b2e
-selector_chooser.fg=#d6deeb
+selector_chooser.bg=#303030
+selector_chooser.fg=#ffffff
 default.selected.bold=false
-default.selected.bg=#1d3b2e
-default.selected.fg=#d6deeb
-completion_default.selected.bg=#7fdbca
+default.selected.bg=#303030
+default.selected.fg=#ffffff
+completion_default.selected.bg=#79a8ff
 [viewer]
 *.default=true
 *.normal=true
-url.fg = #7fdbca
-header.fg = #7fdbca
-signature.fg = #c792ea
-diff_chunk.fg = #7fdbca
-diff_chunk_func.fg = #ecc48d
-diff_add.fg = #22da6e
-diff_del.fg = #ef5350
-quote_1.fg = #22da6e
-quote_2.fg = #7fdbca
-quote_3.fg = #c792ea
-quote_4.fg = #ecc48d
-quote_x.fg = #1d3b2e
+url.fg = #79a8ff
+header.fg = #79a8ff
+signature.fg = #feacd0
+diff_chunk.fg = #79a8ff
+diff_chunk_func.fg = #c0965b
+diff_add.fg = #44bc44
+diff_del.fg = #ff5f59
+quote_1.fg = #44bc44
+quote_2.fg = #79a8ff
+quote_3.fg = #feacd0
+quote_4.fg = #c0965b
+quote_x.fg = #303030
blob - f4e44116b3a09b2c33b1adddbccd8dad8f927ec5
blob + 325429d9d3beddc582372e014187f87ff8d0c14f
--- modules/mixins/dotfiles/config/bat/themes/magnolia.tmTheme
+++ modules/mixins/dotfiles/config/bat/themes/magnolia.tmTheme
@@ -10,21 +10,21 @@
 			<key>settings</key>
 			<dict>
 				<key>background</key>
-				<string>#0d1612</string>
+				<string>#000000</string>
 				<key>divider</key>
-				<string>#1d3b2e</string>
+				<string>#303030</string>
 				<key>foreground</key>
-				<string>#d6deeb</string>
+				<string>#ffffff</string>
 				<key>caret</key>
-				<string>#9ec9d6</string>
+				<string>#ffffff</string>
 				<key>invisibles</key>
-				<string>#1d3b2e</string>
+				<string>#303030</string>
 				<key>lineHighlight</key>
-				<string>#13281e</string>
+				<string>#1e1e1e</string>
 				<key>selection</key>
-				<string>#1d3b2e</string>
+				<string>#303030</string>
 				<key>selectionForeground</key>
-				<string>#d6deeb</string>
+				<string>#ffffff</string>
 			</dict>
 		</dict>
 		<dict>
@@ -35,7 +35,7 @@
 			<key>settings</key>
 			<dict>
 				<key>foreground</key>
-				<string>#637777</string>
+				<string>#989898</string>
 			</dict>
 		</dict>
 		<dict>
@@ -46,7 +46,7 @@
 			<key>settings</key>
 			<dict>
 				<key>foreground</key>
-				<string>#c792ea</string>
+				<string>#feacd0</string>
 			</dict>
 		</dict>
 		<dict>
@@ -57,7 +57,7 @@
 			<key>settings</key>
 			<dict>
 				<key>foreground</key>
-				<string>#ecc48d</string>
+				<string>#c0965b</string>
 			</dict>
 		</dict>
 		<dict>
@@ -68,7 +68,7 @@
 			<key>settings</key>
 			<dict>
 				<key>foreground</key>
-				<string>#7fdbca</string>
+				<string>#79a8ff</string>
 			</dict>
 		</dict>
 		<dict>
@@ -79,7 +79,7 @@
 			<key>settings</key>
 			<dict>
 				<key>foreground</key>
-				<string>#addb67</string>
+				<string>#9cbd6f</string>
 			</dict>
 		</dict>
 	</array>
blob - 24e478a7be58f32d131963b73a4353e814c73072
blob + 910f68b8016b8d35a0ee52705268b3a3a6aeac78
--- modules/mixins/dotfiles/config/eza
+++ modules/mixins/dotfiles/config/eza
@@ -1,47 +1,47 @@
 colourful: true
 
 # base colors
-define: &bg_main "#0d1612"
-define: &bg_dim = "#13281e"
-define: &bg_alt = "#081210"
-define: &fg_main = "#d6deeb"
-define: &fg_dim = "#637777"
-define: &fg_alt = "#a7b9d0"
-define: &border = "#1d3b2e"
-define: &border_highlight = "#5f8f87"
+define: &bg_main "#000000"
+define: &bg_dim = "#1e1e1e"
+define: &bg_alt = "#0f0f0f"
+define: &fg_main = "#ffffff"
+define: &fg_dim = "#989898"
+define: &fg_alt = "#989898"
+define: &border = "#303030"
+define: &border_highlight = "#646464"
 
 # foreground colors
-define: &red "#ef5350"
-define: &red_warmer "#f78c6c"
-define: &red_cooler "#ff5874"
-define: &red_faint "#ec9a93"
-define: &green "#22da6e"
-define: &green_warmer "#addb67"
-define: &green_cooler "#21c7a8"
-define: &green_faint "#82c4a0"
-define: &yellow "#ecc48d"
-define: &yellow_warmer "#ffeb95"
-define: &yellow_cooler "#ecc48d"
-define: &yellow_faint "#c9b58a"
-define: &blue "#7fdbca"
-define: &blue_warmer "#7fdbca"
-define: &blue_cooler "#7fdbca"
-define: &blue_faint "#9ec9d6"
-define: &magenta "#c792ea"
-define: &magenta_warmer "#d7aaff"
-define: &magenta_cooler "#c792ea"
-define: &magenta_faint "#bca0d8"
-define: &cyan "#21c7a8"
-define: &cyan_warmer "#7fdbca"
-define: &cyan_cooler "#7fdbca"
-define: &cyan_faint "#9ec9d6"
-define: &rust "#f78c6c"
-define: &gold "#ecc48d"
-define: &olive "#addb67"
-define: &slate "#5f8f87"
-define: &indigo "#7fdbca"
-define: &maroon "#c792ea"
-define: &pink "#d6a9e0"
+define: &red "#ff5f59"
+define: &red_warmer "#ff6b55"
+define: &red_cooler "#ff7f9f"
+define: &red_faint "#ff9580"
+define: &green "#44bc44"
+define: &green_warmer "#9cbd6f"
+define: &green_cooler "#00d3d0"
+define: &green_faint "#88ca9f"
+define: &yellow "#c0965b"
+define: &yellow_warmer "#fec43f"
+define: &yellow_cooler "#c0965b"
+define: &yellow_faint "#d2b580"
+define: &blue "#79a8ff"
+define: &blue_warmer "#79a8ff"
+define: &blue_cooler "#79a8ff"
+define: &blue_faint "#82b0ec"
+define: &magenta "#feacd0"
+define: &magenta_warmer "#f78fe7"
+define: &magenta_cooler "#feacd0"
+define: &magenta_faint "#caa6df"
+define: &cyan "#00d3d0"
+define: &cyan_warmer "#79a8ff"
+define: &cyan_cooler "#79a8ff"
+define: &cyan_faint "#9ac8e0"
+define: &rust "#db7b5f"
+define: &gold "#c0965b"
+define: &olive "#9cbd6f"
+define: &slate "#76afbf"
+define: &indigo "#9099d9"
+define: &maroon "#cf7fa7"
+define: &pink "#d09dc0"
 
 filekinds:
   normal: {foreground: *fg_main}
blob - ea8b614b9ea172bf5022903906f26a4afa1efdbc
blob + e86b78f38f3ef16f6dabef7db97ea07fa549f8ec
--- modules/mixins/dotfiles/config/foot/common.ini
+++ modules/mixins/dotfiles/config/foot/common.ini
@@ -9,30 +9,30 @@ style=block
 blink=no
 
 [colors-dark]
-cursor=0d1612 9ec9d6
+cursor=000000 ffffff
 
-background=0d1612
-foreground=d6deeb
+background=000000
+foreground=ffffff
 
-selection-background=1d3b2e
-selection-foreground=d6deeb
+selection-background=7030af
+selection-foreground=ffffff
 
-regular0=0d1612
-regular1=ef5350
-regular2=22da6e
-regular3=addb67
-regular4=7fdbca
-regular5=c792ea
-regular6=21c7a8
-regular7=d6deeb
+regular0=000000
+regular1=ff5f59
+regular2=44bc44
+regular3=d0bc00
+regular4=2fafff
+regular5=feacd0
+regular6=00d3d0
+regular7=a6a6a6
 
-bright0=637777
-bright1=ef5350
-bright2=22da6e
-bright3=ffeb95
-bright4=7fdbca
-bright5=c792ea
-bright6=7fdbca
+bright0=595959
+bright1=ff6b55
+bright2=00c06f
+bright3=fec43f
+bright4=79a8ff
+bright5=f78fe7
+bright6=6ae4b9
 bright7=ffffff
 
 [key-bindings]
blob - 2b32065995bbab0511eba441337881c6c9368913
blob + 3e9d44939fa4d241a596a98985215fb2256d563a
--- modules/mixins/dotfiles/config/newsraft/feeds
+++ modules/mixins/dotfiles/config/newsraft/feeds
@@ -264,3 +264,4 @@ https://www.youtube.com/feeds/videos.xml?channel_id=UC
 https://www.youtube.com/feeds/videos.xml?channel_id=UC3nrICIIT0Uj-wVyj1sAcHQ Handmade Network
 https://www.youtube.com/feeds/videos.xml?channel_id=UCpoq2g2xQlZThcj628CCTmQ Tastemaker Design
 https://www.youtube.com/feeds/videos.xml?channel_id=UCFCEuCsyWP0YkP3CZ3Mr01Q The Plain Bagel
+https://www.youtube.com/feeds/videos.xml?channel_id=UCPiMR-Ize9p3dgjzZ8bo9ZQ The Tech Report
blob - fa0bffd97f30cc0753ab21766da08830684adedc
blob + c45caa29b1a20e1d57a569aeab3e0269c656a473
--- modules/mixins/dotfiles/config/nvim/fnl/config/meepo.fnl
+++ modules/mixins/dotfiles/config/nvim/fnl/config/meepo.fnl
@@ -1,19 +1,19 @@
-(local palette {:base00 "#0d1612"
-                :base01 "#13281e"
-                :base02 "#1d3b2e"
-                :base03 "#637777"
-                :base04 "#a7b9d0"
-                :base05 "#d6deeb"
+(local palette {:base00 "#000000"
+                :base01 "#1e1e1e"
+                :base02 "#303030"
+                :base03 "#989898"
+                :base04 "#f4f4f4"
+                :base05 "#ffffff"
                 :base06 "#e6e6e6"
                 :base07 "#ffffff"
-                :base08 "#ef5350"
-                :base09 "#f78c6c"
-                :base0A "#ffeb95"
-                :base0B "#22da6e"
-                :base0C "#21c7a8"
-                :base0D "#7fdbca"
-                :base0E "#c792ea"
-                :base0F "#addb67"})
+                :base08 "#ff5f59"
+                :base09 "#ff6b55"
+                :base0A "#fec43f"
+                :base0B "#44bc44"
+                :base0C "#00d3d0"
+                :base0D "#79a8ff"
+                :base0E "#feacd0"
+                :base0F "#9cbd6f"})
 
 (fn bar-highlights []
   (let [hl (fn [group fg bg attr]
blob - a36d0c93c5e6cff80edb2913ca46766fffcba899
blob + 697538703cf342b52e17f262072b6bd587c08893
--- modules/mixins/dotfiles/config/nvim/fnl/init.fnl
+++ modules/mixins/dotfiles/config/nvim/fnl/init.fnl
@@ -13,7 +13,6 @@
   (local blink (require :config.blink))
   (local lsp (require :config.lsp))
   (local treesitter (require :config.treesitter))
-  (local meepo (require :config.meepo))
 
   (vim.pack.add
      [(gh :nvim-mini/mini.nvim)
@@ -23,11 +22,11 @@
      (gh :ibhagwan/fzf-lua)
      (gh :troydm/zoomwintab.vim)
      (gh :L3MON4D3/LuaSnip)
+     (gh :miikanissi/modus-themes.nvim)
      {:src (gh :neovim/nvim-lspconfig) :version :master}
      {:src (gh :saghen/blink.cmp) :version (vim.version.range "^1")}]
     {:load true})
 
-  ((. meepo :config))
   ((. (require :mini.comment) :setup))
   ((. (require :mini.surround) :setup))
   ((. (require :mini.pairs) :setup))
@@ -43,8 +42,11 @@
     :watch_index true})
   (: blink :config)
   (: lsp :config)
-  (treesitter.config))
+  (treesitter.config)
 
+  (set vim.o.background :dark)
+  (vim.cmd "colorscheme modus_vivendi"))
+
 (fn init []
   (let [vimrc (.. (vim.fn.stdpath :config) :/init_.vim)
         vim-dir (.. (vim.fn.expand "~") :/.vim/)]
blob - 9be903881165d061a6284b9921def38410b87240
blob + 55d4e19b2cbf6d77abb28643fd8e239be7c6fbfa
--- modules/mixins/dotfiles/config/shell/profile/fzf
+++ modules/mixins/dotfiles/config/shell/profile/fzf
@@ -3,8 +3,8 @@ export FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS \
   --ansi \
   --layout=reverse \
   --border=rounded \
-  --color=bg+:#1d3b2e,bg:-1,spinner:#7fdbca,hl:#7fdbca \
-  --color=fg:#d6deeb,header:#637777,info:#637777,pointer:#7fdbca \
-  --color=marker:#7fdbca,fg+:#d6deeb,prompt:#7fdbca,hl+:#7fdbca \
-  --color=border:#0d1612 \
+  --color=bg+:#303030,bg:-1,spinner:#79a8ff,hl:#79a8ff \
+  --color=fg:#ffffff,header:#989898,info:#989898,pointer:#79a8ff \
+  --color=marker:#79a8ff,fg+:#ffffff,prompt:#79a8ff,hl+:#79a8ff \
+  --color=border:#000000 \
 "
blob - 5866ec15996041c8463dec3b2392f1e5582a1fc2
blob + f04c2e4c7b1e06be261825c4c039acc9b2bcb038
--- modules/mixins/dotfiles/default.nix
+++ modules/mixins/dotfiles/default.nix
@@ -5,64 +5,8 @@
   ...
 }: let
   sources = import ./npins;
-
-  date = inputs.self.lastModifiedDate or "19700101000000";
-  year = lib.substring 0 4 date;
-  monthNum = lib.substring 4 2 date;
-  month = lib.elemAt [
-    "january"
-    "february"
-    "march"
-    "april"
-    "may"
-    "june"
-    "july"
-    "august"
-    "september"
-    "october"
-    "november"
-    "december"
-  ] (lib.toInt (lib.removePrefix "0" monthNum) - 1);
-
-  tmplArgs = {
-    inherit year month;
-    homeDir = config.home.homeDirectory;
-  };
-
-  mkMapping = path: prefix: let
-    scan = dir: rel:
-      lib.concatLists (lib.mapAttrsToList (name: type: let
-        newRel =
-          if rel == ""
-          then name
-          else "${rel}/${name}";
-        newPath = dir + "/${name}";
-      in
-        if type == "directory"
-        then scan newPath newRel
-        else [
-          {
-            name = newRel;
-            path = newPath;
-          }
-        ])
-      (builtins.readDir dir));
-  in
-    builtins.listToAttrs (map (file: let
-      isNix = lib.hasSuffix ".nix" file.name;
-      target = prefix + (lib.removeSuffix ".nix" file.name);
-    in
-      lib.nameValuePair target (
-        if isNix
-        then {
-          text = import file.path tmplArgs;
-          force = true;
-        }
-        else {
-          source = file.path;
-          force = true;
-        }
-      )) (scan path ""));
+  overlay = import ../../../lib/mk-overlay.nix {inherit config lib inputs;};
+  inherit (overlay) mkMapping;
 in {
   imports = [./plass.nix];
 
blob - 6aa98ff829be8ff0f3ecc5b68bdb2a5227773c4b
blob + 4aadc15036c4a8d953f5afb148e70343919f4f42
--- modules/mixins/dotfiles/home/SciTEUser.properties
+++ modules/mixins/dotfiles/home/SciTEUser.properties
@@ -1,18 +1,55 @@
 font.base=font:!Fira Mono,size:12
 font.override=$(font.base),notbold,notitalics
-style.*.32=$(font.base),back:#000000,fore:#D0D0D0
-style.*.34=notbold,fore:#FFFFFF
-style.*.35=notbold
-caret.fore=#FFFFFF
-selection.back=#404040
 
+edge.mode=0
 tabbar.visible=0
 toolbar.visible=0
 statusbar.visible=0
 margin.width=0
 blank.margin.left=0
+
 fold=0
 fold.margin.width=0
+horizontal.scrollbar=0
+
 fold.margin.colour=#000000
 fold.margin.highlight.colour=#000000
-horizontal.scrollbar=0
+
+calltip.back=#000000
+calltip.fore=#FFFFFF
+selection.back=#333333
+selection.fore=#FFFFFF
+caret.fore=#FFFFFF
+edge.colour=#333333
+
+style.*.1=fore:#888888
+style.*.2=fore:#888888
+style.*.3=fore:#888888
+style.*.5=fore:#FFFFFF
+style.*.16=fore:#FFFFFF
+style.*.4=fore:#CCCCCC
+style.*.6=fore:#CCCCCC
+style.*.7=fore:#CCCCCC
+style.*.8=fore:#FFFFFF
+style.*.10=fore:#FFFFFF
+style.*.11=fore:#FFFFFF
+style.*.9=fore:#FFFFFF
+style.*.11=fore:#FFFFFF
+style.*.12=fore:#FFFFFF
+style.*.13=fore:#FFFFFF
+style.*.14=fore:#CCCCCC
+style.*.15=fore:#FFFFFF
+style.*.17=fore:#CCCCCC
+style.*.18=fore:#CCCCCC
+style.*.19=fore:#CCCCCC
+style.*.32=$(font.base),back:#000000,fore:#FFFFFF
+style.*.33=back:#000000,fore:#666666
+style.*.34=notbold,fore:#FFFFFF
+style.*.35=notbold,fore:#888888
+style.*.36=back:#000000,fore:#FFFFFF
+style.*.37=fore:#333333
+style.*.40=$(font.base),back:#000000,fore:#FFFFFF
+
+hotspot.active.fore=#FFFFFF
+hotspot.active.back=#000000
+hotspot.active.underline=1
blob - 2eae6f6c75ed22cb4cbe857c7a0aa18ef30e0208
blob + 26e323144cdac3990ab0e257c4451a878b908484
--- modules/mixins/dotfiles/home/tmux.conf
+++ modules/mixins/dotfiles/home/tmux.conf
@@ -7,6 +7,7 @@ set-option -g update-environment "WAYLAND_DISPLAY DISP
 set-option -g focus-events on
 
 set -g default-terminal "tmux-256color"
+set -ag terminal-overrides ",foot*:Tc"
 
 set -g status-interval 30
 
@@ -14,25 +15,25 @@ set -g status off
 set -g status-left ''
 set -g status-right ''
 
-set -g status-style "fg=#d6deeb,bg=default"
-set -g message-style "fg=#d6deeb,bg=#1d3b2e"
-set -g message-command-style "fg=#d6deeb,bg=#1d3b2e"
-set -g mode-style "fg=#d6deeb,bg=#1d3b2e"
+set -g status-style "fg=#ffffff,bg=default"
+set -g message-style "fg=#ffffff,bg=#303030"
+set -g message-command-style "fg=#ffffff,bg=#303030"
+set -g mode-style "fg=#ffffff,bg=#303030"
 
-set -g menu-style "fg=#d6deeb,bg=default"
-set -g menu-selected-style "fg=#0d1612,bg=#d6deeb"
+set -g menu-style "fg=#ffffff,bg=default"
+set -g menu-selected-style "fg=#000000,bg=#ffffff"
 set -g menu-border-style "fg=default,bg=default"
 set -g menu-border-lines "none"
 
-set -g pane-border-style "fg=#1d3b2e"
-set -g pane-active-border-style "fg=#637777"
+set -g pane-border-style "fg=#646464"
+set -g pane-active-border-style "fg=#989898"
 
-set -g window-status-style "fg=#637777,bg=default"
-set -g window-status-current-style "fg=#d6deeb,bg=default,bold"
-set -g window-status-bell-style "fg=#d6deeb,bg=default,bold"
+set -g window-status-style "fg=#989898,bg=default"
+set -g window-status-current-style "fg=#ffffff,bg=default,bold"
+set -g window-status-bell-style "fg=#ffffff,bg=default,bold"
 
-set -g status-left-style "fg=#d6deeb,bg=default"
-set -g status-right-style "fg=#d6deeb,bg=default"
+set -g status-left-style "fg=#ffffff,bg=default"
+set -g status-right-style "fg=#ffffff,bg=default"
 
 setw -g xterm-keys on
 set -ga terminal-overrides ',xterm*:XT'
blob - c18225529680cc28237bb43339c3366e2121a98d
blob + da8853bd2f513f43374ca5db740c486d4387e8d3
--- modules/mixins/dotfiles/plass.nix
+++ modules/mixins/dotfiles/plass.nix
@@ -2,11 +2,13 @@
   sources = import ./npins;
 
   totp = pkgs.stdenv.mkDerivation {
-    name = "totp";
+    pname = "totp";
+    version = sources.plass.revision or "unknown";
     src = sources.plass;
+    strictDeps = true;
     buildInputs = [pkgs.openssl];
-    buildPhase = "cc -Wall -Wextra -o totp totp.c -lcrypto";
-    installPhase = "install -m755 totp $out";
+    buildPhase = "$CC -Wall -Wextra -o totp totp.c -lcrypto";
+    installPhase = "install -Dm755 totp $out/bin/totp";
   };
 in {
   home.file = {
@@ -19,7 +21,7 @@ in {
       executable = true;
     };
     "bin/totp" = {
-      source = totp;
+      source = "${totp}/bin/totp";
       executable = true;
     };
     ".local/share/man/man1/plass.1" = {
blob - 51344cef3ba48af808e8d76a5c48da6a35e55727 (mode 644)
blob + /dev/null
--- modules/mixins/monitoring/alert-rules.yaml
+++ /dev/null
@@ -1,264 +0,0 @@
-groups:
-  - name: targets
-    rules:
-      - alert: TargetDown
-        expr: up == 0
-        for: 2m
-        labels:
-          severity: critical
-        annotations:
-          summary: "Target {{ $labels.job }}/{{ $labels.instance }} is down"
-          description: >
-            Scrape target {{ $labels.instance }} (job: {{ $labels.job }}) has been
-            unreachable for more than 2 minutes.
-
-  - name: node
-    rules:
-      - alert: HighCPULoad
-        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
-        for: 30m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High CPU load: {{ $value | printf \"%.0f\" }}%"
-          description: "CPU usage has been above 90% for more than 30 minutes."
-
-      - alert: HighMemoryUsage
-        expr: (1 - (node_memory_MemAvailable_bytes or node_memory_free_bytes) / node_memory_MemTotal_bytes) * 100 > 90
-        for: 15m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High memory usage: {{ $value | printf \"%.0f\" }}%"
-          description: "Available memory has been below 10% for more than 15 minutes."
-
-      - alert: HighDiskUsage
-        expr: |
-          (
-            1 -
-            node_filesystem_avail_bytes{fstype!~"tmpfs|fuse.lxcfs|squashfs|ramfs|overlay"}
-            / clamp_min(node_filesystem_size_bytes, 1)
-          ) * 100 > 95
-        for: 30m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High disk usage on {{ $labels.mountpoint }}: {{ $value | printf \"%.0f\" }}%"
-          description: >
-            Disk usage on {{ $labels.mountpoint }} ({{ $labels.device }}) has been
-            above 95% for more than 30 minutes.
-
-      - alert: DiskWillFillSoon
-        expr: >
-          predict_linear(
-            node_filesystem_avail_bytes{fstype!~"tmpfs|fuse.lxcfs|squashfs|ramfs|overlay"}[6h],
-            4 * 3600
-          ) < 0
-        for: 30m
-        labels:
-          severity: warning
-        annotations:
-          summary: "Disk {{ $labels.mountpoint }} predicted to fill within 4 hours"
-          description: >
-            Based on the last 6 hours of growth, {{ $labels.mountpoint }} will run
-            out of space within 4 hours.
-
-      - alert: HighSystemLoad
-        expr: node_load15 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) > 2
-        for: 30m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High 15-minute load average: {{ $value | printf \"%.2f\" }}"
-          description: "The 15-minute load average per CPU core has been above 2 for 30 minutes."
-
-      - alert: FilesystemReadOnly
-        expr: node_filesystem_readonly{fstype!~"tmpfs|fuse.lxcfs|squashfs|ramfs|overlay"} == 1
-        for: 3m
-        labels:
-          severity: critical
-        annotations:
-          summary: "Filesystem {{ $labels.mountpoint }} is read-only on {{ $labels.instance }}"
-          description: >
-            The filesystem at {{ $labels.mountpoint }} ({{ $labels.device }}) on
-            {{ $labels.instance }} has become read-only.
-
-      - alert: NetworkReceiveErrors
-        expr: rate(node_network_receive_errs_total{device!~"lo|docker.*|veth.*|br-.*"}[5m]) > 10
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High network receive errors on {{ $labels.instance }}/{{ $labels.device }}"
-          description: >
-            Network interface {{ $labels.device }} on {{ $labels.instance }} is reporting
-            more than 10 receive errors per second.
-
-      - alert: NetworkTransmitErrors
-        expr: rate(node_network_transmit_errs_total{device!~"lo|docker.*|veth.*|br-.*"}[5m]) > 10
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High network transmit errors on {{ $labels.instance }}/{{ $labels.device }}"
-          description: >
-            Network interface {{ $labels.device }} on {{ $labels.instance }} is reporting
-            more than 10 transmit errors per second.
-
-      - alert: NodeOOMKill
-        expr: increase(node_vmstat_oom_kill[5m]) > 0
-        for: 1m
-        labels:
-          severity: critical
-        annotations:
-          summary: "OOM kill detected on {{ $labels.instance }}"
-          description: >
-            One or more out-of-memory kills have been detected on {{ $labels.instance }}
-            in the last 5 minutes.
-
-  - name: zfs
-    rules:
-      - alert: ZFSPoolNotOnline
-        expr: zfs_pool_health != 0
-        for: 1m
-        labels:
-          severity: critical
-        annotations:
-          summary: "ZFS pool {{ $labels.pool }} is not online on {{ $labels.instance }}"
-          description: >
-            The ZFS pool {{ $labels.pool }} on {{ $labels.instance }} is not in the
-            ONLINE state. Health value: {{ $value }} (0=online, 1=degraded, 2=faulted,
-            3=offline, 4=unavail, 5=removed, 6=suspended).
-
-      - alert: ZFSPoolReadOnly
-        expr: zfs_pool_readonly == 1
-        for: 1m
-        labels:
-          severity: critical
-        annotations:
-          summary: "ZFS pool {{ $labels.pool }} is read-only on {{ $labels.instance }}"
-          description: >
-            The ZFS pool {{ $labels.pool }} on {{ $labels.instance }} has become
-            read-only.
-
-      - alert: ZFSPoolHighCapacity
-        expr: zfs_pool_allocated_bytes / zfs_pool_size_bytes * 100 > 95
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "ZFS pool {{ $labels.pool }} is {{ $value | printf \"%.0f\" }}% full"
-          description: >
-            ZFS pool {{ $labels.pool }} on {{ $labels.instance }} has been above 95%
-            capacity for more than 5 minutes.
-
-      - alert: ZFSDatasetQuotaHigh
-        expr: |
-          zfs_dataset_used_bytes{type="filesystem"}
-          /
-          (zfs_dataset_used_bytes{type="filesystem"} + zfs_dataset_available_bytes{type="filesystem"})
-          * 100 > 95
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "ZFS dataset {{ $labels.name }} is {{ $value | printf \"%.0f\" }}% full"
-          description: >
-            ZFS dataset {{ $labels.name }} (pool {{ $labels.pool }}) on
-            {{ $labels.instance }} has been above 95% used space for more than 5 minutes.
-
-  - name: h2o
-    rules:
-      - alert: H2OHighConnectionUtilization
-        expr: h2o_connections / h2o_max_connections * 100 > 85
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "H2O connection utilization is {{ $value | printf \"%.0f\" }}% on {{ $labels.instance }}"
-          description: >
-            H2O on {{ $labels.instance }} has been using more than 85% of its
-            configured maximum connections for more than 5 minutes.
-
-      - alert: H2OHighP99Latency
-        expr: h2o_request_total_time_99 > 500
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "H2O p99 request latency is high on {{ $labels.instance }}"
-          description: >
-            H2O p99 end-to-end request time on {{ $labels.instance }} has been
-            above 500 ms for more than 5 minutes.
-
-      - alert: H2OHighStatusErrorRate
-        expr: |
-          sum by (instance, job) (
-            rate({__name__=~"h2o_status_errors_.+"}[5m])
-          ) > 1
-        for: 5m
-        labels:
-          severity: critical
-        annotations:
-          summary: "H2O HTTP error rate is high on {{ $labels.instance }}"
-          description: >
-            H2O on {{ $labels.instance }} is returning 4xx/5xx responses at a
-            rate higher than 1 per second.
-
-      - alert: H2OSSLHandshakeErrors
-        expr: rate(h2o_ssl_errors[5m]) > 1
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "H2O SSL handshake errors are high on {{ $labels.instance }}"
-          description: >
-            H2O SSL handshake errors on {{ $labels.instance }} have been above
-            1 per second for more than 5 minutes.
-
-  - name: blackbox
-    rules:
-      - alert: BlackboxProbeFailed
-        expr: probe_success == 0
-        for: 5m
-        labels:
-          severity: critical
-        annotations:
-          summary: "Probe failed: {{ $labels.instance }}"
-          description: >
-            The blackbox probe for {{ $labels.instance }} (module: {{ $labels.module }})
-            has been failing for more than 5 minutes.
-
-      - alert: BlackboxProbeSlow
-        expr: probe_duration_seconds > 5
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "Probe is slow: {{ $labels.instance }}"
-          description: >
-            The blackbox probe for {{ $labels.instance }} (module: {{ $labels.module }})
-            has taken more than 5 seconds for more than 5 minutes.
-
-      - alert: SSLCertificateExpiringSoon
-        expr: (probe_ssl_cert_expiry - time()) / 86400 < 21
-        for: 1h
-        labels:
-          severity: warning
-        annotations:
-          summary: "SSL certificate expiring soon: {{ $labels.instance }}"
-          description: >
-            The SSL certificate for {{ $labels.instance }} expires in less than 21 days.
-
-  - name: systemd
-    rules:
-      - alert: SystemdUnitFailed
-        expr: node_systemd_unit_state{state="failed"} == 1
-        for: 5m
-        labels:
-          severity: critical
-        annotations:
-          summary: "Systemd unit {{ $labels.name }} failed"
-          description: >
-            The systemd unit {{ $labels.name }} has been in a failed state
-            for more than 5 minutes.
blob - /dev/null
blob + 9f70ff06c918d6eaa057ca6c10fdecfafc2c6c56 (mode 644)
--- /dev/null
+++ modules/mixins/monitoring/alert-rules.nix
@@ -0,0 +1,285 @@
+{
+  groups = [
+    {
+      name = "targets";
+      rules = [
+        {
+          alert = "TargetDown";
+          expr = "up == 0";
+          "for" = "2m";
+          labels.severity = "critical";
+          annotations.summary = "Target {{ $labels.job }}/{{ $labels.instance }} is down";
+          annotations.description = ''
+            Scrape target {{ $labels.instance }} (job: {{ $labels.job }}) has been
+            unreachable for more than 2 minutes.
+          '';
+        }
+      ];
+    }
+    {
+      name = "node";
+      rules = [
+        {
+          alert = "HighCPULoad";
+          expr = ''100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90'';
+          "for" = "15m";
+          labels.severity = "warning";
+          annotations.summary = "High CPU load: {{ $value | printf \"%.0f\" }}%";
+          annotations.description = "CPU usage has been above 10% for more than 15 minutes.";
+        }
+        {
+          alert = "HighMemoryUsage";
+          expr = "(1 - (node_memory_MemAvailable_bytes or node_memory_free_bytes) / node_memory_MemTotal_bytes) * 100 > 90";
+          "for" = "15m";
+          labels.severity = "warning";
+          annotations.summary = "High memory usage: {{ $value | printf \"%.0f\" }}%";
+          annotations.description = "Available memory has been below 10% for more than 15 minutes.";
+        }
+        {
+          alert = "HighDiskUsage";
+          expr = ''
+            (
+              1 -
+              node_filesystem_avail_bytes{fstype!~"tmpfs|fuse.lxcfs|squashfs|ramfs|overlay"}
+              / clamp_min(node_filesystem_size_bytes, 1)
+            ) * 100 > 95
+          '';
+          "for" = "15m";
+          labels.severity = "warning";
+          annotations.summary = "High disk usage on {{ $labels.mountpoint }}: {{ $value | printf \"%.0f\" }}%";
+          annotations.description = ''
+            Disk usage on {{ $labels.mountpoint }} ({{ $labels.device }}) has been
+            above 95% for more than 15 minutes.
+          '';
+        }
+        {
+          alert = "DiskWillFillSoon";
+          expr = ''
+            predict_linear(
+              node_filesystem_avail_bytes{fstype!~"tmpfs|fuse.lxcfs|squashfs|ramfs|overlay"}[6h],
+              4 * 3600
+            ) < 0
+          '';
+          "for" = "15m";
+          labels.severity = "warning";
+          annotations.summary = "Disk {{ $labels.mountpoint }} predicted to fill within 4 hours";
+          annotations.description = ''
+            Based on the last 6 hours of growth, {{ $labels.mountpoint }} will run
+            out of space within 4 hours.
+          '';
+        }
+        {
+          alert = "HighSystemLoad";
+          expr = ''node_load15 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) > 2'';
+          "for" = "15m";
+          labels.severity = "warning";
+          annotations.summary = "High 15-minute load average: {{ $value | printf \"%.2f\" }}";
+          annotations.description = "The 15-minute load average per CPU core has been above 2 for 15 minutes.";
+        }
+        {
+          alert = "FilesystemReadOnly";
+          expr = ''node_filesystem_readonly{fstype!~"tmpfs|fuse.lxcfs|squashfs|ramfs|overlay",mountpoint!="/nix/store"} == 1'';
+          "for" = "1m";
+          labels.severity = "critical";
+          annotations.summary = "Filesystem {{ $labels.mountpoint }} is read-only on {{ $labels.instance }}";
+          annotations.description = ''
+            The filesystem at {{ $labels.mountpoint }} ({{ $labels.device }}) on
+            {{ $labels.instance }} has become read-only.
+          '';
+        }
+        {
+          alert = "NetworkReceiveErrors";
+          expr = ''rate(node_network_receive_errs_total{device!~"lo|docker.*|veth.*|br-.*"}[5m]) > 10'';
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "High network receive errors on {{ $labels.instance }}/{{ $labels.device }}";
+          annotations.description = ''
+            Network interface {{ $labels.device }} on {{ $labels.instance }} is reporting
+            more than 10 receive errors per second.
+          '';
+        }
+        {
+          alert = "NetworkTransmitErrors";
+          expr = ''rate(node_network_transmit_errs_total{device!~"lo|docker.*|veth.*|br-.*"}[5m]) > 10'';
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "High network transmit errors on {{ $labels.instance }}/{{ $labels.device }}";
+          annotations.description = ''
+            Network interface {{ $labels.device }} on {{ $labels.instance }} is reporting
+            more than 10 transmit errors per second.
+          '';
+        }
+        {
+          alert = "NodeOOMKill";
+          expr = "increase(node_vmstat_oom_kill[5m]) > 0";
+          "for" = "1m";
+          labels.severity = "critical";
+          annotations.summary = "OOM kill detected on {{ $labels.instance }}";
+          annotations.description = ''
+            One or more out-of-memory kills have been detected on {{ $labels.instance }}
+            in the last 5 minutes.
+          '';
+        }
+      ];
+    }
+    {
+      name = "zfs";
+      rules = [
+        {
+          alert = "ZFSPoolNotOnline";
+          expr = "zfs_pool_health != 0";
+          "for" = "1m";
+          labels.severity = "critical";
+          annotations.summary = "ZFS pool {{ $labels.pool }} is not online on {{ $labels.instance }}";
+          annotations.description = ''
+            The ZFS pool {{ $labels.pool }} on {{ $labels.instance }} is not in the
+            ONLINE state. Health value: {{ $value }} (0=online, 1=degraded, 2=faulted,
+            3=offline, 4=unavail, 5=removed, 6=suspended).
+          '';
+        }
+        {
+          alert = "ZFSPoolReadOnly";
+          expr = "zfs_pool_readonly == 1";
+          "for" = "1m";
+          labels.severity = "critical";
+          annotations.summary = "ZFS pool {{ $labels.pool }} is read-only on {{ $labels.instance }}";
+          annotations.description = ''
+            The ZFS pool {{ $labels.pool }} on {{ $labels.instance }} has become
+            read-only.
+          '';
+        }
+        {
+          alert = "ZFSPoolHighCapacity";
+          expr = "zfs_pool_allocated_bytes / zfs_pool_size_bytes * 100 > 95";
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "ZFS pool {{ $labels.pool }} is {{ $value | printf \"%.0f\" }}% full";
+          annotations.description = ''
+            ZFS pool {{ $labels.pool }} on {{ $labels.instance }} has been above 95%
+            capacity for more than 5 minutes.
+          '';
+        }
+        {
+          alert = "ZFSDatasetQuotaHigh";
+          expr = ''
+            zfs_dataset_used_bytes{type="filesystem"}
+            /
+            (zfs_dataset_used_bytes{type="filesystem"} + zfs_dataset_available_bytes{type="filesystem"})
+            * 100 > 95
+          '';
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "ZFS dataset {{ $labels.name }} is {{ $value | printf \"%.0f\" }}% full";
+          annotations.description = ''
+            ZFS dataset {{ $labels.name }} (pool {{ $labels.pool }}) on
+            {{ $labels.instance }} has been above 95% used space for more than 5 minutes.
+          '';
+        }
+      ];
+    }
+    {
+      name = "h2o";
+      rules = [
+        {
+          alert = "H2OHighConnectionUtilization";
+          expr = "h2o_connections / h2o_max_connections * 100 > 85";
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "H2O connection utilization is {{ $value | printf \"%.0f\" }}% on {{ $labels.instance }}";
+          annotations.description = ''
+            H2O on {{ $labels.instance }} has been using more than 85% of its
+            configured maximum connections for more than 5 minutes.
+          '';
+        }
+        {
+          alert = "H2OHighP99Latency";
+          expr = "h2o_request_total_time_99 > 500";
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "H2O p99 request latency is high on {{ $labels.instance }}";
+          annotations.description = ''
+            H2O p99 end-to-end request time on {{ $labels.instance }} has been
+            above 500 ms for more than 5 minutes.
+          '';
+        }
+        {
+          alert = "H2OHighStatusErrorRate";
+          expr = ''
+            sum by (instance, job) (
+              rate({__name__=~"h2o_status_errors_.+"}[5m])
+            ) > 1
+          '';
+          "for" = "5m";
+          labels.severity = "critical";
+          annotations.summary = "H2O HTTP error rate is high on {{ $labels.instance }}";
+          annotations.description = ''
+            H2O on {{ $labels.instance }} is returning 4xx/5xx responses at a
+            rate higher than 1 per second.
+          '';
+        }
+        {
+          alert = "H2OSSLHandshakeErrors";
+          expr = "rate(h2o_ssl_errors[5m]) > 1";
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "H2O SSL handshake errors are high on {{ $labels.instance }}";
+          annotations.description = ''
+            H2O SSL handshake errors on {{ $labels.instance }} have been above
+            1 per second for more than 5 minutes.
+          '';
+        }
+      ];
+    }
+    {
+      name = "blackbox";
+      rules = [
+        {
+          alert = "BlackboxProbeFailed";
+          expr = "probe_success == 0";
+          "for" = "5m";
+          labels.severity = "critical";
+          annotations.summary = "Probe failed: {{ $labels.instance }}";
+          annotations.description = ''
+            The blackbox probe for {{ $labels.instance }} (module: {{ $labels.module }})
+            has been failing for more than 5 minutes.
+          '';
+        }
+        {
+          alert = "BlackboxProbeSlow";
+          expr = "probe_duration_seconds > 5";
+          "for" = "5m";
+          labels.severity = "warning";
+          annotations.summary = "Probe is slow: {{ $labels.instance }}";
+          annotations.description = ''
+            The blackbox probe for {{ $labels.instance }} (module: {{ $labels.module }})
+            has taken more than 5 seconds for more than 5 minutes.
+          '';
+        }
+        {
+          alert = "SSLCertificateExpiringSoon";
+          expr = "(probe_ssl_cert_expiry - time()) / 86400 < 21";
+          "for" = "1h";
+          labels.severity = "warning";
+          annotations.summary = "SSL certificate expiring soon: {{ $labels.instance }}";
+          annotations.description = "The SSL certificate for {{ $labels.instance }} expires in less than 21 days.";
+        }
+      ];
+    }
+    {
+      name = "systemd";
+      rules = [
+        {
+          alert = "SystemdUnitFailed";
+          expr = ''node_systemd_unit_state{state="failed"} == 1'';
+          "for" = "5m";
+          labels.severity = "critical";
+          annotations.summary = "Systemd unit {{ $labels.name }} failed";
+          annotations.description = ''
+            The systemd unit {{ $labels.name }} has been in a failed state
+            for more than 5 minutes.
+          '';
+        }
+      ];
+    }
+  ];
+}
blob - f900788230292956c589a441a176577579338c8b
blob + 8d0ba7dd1dc3312100d22706bb873038c5936afe
--- modules/mixins/overlays.nix
+++ modules/mixins/overlays.nix
@@ -4,63 +4,8 @@ overlayDir: {
   inputs,
   ...
 }: let
-  date = inputs.self.lastModifiedDate or "19700101000000";
-  year = lib.substring 0 4 date;
-  monthNum = lib.substring 4 2 date;
-  month = lib.elemAt [
-    "january"
-    "february"
-    "march"
-    "april"
-    "may"
-    "june"
-    "july"
-    "august"
-    "september"
-    "october"
-    "november"
-    "december"
-  ] (lib.toInt (lib.removePrefix "0" monthNum) - 1);
-
-  tmplArgs = {
-    inherit year month;
-    homeDir = config.home.homeDirectory;
-  };
-
-  mkMapping = path: prefix: let
-    scan = dir: rel:
-      lib.concatLists (lib.mapAttrsToList (name: type: let
-        newRel =
-          if rel == ""
-          then name
-          else "${rel}/${name}";
-        newPath = dir + "/${name}";
-      in
-        if type == "directory"
-        then scan newPath newRel
-        else [
-          {
-            name = newRel;
-            path = newPath;
-          }
-        ])
-      (builtins.readDir dir));
-  in
-    builtins.listToAttrs (map (file: let
-      isNix = lib.hasSuffix ".nix" file.name;
-      target = prefix + (lib.removeSuffix ".nix" file.name);
-    in
-      lib.nameValuePair target (
-        if isNix
-        then {
-          text = import file.path tmplArgs;
-          force = true;
-        }
-        else {
-          source = file.path;
-          force = true;
-        }
-      )) (scan path ""));
+  overlay = import ../../lib/mk-overlay.nix {inherit config lib inputs;};
+  inherit (overlay) mkMapping;
 in {
   config = {
     home.file = lib.mapAttrs (_: lib.mkForce) (
blob - bca5e177e17db7b6c5cd4f6827419101536f813e
blob + 4ac1d24eee89f4c2053b1e10cb3743d3b2672b0f
--- modules/nixos/base.nix
+++ modules/nixos/base.nix
@@ -43,12 +43,12 @@
   time.timeZone = "UTC";
   i18n.defaultLocale = "en_US.UTF-8";
 
-  environment.systemPackages = with pkgs; [
-    vim
-    curl
-    wget
-    htop
-    git
+  environment.systemPackages = [
+    pkgs.vim
+    pkgs.curl
+    pkgs.wget
+    pkgs.htop
+    pkgs.git
   ];
 
   virtualisation.podman.enable = true;
blob - fe41acba70561765161d6d8afa9c64f9a95eb4e3
blob + 1a2820dc02efa5632f793b0b5a7ca8494939bf59
--- modules/services/couchdb.nix
+++ modules/services/couchdb.nix
@@ -12,11 +12,6 @@ in {
       type = lib.types.str;
       description = "CouchDB admin username";
     };
-    adminPassFile = lib.mkOption {
-      type = lib.types.nullOr lib.types.path;
-      default = null;
-      description = "Path to a file containing the CouchDB admin password";
-    };
     publicDomain = lib.mkOption {
       type = lib.types.str;
       description = "Public domain for the CouchDB Fauxton UI (set to null to disable)";
blob - 4d7a513f55cba8c5fd90c6aa7c125826f7e5e127
blob + 21fa3f972319424aa49ce787774aaf20144ea146
--- modules/services/dex.nix
+++ modules/services/dex.nix
@@ -100,15 +100,15 @@ in {
     };
 
     services.caddy.virtualHosts."${cfg.domain}".extraConfig = ''
-            header {
-              Strict-Transport-Security "max-age=31536000; includeSubDomains"
-              X-Content-Type-Options "nosniff"
-              X-Frame-Options "DENY"
-              Referrer-Policy "strict-origin-when-cross-origin"
-      -Server
-            }
+      header {
+        Strict-Transport-Security "max-age=31536000; includeSubDomains"
+        X-Content-Type-Options "nosniff"
+        X-Frame-Options "DENY"
+        Referrer-Policy "strict-origin-when-cross-origin"
+        -Server
+      }
 
-            reverse_proxy ${cfg.address}
+      reverse_proxy ${cfg.address}
     '';
   };
 }
blob - 2b442ffd0f073da57ebf2b706156d7e6da717942
blob + 6cc849c3fc2b3d7106be1eaa090e1edaff331431
--- modules/services/etherpad.nix
+++ modules/services/etherpad.nix
@@ -134,7 +134,6 @@ in {
         description = "Prepare Etherpad password environment file";
         before = ["podman-etherpad.service"];
         requiredBy = ["podman-etherpad.service"];
-        unitConfig = {};
         serviceConfig = {
           Type = "oneshot";
           RemainAfterExit = true;
blob - 48bdd5d8406235ebc08ea253cd7eff12d1bee0d9
blob + a8082b247839a8f15e66f39fc45f0bd75f6a1b0c
--- modules/services/headscale.nix
+++ modules/services/headscale.nix
@@ -64,7 +64,7 @@ in {
         grpc_allow_insecure = true;
         dns = {
           magic_dns = true;
-          base_domain = "${cfg.magicDnsDomain}";
+          base_domain = cfg.magicDnsDomain;
           nameservers.global = [
             "1.1.1.1"
             "8.8.8.8"
blob - a17d1f80118b20394a293a8291d2a1634ec2acdf
blob + 2dde51a3287d77690550a88db3de41af4b07e0f1
--- modules/services/monitoring/default.nix
+++ modules/services/monitoring/default.nix
@@ -12,7 +12,6 @@ in {
     ./exporters.nix
     ./grafana.nix
     ./loki.nix
-    ./vmalert.nix
   ];
 
   options.services.haravara.monitoring = {
@@ -33,7 +32,11 @@ in {
     };
 
     victoriametrics = {
-      enable = lib.mkEnableOption "VictoriaMetrics time-series database" // {default = true;};
+      enable = lib.mkOption {
+        type = lib.types.bool;
+        default = true;
+        description = "Whether to enable VictoriaMetrics time-series database";
+      };
       address = lib.mkOption {
         type = lib.types.str;
         default = "127.0.0.1:8428";
@@ -48,6 +51,12 @@ in {
         type = lib.types.listOf lib.types.attrs;
         default = [];
         description = "Extra Prometheus scrape configs for VictoriaMetrics";
+        example = lib.literalExpression ''
+          [{
+            job_name = "custom";
+            static_configs = [{ targets = [ "127.0.0.1:9000" ]; }];
+          }]
+        '';
       };
     };
   };
@@ -90,9 +99,7 @@ in {
     services.victoriametrics = lib.mkIf cfg.victoriametrics.enable {
       enable = true;
       listenAddress = cfg.victoriametrics.address;
-      extraOptions =
-        lib.optional cfg.vmalert.enable
-        "-vmalert.proxyURL=http://127.0.0.1:${toString cfg.vmalert.port}";
+      extraOptions = [];
       prometheusConfig = {
         global.scrape_interval = "30s";
         scrape_configs =
@@ -139,10 +146,12 @@ in {
             static_configs = [{targets = ["127.0.0.1:${toString config.services.haravara.corpus.port}"];}];
             metrics_path = "/metrics";
           }
-          ++ lib.optional cfg.vmalert.enable {
-            job_name = "vmalert";
-            static_configs = [{targets = ["127.0.0.1:${toString cfg.vmalert.port}"];}];
-          }
+          ++ [
+            {
+              job_name = "vmalert";
+              static_configs = [{targets = ["127.0.0.1:8880"];}];
+            }
+          ]
           ++ lib.optional cfg.alertmanager.enable {
             job_name = "alertmanager";
             static_configs = [{targets = ["127.0.0.1:${toString cfg.alertmanager.port}"];}];
blob - 488af76e1ec5163dd733b96c28e2afa51e670152
blob + df56275a431ee7b6507717323b96e2bda88a423f
--- modules/services/monitoring/exporters.nix
+++ modules/services/monitoring/exporters.nix
@@ -7,7 +7,11 @@
   cfg = config.services.haravara.monitoring;
 in {
   options.services.haravara.monitoring.exporters = {
-    enable = lib.mkEnableOption "Enable node and systemd Prometheus exporters" // {default = true;};
+    enable = lib.mkOption {
+      type = lib.types.bool;
+      default = true;
+      description = "Whether to enable node and systemd Prometheus exporters";
+    };
     extraNodeStaticConfigs = lib.mkOption {
       type = lib.types.listOf lib.types.attrs;
       default = [];
@@ -42,6 +46,14 @@ in {
           };
         };
         description = "Blackbox exporter probe modules";
+        example = lib.literalExpression ''
+          {
+            http = {
+              prober = "http";
+              timeout = "5s";
+            };
+          }
+        '';
       };
       http_targets = lib.mkOption {
         type = lib.types.listOf lib.types.str;
blob - 62b7fe6cd8261e5e8f82bc323b0a50a502030d54
blob + a49110aee1e0abe10410322c1872865540246019
--- modules/services/monitoring/grafana.nix
+++ modules/services/monitoring/grafana.nix
@@ -38,12 +38,12 @@
       {
         name = "node_exporter.json";
         url = "https://grafana.com/api/dashboards/1860/revisions/42/download";
-        sha256 = "a4d827eb1819044bba2d6d257347175f6811910f2583fadeaf7e123c4df2125e";
+        sha256 = "0phjy96kq4kymzggm0r51y8i2s2z2x3p69bd5nx4n10r33mjgn54";
       }
       {
         name = "systemd_exporter.json";
         url = "https://grafana.com/api/dashboards/22872/revisions/1/download";
-        sha256 = "665bc3e86b79749b2fdae7787f4b7502e00830898bf48f73c68134471f72bf33";
+        sha256 = "0cxzf8glfd41qrrqzx4bi4q0iq02fm5pyy77v8prnx3rdglc6nv6";
       }
       {
         name = "alertmanager.json";
@@ -53,13 +53,13 @@
       {
         name = "node_exporter_bsd.json";
         url = "https://grafana.com/api/dashboards/4260/revisions/19/download";
-        sha256 = "ad3aef8744750f1b61f8905b1cddffe1f4274f5594e4aba5e8193f1a617ce765";
+        sha256 = "0rg7gihilgqrx2jspr4lam7jgx71zzfiqnwhz1hin3vm8j3yyfmd";
       }
     ]
     ++ lib.optional config.services.haravara.seaweedfs.enable {
       name = "seaweedfs.json";
       url = "https://raw.githubusercontent.com/chrislusf/seaweedfs/c9100a7213e27963f58a0ba783c9598a177384b6/other/metrics/grafana_seaweedfs.json";
-      sha256 = "e364d113fed54127cbda10c4c2809d99a90dcc38bcd949b91846d0831e1a68e4";
+      sha256 = "1r3838g87l2632wlkndw7360vacrkn0c5i0hvb5jfhfmzq9x2r73";
     }
     ++ [
       {
@@ -88,11 +88,15 @@
     ++ lib.optional config.services.haravara.monitoring.exporters.blackbox.enable (fetchDashboard {
       name = "blackbox_exporter.json";
       url = "https://grafana.com/api/dashboards/14928/revisions/6/download";
-      sha256 = "4643193a1d77ba6c7e8d57e13d517531e2e7a6358cd0d1c832f9999229529286";
+      sha256 = "11lja8lr56gr6b4d3l4c6nkfgqiifm8kvqapimz6rfkp3lx1jhs6";
     }));
 in {
   options.services.haravara.monitoring.grafana = {
-    enable = lib.mkEnableOption "Grafana dashboard and visualization" // {default = true;};
+    enable = lib.mkOption {
+      type = lib.types.bool;
+      default = true;
+      description = "Whether to enable Grafana dashboard and visualization";
+    };
   };
 
   config = lib.mkIf (cfg.enable && cfg.grafana.enable) {
blob - 37b6fb62e8c316ccddabe005c2df7a835ec531c1
blob + bb9cbedee9b07dbcb63a4638b92888161133f101
--- modules/services/monitoring/loki.nix
+++ modules/services/monitoring/loki.nix
@@ -7,7 +7,11 @@
   cfg = config.services.haravara.monitoring;
 in {
   options.services.haravara.monitoring.loki = {
-    enable = lib.mkEnableOption "Loki log aggregation and Alloy collector" // {default = true;};
+    enable = lib.mkOption {
+      type = lib.types.bool;
+      default = true;
+      description = "Whether to enable Loki log aggregation and Alloy collector";
+    };
     port = lib.mkOption {
       type = lib.types.port;
       default = 3100;
blob - 0de7441846ea9e35b4799829ccb12cc8ecc3126f (mode 644)
blob + /dev/null
--- modules/services/monitoring/vmalert.nix
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}: let
-  cfg = config.services.haravara.monitoring;
-in {
-  options.services.haravara.monitoring.vmalert = {
-    enable = lib.mkEnableOption "vmalert for Prometheus-compatible alert rule evaluation";
-    port = lib.mkOption {
-      type = lib.types.port;
-      default = 8880;
-    };
-    rules = lib.mkOption {
-      type = lib.types.listOf lib.types.path;
-      default = [];
-      description = "Paths to YAML files containing alert/recording rules";
-    };
-  };
-
-  config = lib.mkIf (cfg.enable && cfg.vmalert.enable) {
-    systemd.services.vmalert = {
-      description = "VictoriaMetrics alert rule evaluator";
-      wantedBy = ["multi-user.target"];
-      after = ["network.target" "victoriametrics.service"];
-      serviceConfig = {
-        ExecStart = lib.concatStringsSep " " (
-          let
-            baseArgs = [
-              "${pkgs.victoriametrics}/bin/vmalert"
-              "-datasource.url=http://127.0.0.1:8428"
-              "-remoteWrite.url=http://127.0.0.1:8428"
-              "-httpListenAddr=127.0.0.1:${toString cfg.vmalert.port}"
-              "-evaluationInterval=30s"
-            ];
-            alertArgs = lib.optionals cfg.alertmanager.enable [
-              "-notifier.url=http://127.0.0.1:${toString cfg.alertmanager.port}"
-            ];
-            ruleArgs = map (r: "-rule=${r}") cfg.vmalert.rules;
-          in
-            baseArgs ++ alertArgs ++ ruleArgs
-        );
-        DynamicUser = true;
-        Restart = "on-failure";
-        RestartSec = "5s";
-      };
-    };
-  };
-}
blob - f4cd3bf790142206f1db6398e5014f1ceb35d5d7
blob + 5d9951bcf9af7dc0f30c5a08328782b9d25b4463
--- modules/services/redlib.nix
+++ modules/services/redlib.nix
@@ -31,7 +31,7 @@ in {
         ports = ["127.0.0.1:${toString cfg.port}:8080"];
         environment = {
           REDLIB_DEFAULT_SHOW_NSFW = "off";
-          REDLIB_DEFAULT_HIDE_HLS_NOTIFICATION = "on";
+          REDLIB_DEFAULT_USE_HLS = "on";
         };
       };
     };
@@ -39,7 +39,6 @@ in {
     services.caddy.virtualHosts =
       {
         "${cfg.domain}".extraConfig = ''
-          ${haravara.mkAuthImport cfg.authLabel}
           reverse_proxy 127.0.0.1:${toString cfg.port}
         '';
       }
blob - 885ff56a447693009bffb33b81b687d3aad27511
blob + 534f03cbf4733fb690fa907f08f9cd8b4badd97e
--- modules/services/shaarli.nix
+++ modules/services/shaarli.nix
@@ -31,7 +31,7 @@
     owner = "ManufacturaInd";
     repo = "shaarli-2004licious-theme";
     rev = "075833c547c6ca281e7ad31591f5ab0e9a99efcc";
-    sha256 = "16qzzshlyhdrawa3g8jg22j2fb6acmd0smg0ca5ilhjxakip3h81";
+    hash = "sha256-AcFx41RdQhqLYuBVDVplyiwnpBBPojcUV7lBT6H+H5s=";
   };
 in {
   options.services.haravara.shaarli = {
blob - da62b1e01e9806b37987488d255e0b3d9e874894
blob + c9f2481797a5c75fce0394308dbc8a73c75982f6
--- modules/services/soju.nix
+++ modules/services/soju.nix
@@ -9,6 +9,8 @@
 
   # Define the paths for the TLS cert and key.
   # We prefer systemd credentials which are populated from Caddy's certs.
+  certDomain = cfg.acme.certificateDomain;
+
   certPath =
     if cfg.acme.enable
     then "/run/credentials/soju.service/cert.pem"
@@ -35,7 +37,7 @@
   '';
 
   # Path to Caddy's certificates
-  caddyCertDir = "${cfg.acme.caddyCertDir}/${cfg.domain}";
+  caddyCertDir = "${cfg.acme.caddyCertDir}/${certDomain}";
 in {
   options.services.haravara.soju = {
     enable = lib.mkEnableOption "soju IRC bouncer";
@@ -140,8 +142,8 @@ in {
   config = lib.mkIf cfg.enable {
     assertions = [
       {
-        assertion = (cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null);
-        message = "services.haravara.soju.tlsCertificate and services.haravara.soju.tlsCertificateKey must both be specified to enable TLS.";
+        assertion = cfg.acme.enable || ((cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null));
+        message = "services.haravara.soju: tlsCertificate and tlsCertificateKey must both be specified when ACME is disabled.";
       }
     ];
 
@@ -164,8 +166,8 @@ in {
 
         # Load certs from Caddy's storage
         LoadCredential = lib.optionals cfg.acme.enable [
-          "cert.pem:${caddyCertDir}/${cfg.domain}.crt"
-          "key.pem:${caddyCertDir}/${cfg.domain}.key"
+          "cert.pem:${caddyCertDir}/${certDomain}.crt"
+          "key.pem:${caddyCertDir}/${certDomain}.key"
         ];
 
         SupplementaryGroups = lib.optional cfg.acme.enable "caddy";