diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+result
+*.qcow2
+*.txt
diff --git a/.sops.yaml b/.sops.yaml
new file mode 100644
--- /dev/null
+++ b/.sops.yaml
@@ -0,0 +1,17 @@
+keys:
+ - &bathtub age1zqclazll796z6rzxtwn2ethpfnqmfhr23a3uy2ydqvt3weps94fq9rmtdt
+ - &forest age1rgnhhehyjx66rxq793ac2vqq24semmzt4vru06ffamwxsmmhtfqqfax0np
+ - &tundra age19av7xt9r3tyankhjel6kg2tgf4p5gtaf5lm9tch3tp2trh2z7cds0trsta
+creation_rules:
+ - path_regex: secrets/bathtub.yaml$
+ key_groups:
+ - age:
+ - *bathtub
+ - path_regex: secrets/forest.yaml$
+ key_groups:
+ - age:
+ - *forest
+ - path_regex: secrets/tundra.yaml$
+ key_groups:
+ - age:
+ - *tundra
diff --git a/bathtub/default.nix b/bathtub/default.nix
new file mode 100644
--- /dev/null
+++ b/bathtub/default.nix
@@ -0,0 +1,61 @@
+{
+ lib,
+ config,
+ pkgs,
+ ...
+}:
+
+{
+ imports = lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../nixos/core) ++ [
+ ./hardware.nix
+ ./services.nix
+ ./programs.nix
+ ];
+
+ sops = {
+ defaultSopsFile = ../secrets/bathtub.yaml;
+ age.keyFile = "/var/lib/sops-nix/bathtub.txt";
+ secrets = {
+ "passwords/root".neededForUsers = true;
+ "passwords/monke".neededForUsers = true;
+ };
+ };
+
+ networking.hostName = "bathtub";
+ networking.hostId = "2f38e783";
+ networking.networkmanager.enable = true;
+
+ time.timeZone = "Australia/Melbourne";
+ i18n.defaultLocale = "en_AU.UTF-8";
+ console = {
+ font = "solar24x32";
+ keyMap = lib.mkDefault "us";
+ useXkbConfig = true;
+ };
+
+ users.defaultUserShell = pkgs.zsh;
+ users.users = {
+ root.hashedPasswordFile = config.sops.secrets."passwords/root".path;
+ monke = {
+ isNormalUser = true;
+ extraGroups = [
+ "audio"
+ "disk"
+ "input"
+ "lp"
+ "plugdev"
+ "dialout"
+ "render"
+ "video"
+ "wheel"
+ ];
+ hashedPasswordFile = config.sops.secrets."passwords/monke".path;
+ };
+ };
+
+ security.pki.certificateFiles = [
+ ../files/forest.pem
+ ];
+
+ system.stateVersion = "25.11";
+}
diff --git a/bathtub/hardware.nix b/bathtub/hardware.nix
new file mode 100644
--- /dev/null
+++ b/bathtub/hardware.nix
@@ -0,0 +1,69 @@
+{
+ lib,
+ modulesPath,
+ ...
+}:
+
+{
+ imports = [
+ (modulesPath + "/installer/scan/not-detected.nix")
+ ];
+
+ hardware = {
+ graphics.enable = true;
+ asahi = {
+ peripheralFirmwareDirectory = ../files/asahi-firmware;
+ setupAsahiSound = true;
+ };
+ };
+
+ boot.loader.systemd-boot.enable = true;
+ boot.supportedFilesystems = [ "zfs" ];
+ boot.zfs.forceImportRoot = false;
+ boot.loader.efi = {
+ canTouchEfiVariables = false;
+ efiSysMountPoint = "/boot/efi";
+ };
+
+ boot.initrd.availableKernelModules = [
+ "usb_storage"
+ "sdhci_pci"
+ ];
+ boot.initrd.kernelModules = [ ];
+ boot.kernelModules = [ ];
+ boot.kernelParams = [
+ "apple_dcp.show_notch=1"
+ ];
+ boot.extraModulePackages = [ ];
+
+ fileSystems."/" = {
+ device = "bathtub/root/nixos";
+ fsType = "zfs";
+ };
+
+ fileSystems."/home" = {
+ device = "bathtub/home";
+ fsType = "zfs";
+ };
+
+ fileSystems."/boot" = {
+ device = "/dev/disk/by-uuid/70838fa1-5372-49e5-afc8-81d08fd5f7f7";
+ fsType = "ext2";
+ };
+
+ fileSystems."/boot/efi" = {
+ device = "/dev/disk/by-uuid/068B-1C01";
+ fsType = "vfat";
+ options = [
+ "fmask=0022"
+ "dmask=0022"
+ ];
+ };
+
+ swapDevices = [
+ { device = "/dev/disk/by-uuid/e97db0d7-9b58-454e-905e-d21f7b4bc50f"; }
+ ];
+
+ networking.useDHCP = lib.mkDefault true;
+ nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
+}
diff --git a/bathtub/home-overrides.nix b/bathtub/home-overrides.nix
new file mode 100644
--- /dev/null
+++ b/bathtub/home-overrides.nix
@@ -0,0 +1,9 @@
+{
+ lib,
+ ...
+}:
+{
+ programs.waybar.settings = {
+ bar.modules-center = lib.mkForce [ ];
+ };
+}
diff --git a/bathtub/home.nix b/bathtub/home.nix
new file mode 100644
--- /dev/null
+++ b/bathtub/home.nix
@@ -0,0 +1,65 @@
+{
+ pkgs,
+ lib,
+ ...
+}:
+
+{
+ # TODO: make this not shit
+ imports =
+ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../modules/core)
+ ++ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../modules/desktop)
+ ++ [
+ ../modules/rclone.nix
+ ../modules/email.nix
+ ./home-overrides.nix
+ ];
+
+ sops = {
+ defaultSopsFile = ../secrets/bathtub.yaml;
+ age.keyFile = "/home/monke/.config/sops/age/keys.txt";
+ secrets = {
+ "nextcloud/url" = { };
+ "nextcloud/user" = { };
+ "nextcloud/pass" = { };
+ "email/pass" = { };
+ };
+ };
+
+ home = {
+ username = "monke";
+ homeDirectory = "/home/monke";
+
+ sessionVariables = {
+ EDITOR = "nvim";
+ NIXOS_OZONE_WL = 1;
+ QT_QPA_PLATFORM = "wayland-egl";
+ };
+
+ sessionPath = [
+ "$HOME/usr/bin"
+ ];
+ preferXdgDirectories = true;
+
+ stateVersion = "25.11";
+
+ packages = with pkgs; [
+ audacity
+ free42
+ gcc
+ gnumake
+ gsettings-desktop-schemas
+ kicad
+ musescore
+ networkmanagerapplet
+ openscad
+ pass
+ pwvucontrol
+ signal-desktop
+ swaybg
+ tinymist
+ typst
+ wl-clipboard
+ ];
+ };
+}
diff --git a/bathtub/programs.nix b/bathtub/programs.nix
new file mode 100644
--- /dev/null
+++ b/bathtub/programs.nix
@@ -0,0 +1,19 @@
+{
+ lib,
+ pkgs,
+ ...
+}:
+
+{
+ environment.systemPackages = with pkgs; [
+ neovim
+ curl
+ git
+ ];
+
+ programs = {
+ zsh.enable = true;
+ niri.enable = true;
+ dconf.enable = true;
+ };
+}
diff --git a/bathtub/services.nix b/bathtub/services.nix
new file mode 100644
--- /dev/null
+++ b/bathtub/services.nix
@@ -0,0 +1,35 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+{
+ security.rtkit.enable = true;
+ services = {
+ libinput.enable = true;
+
+ pipewire = {
+ enable = true;
+ alsa.enable = lib.mkForce false;
+ #alsa.support32Bit = true;
+ pulse.enable = true;
+ jack.enable = true;
+ };
+
+ udisks2.enable = true;
+ xserver.xkb = {
+ layout = "us";
+ variant = "colemak_dh_ortho";
+ };
+ };
+
+ systemd.services."getty@tty1" = {
+ overrideStrategy = "asDropin";
+ serviceConfig.ExecStart = [
+ ""
+ "@${pkgs.util-linux}/sbin/agetty agetty --login-program ${config.services.getty.loginProgram} --autologin monke --noclear --keep-baud %I 115200,38400,9600 $TERM"
+ ];
+ };
+}
diff --git a/desktop.nix b/desktop.nix
deleted file mode 100644
--- a/desktop.nix
+++ /dev/null
@@ -1,346 +0,0 @@
-{ inputs, pkgs, config, ... }:
-{
- xdg = {
- enable = true;
-
- cacheHome = "${config.home.homeDirectory}/var/cache";
- #configHome = "${config.home.homeDirectory}/etc";
- dataHome = "${config.home.homeDirectory}/usr/share";
- stateHome = "${config.home.homeDirectory}/usr/state";
-
- portal = {
- enable = true;
- extraPortals = with pkgs; [
- xdg-desktop-portal-gtk
- xdg-desktop-portal-wlr
- xdg-desktop-portal-shana
- ];
- config = {
- common = {
- default = [
- "shana"
- "gtk"
- ];
- };
- };
- };
-
- userDirs = {
- enable = true;
- desktop = "/dev/null";
- documents = "${config.home.homeDirectory}/docs";
- download = "${config.home.homeDirectory}/dl";
- music = "${config.home.homeDirectory}/music";
- pictures = "${config.home.homeDirectory}/pics";
- templates = "${config.xdg.userDirs.documents}/templates";
- videos = config.xdg.userDirs.pictures;
- };
- };
-
- programs = {
- hyprlock = {
- enable = true;
- settings = {
- general = {
- hide_cursor = true;
- ignore_empty_input = true;
- };
-
- background = [{
- path = "/home/monke/pics/wall.jpg";
- blur_passes = 3;
- blur_size = 5;
- noise = 0.0117;
- contrast = 1.3000;
- brightness = 0.4000;
- vibrancy = 0.2100;
- vibrancy_darkness = 0.0;
- }];
-
- input-field = [{
- font_family = "Victor Mono Light";
- placeholder_text = "enter password...";
- rounding = 16;
- inner_color = "rgba(227,221,223,1.0)";
- check_color = "rgba(141,191,160,1.0)";
- fail_color = "rgba(177,92,102,1.0)";
- outline_thickness = 0;
- size = "500, 100";
- fade_on_empty = false;
- }];
-
- label = [
- {
- text = ''cmd[update:1000] echo " $(date +"%T") "'';
- color = "rgba(227,221,223,1.0)";
- font_size = 120;
- font_family = "Victor Mono Light";
-
- position = "0, -100";
- halign = "center";
- valign = "top";
- }
- {
- text = "cmd[update:60000] acpi | awk -F ', ' '{print $2}'";
- color = "rgba(227,221,223,1.0)";
- font_size = 40;
- font_family = "Victor Mono Light";
-
- position = "0, -300";
- halign = "center";
- valign = "top";
- }
- {
- text = ''cmd[update:1000] echo " $USER (up for $(go-uptime))"'';
- color = "rgb(227,221,223)";
- font_size = 18;
- font_family = "Victor Mono";
-
- position = "0, 100";
- halign = "center";
- valign = "bottom";
- }
- ];
- };
- };
- waybar = {
- enable = true;
- systemd.enable = true;
- settings = {
- bar = {
- layer = "overlay";
- position = "top";
- #exclusive = false;
-
- modules-left = [ "niri/workspaces" ];
- modules-center = [ "clock" ];
- modules-right = [
- "backlight"
- "battery"
- "wireplumber"
- "tray"
- ];
-
- backlight = {
- format = "{percent}% {icon}";
- format-icons = [ "" "" "" "" "" "" "" "" "" ];
- };
-
- battery = {
- adapter = "AC";
- states = {
-# good = 95;
- warning = 30;
- critical = 20;
- };
- format = "{capacity}% {icon}";
- format-charging = "{capacity}% ";
- format-plugged = "{capacity}% ";
- format-icons = [ "" "" "" "" "" "" "" "" "" "" ];
- };
-
- clock = {
- interval = 1;
- locale = "en_US.UTF-8";
-
- tooltip-format = "{:%Y %B}\n{calendar}";
-
- calendar = {
- mode = "year";
- mode-mon-col = 3;
- weeks-pos = "left";
- format = {
- today = "{}";
- weekdays = "{}";
- months = "{}";
- weeks = "W{}";
- days = "W{}";
- };
- };
- format = "{:%EX}";
- format-alt = "{:%F %A}";
- };
-
- "custom/easyeffects" = {
- exec = builtins.readFile ./files/waybar/easyeffects.sh;
- interval = 1;
- format = "{} ";
- tooltip = false;
- };
-
- mpd = {
- server = "/run/user/1000/mpd_socket";
- max-length = 55;
- interval = 1;
-
- format = "{artist} - {title} [{elapsedTime:%M:%S}/{totalTime:%M:%S}] ";
- format-disconnected = "disconnected [--:--] ";
- format-stopped = "[--:--] ";
-
- repeat-icons = {
- off = "-";
- on = "z";
- };
- single-icons = {
- off = "-";
- on = "s";
- };
- consume-icons = {
- off = "-";
- on = "c";
- };
- state-icons = {
- paused = "";
- playing = "";
- };
-
- tooltip-format = "status: [{repeatIcon}{randomIcon}{singleIcon}{consumeIcon}]";
- tooltip-format-disconnected = "MPD (disconnected)";
-
- on-click-right = "mpc toggle";
- };
-
- "niri/workspaces" = {
- format = "{icon}楼";
- current-only = true;
- format-icons = {
- "1" = "一";
- "2" = "二";
- "3" = "三";
- "4" = "四";
- "5" = "五";
- };
- };
-
- tray = {
- icon-size = 23;
- };
-
- wireplumber = {
- format = "{volume}% {icon} ";
- format-muted = "muted ";
- on-click = "easyeffects";
- format-icons = [ "" "" "" ];
- };
- };
- };
- style = builtins.readFile ./files/waybar/style.css;
- };
- wezterm = {
- enable = true;
- extraConfig = ''
- local wezterm = require("wezterm")
-
- local config = {}
-
- config.colors = {
- foreground = "#e3dddf",
- background = "#2e2629",
-
- cursor_fg = "#2e2629",
- cursor_bg = "#e3dddf",
- cursor_border = "#e3dddf",
-
- ansi = {
- "#272023",
- "#b15c66",
- "#54646c",
- "#e6daca",
- "#707880",
- "#6e4855",
- "#ad6b81",
- "#e3dddf"
- },
- brights = {
- "#47373c",
- "#b15c66",
- "#54646c",
- "#e6daca",
- "#707880",
- "#6e4855",
- "#ad6b81",
- "#e3dddf"
- }
- }
- -- config.line_height = 0.95
-
- config.font = wezterm.font_with_fallback {
- {
- family = 'Victor Mono'
- },
- {
- family = 'VictorMono Nerd Font',
- -- scale = 0.7
- },
- {
- family = 'Noto Serif CJK JP',
- weight = 'Light'
- }
- }
- config.font_size = 14
- config.window_decorations = "NONE"
-
- config.hide_tab_bar_if_only_one_tab = true
-
- config.default_cursor_style = "SteadyUnderline"
-
- config.use_fancy_tab_bar = false
- config.use_cap_height_to_scale_fallback_fonts = true
- config.tab_bar_at_bottom = true
-
- return config
- '';
- };
- wofi = {
- enable = true;
- settings = {
- show = "drun";
- width = 300;
- prompt = "type to search...";
- allow_images = true;
- insensitive = true;
- gtk_dark = true;
- image_size = 18;
- line_wrap = "word";
- };
- style = builtins.readFile ./files/wofi/style.css;
- };
- };
-
- services = {
- dunst = {
- enable = true;
- settings = {
- global = {
- follow = "mouse";
- enable_posix_regex = true;
- width = 450;
-
- origin = "top-right";
- offset = "8x8";
-
- frame_color = "#b15c66";
- background = "#2e2629";
- timeout = 10;
- frame_width = 2;
- corner_radius = 8;
- alignment = "center";
-
- font = "Victor Mono 9";
- format = "%a: %s\\n%b";
- show_age_threshold = 10;
-
- icon_corner_radius = 4;
- max_icon_size = 120;
-
- progress_bar_frame_width = 2;
- };
-
- urgency_critical = {
- timeout = 0;
- format = "%a: %s\\n%b";
- };
- };
- };
- };
-}
diff --git a/files/asahi-firmware/all_firmware.tar.gz b/files/asahi-firmware/all_firmware.tar.gz
new file mode 100644
--- /dev/null
+++ b/files/asahi-firmware/all_firmware.tar.gz
diff --git a/files/asahi-firmware/kernelcache.release.mac13j b/files/asahi-firmware/kernelcache.release.mac13j
new file mode 100644
--- /dev/null
+++ b/files/asahi-firmware/kernelcache.release.mac13j
diff --git a/files/calib-data.bin b/files/calib-data.bin
new file mode 100644
--- /dev/null
+++ b/files/calib-data.bin
diff --git a/files/eww/eww.scss b/files/eww/eww.scss
new file mode 100644
--- /dev/null
+++ b/files/eww/eww.scss
@@ -0,0 +1,2 @@
+@use "styles/notif-bar.scss";
+@use "styles/menu.scss";
diff --git a/files/eww/eww.yuck b/files/eww/eww.yuck
new file mode 100644
--- /dev/null
+++ b/files/eww/eww.yuck
@@ -0,0 +1,66 @@
+(include "./widgets/notifications.yuck")
+(include "./widgets/menu.yuck")
+
+(defpoll history :interval "1s"
+ :initial '[]'
+ :run-while notif-open
+ `dunstctl history | jq .data[]`)
+(defpoll uptime :interval "0.1s"
+ :initial '0.0'
+ :run-while {notif-open || menu-open}
+ `cut -d ' ' -f 1 /proc/uptime`)
+(defpoll pretty-uptime :interval "1s"
+ :run-while menu-open
+ `go-uptime`)
+(defpoll sv :interval "1s"
+ :initial '[]'
+ :run-while menu-open
+ `checkit`)
+
+(defpoll weather-info :interval "15s"
+ :initial "{}"
+ :run-while menu-open
+ `scripts/weather.sh current`)
+(defpoll weather-icons :interval "24h"
+ :initial "{}"
+ :run-while menu-open
+ `cat scripts/weather-icons.json`)
+
+(defpoll boxy :interval "20s"
+ :initial "[]"
+ :run-while menu-open
+ `boxy`)
+
+(defpoll mpd-art :interval "1s"
+ :initial ""
+ :run-while menu-open
+ `scripts/mpd.sh art`)
+(defpoll mpd-progress :interval "1s"
+ :initial ""
+ :run-while menu-open
+ `scripts/mpd.sh progress`)
+(defpoll mpd-time :interval "1s"
+ :initial "[--:--]"
+ :run-while menu-open
+ `scripts/mpd.sh time`)
+(defpoll mpd-album :interval "1s"
+ :run-while menu-open
+ `scripts/mpd.sh album`)
+(defpoll mpd-title :interval "1s"
+ :run-while menu-open
+ `mpc current -f '%title%'`)
+
+(defvar deck-selected 2)
+(defpoll deck-stacks :interval "2s"
+ :run-while {menu-open && menu-index == 1}
+ "scripts/deck.sh")
+
+(defvar notif-open false)
+(defvar menu-open false)
+
+(defvar menu-index 0)
+(defvar menu-transition "slideright")
+
+(defpoll xbps-outdated :interval "5m"
+ :run-while menu-open
+ `scripts/outdated.sh`)
diff --git a/files/eww/scripts/menu-opener.sh b/files/eww/scripts/menu-opener.sh
new file mode 100644
--- /dev/null
+++ b/files/eww/scripts/menu-opener.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+pkill -SIGUSR1 waybar
+case "$@" in
+ open)
+ eww update menu-open=true
+ eww open menu
+ ;;
+ close)
+ eww update menu-open=false
+ eww close menu
+ ;;
+ *)
+ ;;
+esac
diff --git a/files/eww/scripts/mpd.sh b/files/eww/scripts/mpd.sh
new file mode 100644
--- /dev/null
+++ b/files/eww/scripts/mpd.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+previewdir="${XDG_CACHE_HOME}/music_previews"
+album="$(mpc current -f %album%)"
+
+case "$@" in
+ art)
+ previewname="$previewdir/$(mpc --format %album% current | base64 -w 0).png"
+ if [ "$album" = "" ]; then
+ previewname="$previewdir/$(mpc -f '%artist% - %title%' current | base64 -w 0).png"
+ fi
+
+ echo "$previewname"
+ ;;
+ progress)
+ mpc status | grep "%)" | awk '{print $4}' | tr -d '(%)'
+ ;;
+ time)
+ printf "[%s]" "$(mpc | grep '%)' | awk '{print $3}')"
+ ;;
+ album)
+ if [ "$album" = "" ]; then
+ mpc current -f '%artist%'
+ else
+ mpc current -f '%albumartist% - %album%'
+ fi
+ ;;
+esac
diff --git a/files/eww/scripts/notif-opener.sh b/files/eww/scripts/notif-opener.sh
new file mode 100644
--- /dev/null
+++ b/files/eww/scripts/notif-opener.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+case "$@" in
+ open)
+ eww open notifbar
+ eww update notif-open=true
+ ;;
+ close)
+ eww update notif-open=false
+ eww close notifbar
+ dunstctl close-all
+ ;;
+ *)
+ ;;
+esac
diff --git a/files/eww/scripts/outdated.sh b/files/eww/scripts/outdated.sh
new file mode 100644
--- /dev/null
+++ b/files/eww/scripts/outdated.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+xbps-install -Mnu | grep -Fe update -e install -c
diff --git a/files/eww/scripts/switcher.sh b/files/eww/scripts/switcher.sh
new file mode 100644
--- /dev/null
+++ b/files/eww/scripts/switcher.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+INDEX="$(eww get menu-index)"
+
+case "$@" in
+ forward)
+ eww update menu-transition="slideleft"
+ [ $((INDEX)) -ne 1 ] && eww update menu-index="$((INDEX + 1))"
+ ;;
+ backward)
+ eww update menu-transition="slideright"
+ [ $((INDEX)) -ne 0 ] && eww update menu-index="$((INDEX - 1))"
+ ;;
+esac
diff --git a/files/eww/scripts/weather-icons.json b/files/eww/scripts/weather-icons.json
new file mode 100644
--- /dev/null
+++ b/files/eww/scripts/weather-icons.json
@@ -0,0 +1,102 @@
+{
+ "day": {
+ "1000": "",
+ "1003": "",
+ "1006": "",
+ "1009": "",
+ "1030": "",
+ "1063": "",
+ "1066": "",
+ "1069": "",
+ "1072": "",
+ "1087": "",
+ "1114": "",
+ "1117": "",
+ "1135": "",
+ "1147": "",
+ "1150": "",
+ "1153": "",
+ "1168": "",
+ "1171": "",
+ "1180": "",
+ "1183": "",
+ "1186": "",
+ "1189": "",
+ "1192": "",
+ "1195": "",
+ "1198": "",
+ "1201": "",
+ "1204": "",
+ "1207": "",
+ "1210": "",
+ "1213": "",
+ "1216": "",
+ "1219": "",
+ "1222": "",
+ "1225": "",
+ "1237": "",
+ "1240": "",
+ "1243": "",
+ "1246": "",
+ "1249": "",
+ "1252": "",
+ "1255": "",
+ "1258": "+",
+ "1261": "",
+ "1264": "",
+ "1273": "",
+ "1276": "",
+ "1279": "",
+ "1282": ""
+ },
+ "night": {
+ "1000": "",
+ "1003": "",
+ "1006": "",
+ "1009": "",
+ "1030": "",
+ "1063": "",
+ "1066": "",
+ "1069": "",
+ "1072": "",
+ "1087": "",
+ "1114": "",
+ "1117": "",
+ "1135": "",
+ "1147": "",
+ "1150": "",
+ "1153": "",
+ "1168": "",
+ "1171": "",
+ "1180": "",
+ "1183": "",
+ "1186": "",
+ "1189": "",
+ "1192": "",
+ "1195": "",
+ "1198": "",
+ "1201": "",
+ "1204": "",
+ "1207": "",
+ "1210": "",
+ "1213": "",
+ "1216": "",
+ "1219": "",
+ "1222": "",
+ "1225": "",
+ "1237": "",
+ "1240": "",
+ "1243": "",
+ "1246": "",
+ "1249": "",
+ "1252": "",
+ "1255": "",
+ "1258": "",
+ "1261": "",
+ "1264": "",
+ "1273": "",
+ "1276": "",
+ "1279": "",
+ "1282": ""
+ }
+}
diff --git a/files/eww/styles/menu.scss b/files/eww/styles/menu.scss
new file mode 100644
--- /dev/null
+++ b/files/eww/styles/menu.scss
@@ -0,0 +1,187 @@
+@use "vars.scss";
+
+.menu {
+ background-color: vars.$bg-trans;
+ color: vars.$fg;
+
+ font-family: vars.$fonts;
+}
+.menu-thing {
+ background-color: vars.$bg;
+ border-radius: 1em;
+ border: 0;
+ padding: 1em;
+ margin: 0.3em;
+}
+.menu-container {
+ background-color: rgba(0,0,0,0);
+ margin: 5em 8em 8em 8em;
+ border: 0;
+}
+
+.cpu-bar,
+.ram-bar,
+.disk-bar,
+.bat-bar{
+ trough {
+ min-width: 2em;
+ background-color: vars.$bg-dark;
+ border-radius: 20em;
+ highlight {
+ border-radius: 20em;
+ }
+ slider {
+ background-color: rgba(0,0,0,0);
+ border: 0;
+ }
+ }
+}
+.cpu-bar trough highlight {
+ background-color: vars.$red;
+}
+.ram-bar trough highlight {
+ background-color: vars.$brown;
+}
+.disk-bar trough highlight {
+ background-color: vars.$purple;
+}
+.bat-bar trough highlight {
+ background-color: vars.$green;
+}
+
+.weather-icon {
+ font-size: 12em;
+}
+.weather-temp {
+ font-size: 3em;
+}
+
+.screen-time-hm {
+ font-size: 3em;
+}
+
+.service {
+ margin-bottom: 1em;
+ border-radius: 1em;
+ border: 2px solid vars.$brown-3;
+ padding: 0.5em;
+}
+.service-button {
+ background-color: vars.$turquoise;
+ border-radius: 0.5em;
+ margin: 0.2em;
+ padding-bottom: 0.2em;
+
+ * {
+ font-size: 1.5em;
+ }
+}
+.service-button-down {
+ background-color: vars.$red;
+}
+.service-button-up {
+ background-color: vars.$green;
+}
+
+.power {
+ padding: 0em 5.75em 0em 3.5em;
+}
+.power-icon {
+ font-size: 8em;
+}
+.power-logout {
+ background-color: vars.$purple;
+}
+.power-sleep {
+ background-color: vars.$brown;
+}
+.power-shutdown {
+ background-color: vars.$red;
+}
+.power-reboot {
+ background-color: vars.$turquoise;
+}
+.power-lock {
+ background-color: vars.$grey;
+}
+
+.email {
+ margin-bottom: 1em;
+ border-radius: 1em;
+ border: 2px solid vars.$brown-3;
+ padding: 1em;
+}
+.email-subject {
+ font-size: 1.3em;
+}
+.email-body {
+ font-style: italic;
+ color: #898284;
+}
+.email-date {
+ color: vars.$brown-3;
+}
+
+.quotes-body {
+ font-style: italic;
+ font-size: 1.5em;
+}
+
+.mpd-art {
+ border-radius: 0.6em;
+ background-repeat: no-repeat;
+}
+.mpd-progress-bar {
+ trough {
+ min-height: 1em;
+ background-color: vars.$bg-dark;
+ border-radius: 2em;
+ highlight {
+ background-color: vars.$purple;
+ border-radius: 20em;
+ }
+ slider {
+ background-color: rgba(0,0,0,0);
+ border: 0;
+ }
+ }
+}
+.mpd-title {
+ font-size: 1.5em;
+ font-style: italic;
+}
+
+.outdated-pkgs-count {
+ font-size: 2em;
+}
+
+.deck-stack-title {
+ font-size: 2em;
+ font-style: italic;
+ margin-bottom: 0.5em;
+}
+.deck-card {
+ margin-bottom: 1em;
+ border-radius: 1em;
+ border: 2px solid vars.$brown-3;
+ padding: 1em;
+}
+.deck-card-overdue {
+ border: 2px solid vars.$red;
+}
+.deck-card-done {
+ border: 2px solid vars.$green;
+}
+.deck-card-id {
+ color: vars.$brown-3;
+}
+.deck-card-title {
+ font-size: 1.3em;
+}
+.deck-card-tags {
+ color: vars.$brown-3;
+}
+
+.deck-duedate-overdue {
+ color: vars.$red;
+}
diff --git a/files/eww/styles/notif-bar.scss b/files/eww/styles/notif-bar.scss
new file mode 100644
--- /dev/null
+++ b/files/eww/styles/notif-bar.scss
@@ -0,0 +1,41 @@
+@use "vars.scss";
+
+.notifbar {
+ background-color: vars.$bg-dark;
+ color: vars.$fg;
+
+ font-family: vars.$fonts;
+ margin: 1em 1em 1em 1em;
+ border-radius: 1em;
+}
+
+.notif-text {
+ padding: 0.6em;
+ .title {
+ font-size: 1.3em;
+ margin: 0em;
+ }
+ .body {
+ font-size: 11px;
+ margin: 0em;
+ }
+}
+.notif {
+ margin: 1em 1em 0em 1em;
+ border-radius: 1em;
+ border: 2px solid vars.$red;
+}
+.notif:last-child {
+ margin: 1em;
+}
+
+.notif-bar-title {
+ font-size: 2em;
+ font-style: italic;
+ padding: 0.5em;
+}
+
+.notif-titlebar-x {
+ color: vars.$red;
+ font-size: 3em;
+}
diff --git a/files/eww/styles/vars.scss b/files/eww/styles/vars.scss
new file mode 100644
--- /dev/null
+++ b/files/eww/styles/vars.scss
@@ -0,0 +1,16 @@
+$bg: rgba(46, 38, 41, 1);
+$bg-dark: #272023;
+$bg-dark-trans: rgba(46, 38, 41, 0.5);
+$bg-trans: rgba(227, 221, 223, 0.3);
+$fg: #e3dddf;
+
+$fonts: "VictorMono Nerd Font", "Noto Sans CJK JP", "Victor Mono";
+$red: #b15c66;
+$green: #8dbfa0;
+$purple: #9c9cb7;
+$brown: #b79fa8;
+$brown-2: #99858b;
+$brown-3: #6d595f;
+$yellow: #e6daca;
+$turquoise: #5b8681;
+$grey: #707880;
diff --git a/files/eww/widgets/menu.yuck b/files/eww/widgets/menu.yuck
new file mode 100644
--- /dev/null
+++ b/files/eww/widgets/menu.yuck
@@ -0,0 +1,362 @@
+(defwindow menu
+ :monitor 0
+ :geometry (geometry :width "100%"
+ :height "100%"
+ :anchor "bottom center")
+ :stacking "overlay"
+ (box :orientation "vertical"
+ :class "menu-container"
+ :space-evenly false
+ (switcher)
+ (box :vexpand true
+ (stack :selected menu-index
+ :transition menu-transition
+ (menu-0)
+ (menu-1)))))
+
+(defwidget menu-0 []
+ (box :space-evenly false
+ :vexpand true
+ (box :orientation "vertical"
+ :space-evenly false
+ :width 370
+ (usage)
+ (screen-time)
+ (outdated-pkgs)
+ (services))
+ (box :hexpand true
+ :space-evenly false
+ (box :orientation "vertical"
+ :space-evenly false
+ (weather)
+ (quotes)
+ (mpd))
+ (box :orientation "vertical"
+ :hexpand true
+ (emails)
+ (rss)))
+ (box :orientation "vertical"
+ (power-button :command "hyprctl dispatch exit"
+ :class "power power-logout"
+ :icon "")
+ (power-button :command "doas zzz"
+ :class "power power-sleep"
+ :icon "")
+ (power-button :command "doas poweroff"
+ :class "power power-shutdown"
+ :icon "")
+ (power-button :command "doas reboot"
+ :class "power power-reboot"
+ :icon "")
+ (power-button :command "hyprlock"
+ :class "power power-lock"
+ :icon ""))))
+
+(defwidget menu-1 []
+ (deck))
+
+(defwidget deck []
+ (scroll
+ (box :vexpand true
+ :space-evenly false
+ (for item in deck-stacks
+ (deck-stack :name {item.title}
+ :cards {item.cards})))))
+
+(defwidget deck-stack [name cards]
+ (box :class "menu-thing"
+ :width 400
+ :orientation "vertical"
+ :space-evenly false
+ :hexpand false
+ (label :class "deck-stack-title"
+ :text name)
+ (scroll :hscroll false
+ :vscroll true
+ :vexpand true
+ (box :orientation "vertical"
+ :space-evenly false
+ (for item in cards
+ (deck-card :title {item.title}
+ :id {item.id}
+ :tags {item.labels}
+ :duedate {item.duedate}
+ :done {item.done}))))))
+
+(defwidget deck-card [title id tags duedate done]
+ (box :class `deck-card${done == 0 && duedate != 0 && duedate < EWW_TIME ? " deck-card-overdue" : ""}${done != 0 ? " deck-card-done" : ""}`
+ :orientation `${tags == "" ? "horizontal" : "vertical"}`
+ :space-evenly false
+ (box :space-evenly false
+ :hexpand true
+ :orientation "horizontal"
+ (label :class "deck-card-title"
+ :markup `${title}`)
+ (label :hexpand true)
+ (label :class "deck-card-id"
+ :text "#${id}"))
+ (box :space-evenly false
+ :class "deck-card-tags"
+ (label :text `${tags != "" ? " "+tags : "" }`
+ :limit-width 25
+ :truncate true
+ :tooltip tags)
+ (label :hexpand true)
+ (label :markup `${duedate != 0 ? formattime(duedate, "%FT%T") : "" }`
+ :class `${duedate != 0 && duedate < EWW_TIME ? "deck-duedate-overdue" : ""}`))))
+
+(defwidget switcher []
+ (box :space-evenly false
+ (eventbox :onclick `scripts/switcher.sh backward`
+ (box :class "menu-thing"
+ "prev"))
+ (eventbox :onclick `scripts/switcher.sh forward`
+ (box :class "menu-thing"
+ "next"))))
+
+(defwidget power-button [command icon class]
+ (eventbox :onrightclick command
+ (box :class "menu-thing ${class}"
+ (label :text icon
+ :class "power-icon"))))
+
+(defwidget screen-time []
+ (box :class "menu-thing"
+ :orientation "vertical"
+ :space-evenly false
+ (label :text ` ${pretty-uptime}`
+ :class "screen-time-hm")
+ (label :text "up ${round(uptime, 1)}s")))
+
+(defwidget usage []
+ (box :class "menu-thing"
+ :height 300
+ (box :orientation "vertical"
+ :space-evenly false
+ (scale :orientation "vertical"
+ :class "cpu-bar"
+ :vexpand true
+ :active false
+ :flipped true
+ :tooltip "${round(EWW_CPU.avg,0)}%"
+ :value "${EWW_CPU.avg}")
+ (label :text "cpu"))
+ (box :orientation "vertical"
+ :space-evenly false
+ (scale :orientation "vertical"
+ :class "ram-bar"
+ :vexpand true
+ :active false
+ :flipped true
+ :tooltip "${round(EWW_RAM.used_mem_perc,0)}%, ${round(EWW_RAM.free_mem/1048576000, 1)} G free"
+ :value "${EWW_RAM.used_mem_perc}")
+ (label :text "ram"))
+ (box :orientation "vertical"
+ :space-evenly false
+ (scale :orientation "vertical"
+ :class "disk-bar"
+ :vexpand true
+ :active false
+ :flipped true
+ :tooltip "${round(EWW_DISK['/'].free/1048576000,3)} G free"
+ :value "${EWW_DISK['/'].used_perc}")
+ (label :text "disk"))
+ (box :orientation "vertical"
+ :space-evenly false
+ (scale :orientation "vertical"
+ :class "bat-bar"
+ :vexpand true
+ :active false
+ :flipped true
+ :tooltip "${round(EWW_BATTERY.total_avg,0)}% (${EWW_BATTERY.macsmc-battery.status})"
+ :value "${EWW_BATTERY.total_avg}")
+ (label :text "bat"))))
+
+(defwidget services []
+ (box :class "menu-thing"
+ :vexpand true
+ (scroll :hscroll false
+ :vexpand true
+ :vscroll true
+ (box :orientation "vertical"
+ :space-evenly false
+ (for item in sv
+ (service :stat {item.stat}
+ :name {item.name}
+ :pid {item.pid}
+ :up {item.up}))))))
+
+(defwidget service [stat name pid up]
+ (box :space-evenly false
+ :class "service"
+ (box :orientation "vertical"
+ :hexpand true
+ (label :class "service-name"
+ :text name)
+ (label :text `${stat == "run" ? "pid ${pid} up for ${up}s" : "down"}`))
+ (box :orientation "vertical"
+ (eventbox :onrightclick `sv ${stat == "run" ? "down" : "up"} ${name}`
+ (box :class `service-button service-button-${stat == "run" ? "down" : "up"}`
+ (label :text `${stat == "run" ? "" : ""}`
+ :gravity "west")))
+ (eventbox :onrightclick `sv restart ${name}`
+ (box :class "service-button"
+ (label :text ""
+ :gravity "west"))))))
+
+(defwidget emails []
+ (box :class "menu-thing"
+ :orientation "vertical"
+ :hexpand true
+ :space-evenly false
+ (scroll :hscroll false
+ :vexpand {arraylength(boxy) != 0}
+ :vscroll true
+ (box :orientation "vertical"
+ :space-evenly false
+ (for item in boxy
+ (email :date {item.date}
+ :subject {item.subject}
+ :from {item.from}
+ :body {item.body}))))
+ (label :text {arraylength(boxy) == 0 ? "no emails to see here!" : ""})))
+
+(defwidget rss []
+ (box :class "menu-thing"
+ "rss, maybe?"))
+
+
+(defwidget email [date subject from body]
+ (box :orientation "vertical"
+ :class "email"
+ :space-evenly false
+ (box :space-evenly false
+ (box :hexpand true
+ :space-evenly false
+ (label :text subject
+ :class "email-subject"
+ :tooltip subject
+ :truncate true)
+ (label))
+ (label :text `${formattime(date, "%FT%T")}`
+ :class "email-date"))
+ (box :space-evenly false
+ (label :text " ${from}")
+ (label))
+ (label)
+ (label :text body
+ :class "email-body"
+ :wrap true
+ :limit-width 30)))
+
+(defwidget weather []
+ (box :class "menu-thing"
+ :vexpand false
+ :width 500
+ (box
+ (label :text `${weather-icons[weather-info.current.is_day == 1 ? "day" : "night"][weather-info.current.condition.code]}`
+ :class "weather-icon"
+ :tooltip "${weather-info.current.condition.text}")
+ (box :orientation "vertical"
+ :vexpand true
+ (box :orientation "vertical"
+ :space-evenly false
+ (label :text " ${round(weather-info.current.temp_c,0)}°C"
+ :class "weather-temp"
+ :tooltip "Feels like ${weather-info.current.feelslike_c}°C")
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${round(weather-info.forecast.forecastday[0].day.maxtemp_c,0)}°C")
+ (label :hexpand true)))
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${round(weather-info.forecast.forecastday[0].day.mintemp_c,0)}°C")
+ (label :hexpand true)))
+ (label)
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${round(weather-info.current.wind_kph/3.6,1)} m/s"
+ :tooltip "@ ${weather-info.current.wind_degree}°")
+ (label :hexpand true)))
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${weather-info.current.humidity}%")
+ (label :hexpand true)))
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${weather-info.current.uv}")
+ (label :hexpand true)))
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${weather-info.forecast.forecastday[0].day.daily_chance_of_rain}%"
+ :tooltip "${weather-info.current.precip_mm} mm")
+ (label :hexpand true)))
+ (box
+ (box :space-evenly false
+ (label :hexpand true)
+ (label :text " "))
+ (box :space-evenly false
+ (label :text "${weather-info.forecast.forecastday[0].day.air_quality.us-epa-index}"
+ :tooltip "Carbon monoxide: ${round(weather-info.forecast.forecastday[0].day.air_quality.co,0)} ppm
+ Nitrogen dioxide: ${round(weather-info.forecast.forecastday[0].day.air_quality.no2,0)} ppm
+ Ozone: ${round(weather-info.forecast.forecastday[0].day.air_quality.o3,0)} ppm
+ Sulphur dioxide: ${round(weather-info.forecast.forecastday[0].day.air_quality.so2,0)} ppm")
+ (label :hexpand true))))))))
+
+(defwidget quotes []
+ (box :class "menu-thing"
+ :orientation "vertical"
+ (label :text "\"girls kissing? WHERE ?!!!\""
+ :class "quotes-body")
+ (label :text "- Aaron")))
+
+(defwidget outdated-pkgs[]
+ (eventbox :onclick "wezterm start cpm U"
+ (box :class "menu-thing"
+ (label :text ` ${xbps-outdated == 0 ? "up to date" : xbps-outdated}`
+ :class "outdated-pkgs-count"))))
+
+(defwidget mpd []
+ (box :class "menu-thing"
+ :orientation "vertical"
+ :vexpand true
+ :space-evenly false
+ :spacing 10
+ :width 500
+ (box :class "mpd-art" :style "background-image: url('${mpd-art}');"
+ :height 500)
+ (box :orientation "vertical"
+ :width 500
+ :vexpand true
+ :space-evenly false
+ (scale :value mpd-progress
+ :class "mpd-progress-bar"
+ :active false
+ :tooltip mpd-time)
+ (label :text mpd-title
+ :width 500
+ :class "mpd-title"
+ :limit-width 10
+ :wrap true)
+ (label :text mpd-album
+ :width 500
+ :limit-width 10
+ :wrap true))))
diff --git a/files/eww/widgets/notifications.yuck b/files/eww/widgets/notifications.yuck
new file mode 100644
--- /dev/null
+++ b/files/eww/widgets/notifications.yuck
@@ -0,0 +1,50 @@
+(defwindow notifbar
+ :monitor 0
+ :geometry (geometry :width "23%"
+ :height "100%"
+ :anchor "right center")
+ :stacking "overlay"
+ :exclusive true
+ (box :orientation "vertical"
+ :space-evenly false
+ (notif-titlebar :items history)
+ (scroll :hscroll false
+ :vexpand true
+ :vscroll true
+ (box :orientation "vertical"
+ :space-evenly false
+ (for item in history
+ (notif :appname "${item.appname.data}"
+ :summary "${item.summary.data}"
+ :body "${item.body.data}"
+ :time "${item.timestamp.data}"))))))
+
+(defwidget notif-titlebar [items]
+ (eventbox :onclick "dunstctl history-clear"
+ :tooltip "Click to clear ${jq(items, 'length')} notification(s)"
+ :hexpand true
+ (label :class "notif-bar-title"
+ :hexpand true
+ :text "Notifications (${jq(items, 'length')})"
+ :halign "center")))
+
+
+(defwidget notif [appname summary body time]
+ (box :class "notif"
+ :hexpand false
+ (box :orientation "vertical"
+ :class "notif-text"
+ :halign "center"
+ :tooltip "${round(uptime - time / 1000000, 0)}s ago"
+ (label :class "title"
+ :height 0
+ :hexpand true
+ :justify "center"
+ :text "${appname}: ${summary}")
+ (label :class "body"
+ :height 0
+ :hexpand true
+ :justify "center"
+ :wrap true
+ :text body))))
+
diff --git a/files/forest.pem b/files/forest.pem
new file mode 100644
--- /dev/null
+++ b/files/forest.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGETCCA/mgAwIBAgIBADANBgkqhkiG9w0BAQ0FADB8MQswCQYDVQQGEwJBVTER
+MA8GA1UECAwIVmljdG9yaWExEjAQBgNVBAcMCU1lbGJvdXJuZTEVMBMGA1UECgwM
+U29tZSBNb25rZXJzMR4wHAYJKoZIhvcNAQkBFg9tb25rZUBtb25rZS5tb2UxDzAN
+BgNVBAMMBmZvcmVzdDAeFw0yNTA4MTkwMzI3MjJaFw0zNTA4MTcwMzI3MjJaMHwx
+CzAJBgNVBAYTAkFVMREwDwYDVQQIDAhWaWN0b3JpYTESMBAGA1UEBwwJTWVsYm91
+cm5lMRUwEwYDVQQKDAxTb21lIE1vbmtlcnMxHjAcBgkqhkiG9w0BCQEWD21vbmtl
+QG1vbmtlLm1vZTEPMA0GA1UEAwwGZm9yZXN0MIICIjANBgkqhkiG9w0BAQEFAAOC
+Ag8AMIICCgKCAgEAlgnJrRB5olypsmBJSn2a8fefk4tCliadnTZKyCAe/St4WHRc
+9Hsyr2vA0aPm3KL7ESVnLv1iQJ0tKeS2BkpUUU3c80ZylrfeRW5dTFP3vDpnP/a5
+BGQIMR8UjHdu+B2rHJqisVV9XdUA18ggldNzrFPFwbV9MZOyWlWzzq5f878AcP2A
+X2eAh9ztmZAT1PAv/hDX3cgNLPXGZN34yYZ2TFLXH5Fsayecox8Tc79hZUpigDeX
+GwWz/LS1rFVur9BFKA6Mh4YOSzm7XNg60zesBak1+b2qxy3tK2hooKM+KDFbKJx0
+tiDwGAqF9fYkP7mDy4WxMA+zLU8TpK8XKPU8eqWd1GbSOM7JhAJEo7yMPCmr0OzL
+K9t94l6OWUe9Ny/vukFygaZYIWutVd00+KIVtMCAYpvf3r0o8Lpvgtyds0xGQre4
+f70KWeHbN4UexkYZLqK1+ezWff5iHWVq7gKCugWM2YJ7KjjnW0rgJrjVrZeqTNPe
+RTuOWfJRN6uSB4p7vcEGeAKdLNN5rhoB99EQXkXBiAnrSEOKBqLsGtuxiOR3Usly
+Kc254wBX18N1xdx0jNIPso9CBWha38JgnnULr/pytEEUxN4ictn5oQSRKWuagzkW
+n/rBWPoxOuyJkEMXzrCGVvLzyJITBkdlq4Bc+UnlGHhUHYhMDFs417Q2/8UCAwEA
+AaOBnTCBmjA3BglghkgBhvhCAQ0EKhYoT1BOc2Vuc2UgR2VuZXJhdGVkIENlcnRp
+ZmljYXRlIEF1dGhvcml0eTAdBgNVHQ4EFgQUuL0yVPGlli6MbSrfyzK+fW5y1vcw
+HwYDVR0jBBgwFoAUuL0yVPGlli6MbSrfyzK+fW5y1vcwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQENBQADggIBAEhHOXRzJIXPZWAR
+lCeLKUIrqtzGNJwJHWVgIpUUkPMKHGGWUb8RRlesMvqlvBPgnIgwSNFzAODcZdxb
+Tzf8qPzW6kEFCNB/VbhtOv1rejUa/z2jhKV8dkBQOt/cgwXNoWtnizA7zj+EkvUg
+82N+JgpU9pAi3SIjeHku+1hMnMLxwPCI5Yd/I6lTPAisuuUEOHQAEZEF7VCEiBnW
+s5QEbfarjfMB3ookdoN+ptWMAJ2PhR8zBcozVZspo/8zijllgQEzzNKMHFIEspAA
+FjceK5ozbSKMd7yQlO9yPmcPz+IPtcEErqGuNdvE/uyBJIR1phU8lT7Fc5c4B2Id
+1m3qFwsOQ4sqhHf277vVKQHQ468T5jEncuvUA5WUIZAGkshHrJg4AeAfvKsOY5oa
+9QxL9qlgjq3AXr9LMNpGZSg1FXf5LrscKa8zTX35Rd088ftpCb0gzeQiya5JdP6m
+ZYz3Os4Gf9e8nV+HjdgrG+vrCqJjGR3wx7tFpDGK3nYKFo0pPiisFUOkg/F4Y+H8
+NokmwmflE/QzO7+ozctwq4oBE2JlWIaZwBoz3SOHshWyqO9gRP4n7z5ccy87UWhX
+dpHfoYBrnXjVlYuzuPxhD8O9hHKx9CHlFcM7MiFnS4AH5AMRBO04Vy9acDFJq04d
+hXvxdaiNkLMJZO/fYhvcT5vJUWEK
+-----END CERTIFICATE-----
diff --git a/files/waybar/style.css b/files/waybar/style.css
--- a/files/waybar/style.css
+++ b/files/waybar/style.css
@@ -62,3 +62,7 @@ border-radius: 2em;
padding: 0 1em;
margin-left: 0.4em;
}
+
+#clock {
+ min-width: 15em;
+}
diff --git a/files/wezterm/wezterm.lua b/files/wezterm/wezterm.lua
new file mode 100644
--- /dev/null
+++ b/files/wezterm/wezterm.lua
@@ -0,0 +1,61 @@
+
+local wezterm = require("wezterm")
+
+local config = {}
+
+config.colors = {
+ foreground = "#e3dddf",
+ background = "#2e2629",
+
+ cursor_fg = "#2e2629",
+ cursor_bg = "#e3dddf",
+ cursor_border = "#e3dddf",
+
+ ansi = {
+ "#272023",
+ "#b15c66",
+ "#54646c",
+ "#e6daca",
+ "#707880",
+ "#6e4855",
+ "#ad6b81",
+ "#e3dddf"
+ },
+ brights = {
+ "#47373c",
+ "#b15c66",
+ "#54646c",
+ "#e6daca",
+ "#707880",
+ "#6e4855",
+ "#ad6b81",
+ "#e3dddf"
+ }
+}
+-- config.line_height = 0.95
+
+config.font = wezterm.font_with_fallback {
+ {
+ family = 'Victor Mono'
+ },
+ {
+ family = 'VictorMono Nerd Font',
+ -- scale = 0.7
+ },
+ {
+ family = 'Noto Serif CJK JP',
+ weight = 'Light'
+ }
+}
+config.font_size = 14
+config.window_decorations = "NONE"
+
+config.hide_tab_bar_if_only_one_tab = true
+
+config.default_cursor_style = "SteadyUnderline"
+
+config.use_fancy_tab_bar = false
+config.use_cap_height_to_scale_fallback_fonts = true
+config.tab_bar_at_bottom = true
+
+return config
diff --git a/files/wofi/style.css b/files/wofi/style.css
--- a/files/wofi/style.css
+++ b/files/wofi/style.css
@@ -1,5 +1,5 @@
* {
- border-radius: 0;
+ border-radius: 16;
}
#outer-box {
diff --git a/flake.lock b/flake.lock
--- a/flake.lock
+++ b/flake.lock
@@ -1,5 +1,62 @@
{
"nodes": {
+ "disko": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1746728054,
+ "narHash": "sha256-eDoSOhxGEm2PykZFa/x9QG5eTH0MJdiJ9aR00VAofXE=",
+ "owner": "nix-community",
+ "repo": "disko",
+ "rev": "ff442f5d1425feb86344c028298548024f21256d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "ref": "latest",
+ "repo": "disko",
+ "type": "github"
+ }
+ },
+ "finge": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1757592798,
+ "narHash": "sha256-jxp4zSSjg2M3xUHdngj9xjryPtKtgDOcGrvJFd5lvqo=",
+ "owner": "monke0192",
+ "repo": "nixos-06cb-009a-fingerprint-sensor",
+ "rev": "32f5313ffd1e7491b8d9fe82f1d2ab17c8c08f2b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "monke0192",
+ "ref": "unstable",
+ "repo": "nixos-06cb-009a-fingerprint-sensor",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "locked": {
+ "lastModified": 1746162366,
+ "narHash": "sha256-5SSSZ/oQkwfcAz/o/6TlejlVGqeK08wyREBQ5qFFPhM=",
+ "owner": "nix-community",
+ "repo": "flake-compat",
+ "rev": "0f158086a2ecdbb138cd0429410e44994f1b7e4b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -7,11 +64,11 @@ "nixpkgs"
]
},
"locked": {
- "lastModified": 1752373701,
- "narHash": "sha256-d0d7y9gjv9HU0Amws6kHJucR8bxrQ0PfVKxt2ll5cfs=",
+ "lastModified": 1758810399,
+ "narHash": "sha256-bpWoE1tiFX5T1tr5EudkpW9Kk02XR+6olkoSkf3nHZU=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "fc25398450cdab61af9654928dfef9d101f51140",
+ "rev": "39d26c16866260eee6d0487fe9c102ba1c1bf7b2",
"type": "github"
},
"original": {
@@ -25,17 +82,19 @@ "niri": {
"inputs": {
"niri-stable": "niri-stable",
"niri-unstable": "niri-unstable",
- "nixpkgs": "nixpkgs",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
"nixpkgs-stable": "nixpkgs-stable",
"xwayland-satellite-stable": "xwayland-satellite-stable",
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
},
"locked": {
- "lastModified": 1752400452,
- "narHash": "sha256-zXQhbc4LJBGt9axU9nkE3pk5V8BJhht+7jxqXEHPydU=",
+ "lastModified": 1758818425,
+ "narHash": "sha256-mNtae7u7vYOlj8kUD1nschvL33HPeEFl0WVI9DwiLDA=",
"owner": "sodiboo",
"repo": "niri-flake",
- "rev": "f1d0ad839764f9c50089bb069e9ad7b9c96b70d6",
+ "rev": "062a8edd61960989f518d41cbbb9bd57d1d128da",
"type": "github"
},
"original": {
@@ -47,16 +106,16 @@ },
"niri-stable": {
"flake": false,
"locked": {
- "lastModified": 1748151941,
- "narHash": "sha256-z4viQZLgC2bIJ3VrzQnR+q2F3gAOEQpU1H5xHtX/2fs=",
+ "lastModified": 1756556321,
+ "narHash": "sha256-RLD89dfjN0RVO86C/Mot0T7aduCygPGaYbog566F0Qo=",
"owner": "YaLTeR",
"repo": "niri",
- "rev": "8ba57fcf25d2fc9565131684a839d58703f1dae7",
+ "rev": "01be0e65f4eb91a9cd624ac0b76aaeab765c7294",
"type": "github"
},
"original": {
"owner": "YaLTeR",
- "ref": "v25.05.1",
+ "ref": "v25.08",
"repo": "niri",
"type": "github"
}
@@ -64,11 +123,11 @@ },
"niri-unstable": {
"flake": false,
"locked": {
- "lastModified": 1752396239,
- "narHash": "sha256-7XSHUPkEQRgoDjgndcW98LpDeff014UEhHVNyIjPHv0=",
+ "lastModified": 1758691861,
+ "narHash": "sha256-CYgoGrY/Fx+hjzp8graTxJw1M7mn1f2jBkK26M04T0s=",
"owner": "YaLTeR",
"repo": "niri",
- "rev": "ce9ba00d54104f250f0074a54f14d1a5e4ff427f",
+ "rev": "e837e39623457dc5ad29c34a5ce4d4616e5fbf1e",
"type": "github"
},
"original": {
@@ -77,74 +136,104 @@ "repo": "niri",
"type": "github"
}
},
- "nixpkgs": {
+ "nixos-apple-silicon": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
"locked": {
- "lastModified": 1751984180,
- "narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
+ "lastModified": 1758525110,
+ "narHash": "sha256-iEF0aG6df4NjPV88uqwAph/WujIabENZabS7C9Ljf0A=",
+ "owner": "nix-community",
+ "repo": "nixos-apple-silicon",
+ "rev": "9eb8ad09af823be7088dcfa908071e71cc19359a",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-unstable",
- "repo": "nixpkgs",
+ "owner": "nix-community",
+ "ref": "main",
+ "repo": "nixos-apple-silicon",
"type": "github"
}
},
- "nixpkgs-stable": {
+ "nixpkgs": {
"locked": {
- "lastModified": 1752162966,
- "narHash": "sha256-3MxxkU8ZXMHXcbFz7UE4M6qnIPTYGcE/7EMqlZNnVDE=",
- "owner": "NixOS",
+ "lastModified": 1758736440,
+ "narHash": "sha256-ssTkeaADdxhQl8y1ByejG5TlYakYElAIRhxnfYoQTRk=",
+ "owner": "nixos",
"repo": "nixpkgs",
- "rev": "10e687235226880ed5e9f33f1ffa71fe60f2638a",
+ "rev": "2cd3cac16691a933e94276f0a810453f17775c28",
"type": "github"
},
"original": {
- "owner": "NixOS",
- "ref": "nixos-25.05",
+ "owner": "nixos",
+ "ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
- "nixpkgs_2": {
+ "nixpkgs-stable": {
"locked": {
- "lastModified": 1751984180,
- "narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
- "owner": "nixos",
+ "lastModified": 1758589230,
+ "narHash": "sha256-zMTCFGe8aVGTEr2RqUi/QzC1nOIQ0N1HRsbqB4f646k=",
+ "owner": "NixOS",
"repo": "nixpkgs",
- "rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
+ "rev": "d1d883129b193f0b495d75c148c2c3a7d95789a0",
"type": "github"
},
"original": {
- "owner": "nixos",
- "ref": "nixos-unstable",
+ "owner": "NixOS",
+ "ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
+ "disko": "disko",
+ "finge": "finge",
"home-manager": "home-manager",
"niri": "niri",
- "nixpkgs": "nixpkgs_2"
+ "nixos-apple-silicon": "nixos-apple-silicon",
+ "nixpkgs": "nixpkgs",
+ "sops-nix": "sops-nix"
+ }
+ },
+ "sops-nix": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1758425756,
+ "narHash": "sha256-L3N8zV6wsViXiD8i3WFyrvjDdz76g3tXKEdZ4FkgQ+Y=",
+ "owner": "Mic92",
+ "repo": "sops-nix",
+ "rev": "e0fdaea3c31646e252a60b42d0ed8eafdb289762",
+ "type": "github"
+ },
+ "original": {
+ "owner": "Mic92",
+ "repo": "sops-nix",
+ "type": "github"
}
},
"xwayland-satellite-stable": {
"flake": false,
"locked": {
- "lastModified": 1748488455,
- "narHash": "sha256-IiLr1alzKFIy5tGGpDlabQbe6LV1c9ABvkH6T5WmyRI=",
+ "lastModified": 1755491097,
+ "narHash": "sha256-m+9tUfsmBeF2Gn4HWa6vSITZ4Gz1eA1F5Kh62B0N4oE=",
"owner": "Supreeeme",
"repo": "xwayland-satellite",
- "rev": "3ba30b149f9eb2bbf42cf4758d2158ca8cceef73",
+ "rev": "388d291e82ffbc73be18169d39470f340707edaa",
"type": "github"
},
"original": {
"owner": "Supreeeme",
- "ref": "v0.6",
+ "ref": "v0.7",
"repo": "xwayland-satellite",
"type": "github"
}
@@ -152,11 +241,11 @@ },
"xwayland-satellite-unstable": {
"flake": false,
"locked": {
- "lastModified": 1752338000,
- "narHash": "sha256-Fxlp/yKtynug0jyuauAmvZU2SzHCfwlwWf85j+IvQ0U=",
+ "lastModified": 1758577423,
+ "narHash": "sha256-sB2GAOjhjoWnjU6A/uHNJiY6O3UeztV5pJAN2g1FkXU=",
"owner": "Supreeeme",
"repo": "xwayland-satellite",
- "rev": "ba78881a68182ce338041846164cbfed0d70935c",
+ "rev": "03368548ba745e17a85bd631613a59cb2d8469a4",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
--- a/flake.nix
+++ b/flake.nix
@@ -1,36 +1,102 @@
{
- description = "Home Manager configuration of monke";
-
- inputs = {
- nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
- home-manager = {
- url = "github:nix-community/home-manager/master";
- inputs.nixpkgs.follows = "nixpkgs";
- };
- niri.url = "github:sodiboo/niri-flake";
-#wezterm.url = "github:wezterm/wezterm?dir=nix";
- };
+ description = "monke's configs";
- outputs = inputs @ { nixpkgs, home-manager, niri, ... }:
- let
- pkgs = import nixpkgs {
- system = "aarch64-linux";
- overlays = [
- niri.overlays.niri
- ];
- };
- in {
- homeConfigurations."monke" = home-manager.lib.homeManagerConfiguration {
- inherit pkgs;
+ inputs = {
+ disko = {
+ url = "github:nix-community/disko/latest";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ home-manager = {
+ url = "github:nix-community/home-manager/master";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ niri = {
+ url = "github:sodiboo/niri-flake";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nixos-apple-silicon = {
+ url = "github:nix-community/nixos-apple-silicon/main";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small";
+ sops-nix = {
+ url = "github:Mic92/sops-nix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ finge = {
+ url = "github:monke0192/nixos-06cb-009a-fingerprint-sensor?ref=unstable";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ };
- modules = [
- ./home.nix
- niri.homeModules.niri
- ];
+ outputs =
+ inputs@{ nixpkgs, ... }:
+ let
+ forArchs = nixpkgs.lib.genAttrs [
+ "aarch64-linux"
+ "x86_64-linux"
+ ];
+ systems = {
+ bathtub = {
+ system = "aarch64-linux";
+ extraModules = [
+ inputs.nixos-apple-silicon.nixosModules.apple-silicon-support
+ inputs.niri.nixosModules.niri
+ ];
+ };
+ forest = {
+ system = "x86_64-linux";
+ extraModules = [ ];
+ };
+ tundra = {
+ system = "x86_64-linux";
+ extraModules = [
+ inputs.niri.nixosModules.niri
+ inputs.finge.nixosModules."06cb-009a-fingerprint-sensor"
+ ];
+ };
+ };
+ in
+ {
+ formatter = forArchs (a: nixpkgs.legacyPackages.${a}.nixfmt-tree);
+ devShell = forArchs (
+ a:
+ let
+ pkgs = nixpkgs.legacyPackages.${a};
+ in
+ pkgs.mkShell {
+ packages = with pkgs; [
+ sops
+ age
+ just
+ ];
+ }
+ );
- extraSpecialArgs = {
- niri = niri;
- };
- };
- };
+ nixosConfigurations = nixpkgs.lib.mapAttrs (
+ hostname: config:
+ nixpkgs.lib.nixosSystem {
+ system = config.system;
+ specialArgs = { inherit inputs; };
+ modules = [
+ ./${hostname}
+ inputs.home-manager.nixosModules.home-manager
+ inputs.disko.nixosModules.disko
+ inputs.sops-nix.nixosModules.sops
+ {
+ home-manager = {
+ extraSpecialArgs = inputs;
+ useGlobalPkgs = true;
+ useUserPackages = true;
+ users."monke" = import ./${hostname}/home.nix;
+ sharedModules = [
+ inputs.sops-nix.homeManagerModules.sops
+ ];
+ };
+ }
+ ]
+ ++ config.extraModules;
+ }
+ ) systems;
+ };
}
diff --git a/forest/default.nix b/forest/default.nix
new file mode 100644
--- /dev/null
+++ b/forest/default.nix
@@ -0,0 +1,82 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+{
+ imports =
+ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../nixos/core)
+ ++ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../nixos/server)
+ ++ [
+ ./hardware.nix
+ ./disk-config.nix
+ ];
+
+ sops = {
+ defaultSopsFile = ../secrets/forest.yaml;
+ age.keyFile = "/var/lib/sops-nix/forest.txt";
+ secrets = {
+ "passwords/root".neededForUsers = true;
+ "passwords/monke".neededForUsers = true;
+ };
+ };
+
+ boot.loader.systemd-boot.enable = true;
+ boot.loader.efi.canTouchEfiVariables = true;
+ boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
+
+ networking.hostName = "forest";
+ networking.hostId = "bca37001";
+ networking.networkmanager.enable = true;
+
+ time.timeZone = "Australia/Melbourne";
+
+ console = {
+ font = "Lat2-Terminus16";
+ keyMap = lib.mkDefault "us";
+ useXkbConfig = true;
+ };
+
+ services.xserver.xkb = {
+ layout = "us";
+ variant = "colemak_dh_ortho";
+ };
+
+ programs.zsh.enable = true;
+ users.defaultUserShell = pkgs.zsh;
+ users.users = {
+ root.hashedPasswordFile = config.sops.secrets."passwords/root".path;
+ monke = {
+ isNormalUser = true;
+ extraGroups = [
+ "audio"
+ "disk"
+ "docker"
+ "input"
+ "lp"
+ "plugdev"
+ "render"
+ "video"
+ "wheel"
+ ];
+ hashedPasswordFile = config.sops.secrets."passwords/monke".path;
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICSgzkYEkUDfUWwS2fvPy7gVgjh0zRz4HphkjlUbUkF/ monke@bathtub"
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDUk5RJWdyqqtA7Nh3aO0PYxtywJxRLLNvWO3FEg6WGc8PdxsHczlug5XBKYXonP9VzFcu427udb4DIEzhqsj7zUVRmeEmDAAyIFA8q36ZdMAmIhDp1oLpJVIgm1w/wiBtd8SPFBjZ1aYFCWLDz4kYroC/mhfwKRaXbJcG7b0B55ZHeJ4P/YpAZURX6+q9aNm61K5m0bnvtLoGx5OsQrsqMpmhlwahUdlQe5jbnq4DvwNh3W/u0+N/BABf1wdGW2l5yEBueWbr96DqxV9rFy60kt53l5Ce4RAhNp5bW5y830A7YoHWfq1cQam45LwCAVeDUsnKlYsXQkW6oVMomUJuxh0TmEOUBuA3jR7DM4rKMVPlCKOl54bwstawZR63lRkwNt9MARlbFDID+sUzJgmRLyayEDPqliymHu6mkBTUT9fAmmU6I3ohvVzR8tqy+45zSoQTtZBLZ+DQ//1sqoNgDOKl/DoCx4dFaGvfORpXbqKxmA43eF842hfC6icFeLHx8fGbzfUKAPvPn3aslJtD00j5FrX/LILBFcscY2bu11Hae3qk0W4F9dz5NfIeVh9VMikAr9kfvHzBf/7ayiwE4XxiZkdkxk6sYOzMm1Aw+hzYqpfzz32qRkOptWDgQ2gN20hyKU2IZ3rllYN9xCGWHmGUBBk53EH49e22ThnwGyw== monke@tundra"
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJjEyGfx4H3lyIhSs2Cc4GhfEQkl/oR4oUPAtpbMjohA"
+ ];
+ };
+ };
+
+ environment.systemPackages = with pkgs; [
+ neovim
+ curl
+ git
+ storcli
+ arion
+ ];
+
+ system.stateVersion = "25.05";
+}
diff --git a/forest/disk-config.nix b/forest/disk-config.nix
new file mode 100644
--- /dev/null
+++ b/forest/disk-config.nix
@@ -0,0 +1,74 @@
+{
+ fileSystems = {
+ "/mnt/key" = {
+ device = "/dev/disk/by-uuid/e11f553a-d2dd-48c7-b9cb-98be0a562c7e";
+ fsType = "ext4";
+ neededForBoot = true;
+ };
+ };
+ boot.zfs.extraPools = [ "stuff" ];
+
+ disko.devices = {
+ disk = {
+ main = {
+ device = "/dev/nvme0n1";
+ type = "disk";
+ content = {
+ type = "gpt";
+ partitions = {
+ esp = {
+ size = "512M";
+ type = "EF00";
+ content = {
+ type = "filesystem";
+ format = "vfat";
+ mountpoint = "/boot";
+ mountOptions = [ "umask=0077" ];
+ };
+ };
+ swap = {
+ size = "32G";
+ content = {
+ type = "swap";
+ discardPolicy = "both";
+ };
+ };
+ pool = {
+ size = "100%";
+ content = {
+ type = "zfs";
+ pool = "forest";
+ };
+ };
+ };
+ };
+ };
+ };
+ zpool = {
+ forest = {
+ type = "zpool";
+ rootFsOptions = {
+ compression = "zstd";
+ acltype = "posixacl";
+ xattr = "sa";
+ mountpoint = "none";
+ relatime = "on";
+ "com.sun:auto-snapshot" = "false";
+ };
+ options = {
+ autotrim = "on";
+ };
+ datasets = {
+ root = {
+ type = "zfs_fs";
+ mountpoint = "/";
+ };
+ home = {
+ type = "zfs_fs";
+ mountpoint = "/home";
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/forest/hardware.nix b/forest/hardware.nix
new file mode 100644
--- /dev/null
+++ b/forest/hardware.nix
@@ -0,0 +1,30 @@
+{
+ config,
+ lib,
+ modulesPath,
+ ...
+}:
+
+{
+ imports = [
+ (modulesPath + "/installer/scan/not-detected.nix")
+ ];
+
+ boot.initrd.availableKernelModules = [
+ "mpt3sas"
+ "xhci_pci"
+ "ahci"
+ "nvme"
+ "usbhid"
+ "usb_storage"
+ "sd_mod"
+ ];
+ boot.initrd.kernelModules = [ ];
+ boot.kernelModules = [ "kvm-amd" ];
+ boot.extraModulePackages = [ ];
+
+ networking.useDHCP = lib.mkDefault true;
+
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+ hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}
diff --git a/forest/home-overrides.nix b/forest/home-overrides.nix
new file mode 100644
--- /dev/null
+++ b/forest/home-overrides.nix
@@ -0,0 +1,10 @@
+{ lib, ... }:
+{
+ programs.zsh.initContent = lib.mkForce ''
+ PROMPT="[%F{blue}%~%f] %F{green}>%f "
+ bindkey '^R' history-incremental-search-backward
+ if [[ $- =~ i ]] && [[ -z "$TMUX" ]] && [[ -n "$SSH_TTY" ]]; then
+ exec tmux new -A -s ssh
+ fi
+ '';
+}
diff --git a/forest/home.nix b/forest/home.nix
new file mode 100644
--- /dev/null
+++ b/forest/home.nix
@@ -0,0 +1,30 @@
+{
+ pkgs,
+ lib,
+ ...
+}:
+
+{
+ imports =
+ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../modules/core)
+ ++ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../modules/server)
+ ++ [
+ ./home-overrides.nix
+ ];
+
+ home = {
+ username = "monke";
+ homeDirectory = "/home/monke";
+
+ sessionVariables = {
+ EDITOR = "nvim";
+ };
+
+ sessionPath = [
+ "$HOME/usr/bin"
+ ];
+ preferXdgDirectories = true;
+
+ stateVersion = "25.11";
+ };
+}
diff --git a/gtk.nix b/gtk.nix
deleted file mode 100644
--- a/gtk.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-{ inputs, pkgs, config, ... }:
-
-{
- gtk = {
- enable = true;
- cursorTheme = {
- name = "Breeze";
- package = pkgs.kdePackages.breeze-icons;
- };
- iconTheme = {
- name = "Arc";
- package = pkgs.arc-icon-theme;
- };
- theme = {
- name = "Arc-Dark";
- package = pkgs.arc-theme;
- };
- };
-}
diff --git a/home.nix b/home.nix
deleted file mode 100644
--- a/home.nix
+++ /dev/null
@@ -1,63 +0,0 @@
-{ config, pkgs, lib, niri, ... }:
-{
- imports = [
- ./desktop.nix
- ./niri.nix
- ./music.nix
- ./sioyek.nix
- ./services.nix
- ./programs.nix
- ./gtk.nix
- ];
-
- home = {
- username = "monke";
- homeDirectory = "/home/monke";
-
- sessionVariables = {
- EDITOR = "nvim";
- NIXOS_OZONE_WL = 1;
- };
-
- sessionPath = [
- "$HOME/usr/bin"
- ];
- preferXdgDirectories = true;
-
- stateVersion = "25.11";
-
- packages = with pkgs; [
- anki
- audacity
- btop
- duf
- dust
- gcc
- gnumake
- htop
- kicad
- mpv
- musescore
- nerd-fonts.victor-mono
- networkmanagerapplet
- noto-fonts
- noto-fonts-cjk-sans
- openscad
- pass
- pwvucontrol
- python313Packages.west
- qmk
- rclone
- signal-desktop
- swaybg
- swww
- undefined-medium
- unzip
- victor-mono
- wl-clipboard
- yt-dlp
- ];
- };
-
- programs.home-manager.enable = true;
-}
diff --git a/justfile b/justfile
new file mode 100644
--- /dev/null
+++ b/justfile
@@ -0,0 +1,25 @@
+build host:
+ nixos-rebuild build --flake .#{{host}} -L -j "$(nproc)"
+build-vm host:
+ nixos-rebuild build-vm --flake .#{{host}} -L -j "$(nproc)"
+install host:
+ nixos-install --flake .#{{host}} -j "$(nproc)" --no-root-passwd
+deploy host: (partition host) (install host) (sops host)
+switch host: (build host)
+ doas ./result/bin/switch-to-configuration switch
+ doas nix-env -p /nix/var/nix/profiles/system --set ./result
+ doas ./result/bin/switch-to-configuration boot
+partition host:
+ sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount {{host}}/disk-config.nix
+sops host:
+ mkdir -pv /mnt/var/lib/sops-nix
+ mkdir -pv /mnt/home/monke/.config/sops/age
+ cp /mnt2/age/{{host}}.txt /mnt/var/lib/sops-nix
+ cp /mnt2/age/{{host}}.txt /mnt/home/monke/.config/sops/age/keys.txt
+ssh host:
+ cp -rv /mnt2/ssh/{{host}} /mnt/home/monke/.ssh
+clean:
+ rm ./result
+gc: clean
+ doas nix-collect-garbage -d
+ nix-collect-garbage -d
diff --git a/modules/core/bat.nix b/modules/core/bat.nix
new file mode 100644
--- /dev/null
+++ b/modules/core/bat.nix
@@ -0,0 +1,7 @@
+{
+ programs.bat.enable = true;
+ programs.zsh.shellAliases = {
+ "cat" = "bat";
+ "less" = "bat";
+ };
+}
diff --git a/modules/core/git.nix b/modules/core/git.nix
new file mode 100644
--- /dev/null
+++ b/modules/core/git.nix
@@ -0,0 +1,7 @@
+{
+ programs.git = {
+ enable = true;
+ userName = "Aaron Chen";
+ userEmail = "monke@monke.moe";
+ };
+}
diff --git a/modules/core/gpg.nix b/modules/core/gpg.nix
new file mode 100644
--- /dev/null
+++ b/modules/core/gpg.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+{
+ programs.gpg.enable = true;
+
+ services.gpg-agent = {
+ enable = true;
+ pinentry.package = pkgs.pinentry-tty;
+ };
+}
diff --git a/modules/core/misc.nix b/modules/core/misc.nix
new file mode 100644
--- /dev/null
+++ b/modules/core/misc.nix
@@ -0,0 +1,11 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ dust
+ duf
+ unzip
+ file
+ ];
+
+ programs.yt-dlp.enable = true;
+}
diff --git a/modules/core/monitors.nix b/modules/core/monitors.nix
new file mode 100644
--- /dev/null
+++ b/modules/core/monitors.nix
@@ -0,0 +1,4 @@
+{
+ programs.htop.enable = true;
+ programs.btop.enable = true;
+}
diff --git a/modules/core/zsh.nix b/modules/core/zsh.nix
new file mode 100644
--- /dev/null
+++ b/modules/core/zsh.nix
@@ -0,0 +1,21 @@
+{
+ programs.zsh = {
+ enable = true;
+ shellAliases = {
+ "v" = "nvim";
+ "vi" = "nvim";
+ "vim" = "nvim";
+ };
+ syntaxHighlighting = {
+ enable = true;
+ highlighters = [
+ "main"
+ "brackets"
+ ];
+ };
+ initContent = ''
+ PROMPT="[%F{red}%~%f] %F{green}>%f "
+ bindkey '^R' history-incremental-search-backward
+ '';
+ };
+}
diff --git a/modules/desktop/anki.nix b/modules/desktop/anki.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/anki.nix
@@ -0,0 +1,334 @@
+{ pkgs, ... }:
+{
+ programs.anki = {
+ enable = true;
+ reduceMotion = false;
+ addons = [
+ (pkgs.ankiAddons.recolor.withConfig {
+ config = {
+ colors = {
+ ACCENT_CARD = [
+ "Card mode"
+ "#60a5fa"
+ "#93c5fd"
+ "--accent-card"
+ ];
+ ACCENT_DANGER = [
+ "Danger"
+ "#ef4444"
+ "#f87171"
+ "--accent-danger"
+ ];
+ ACCENT_NOTE = [
+ "Note mode"
+ "#22c55e"
+ "#4ade80"
+ "--accent-note"
+ ];
+ BORDER = [
+ "Border"
+ "#c4c4c4"
+ "#202020"
+ "--border"
+ ];
+ BORDER_FOCUS = [
+ "Border (focused input)"
+ "#3b82f6"
+ "#3b82f6"
+ "--border-focus"
+ ];
+ BORDER_STRONG = [
+ "Border (strong)"
+ "#858585"
+ "#020202"
+ "--border-strong"
+ ];
+ BORDER_SUBTLE = [
+ "Border (subtle)"
+ "#e4e4e4"
+ "#252525"
+ "--border-subtle"
+ ];
+ BUTTON_BG = [
+ "Button background"
+ "white"
+ "#363636"
+ "--button-bg"
+ ];
+ BUTTON_DISABLED = [
+ "Button background (disabled)"
+ "#d6d6d680"
+ "#45454580"
+ "--button-disabled"
+ ];
+ BUTTON_HOVER = [
+ "Button background (hover)"
+ "#f4f4f4"
+ "#313131"
+ [
+ "--button-gradient-start"
+ "--button-gradient-end"
+ ]
+ ];
+ BUTTON_HOVER_BORDER = [
+ "Button border (hover)"
+ "#999999"
+ "#141414"
+ "--button-hover-border"
+ ];
+ BUTTON_PRIMARY_BG = [
+ "Button Primary Bg"
+ "#60a5fa"
+ "#2f67e1"
+ "--button-primary-bg"
+ ];
+ BUTTON_PRIMARY_DISABLED = [
+ "Button Primary Disabled"
+ "#93c5fd"
+ "#4484ed"
+ "--button-primary-disabled"
+ ];
+ BUTTON_PRIMARY_GRADIENT_END = [
+ "Button Primary Gradient End"
+ "#2563eb"
+ "#2544a8"
+ "--button-primary-gradient-end"
+ ];
+ BUTTON_PRIMARY_GRADIENT_START = [
+ "Button Primary Gradient Start"
+ "#60a5fa"
+ "#2f67e1"
+ "--button-primary-gradient-start"
+ ];
+ CANVAS = [
+ "Background"
+ "#f5f5f5"
+ "#2c2c2c"
+ [
+ "--canvas"
+ "--bs-body-bg"
+ ]
+ ];
+ CANVAS_CODE = [
+ "Code editor background"
+ "white"
+ "#252525"
+ "--canvas-code"
+ ];
+ CANVAS_ELEVATED = [
+ "Background (elevated)"
+ "white"
+ "#363636"
+ "--canvas-elevated"
+ ];
+ CANVAS_GLASS = [
+ "Background (transparent text surface)"
+ "##ffffff66"
+ "##36363666"
+ "--canvas-glass"
+ ];
+ CANVAS_INSET = [
+ "Background (inset)"
+ "#eeeeee"
+ "#252525"
+ "--canvas-inset"
+ ];
+ CANVAS_OVERLAY = [
+ "Background (menu & tooltip)"
+ "#fcfcfc"
+ "#2c2c2c"
+ "--canvas-overlay"
+ ];
+ FG = [
+ "Text"
+ "#020202"
+ "#fcfcfc"
+ [
+ "--fg"
+ "--bs-body-color"
+ ]
+ ];
+ FG_DISABLED = [
+ "Text (disabled)"
+ "#858585"
+ "#737373"
+ "--fg-disabled"
+ ];
+ FG_FAINT = [
+ "Text (faint)"
+ "#afafaf"
+ "#545454"
+ "--fg-faint"
+ ];
+ FG_LINK = [
+ "Text (link)"
+ "#1d4ed8"
+ "#bfdbfe"
+ "--fg-link"
+ ];
+ FG_SUBTLE = [
+ "Text (subtle)"
+ "#737373"
+ "#858585"
+ "--fg-subtle"
+ ];
+ FLAG_1 = [
+ "Flag 1"
+ "#ef4444"
+ "#f87171"
+ "--flag-1"
+ ];
+ FLAG_2 = [
+ "Flag 2"
+ "#fb923c"
+ "#fdba74"
+ "--flag-2"
+ ];
+ FLAG_3 = [
+ "Flag 3"
+ "#4ade80"
+ "#86efac"
+ "--flag-3"
+ ];
+ FLAG_4 = [
+ "Flag 4"
+ "#3b82f6"
+ "#60a5fa"
+ "--flag-4"
+ ];
+ FLAG_5 = [
+ "Flag 5"
+ "#e879f9"
+ "#f0abfc"
+ "--flag-5"
+ ];
+ FLAG_6 = [
+ "Flag 6"
+ "#2dd4bf"
+ "#5eead4"
+ "--flag-6"
+ ];
+ FLAG_7 = [
+ "Flag 7"
+ "#a855f7"
+ "#c084fc"
+ "--flag-7"
+ ];
+ HIGHLIGHT_BG = [
+ "Highlight background"
+ "#2563eb80"
+ "#93c5fd80"
+ "--highlight-bg"
+ ];
+ HIGHLIGHT_FG = [
+ "Highlight text"
+ "black"
+ "white"
+ "--highlight-fg"
+ ];
+ SCROLLBAR_BG = [
+ "Scrollbar background"
+ "#d6d6d6"
+ "#363636"
+ "--scrollbar-bg"
+ ];
+ SCROLLBAR_BG_ACTIVE = [
+ "Scrollbar background (active)"
+ "#afafaf"
+ "#636363"
+ "--scrollbar-bg-active"
+ ];
+ SCROLLBAR_BG_HOVER = [
+ "Scrollbar background (hover)"
+ "#c4c4c4"
+ "#454545"
+ "--scrollbar-bg-hover"
+ ];
+ SELECTED_BG = [
+ "Selected Bg"
+ "#d6d6d680"
+ "#93c5fd80"
+ "--selected-bg"
+ ];
+ SELECTED_FG = [
+ "Selected Fg"
+ "black"
+ "white"
+ "--selected-fg"
+ ];
+ SHADOW = [
+ "Shadow"
+ "#c4c4c4"
+ "#202020"
+ "--shadow"
+ ];
+ SHADOW_FOCUS = [
+ "Shadow (focused input)"
+ "#6366f1"
+ "#6366f1"
+ "--shadow-focus"
+ ];
+ SHADOW_INSET = [
+ "Shadow (inset)"
+ "#454545"
+ "#202020"
+ "--shadow-inset"
+ ];
+ SHADOW_SUBTLE = [
+ "Shadow (subtle)"
+ "#737373"
+ "#363636"
+ "--shadow-subtle"
+ ];
+ STATE_BURIED = [
+ "Buried"
+ "#f59e0b"
+ "#92400e"
+ "--state-buried"
+ ];
+ STATE_LEARN = [
+ "Learn"
+ "#dc2626"
+ "#f87171"
+ "--state-learn"
+ ];
+ STATE_MARKED = [
+ "Marked"
+ "#c7d2fe"
+ "#a855f7"
+ "--state-marked"
+ ];
+ STATE_NEW = [
+ "New"
+ "#3b82f6"
+ "#93c5fd"
+ "--state-new"
+ ];
+ STATE_REVIEW = [
+ "Review"
+ "#16a34a"
+ "#22c55e"
+ "--state-review"
+ ];
+ STATE_SUSPENDED = [
+ "Suspended"
+ "#facc15"
+ "#fef9c3"
+ "--state-suspended"
+ ];
+ };
+ version = {
+ major = -1;
+ minor = -1;
+ };
+ };
+ })
+ ];
+ hideTopBarMode = "always";
+ language = "en_GB";
+ sync = {
+ username = "monke";
+ url = "http://10.0.0.10:8087";
+ };
+ };
+}
diff --git a/modules/desktop/cliphist.nix b/modules/desktop/cliphist.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/cliphist.nix
@@ -0,0 +1,3 @@
+{
+ services.cliphist.enable = true;
+}
diff --git a/modules/desktop/desktop.nix b/modules/desktop/desktop.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/desktop.nix
@@ -0,0 +1,38 @@
+{ pkgs, config, ... }:
+{
+ xdg = {
+ enable = true;
+ cacheHome = "${config.home.homeDirectory}/var/cache";
+ #configHome = "${config.home.homeDirectory}/etc";
+ dataHome = "${config.home.homeDirectory}/usr/share";
+ stateHome = "${config.home.homeDirectory}/usr/state";
+
+ portal = {
+ enable = true;
+ extraPortals = with pkgs; [
+ xdg-desktop-portal-gtk
+ xdg-desktop-portal-wlr
+ xdg-desktop-portal-shana
+ ];
+ config = {
+ common = {
+ default = [
+ "shana"
+ "gtk"
+ ];
+ };
+ };
+ };
+
+ userDirs = {
+ enable = true;
+ desktop = "/dev/null";
+ documents = "${config.home.homeDirectory}/docs";
+ download = "${config.home.homeDirectory}/dl";
+ music = "${config.home.homeDirectory}/music";
+ pictures = "${config.home.homeDirectory}/pics";
+ templates = "${config.xdg.userDirs.documents}/templates";
+ videos = config.xdg.userDirs.pictures;
+ };
+ };
+}
diff --git a/modules/desktop/dunst.nix b/modules/desktop/dunst.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/dunst.nix
@@ -0,0 +1,36 @@
+{
+ services.dunst = {
+ enable = true;
+ settings = {
+ global = {
+ follow = "mouse";
+ enable_posix_regex = true;
+ width = 450;
+
+ origin = "top-right";
+ offset = "8x8";
+
+ frame_color = "#b15c66";
+ background = "#2e2629";
+ timeout = 10;
+ frame_width = 2;
+ corner_radius = 8;
+ alignment = "center";
+
+ font = "Victor Mono 9";
+ format = "%a: %s\\n%b";
+ show_age_threshold = 10;
+
+ icon_corner_radius = 4;
+ max_icon_size = 120;
+
+ progress_bar_frame_width = 2;
+ };
+
+ urgency_critical = {
+ timeout = 0;
+ format = "%a: %s\\n%b";
+ };
+ };
+ };
+}
diff --git a/modules/desktop/easyeffects.nix b/modules/desktop/easyeffects.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/easyeffects.nix
@@ -0,0 +1,14 @@
+{
+ services.easyeffects = {
+ enable = true;
+ };
+
+ programs.waybar.settings = {
+ "custom/easyeffects" = {
+ exec = builtins.readFile ../../files/waybar/easyeffects.sh;
+ interval = 1;
+ format = "{} ";
+ tooltip = false;
+ };
+ };
+}
diff --git a/modules/desktop/eww.nix b/modules/desktop/eww.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/eww.nix
@@ -0,0 +1,7 @@
+{
+ programs.eww = {
+ enable = true;
+ enableZshIntegration = true;
+ configDir = ../../files/eww;
+ };
+}
diff --git a/modules/desktop/fcitx.nix b/modules/desktop/fcitx.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/fcitx.nix
@@ -0,0 +1,24 @@
+{ pkgs, ... }:
+{
+ i18n = {
+ glibcLocales = pkgs.glibcLocales.override {
+ allLocales = false;
+ locales = [
+ "en_US.UTF-8/UTF-8"
+ "en_AU.UTF-8/UTF-8"
+ "ja_JP.UTF-8/UTF-8"
+ ];
+ };
+ inputMethod = {
+ enable = true;
+ type = "fcitx5";
+ fcitx5 = {
+ waylandFrontend = true;
+ addons = with pkgs; [
+ fcitx5-mozc
+ kdePackages.fcitx5-configtool
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/desktop/firefox.nix b/modules/desktop/firefox.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/firefox.nix
@@ -0,0 +1,95 @@
+{ pkgs, ... }:
+{
+ programs.firefox = {
+ enable = true;
+ package = pkgs.firefox-bin;
+ languagePacks = [
+ "en-GB"
+ "en-US"
+ ];
+ policies = {
+ DefaultDownloadDirectory = "\${home}/dl";
+ DisableBuiltinPDFViewer = true;
+ DisablePocket = true;
+ DisableTelemetry = true;
+ EnableTrackingProtection = true;
+ FirefoxHome = {
+ Search = true;
+ TopSites = false;
+ SponsoredTopSites = false;
+ Highlights = false;
+ Pocket = false;
+ SponsoredPocket = false;
+ Snippets = false;
+ Locked = true;
+ };
+ };
+ policies.Preferences = {
+ "browser.aboutConfig.showWarning" = false;
+ "browser.shell.checkDefaultBrowser" = false;
+ "browser.toolbars.bookmarks.visibility" = "never";
+ "devtools.everOpened" = true;
+ "mousewheel.with_control.action" = 5;
+ "sidebar.revamp" = true;
+ "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+ };
+ policies.ExtensionSettings = {
+ "uBlock0@raymondhill.net" = {
+ install_url = "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi";
+ installation_mode = "force_installed";
+ private_browsing = true;
+ };
+ "{3c078156-979c-498b-8990-85f7987dd929}" = {
+ install_url = "https://addons.mozilla.org/firefox/downloads/latest/sidebery/latest.xpi";
+ private_browsing = true;
+ };
+ "@testpilot-containers" = {
+ install_url = "https://addons.mozilla.org/firefox/downloads/latest/multi-account-containers/latest.xpi";
+ installation_mode = "force_installed";
+ private_browsing = false;
+ };
+ };
+ profiles.default = {
+ isDefault = true;
+ containersForce = true;
+ containers = {
+ school = {
+ id = 0;
+ color = "purple";
+ icon = "circle";
+ };
+
+ shopping = {
+ id = 1;
+ name = "online shopping";
+ color = "green";
+ icon = "dollar";
+ };
+ };
+ search = {
+ default = "ddg";
+ engines = {
+ "ddg" = {
+ urls = [
+ {
+ template = "https://duckduckgo.com/?q={searchTerms}";
+ }
+ ];
+ definedAliases = [ "@ddg" ];
+ };
+
+ "piped" = {
+ urls = [
+ {
+ template = "https://piped.forest.monke/results?search_query={searchTerms}";
+ }
+ ];
+ definedAliases = [ "yt" ];
+ };
+ };
+ force = true;
+ };
+ userChrome = builtins.readFile ../../files/firefox/userChrome.css;
+ };
+ };
+}
diff --git a/modules/desktop/fonts.nix b/modules/desktop/fonts.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/fonts.nix
@@ -0,0 +1,11 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ nerd-fonts.victor-mono
+ noto-fonts
+ noto-fonts-color-emoji
+ noto-fonts-cjk-sans
+ undefined-medium
+ victor-mono
+ ];
+}
diff --git a/modules/desktop/fusuma.nix b/modules/desktop/fusuma.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/fusuma.nix
@@ -0,0 +1,11 @@
+{
+ services.fusuma = {
+ enable = true;
+ settings = {
+ pinch."3" = {
+ "in".command = "eww close menu";
+ out.command = "eww open menu";
+ };
+ };
+ };
+}
diff --git a/modules/desktop/gtk.nix b/modules/desktop/gtk.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/gtk.nix
@@ -0,0 +1,27 @@
+{
+ pkgs,
+ ...
+}:
+
+{
+ home.pointerCursor = {
+ gtk.enable = true;
+ package = pkgs.numix-cursor-theme;
+ name = "Numix-Cursor-Light";
+ };
+ gtk = {
+ enable = true;
+ cursorTheme = {
+ name = "Numix-Cursor-Light";
+ package = pkgs.numix-cursor-theme;
+ };
+ iconTheme = {
+ name = "Arc";
+ package = pkgs.arc-icon-theme;
+ };
+ theme = {
+ name = "Arc-Dark";
+ package = pkgs.arc-theme;
+ };
+ };
+}
diff --git a/modules/desktop/hyprlock.nix b/modules/desktop/hyprlock.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/hyprlock.nix
@@ -0,0 +1,71 @@
+{
+ programs.hyprlock = {
+ enable = true;
+ settings = {
+ general = {
+ hide_cursor = true;
+ ignore_empty_input = true;
+ };
+
+ background = [
+ {
+ path = "/home/monke/pics/wall.jpg";
+ blur_passes = 3;
+ blur_size = 5;
+ noise = 0.0117;
+ contrast = 1.3000;
+ brightness = 0.4000;
+ vibrancy = 0.2100;
+ vibrancy_darkness = 0.0;
+ }
+ ];
+
+ input-field = [
+ {
+ font_family = "Victor Mono Light";
+ placeholder_text = "enter password...";
+ rounding = 16;
+ inner_color = "rgba(227,221,223,1.0)";
+ check_color = "rgba(141,191,160,1.0)";
+ fail_color = "rgba(177,92,102,1.0)";
+ outline_thickness = 0;
+ size = "500, 100";
+ fade_on_empty = false;
+ }
+ ];
+
+ label = [
+ {
+ text = ''cmd[update:1000] echo " $(date +"%T") "'';
+ color = "rgba(227,221,223,1.0)";
+ font_size = 120;
+ font_family = "Victor Mono Light";
+
+ position = "0, -100";
+ halign = "center";
+ valign = "top";
+ }
+ {
+ text = "cmd[update:60000] acpi | awk -F ', ' '{print $2}'";
+ color = "rgba(227,221,223,1.0)";
+ font_size = 40;
+ font_family = "Victor Mono Light";
+
+ position = "0, -300";
+ halign = "center";
+ valign = "top";
+ }
+ {
+ text = ''cmd[update:1000] echo " $USER (up for $(go-uptime))"'';
+ color = "rgb(227,221,223)";
+ font_size = 18;
+ font_family = "Victor Mono";
+
+ position = "0, 100";
+ halign = "center";
+ valign = "bottom";
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/desktop/misc.nix b/modules/desktop/misc.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/misc.nix
@@ -0,0 +1,8 @@
+{ pkgs, ... }:
+{
+ home.packages = with pkgs; [
+ playerctl
+ brightnessctl
+ xwayland-satellite
+ ];
+}
diff --git a/modules/desktop/mpv.nix b/modules/desktop/mpv.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/mpv.nix
@@ -0,0 +1,3 @@
+{
+ programs.mpv.enable = true;
+}
diff --git a/modules/desktop/music.nix b/modules/desktop/music.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/music.nix
@@ -0,0 +1,86 @@
+{ pkgs, ... }:
+{
+ programs = {
+ inori = {
+ enable = true;
+ settings = {
+ mpd_address = "/run/user/1000/mpd_socket";
+ };
+ };
+
+ ncmpcpp = {
+ enable = true;
+ package = pkgs.ncmpcpp.override {
+ visualizerSupport = true;
+ };
+ settings = {
+ progressbar_look = "━━";
+ display_bitrate = true;
+ user_interface = "alternative";
+ ncmpcpp_directory = "~/.config/ncmpcpp";
+ mpd_host = "/run/user/1000/mpd_socket";
+ };
+ };
+ };
+
+ services = {
+ mopidy = {
+ enable = false;
+ extensionPackages = with pkgs; [
+ mopidy-mpd
+ mopidy-mpris
+ mopidy-subidy
+ ];
+ settings = {
+ mpris = {
+ enabled = true;
+ };
+ subidy = {
+ enabled = true;
+ url = "http://10.0.0.10:4533";
+ username = "monke";
+ password = "kyacnn8Xc3yDMSA$c50QfkcW49JA8aG$7VcWx#AzcIGm$X0FdL2BVkw";
+ };
+ mpd = {
+ enabled = true;
+ hostname = "unix:/run/user/1000/mpd_socket";
+ };
+ file = {
+ enabled = true;
+ media_dirs = [
+ "~/music"
+ ];
+ excluded_file_extensions = [
+ ".html"
+ ".zip"
+ ".jpg"
+ ".jpeg"
+ ".png"
+ ];
+ };
+ http = {
+ enabled = false;
+ };
+ };
+ };
+ mpd = {
+ enable = true;
+ network = {
+ listenAddress = "/run/user/1000/mpd_socket";
+ };
+ extraConfig = ''
+ audio_output {
+ type "fifo"
+ name "my_fifo"
+ path "/tmp/mpd.fifo"
+ format "44100:16:2"
+ }
+
+ audio_output {
+ type "pipewire"
+ name "pipewire"
+ }
+ '';
+ };
+ };
+}
diff --git a/modules/desktop/neovide.nix b/modules/desktop/neovide.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/neovide.nix
@@ -0,0 +1,3 @@
+{
+ programs.neovide.enable = true;
+}
diff --git a/modules/desktop/niri.nix b/modules/desktop/niri.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/niri.nix
@@ -0,0 +1,348 @@
+{
+ config,
+ niri,
+ ...
+}:
+let
+ inherit (niri.lib.kdl)
+ node
+ plain
+ leaf
+ flag
+ ;
+in
+{
+ programs.niri = {
+ settings = {
+ prefer-no-csd = true;
+ spawn-at-startup = [
+ { command = [ "nm-applet" ]; }
+ { command = [ "swww-daemon" ]; }
+ {
+ command = [
+ "swaybg"
+ "-c"
+ "b79fa8"
+ ];
+ }
+ {
+ command = [
+ "eww"
+ "daemon"
+ ];
+ }
+ ];
+
+ workspaces."1" = { };
+ workspaces."2" = { };
+ workspaces."3" = { };
+ workspaces."4" = { };
+
+ input = {
+ focus-follows-mouse = {
+ enable = true;
+ };
+
+ keyboard.xkb = {
+ layout = "us";
+ variant = "colemak_dh_ortho";
+ };
+
+ touchpad = {
+ accel-profile = "adaptive";
+ accel-speed = 1.0;
+ dwt = true;
+ tap = false;
+ natural-scroll = false;
+ };
+
+ mouse = {
+ accel-profile = "flat";
+ accel-speed = 1.0;
+ };
+
+ warp-mouse-to-focus.enable = true;
+ };
+
+ outputs."eDP-1" = {
+ mode = {
+ width = 3024;
+ height = 1890;
+ refresh = 60.0;
+ };
+ scale = 1.5;
+ variable-refresh-rate = true;
+ };
+
+ layout = {
+ gaps = 15;
+ center-focused-column = "never";
+ preset-column-widths = [
+ { proportion = 1. / 3.; }
+ { proportion = 1. / 2.; }
+ { proportion = 3. / 5.; }
+ { proportion = 9. / 10.; }
+ ];
+ default-column-width.proportion = 3. / 5.;
+
+ focus-ring.enable = false;
+
+ border = {
+ enable = true;
+ width = 2.5;
+ active.color = "#b15c66";
+ inactive.color = "#b1888d";
+ };
+
+ shadow = {
+ enable = true;
+ softness = 10;
+ spread = 2;
+ offset = {
+ x = 3;
+ y = 3;
+ };
+ color = "#0009";
+ };
+
+ struts = {
+ top = 36;
+ };
+ };
+
+ layer-rules = [
+ {
+ matches = [ { namespace = "^wallpaper$"; } ];
+ place-within-backdrop = true;
+ }
+ ];
+
+ animations = {
+ workspace-switch.kind.spring = {
+ damping-ratio = 0.8;
+ stiffness = 800;
+ epsilon = 0.0001;
+ };
+
+ window-open = {
+ kind.spring = {
+ damping-ratio = 0.8;
+ stiffness = 800;
+ epsilon = 0.0001;
+ };
+
+ custom-shader = builtins.readFile ../../files/niri/window-open.glsl;
+ };
+
+ window-close = {
+ kind.easing = {
+ curve = "linear";
+ duration-ms = 250;
+ };
+
+ custom-shader = builtins.readFile ../../files/niri/window-close.glsl;
+ };
+
+ horizontal-view-movement.kind.spring = {
+ damping-ratio = 1.0;
+ stiffness = 800;
+ epsilon = 0.0001;
+ };
+
+ window-movement.kind.spring = {
+ damping-ratio = 1.0;
+ stiffness = 800;
+ epsilon = 0.0001;
+ };
+
+ window-resize.kind.spring = {
+ damping-ratio = 1.0;
+ stiffness = 800;
+ epsilon = 0.0001;
+ };
+
+ config-notification-open-close.kind.spring = {
+ damping-ratio = 0.6;
+ stiffness = 1000;
+ epsilon = 0.001;
+ };
+ };
+
+ window-rules = [
+ {
+ matches = [
+ {
+ title = "^Picture-in-Picture$";
+ }
+ ];
+ open-floating = true;
+ }
+ {
+ geometry-corner-radius = {
+ bottom-left = 8.0;
+ bottom-right = 8.0;
+ top-left = 8.0;
+ top-right = 8.0;
+ };
+ clip-to-geometry = true;
+ }
+ ];
+
+ binds = with config.lib.niri.actions; {
+ "Mod+Shift+Slash".action = show-hotkey-overlay;
+
+ "Mod+Return".action = spawn "wezterm";
+ "Mod+Space".action = spawn "wofi" "--show" "drun";
+ "Mod+Alt+Space".action = spawn "sh" "-c" "cliphist-wofi-img | wl-copy";
+ "Mod+Shift+3".action = spawn "screenshot";
+ "Mod+Shift+4".action = spawn "screenshot" "area";
+ "Mod+X".action = spawn "clipclear";
+ "Super+Alt+L".action = spawn "hyprlock";
+
+ "XF86AudioRaiseVolume" = {
+ allow-when-locked = true;
+ action = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "2%+" "-l" "1.0";
+ };
+ "XF86AudioLowerVolume" = {
+ allow-when-locked = true;
+ action = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "2%-";
+ };
+ "XF86AudioMute" = {
+ allow-when-locked = true;
+ action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle";
+ };
+ "XF86AudioMicMute" = {
+ allow-when-locked = true;
+ action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle";
+ };
+ "XF86AudioPlay" = {
+ allow-when-locked = true;
+ action = spawn "playerctl" "play-pause";
+ };
+ "XF86MonBrightnessUp" = {
+ allow-when-locked = true;
+ action = spawn "brightnessctl" "s" "+2%";
+ };
+ "XF86MonBrightnessDown" = {
+ allow-when-locked = true;
+ action = spawn "brightnessctl" "s" "2%-";
+ };
+
+ "Mod+Q".action = close-window;
+
+ "Mod+Left".action = focus-column-left;
+ "Mod+Down".action = focus-window-down;
+ "Mod+Up".action = focus-window-up;
+ "Mod+Right".action = focus-column-right;
+
+ "Mod+Ctrl+Left".action = move-column-left;
+ "Mod+Ctrl+Down".action = move-window-down;
+ "Mod+Ctrl+Up".action = move-window-up;
+ "Mod+Ctrl+Right".action = move-column-right;
+
+ "Mod+Shift+Left".action = focus-monitor-left;
+ "Mod+Shift+Down".action = focus-monitor-down;
+ "Mod+Shift+Up".action = focus-monitor-up;
+ "Mod+Shift+Right".action = focus-monitor-right;
+
+ "Mod+Shift+Ctrl+Left".action = move-column-to-monitor-left;
+ "Mod+Shift+Ctrl+Down".action = move-column-to-monitor-down;
+ "Mod+Shift+Ctrl+Up".action = move-column-to-monitor-up;
+ "Mod+Shift+Ctrl+Right".action = move-column-to-monitor-right;
+
+ "Mod+Page_Down".action = focus-workspace-down;
+ "Mod+Page_Up".action = focus-workspace-up;
+ "Mod+U".action = focus-workspace-down;
+ "Mod+I".action = focus-workspace-up;
+ "Mod+Alt+Ctrl+Down".action = move-column-to-workspace-down;
+ "Mod+Alt+Ctrl+Up".action = move-column-to-workspace-up;
+ "Mod+Ctrl+U".action = move-column-to-workspace-down;
+ "Mod+Ctrl+I".action = move-column-to-workspace-up;
+
+ "Mod+Shift+Page_Down".action = move-workspace-down;
+ "Mod+Shift+Page_Up".action = move-workspace-up;
+ "Mod+Shift+U".action = move-workspace-down;
+ "Mod+Shift+I".action = move-workspace-up;
+
+ "Mod+WheelScrollDown" = {
+ cooldown-ms = 150;
+ action = focus-workspace-down;
+ };
+ "Mod+WheelScrollUp" = {
+ cooldown-ms = 150;
+ action = focus-workspace-up;
+ };
+ "Mod+Ctrl+WheelScrollDown" = {
+ cooldown-ms = 150;
+ action = move-column-to-workspace-down;
+ };
+ "Mod+Ctrl+WheelScrollUp" = {
+ cooldown-ms = 150;
+ action = move-column-to-workspace-up;
+ };
+
+ "Mod+WheelScrollRight".action = focus-column-right;
+ "Mod+WheelScrollLeft".action = focus-column-left;
+ "Mod+Ctrl+WheelScrollRight".action = move-column-right;
+ "Mod+Ctrl+WheelScrollLeft".action = move-column-left;
+
+ "Mod+Shift+WheelScrollDown".action = focus-column-right;
+ "Mod+Shift+WheelScrollUp".action = focus-column-left;
+ "Mod+Ctrl+Shift+WheelScrollDown".action = move-column-right;
+ "Mod+Ctrl+Shift+WheelScrollUp".action = move-column-left;
+
+ "Mod+1".action = focus-workspace 1;
+ "Mod+2".action = focus-workspace 2;
+ "Mod+3".action = focus-workspace 3;
+ "Mod+4".action = focus-workspace 4;
+ "Mod+5".action = focus-workspace 5;
+ #"Mod+Ctrl+1".action = move-column-to-workspace-index 1;
+ #"Mod+Ctrl+2".action = move-column-to-workspace-index 2;
+ #"Mod+Ctrl+3".action = move-column-to-workspace-index 3;
+ #"Mod+Ctrl+4".action = move-column-to-workspace-index 4;
+ #"Mod+Ctrl+5".action = move-column-to-workspace-index 5;
+
+ "Mod+BracketLeft".action = consume-or-expel-window-left;
+ "Mod+BracketRight".action = consume-or-expel-window-right;
+
+ "Mod+Comma".action = consume-window-into-column;
+ "Mod+Period".action = expel-window-from-column;
+
+ "Mod+R".action = switch-preset-column-width;
+ "Mod+Shift+R".action = switch-preset-window-height;
+ "Mod+Ctrl+R".action = reset-window-height;
+ "Mod+F".action = maximize-column;
+ "Mod+Shift+F".action = fullscreen-window;
+
+ "Mod+Ctrl+F".action = expand-column-to-available-width;
+
+ "Mod+C".action = center-column;
+
+ "Mod+Minus".action = set-column-width "-10%";
+ "Mod+Equal".action = set-column-width "+10%";
+
+ "Mod+Shift+Minus".action = set-window-height "-10%";
+ "Mod+Shift+Equal".action = set-window-height "+10%";
+
+ "Mod+V".action = toggle-window-floating;
+ "Mod+Shift+V".action = switch-focus-between-floating-and-tiling;
+
+ "Mod+W".action = toggle-column-tabbed-display;
+
+ "Mod+Escape" = {
+ allow-inhibiting = false;
+ action = toggle-keyboard-shortcuts-inhibit;
+ };
+
+ "Mod+Shift+E".action = quit;
+ "Ctrl+Alt+Delete".action = quit;
+
+ "Mod+Shift+P".action = power-off-monitors;
+ };
+
+ debug = {
+ render-drm-device = "/dev/dri/renderD128";
+ };
+ };
+ };
+}
diff --git a/modules/desktop/sioyek.nix b/modules/desktop/sioyek.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/sioyek.nix
@@ -0,0 +1,31 @@
+{
+ programs.sioyek = {
+ enable = true;
+ bindings = {
+ # main navigation
+ "move_left" = "i";
+ "move_down" = "n";
+ "move_up" = "e";
+ "move_right" = "m";
+ # marks
+ "move_visual_mark_down" = "n";
+ "move_visual_mark_up" = "e";
+ # search
+ "next_item" = "k";
+ "previous_item" = "K";
+ # misc
+ "set_mark" = "h";
+ "toggle_custom_color" = "";
+ };
+ config = {
+ custom_background_color = "0.18 0.14 0.16";
+ custom_text_color = "0.89 0.867 0.87";
+ ruler_display_mode = "slit";
+ startup_commands = "toggle_custom_color";
+ status_bar_color = "0.18 0.14 0.16";
+ ui_font = "Victor Mono";
+ visual_mark_color = "1.0 1.0 1.0 0.8";
+ show_statusbar_only_when_hovered = "1";
+ };
+ };
+}
diff --git a/modules/desktop/swayidle.nix b/modules/desktop/swayidle.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/swayidle.nix
@@ -0,0 +1,17 @@
+{
+ services.swayidle = {
+ enable = true;
+ events = [
+ {
+ event = "before-sleep";
+ command = "hyprlock";
+ }
+ ];
+ timeouts = [
+ {
+ timeout = 600;
+ command = "hyprlock";
+ }
+ ];
+ };
+}
diff --git a/modules/desktop/swayimg.nix b/modules/desktop/swayimg.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/swayimg.nix
@@ -0,0 +1,5 @@
+{
+ programs.swayimg = {
+ enable = true;
+ };
+}
diff --git a/modules/desktop/swww.nix b/modules/desktop/swww.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/swww.nix
@@ -0,0 +1,3 @@
+{
+ services.swww.enable = true;
+}
diff --git a/modules/desktop/udiskie.nix b/modules/desktop/udiskie.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/udiskie.nix
@@ -0,0 +1,3 @@
+{
+ services.udiskie.enable = true;
+}
diff --git a/modules/desktop/waybar.nix b/modules/desktop/waybar.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/waybar.nix
@@ -0,0 +1,143 @@
+{
+ programs.waybar = {
+ enable = true;
+ systemd.enable = true;
+ settings = {
+ bar = {
+ layer = "top";
+ position = "top";
+ exclusive = false;
+
+ modules-left = [ "niri/workspaces" ];
+ modules-center = [ "clock" ];
+ modules-right = [
+ "backlight"
+ "battery"
+ "wireplumber"
+ "tray"
+ ];
+
+ backlight = {
+ format = "{percent}% {icon}";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+
+ battery = {
+ adapter = "AC";
+ states = {
+ # good = 95;
+ warning = 30;
+ critical = 20;
+ };
+ format = "{capacity}% {icon}";
+ format-charging = "{capacity}% ";
+ format-plugged = "{capacity}% ";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+
+ clock = {
+ interval = 1;
+ locale = "en_US.UTF-8";
+
+ tooltip-format = "{:%Y %B}\n{calendar}";
+
+ calendar = {
+ mode = "year";
+ mode-mon-col = 3;
+ weeks-pos = "left";
+ format = {
+ today = "{}";
+ weekdays = "{}";
+ months = "{}";
+ weeks = "W{}";
+ days = "W{}";
+ };
+ };
+ format = "{:%EX}";
+ format-alt = "{:%F %A}";
+ };
+
+ mpd = {
+ server = "/run/user/1000/mpd_socket";
+ max-length = 55;
+ interval = 1;
+
+ format = "{artist} - {title} [{elapsedTime:%M:%S}/{totalTime:%M:%S}] ";
+ format-disconnected = "disconnected [--:--] ";
+ format-stopped = "[--:--] ";
+
+ repeat-icons = {
+ off = "-";
+ on = "z";
+ };
+ single-icons = {
+ off = "-";
+ on = "s";
+ };
+ consume-icons = {
+ off = "-";
+ on = "c";
+ };
+ state-icons = {
+ paused = "";
+ playing = "";
+ };
+
+ tooltip-format = "status: [{repeatIcon}{randomIcon}{singleIcon}{consumeIcon}]";
+ tooltip-format-disconnected = "MPD (disconnected)";
+
+ on-click-right = "mpc toggle";
+ };
+
+ "niri/workspaces" = {
+ format = "{icon}楼";
+ current-only = true;
+ format-icons = {
+ "1" = "一";
+ "2" = "二";
+ "3" = "三";
+ "4" = "四";
+ "5" = "五";
+ };
+ };
+
+ tray = {
+ icon-size = 23;
+ };
+
+ wireplumber = {
+ format = "{volume}% {icon} ";
+ format-muted = "muted ";
+ on-click = "pwvucontrol";
+ format-icons = [
+ ""
+ ""
+ ""
+ ];
+ };
+ };
+ };
+ style = builtins.readFile ../../files/waybar/style.css;
+ };
+}
diff --git a/modules/desktop/wezterm.nix b/modules/desktop/wezterm.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/wezterm.nix
@@ -0,0 +1,6 @@
+{
+ programs.wezterm = {
+ enable = true;
+ extraConfig = builtins.readFile ../../files/wezterm/wezterm.lua;
+ };
+}
diff --git a/modules/desktop/wofi.nix b/modules/desktop/wofi.nix
new file mode 100644
--- /dev/null
+++ b/modules/desktop/wofi.nix
@@ -0,0 +1,16 @@
+{
+ programs.wofi = {
+ enable = true;
+ settings = {
+ show = "drun";
+ width = 300;
+ prompt = "type to search...";
+ allow_images = true;
+ insensitive = true;
+ gtk_dark = true;
+ image_size = 18;
+ line_wrap = "word";
+ };
+ style = ../../files/wofi/style.css;
+ };
+}
diff --git a/modules/email.nix b/modules/email.nix
new file mode 100644
--- /dev/null
+++ b/modules/email.nix
@@ -0,0 +1,57 @@
+{ lib, config, ... }:
+{
+ accounts.email.maildirBasePath = "mail";
+ accounts.email.accounts = {
+ "monke" = {
+ enable = true;
+ primary = true;
+ address = "monke@monke.moe";
+ userName = "monke@monke.moe";
+ realName = "Aaron Chen";
+ folders = {
+ drafts = "Drafts";
+ inbox = "INBOX";
+ sent = "Sent";
+ trash = "Trash";
+ };
+ imap = {
+ authentication = "plain";
+ host = "imap.purelymail.com";
+ port = 993;
+ };
+ smtp = {
+ tls.useStartTls = true;
+ host = "smtp.purelymail.com";
+ port = 587;
+ };
+ passwordCommand = lib.strings.concatStrings [
+ "cat "
+ config.sops.secrets."email/pass".path
+ ];
+ astroid.enable = true;
+ msmtp.enable = true;
+ notmuch.enable = true;
+ mbsync.enable = true;
+ };
+ };
+
+ programs.astroid = {
+ enable = true;
+ externalEditor = "neovide -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
+ pollScript = ''
+ mbsync monke
+ notmuch new
+ '';
+ };
+ programs.mbsync.enable = true;
+ programs.msmtp.enable = true;
+ programs.notmuch = {
+ enable = true;
+ extraConfig = {
+ user = {
+ name = "Aaron Chen";
+ primary_email = "monke@monke.moe";
+ };
+ };
+ };
+}
diff --git a/modules/rclone.nix b/modules/rclone.nix
new file mode 100644
--- /dev/null
+++ b/modules/rclone.nix
@@ -0,0 +1,39 @@
+{ config, ... }:
+{
+ programs.rclone = {
+ enable = true;
+ remotes = {
+ nc = {
+ config = {
+ type = "webdav";
+ vendor = "nextcloud";
+ };
+ secrets = {
+ url = config.sops.secrets."nextcloud/url".path;
+ user = config.sops.secrets."nextcloud/user".path;
+ pass = config.sops.secrets."nextcloud/pass".path;
+ };
+ mounts = {
+ "/" = {
+ enable = true;
+ mountPoint = "${config.home.homeDirectory}/nc";
+ options = {
+ dir-cache-time = "5000h";
+ poll-interval = "60s";
+ umask = "002";
+ };
+ };
+ "/backups/sidebery" = {
+ enable = true;
+ mountPoint = "${config.xdg.userDirs.download}/sidebery";
+ options = {
+ dir-cache-time = "5000h";
+ poll-interval = "5m";
+ umask = "002";
+ };
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/server/tmux.nix b/modules/server/tmux.nix
new file mode 100644
--- /dev/null
+++ b/modules/server/tmux.nix
@@ -0,0 +1,21 @@
+{
+ programs.tmux = {
+ enable = true;
+ historyLimit = 100000;
+ mouse = true;
+ extraConfig = ''
+ set -g mouse on
+ set -g terminal-overrides ",xterm*:Tc"
+
+ set -g status-bg "#2e2629"
+ set -g status-fg colour4
+ set -g status-interval 1
+ set -g status-right '#{USER}@#{host}'
+
+ set -g status-position top
+
+ setw -g window-status-current-style 'fg=colour0 bg=colour4 bold'
+ setw -g window-status-current-format ' #I #W #F '
+ '';
+ };
+}
diff --git a/modules/wlsunset.nix b/modules/wlsunset.nix
new file mode 100644
--- /dev/null
+++ b/modules/wlsunset.nix
@@ -0,0 +1,11 @@
+{
+ services.wlsunset = {
+ enable = true;
+ temperature = {
+ day = 6500;
+ night = 3500;
+ };
+ sunrise = "07:00";
+ sunset = "18:00";
+ };
+}
diff --git a/music.nix b/music.nix
deleted file mode 100644
--- a/music.nix
+++ /dev/null
@@ -1,86 +0,0 @@
-{ config, pkgs, ... }:
-{
- programs = {
- inori = {
- enable = false;
- settings = {
- mpd_address = "/run/user/1000/mpd_socket";
- };
- };
-
- ncmpcpp = {
- enable = true;
- package = pkgs.ncmpcpp.override {
- visualizerSupport = true;
- };
- settings = {
- progressbar_look = "━━";
- display_bitrate = true;
- user_interface = "alternative";
- ncmpcpp_directory = "~/.config/ncmpcpp";
- mpd_host = "/run/user/1000/mpd_socket";
- };
- };
- };
-
- services = {
- mopidy = {
- enable = false;
- extensionPackages = with pkgs; [
- mopidy-mpd
- mopidy-mpris
- mopidy-subidy
- ];
- settings = {
- mpris = {
- enabled = true;
- };
- subidy = {
- enabled = true;
- url = "http://10.0.0.10:4533";
- username = "monke";
- password = "kyacnn8Xc3yDMSA$c50QfkcW49JA8aG$7VcWx#AzcIGm$X0FdL2BVkw";
- };
- mpd = {
- enabled = true;
- hostname = "unix:/run/user/1000/mpd_socket";
- };
- file = {
- enabled = true;
- media_dirs = [
- "~/music"
- ];
- excluded_file_extensions = [
- ".html"
- ".zip"
- ".jpg"
- ".jpeg"
- ".png"
- ];
- };
- http = {
- enabled = false;
- };
- };
- };
- mpd = {
- enable = true;
- network = {
- listenAddress = "/run/user/1000/mpd_socket";
- };
- extraConfig = ''
- audio_output {
- type "fifo"
- name "my_fifo"
- path "/tmp/mpd.fifo"
- format "44100:16:2"
- }
-
- audio_output {
- type "pipewire"
- name "pipewire"
- }
- '';
- };
- };
-}
diff --git a/niri.nix b/niri.nix
deleted file mode 100644
--- a/niri.nix
+++ /dev/null
@@ -1,322 +0,0 @@
-{ config, pkgs, niri, ... }: let
- inherit (niri.lib.kdl) node plain leaf flag;
-in {
- programs.niri = {
- enable = true;
- package = pkgs.niri-stable;
- settings = {
- spawn-at-startup = [
- { command = [ "nm-applet" ]; }
- { command = [ "swww-daemon" ]; }
- { command = [ "swaybg" "-c" "b79fa8" ]; }
- { command = [ "eww" "daemon" ]; }
- { command = [ "xwayland-satellite" ]; }
- ];
-
- workspaces."1" = {};
- workspaces."2" = {};
- workspaces."3" = {};
- workspaces."4" = {};
-
- cursor = {
- theme = "breeze-dark";
- size = 48;
- };
-
- input = {
- focus-follows-mouse = {
- enable = true;
- max-scroll-amount = "10%";
- };
-
- keyboard.xkb = {
- layout = "us";
- variant = "colemak_dh_ortho";
- };
-
- touchpad = {
- accel-profile = "adaptive";
- accel-speed = 1.0;
- dwt = true;
- natural-scroll = false;
- };
-
- mouse = {
- accel-profile = "flat";
- accel-speed = 1.0;
- };
-
- warp-mouse-to-focus.enable = true;
- };
-
- outputs."eDP-1" = {
- mode = {
- width = 3024;
- height = 1890;
- refresh = 60.0;
- };
- scale = 1.5;
- variable-refresh-rate = true;
- };
-
- layout = {
- gaps = 15;
- center-focused-column = "never";
- preset-column-widths = [
- { proportion = 1. / 3.; }
- { proportion = 1. / 2.; }
- { proportion = 2. / 3.; }
- ];
- default-column-width.proportion = 1. / 2.;
-
- focus-ring.enable = false;
-
- border = {
- enable = true;
- width = 2.5;
- active.color = "#b15c66";
- inactive.color = "#b1888d";
- };
-
- shadow = {
- enable = true;
- softness = 10;
- spread = 2;
- offset = {
- x = 3;
- y = 3;
- };
- color = "#0009";
- };
- };
-
- layer-rules = [
- {
- matches = [
- { namespace = "^wallpaper$"; }
- ];
- place-within-backdrop = true;
- }
- ];
-
- animations = {
- workspace-switch.kind.spring = {
- damping-ratio = 0.8;
- stiffness = 800;
- epsilon = 0.0001;
- };
-
- window-open = {
- kind.spring = {
- damping-ratio = 0.8;
- stiffness = 800;
- epsilon = 0.0001;
- };
-
- custom-shader = builtins.readFile ./files/niri/window-open.glsl;
- };
-
- window-close = {
- kind.easing = {
- curve = "linear";
- duration-ms = 250;
- };
-
- custom-shader = builtins.readFile ./files/niri/window-close.glsl;
- };
-
- horizontal-view-movement.kind.spring = {
- damping-ratio = 1.0;
- stiffness = 800;
- epsilon = 0.0001;
- };
-
- window-movement.kind.spring = {
- damping-ratio = 1.0;
- stiffness = 800;
- epsilon = 0.0001;
- };
-
- window-resize.kind.spring = {
- damping-ratio = 1.0;
- stiffness = 800;
- epsilon = 0.0001;
- };
-
- config-notification-open-close.kind.spring = {
- damping-ratio = 0.6;
- stiffness = 1000;
- epsilon = 0.001;
- };
- };
-
- window-rules = [
- {
- matches = [
- {
- title = "^Picture-in-Picture$";
- }
- ];
- open-floating = true;
- }
- {
- geometry-corner-radius = {
- bottom-left = 8.0;
- bottom-right = 8.0;
- top-left = 8.0;
- top-right = 8.0;
- };
- clip-to-geometry = true;
- }
- ];
-
- binds = with config.lib.niri.actions; {
- "Mod+Shift+Slash".action = show-hotkey-overlay;
-
- "Mod+Return".action = spawn "wezterm";
- "Mod+Space".action = spawn "wofi" "--show" "drun";
- "Mod+Alt+Space".action = spawn "sh" "-c" "cliphist-wofi-img | wl-copy";
- "Mod+Shift+3".action = spawn "screenshot";
- "Mod+Shift+4".action = spawn "screenshot" "area";
- "Mod+X".action = spawn "clipclear";
- "Super+Alt+L".action = spawn "hyprlock";
-
- "XF86AudioRaiseVolume" = {
- allow-when-locked = true;
- action = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "2%+" "-l" "1.0";
- };
- "XF86AudioLowerVolume" = {
- allow-when-locked = true;
- action = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "2%-";
- };
- "XF86AudioMute" = {
- allow-when-locked = true;
- action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle";
- };
- "XF86AudioMicMute" = {
- allow-when-locked = true;
- action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle";
- };
- "XF86AudioPlay" = {
- allow-when-locked = true;
- action = spawn "playerctl" "play-pause";
- };
-
- "Mod+Q".action = close-window;
-
- "Mod+Left".action = focus-column-left;
- "Mod+Down".action = focus-window-down;
- "Mod+Up".action = focus-window-up;
- "Mod+Right".action = focus-column-right;
-
- "Mod+Ctrl+Left".action = move-column-left;
- "Mod+Ctrl+Down".action = move-window-down;
- "Mod+Ctrl+Up".action = move-window-up;
- "Mod+Ctrl+Right".action = move-column-right;
-
- "Mod+Shift+Left".action = focus-monitor-left;
- "Mod+Shift+Down".action = focus-monitor-down;
- "Mod+Shift+Up".action = focus-monitor-up;
- "Mod+Shift+Right".action = focus-monitor-right;
-
- "Mod+Shift+Ctrl+Left".action = move-column-to-monitor-left;
- "Mod+Shift+Ctrl+Down".action = move-column-to-monitor-down;
- "Mod+Shift+Ctrl+Up".action = move-column-to-monitor-up;
- "Mod+Shift+Ctrl+Right".action = move-column-to-monitor-right;
-
- "Mod+Page_Down".action = focus-workspace-down;
- "Mod+Page_Up".action = focus-workspace-up;
- "Mod+U".action = focus-workspace-down;
- "Mod+I".action = focus-workspace-up;
- "Mod+Alt+Ctrl+Down".action = move-column-to-workspace-down;
- "Mod+Alt+Ctrl+Up".action = move-column-to-workspace-up;
- "Mod+Ctrl+U".action = move-column-to-workspace-down;
- "Mod+Ctrl+I".action = move-column-to-workspace-up;
-
- "Mod+Shift+Page_Down".action = move-workspace-down;
- "Mod+Shift+Page_Up".action = move-workspace-up;
- "Mod+Shift+U".action = move-workspace-down;
- "Mod+Shift+I".action = move-workspace-up;
-
- "Mod+WheelScrollDown" = {
- cooldown-ms = 150;
- action = focus-workspace-down;
- };
- "Mod+WheelScrollUp" = {
- cooldown-ms = 150;
- action = focus-workspace-up;
- };
- "Mod+Ctrl+WheelScrollDown" = {
- cooldown-ms = 150;
- action = move-column-to-workspace-down;
- };
- "Mod+Ctrl+WheelScrollUp" = {
- cooldown-ms = 150;
- action = move-column-to-workspace-up;
- };
-
- "Mod+WheelScrollRight".action = focus-column-right;
- "Mod+WheelScrollLeft".action = focus-column-left;
- "Mod+Ctrl+WheelScrollRight".action = move-column-right;
- "Mod+Ctrl+WheelScrollLeft".action = move-column-left;
-
- "Mod+Shift+WheelScrollDown".action = focus-column-right;
- "Mod+Shift+WheelScrollUp".action = focus-column-left;
- "Mod+Ctrl+Shift+WheelScrollDown".action = move-column-right;
- "Mod+Ctrl+Shift+WheelScrollUp".action = move-column-left;
-
- "Mod+1".action = focus-workspace 1;
- "Mod+2".action = focus-workspace 2;
- "Mod+3".action = focus-workspace 3;
- "Mod+4".action = focus-workspace 4;
- "Mod+5".action = focus-workspace 5;
- #"Mod+Ctrl+1".action = move-column-to-workspace-index 1;
- #"Mod+Ctrl+2".action = move-column-to-workspace-index 2;
- #"Mod+Ctrl+3".action = move-column-to-workspace-index 3;
- #"Mod+Ctrl+4".action = move-column-to-workspace-index 4;
- #"Mod+Ctrl+5".action = move-column-to-workspace-index 5;
-
- "Mod+BracketLeft".action = consume-or-expel-window-left;
- "Mod+BracketRight".action = consume-or-expel-window-right;
-
- "Mod+Comma".action = consume-window-into-column;
- "Mod+Period".action = expel-window-from-column;
-
- "Mod+R".action = switch-preset-column-width;
- "Mod+Shift+R".action = switch-preset-window-height;
- "Mod+Ctrl+R".action = reset-window-height;
- "Mod+F".action = maximize-column;
- "Mod+Shift+F".action = fullscreen-window;
-
- "Mod+Ctrl+F".action = expand-column-to-available-width;
-
- "Mod+C".action = center-column;
-
- "Mod+Minus".action = set-column-width "-10%";
- "Mod+Equal".action = set-column-width "+10%";
-
- "Mod+Shift+Minus".action = set-window-height "-10%";
- "Mod+Shift+Equal".action = set-window-height "+10%";
-
- "Mod+V".action = toggle-window-floating;
- "Mod+Shift+V".action = switch-focus-between-floating-and-tiling;
-
- "Mod+W".action = toggle-column-tabbed-display;
-
- "Mod+Escape" = {
- allow-inhibiting = false;
- action = toggle-keyboard-shortcuts-inhibit;
- };
-
- "Mod+Shift+E".action = quit;
- "Ctrl+Alt+Delete".action = quit;
-
- "Mod+Shift+P".action = power-off-monitors;
- };
-
- debug = {
- render-drm-device = "/dev/dri/renderD128";
- };
- };
- };
-}
diff --git a/nixos/core/doas.nix b/nixos/core/doas.nix
new file mode 100644
--- /dev/null
+++ b/nixos/core/doas.nix
@@ -0,0 +1,15 @@
+{
+ security = {
+ doas = {
+ enable = true;
+ extraRules = [
+ {
+ groups = [ "wheel" ];
+ keepEnv = true;
+ persist = true;
+ }
+ ];
+ };
+ sudo.enable = false;
+ };
+}
diff --git a/nixos/core/nix.nix b/nixos/core/nix.nix
new file mode 100644
--- /dev/null
+++ b/nixos/core/nix.nix
@@ -0,0 +1,8 @@
+{
+ nix.settings = {
+ experimental-features = "nix-command flakes";
+ trusted-users = [
+ "@wheel"
+ ];
+ };
+}
diff --git a/nixos/core/packages.nix b/nixos/core/packages.nix
new file mode 100644
--- /dev/null
+++ b/nixos/core/packages.nix
@@ -0,0 +1,42 @@
+{ pkgs, lib, ... }:
+
+{
+ nixpkgs.overlays = [
+ (final: prev: {
+ musescore = prev.musescore.overrideAttrs (old: {
+ version = "4.6.0-unstable-2025-08-10";
+ src = prev.fetchFromGitHub {
+ owner = "musescore";
+ repo = "MuseScore";
+ rev = "afb7b910e53d8a41c2554f229092a82425beaa6d";
+ hash = "sha256-QtiZigGw2H3u9p0OVdVN2scCouFASKS/DRzL/gQI4zw=";
+ };
+ buildInputs = old.buildInputs ++ [
+ pkgs.pipewire
+ ];
+ cmakeFlags = old.cmakeFlags ++ [
+ "-DMUSE_PIPEWIRE_AUDIO_DRIVER=ON"
+ ];
+ patches = [
+ (prev.fetchpatch {
+ url = "https://github.com/monke0192/MuseScore/commit/45e87e3d973c222fa9b894e645af46676a5586e5.patch";
+ hash = "sha256-10gAH76YVNnVdcPMcNBSXNNCQ1h9/1wsjp5urVQbep0=";
+ })
+ ];
+ });
+ })
+ ];
+
+ nixpkgs.config.allowUnfreePredicate =
+ pkg:
+ builtins.elem (lib.getName pkg) [
+ "firefox-bin"
+ "firefox-bin-unwrapped"
+ "libfprint-2-tod1-elan"
+ "steam"
+ "steam-original"
+ "steam-run"
+ "steam-unwrapped"
+ "storcli"
+ ];
+}
diff --git a/nixos/server/acme.nix b/nixos/server/acme.nix
new file mode 100644
--- /dev/null
+++ b/nixos/server/acme.nix
@@ -0,0 +1,22 @@
+{ config, ... }:
+
+{
+ sops.secrets = {
+ "cloudflare/token" = { };
+ };
+
+ security.acme = {
+ acceptTerms = true;
+ defaults = {
+ email = "monke+acme@monke.moe";
+ group = config.services.nginx.user;
+ };
+ certs."monke.moe" = {
+ dnsProvider = "cloudflare";
+ extraDomainNames = [ "*.monke.moe" ];
+ credentialFiles = {
+ "CF_DNS_API_TOKEN_FILE" = config.sops.secrets."cloudflare/token".path;
+ };
+ };
+ };
+}
diff --git a/nixos/server/docker.nix b/nixos/server/docker.nix
new file mode 100644
--- /dev/null
+++ b/nixos/server/docker.nix
@@ -0,0 +1,3 @@
+{
+ virtualisation.docker.enable = true;
+}
diff --git a/nixos/server/nginx.nix b/nixos/server/nginx.nix
new file mode 100644
--- /dev/null
+++ b/nixos/server/nginx.nix
@@ -0,0 +1,185 @@
+{ pkgs, config, ... }:
+
+{
+ sops.secrets = {
+ "ssl/cert" = {
+ owner = config.services.nginx.user;
+ };
+ "ssl/key" = {
+ owner = config.services.nginx.user;
+ };
+ };
+
+ networking.firewall.allowedTCPPorts = [
+ 80
+ 443
+ ];
+
+ services.nginx = {
+ enable = true;
+ recommendedProxySettings = true;
+ recommendedGzipSettings = true;
+ recommendedTlsSettings = true;
+ recommendedOptimisation = true;
+ clientMaxBodySize = "10G";
+ upstreams = {
+ nc.servers."127.0.0.1:8081" = { };
+ };
+ appendHttpConfig = ''
+ map $arg_v $asset_immutable {
+ "" "";
+ default ", immutable";
+ }
+ '';
+ virtualHosts = {
+ "jellyfin.forest.monke" = {
+ onlySSL = true;
+ http2 = true;
+ sslCertificate = config.sops.secrets."ssl/cert".path;
+ sslCertificateKey = config.sops.secrets."ssl/key".path;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8096";
+ };
+ };
+ "monke.moe" = {
+ onlySSL = true;
+ useACMEHost = "monke.moe";
+ http2 = true;
+ locations."/" = {
+ return = ''200 "under construction
"'';
+ };
+ };
+ "music.forest.monke" = {
+ onlySSL = true;
+ http2 = true;
+ sslCertificate = config.sops.secrets."ssl/cert".path;
+ sslCertificateKey = config.sops.secrets."ssl/key".path;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:4533";
+ };
+ };
+ "nextcloud.monke.moe" = {
+ onlySSL = true;
+ useACMEHost = "monke.moe";
+ http2 = true;
+ root = "/var/www/html";
+ extraConfig = ''
+ client_body_buffer_size 512k;
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "noindex, nofollow" always;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
+ fastcgi_hide_header X-Powered-By;
+ include ${pkgs.nginx}/conf/mime.types;
+ types {
+ text/javascript mjs;
+ application/wasm wasm;
+ }
+ index index.php index.html /index.php$request_uri;
+ location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ {
+ try_files $uri /index.php$request_uri;
+ add_header Cache-Control "public, max-age=15778463$asset_immutable";
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "noindex, nofollow" always;
+ }
+ '';
+ locations = {
+ "= /".extraConfig = ''
+ if ( $http_user_agent ~ ^DavClnt ) {
+ return 302 /remote.php/webdav/$is_args$args;
+ }
+ '';
+ "= robots.txt".extraConfig = ''
+ allow all;
+ log_not_found off;
+ access_log off;
+ '';
+ "^~ /.well-known" = {
+ extraConfig = ''
+ location = /.well-known/carddav { return 301 /remote.php/dav/; }
+ location = /.well-known/caldav { return 301 /remote.php/dav/; }
+ '';
+ return = "301 /index.php$request_uri";
+ };
+ "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".return = "404";
+ "~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)".return = "404";
+ /*
+ "~ \\.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$" = {
+ tryFiles = "$uri /index.php$request_uri";
+ extraConfig = ''
+ add_header Cache-Control "public, max-age=15778463$asset_immutable";
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "noindex, nofollow" always;
+ '';
+ };
+ */
+ "~ \\.php(?:$|/)" = {
+ extraConfig = ''
+ rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ set $path_info $fastcgi_path_info;
+ try_files $fastcgi_script_name =404;
+ fastcgi_pass nc;
+ fastcgi_intercept_errors on;
+ fastcgi_request_buffering on;
+ fastcgi_max_temp_file_size 0;
+ include ${pkgs.nginx}/conf/fastcgi.conf;
+ '';
+
+ fastcgiParams = {
+ "SCRIPT_FILENAME" = "$document_root$fastcgi_script_name";
+ "PATH_INFO" = "$path_info";
+ "HTTPS" = "on";
+ "modHeadersAvailable" = "true";
+ "front_controller_active" = "true";
+ };
+ };
+ "~ \\.(otf|woff2?)$" = {
+ tryFiles = "$uri /index.php$request_uri";
+ extraConfig = "expires 7d;";
+ };
+ "/remote".return = "301 /remote.php$request_uri";
+ "/".tryFiles = "$uri $uri/ /index.php$request_uri";
+ };
+ };
+ "piped.forest.monke" = {
+ serverAliases = [
+ "pipedapi.forest.monke"
+ "pipedproxy.forest.monke"
+ ];
+ onlySSL = true;
+ http2 = true;
+ sslCertificate = config.sops.secrets."ssl/cert".path;
+ sslCertificateKey = config.sops.secrets."ssl/key".path;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8085";
+ };
+ };
+ "search.monke.moe" = {
+ onlySSL = true;
+ useACMEHost = "monke.moe";
+ http2 = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8086";
+ };
+ };
+ "vault.forest.monke" = {
+ onlySSL = true;
+ http2 = true;
+ sslCertificate = config.sops.secrets."ssl/cert".path;
+ sslCertificateKey = config.sops.secrets."ssl/key".path;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8084";
+ };
+ };
+ };
+ };
+}
diff --git a/nixos/server/print.nix b/nixos/server/print.nix
new file mode 100644
--- /dev/null
+++ b/nixos/server/print.nix
@@ -0,0 +1,19 @@
+{
+ services.avahi = {
+ enable = true;
+ nssmdns4 = true;
+ openFirewall = true;
+ publish = {
+ enable = true;
+ userServices = true;
+ };
+ };
+ services.printing = {
+ enable = true;
+ listenAddresses = [ "*:631" ];
+ allowFrom = [ "all" ];
+ browsing = true;
+ defaultShared = true;
+ openFirewall = true;
+ };
+}
diff --git a/nixos/server/ssh.nix b/nixos/server/ssh.nix
new file mode 100644
--- /dev/null
+++ b/nixos/server/ssh.nix
@@ -0,0 +1,10 @@
+{
+ services.openssh = {
+ enable = true;
+ ports = [ 69 ];
+ settings = {
+ PasswordAuthentication = false;
+ PermitRootLogin = "no";
+ };
+ };
+}
diff --git a/nixos/server/systemd.nix b/nixos/server/systemd.nix
new file mode 100644
--- /dev/null
+++ b/nixos/server/systemd.nix
@@ -0,0 +1,13 @@
+{
+ systemd.services."nextcloud-bg-job" = {
+ script = ''
+ cd /srv/compose/nextcloud
+ /run/current-system/sw/bin/docker compose exec -u 60 app php -f /var/www/html/cron.php > /dev/null
+ '';
+ serviceConfig = {
+ Type = "oneshot";
+ User = "monke";
+ };
+ startAt = "*:0/5";
+ };
+}
diff --git a/programs.nix b/programs.nix
deleted file mode 100644
--- a/programs.nix
+++ /dev/null
@@ -1,102 +0,0 @@
-{ inputs, pkgs, config, ... }:
-{
- programs = {
- git = {
- enable = true;
- userName = "Aaron Chen";
- userEmail = "monke@monke.moe";
- };
- gpg = {
- enable = true;
- };
- neovide.enable = true;
- firefox = {
- enable = true;
- languagePacks = [ "en-GB" "en-US" ];
- policies = {
- DefaultDownloadDirectory = "\${home}/dl";
- DisableBuiltinPDFViewer = true;
- DisablePocket = true;
- DisableTelemetry = true;
- EnableTrackingProtection = true;
- FirefoxHome = {
- Search = true;
- TopSites = false;
- SponsoredTopSites = false;
- Highlights = false;
- Pocket = false;
- SponsoredPocket = false;
- Snippets = false;
- Locked = true;
- };
- };
- policies.Preferences = {
- "browser.aboutConfig.showWarning" = false;
- "browser.shell.checkDefaultBrowser" = false;
- "browser.toolbars.bookmarks.visibility" = "never";
- "devtools.everOpened" = true;
- "mousewheel.with_control.action" = 5;
- "sidebar.revamp" = true;
- "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
- };
- policies.ExtensionSettings = {
- "uBlock0@raymondhill.net" = {
- install_url = "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi";
- installation_mode = "force_installed";
- private_browsing = true;
- };
- "{3c078156-979c-498b-8990-85f7987dd929}" = {
- install_url = "https://addons.mozilla.org/firefox/downloads/latest/sidebery/latest.xpi";
- private_browsing = true;
- };
- "@testpilot-containers" = {
- install_url = "https://addons.mozilla.org/firefox/downloads/latest/multi-account-containers/latest.xpi";
- installation_mode = "force_installed";
- private_browsing = false;
- };
- };
- profiles.default = {
- isDefault = true;
- containersForce = true;
- containers = {
- school = {
- id = 0;
- color = "purple";
- icon = "circle";
- };
-
- shopping = {
- id = 1;
- name = "online shopping";
- color = "green";
- icon = "dollar";
- };
- };
- search = {
- default = "ddg";
- engines = {
- "ddg" = {
- urls = [{
- template = "https://duckduckgo.com/?q={searchTerms}";
- }];
- definedAliases = [ "@ddg" ];
- };
-
- "piped" = {
- urls = [{
- template = "https://piped.forest.monke/results?search_query={searchTerms}";
- }];
- definedAliases = [ "yt" ];
- };
- };
- force = true;
- };
- userChrome = builtins.readFile ./files/firefox/userChrome.css;
- };
- };
-
- zsh = {
- enable = true;
- };
- };
-}
diff --git a/secrets/bathtub.yaml b/secrets/bathtub.yaml
new file mode 100644
--- /dev/null
+++ b/secrets/bathtub.yaml
@@ -0,0 +1,24 @@
+passwords:
+ monke: ENC[AES256_GCM,data:xhD933/Ko5bH518jLgNkwfKgDvm7g5edxGDYx7yOKwAkqaDcWMhoxx0T6JdrhWcMNEeQmcqkruNcw2GMETHoqNAa/VlF03NxFA==,iv:+pM27zC3ImGSlCQmLTSHtf/ByOXw7XjLujH4CX0h5nA=,tag:2VayIhXd/WJZ/CyvuupL2w==,type:str]
+ root: ENC[AES256_GCM,data:8vDiU7Ul123JVVW7pm9iXZpdNdCQ4WBSHlR4EOQ6WeDeGBB5mPHZn/fBovtqqd4uneFQE6c4Bz3AACxwfORLCDYVq2+qJ2pF2Q==,iv:SgPByyB2vcsCGiHGQUFu/Naxk37y0P8shtMVtVOe9cg=,tag:6543kqB5USp1cWon+/1a7g==,type:str]
+nextcloud:
+ url: ENC[AES256_GCM,data:bNaCQtyKbxLszoxb5RcW8yvSEPWmTuORwiQM6VWo4EA4QWGtC5NCEnOdNcwW4RY+NN+3hJMe/KI/+u0nsZqbMA==,iv:YihIMDrj+bMH0U77iQGiNYf+KQdWpE5iAIqFBfiAAIM=,tag:VFamc0pZMSmzL9NQGQYspg==,type:str]
+ user: ENC[AES256_GCM,data:daDcTdgTZkynUaw69JLz,iv:zEwMnKynA9jiJLApotoek5LR2I4jXAm5ZD47mevv76o=,tag:IvCdVS/3dpFeowp4hzPOng==,type:str]
+ pass: ENC[AES256_GCM,data:hdKJFcJN2ZVnghnE9RXl8dd/JSEm3ux9lbaUU2RPZmMIDJPl1ZULtKmhlnIXVzc8igbIlMC+6Lb4Q+OE,iv:OSw8bONezUlpIHJsLKl16lIn05J7bWjA01qGNa25ks0=,tag:j5mJOmiAklJcRm/i91jmfQ==,type:str]
+email:
+ pass: ENC[AES256_GCM,data:V2IeBYisyZZwiIVc06HCS1vaY/A=,iv:JGiXfdz/jOVAJCT2mvhapNFWbpOp+NsUt+bMp+LadUU=,tag:3E+O+PL3Cd3ht/bM9QoqAw==,type:str]
+sops:
+ age:
+ - recipient: age1zqclazll796z6rzxtwn2ethpfnqmfhr23a3uy2ydqvt3weps94fq9rmtdt
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpY3RFSmdMWHJ2R2ZnS0dS
+ RjV0RFJQMXY4NGo4SmpQaDJHRFNpcmpEcmd3CkV6YWd0NW5VNkZ0aUF6UUFxa09q
+ MnJVZlpKVFRZdGRvVGJmQzdDcCtIejgKLS0tIHFmVTRYditkQU8wMTVIUGorNjFq
+ QkpkTDQrYU00VzZpQXhOVzAvT252VlEKeDi+e6ayEDXwBnQuLvQM4WFKJ/L0G/U3
+ oeH8BzGDbiMdhjDqj5H7IbGFLd5CjRYBg1SGZ3y6glw/P6Brmh7uXg==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2025-09-25T21:37:00Z"
+ mac: ENC[AES256_GCM,data:54Z5+nSZ1FpRjChCmCgxy5+f9Hnf8+p9mIHXXfaEt5EnP5Wmn5jbdwINcuJlhh85i+f9m2rF8OqtvNYAg/FZRyDzGWw34tUqWfToxVdLsSPkJxH6cexb0hiBKm9qgoTCxnmyNsW2ZqxoFEJfRX8tB1NV+yjyI6TwNf16+J/i6bc=,iv:Wp4tdi+3+R3wI1hBTkV7Zc+VZc1UY3Xb3uzuZvtEqlI=,tag:h2bLecWrxN3eOugau3kn6A==,type:str]
+ unencrypted_suffix: _unencrypted
+ version: 3.10.2
diff --git a/secrets/forest.yaml b/secrets/forest.yaml
new file mode 100644
--- /dev/null
+++ b/secrets/forest.yaml
@@ -0,0 +1,23 @@
+passwords:
+ root: ENC[AES256_GCM,data:4g87dG2Y+kz0zu66EpHZlObWwds1Arkjg1/nvxHrMErLhFB8M2rFOaNhS+RFQaYDwlhSXDWSinYXTp+7OipwWBPaC0Ad+C0+KQ==,iv:7lzxuV74uq6vvl+X7imIzPc019b6MbgSjyoMaiF0WIY=,tag:MXrANiv9cMnkyXNfIvWIcw==,type:str]
+ monke: ENC[AES256_GCM,data:kScs+gH39P8CuWsYBV9A4cGuItiyRb8Ea3155W1CmOTOdpBQPqAdalAeSyT8Otuik5H1lo1cRWNEHCT78qO03FtSjui08zrXCg==,iv:5ecPv00sUU0V7JoNcKHcllrah3AZyVvRaAFViwzqkFM=,tag:YMbAxmRTcIqgtd/Fs4QiEA==,type:str]
+cloudflare:
+ token: ENC[AES256_GCM,data:FdOz8az4OPq4LpQxGTpA8xk7TEpXX1CiihvjqXV/yu9GQCEKkZR2lg==,iv:MVndjxA+BR8hB7gsOeMnvQfxu3NS7xxirYVMULBZRCU=,tag:8X6l+I7VeddzTo/clu6PTQ==,type:str]
+ssl:
+ cert: ENC[AES256_GCM,data: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,iv:Q60z0N6AluZl81nwX3QuTY6mOqHcql8viakARLYOc6Y=,tag:BDOr3ozlSiAWMPSecdEPTA==,type:str]
+ key: ENC[AES256_GCM,data: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,iv:jokrMWx6iyXA5xPdU8SBVp3JUXyHHAFw7I/8UbLOxns=,tag:8x/iGXomMCA4+zDKlxZd9Q==,type:str]
+sops:
+ age:
+ - recipient: age1rgnhhehyjx66rxq793ac2vqq24semmzt4vru06ffamwxsmmhtfqqfax0np
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtbnBOaTVuK2QxMk8zTFNm
+ clFONFpIVm9CUWoyekhiN29nM1JRS3FKeGtrCkFaOEx5ZDQ3SDJ5eU0vTitYaHND
+ cHlGODR6dmdqWTd2dUI0U01ubHJCNVkKLS0tIDJVV1Vrd1dGdmt6dW8vN214OUdZ
+ Q0hjS2ZHamZXUHhCWE5MOHJIZ2xNa0kKUrtOBXmsBhwmDfehU0kDymfTCGaCSoBm
+ fwzrYdaF72+lxgvuqm8t6KK+x3yrz3/ksuVRvHPfgvM0cKp1D2vNKA==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2025-09-12T12:15:15Z"
+ mac: ENC[AES256_GCM,data:XJ0H3V3MpWTgZ2UkV3V9uq7ak3XWhMK/WsFKYzpDF+DkieCUpH5cZhyA1FbXNP4fs/M/p1vXrKPsnQM3Bw0Ev9vIPy1HJ39HK46RNSZ7re4LRo1hlZqUevIdRE8lRUR9FRN84hV5JEZA/UCMLyyYX1qijL9mbBAy1oVGjwcQ7ic=,iv:tpYdDkzguaufvNAQn9lnGn1YUaRrUFfypJ29/dpPAWk=,tag:QM0IdScTt7WbMLasejojpw==,type:str]
+ unencrypted_suffix: _unencrypted
+ version: 3.10.2
diff --git a/secrets/tundra.yaml b/secrets/tundra.yaml
new file mode 100644
--- /dev/null
+++ b/secrets/tundra.yaml
@@ -0,0 +1,22 @@
+passwords:
+ root: ENC[AES256_GCM,data:Z49FyfMjJtXfUQ6aqzD3ImUqAr5uOf7SeIagU0cfC106phYywB9otg7xP/EHTPCM9nM3wDmCuyjFbIwN2gkWcQcGMYI23ceiMg==,iv:RoqBoJ8jLXDAW82RmoeanGG61oTlOVT8Od9mZms7ytQ=,tag:n1lTXCT77qp8AWaXeJq+Gw==,type:str]
+ monke: ENC[AES256_GCM,data:JGJYeFqVwSOYL5z9r3EN0zwpfXrOC/2l/Jvt3KKOxKl751qskXWBUf10Cv55IWcBt4jGjM59u8FJu2PQLXDpvhbwJ5ttff3FSQ==,iv:aCEVGI1oD+gNAnWlAAa/NW7jc3ee/92Yhxl3S/uRoPQ=,tag:LRmQs2TQqZHYdIshb+GkqA==,type:str]
+nextcloud:
+ url: ENC[AES256_GCM,data:SejAvB084O73V546KskeFAeiGSazwru1+txWL8GojZ3IqqiLPT/Yog5ggpJEdQi/Hv71HoVpRRpDmAk4acCZtw==,iv:FWx7+MVEMf0eWptKBUNTlJT2p8oJbgvx4LUGcwO/4O8=,tag:PXlFp5ctieUD4SMhNVouTw==,type:str]
+ user: ENC[AES256_GCM,data:vYDZc3rTe2loIEYLql0X,iv:JiIkR0o8pjEZu+S2ppG6RB36BKemCSkSOFb7o5fwZnA=,tag:qaTioVTuVHUBsq3b8A65yg==,type:str]
+ pass: ENC[AES256_GCM,data:bXBBzdtqiZQcjY0d7PdGa6bL8rMNb3NNhBzzmT+P36jUHBPzD66NN87HBUKmbmk7fsZdY+S+8HpckL0B,iv:HrGoB9O/8lOO2rJ1xjposDSHJyM4olBD8/pKPDuQCDE=,tag:vCFF7bfK5Chn38OmMH62Lw==,type:str]
+sops:
+ age:
+ - recipient: age19av7xt9r3tyankhjel6kg2tgf4p5gtaf5lm9tch3tp2trh2z7cds0trsta
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrNmh1Mm9aajFkcnNlQ25j
+ Nm1yL3hzNS94VE9ZaFd5TGxCcFcxUHIxa1JvClhoMnJoYXNCbFJEaXVucnI3aEZQ
+ bGk0TDg2aGkyYlc3elAzZ1lKNHA2OTgKLS0tIElzS282Q2tBSnVNWU5UamI0OStk
+ Z3FrZXNqNDc1cW15bElXT2FGbFVUbkUKSHZEbwPNSMwN6hWDn2W8HxuZ1r4Pc5Gz
+ jOHrQOcdm+iz1lWnvoRVSa5bqpltDOI+KswTekl3poSSSbyif+aEUg==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2025-09-11T02:56:26Z"
+ mac: ENC[AES256_GCM,data:dZfytClDNJEhixFk46rFTrXjxy4KVuUqSPIENv4TuQvKuxo+m/oGWWAWeK4Uxjmk6b+/W1Z5WKDqs7XSW0PrZbLw03EX1s7dXRk2HBik1pALtR//c/aX5mz+DzeGP3NasmFb8J2YBbQ97VzD5le0U4wLh029o0zL8w/DLIvCuGM=,iv:UDt22ogTyY7Ys6aeLGYX0OwJtUh3/5drtRezztCtSrw=,tag:BaEqOzKDIifaFVm3Pe8jzw==,type:str]
+ unencrypted_suffix: _unencrypted
+ version: 3.10.2
diff --git a/services.nix b/services.nix
deleted file mode 100644
--- a/services.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{ config, pkgs, ... }:
-
-{
- services = {
- cliphist.enable = true;
-
- easyeffects = {
- enable = true;
- };
-
- gpg-agent = {
- enable = true;
- pinentry.package = pkgs.pinentry-tty;
- };
-
- swayidle = {
- enable = true;
- events = [{
- event = "before-sleep"; command = "hyprlock";
- }];
- timeouts = [{
- timeout = 600;
- command = "hyprlock";
- }];
- };
-
- udiskie.enable = true;
- };
-}
diff --git a/sioyek.nix b/sioyek.nix
deleted file mode 100644
--- a/sioyek.nix
+++ /dev/null
@@ -1,28 +0,0 @@
-{ config, pkgs, ... }:
-{
- programs.sioyek = {
- enable = true;
- bindings = {
- # main navigation
- "move_left" = "i";
- "move_down" = "n";
- "move_up" = "e";
- "move_right" = "m";
- # marks
- "move_visual_mark_down" = "n";
- "move_visual_mark_up" = "e";
- # search
- "next_item" = "k";
- "previous_item" = "K";
- # misc
- "set_mark" = "h";
- "toggle_custom_color" = "";
- };
- config = {
- custom_background_color = "0.18 0.14 0.16";
- custom_text_color = "0.89 0.867 0.87";
- startup_commands = "toggle_custom_color";
- ui_font = "Victor Mono";
- };
- };
-}
diff --git a/tundra/default.nix b/tundra/default.nix
new file mode 100644
--- /dev/null
+++ b/tundra/default.nix
@@ -0,0 +1,113 @@
+{
+ lib,
+ pkgs,
+ config,
+ ...
+}:
+
+{
+ imports = lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../nixos/core) ++ [
+ ./hardware.nix
+ ./programs.nix
+ ./disk-config.nix
+ ];
+
+ sops = {
+ defaultSopsFile = ../secrets/tundra.yaml;
+ age.keyFile = "/var/lib/sops-nix/tundra.txt";
+ secrets = {
+ "passwords/root".neededForUsers = true;
+ "passwords/monke".neededForUsers = true;
+ };
+ };
+
+ networking.hostName = "tundra";
+ networking.hostId = "b9a8fced";
+ networking.networkmanager.enable = true;
+
+ time.timeZone = "Australia/Melbourne";
+ i18n.defaultLocale = "en_AU.UTF-8";
+ console = {
+ font = "Lat2-Terminus16";
+ keyMap = lib.mkDefault "us";
+ useXkbConfig = true;
+ };
+
+ users.defaultUserShell = pkgs.zsh;
+ users.users = {
+ root.hashedPasswordFile = config.sops.secrets."passwords/root".path;
+ monke = {
+ isNormalUser = true;
+ extraGroups = [
+ "audio"
+ "disk"
+ "input"
+ "libvirtd"
+ "lp"
+ "plugdev"
+ "dialout"
+ "render"
+ "video"
+ "wheel"
+ ];
+ hashedPasswordFile = config.sops.secrets."passwords/monke".path;
+ };
+ };
+
+ services.xserver.xkb = {
+ layout = "us";
+ variant = "colemak_dh_ortho";
+ };
+
+ security.pki.certificateFiles = [
+ ../files/forest.pem
+ ];
+
+ specialisation = {
+ librebootFlash.configuration = {
+ boot.kernelParams = [
+ "iomem=relaxed"
+ ];
+ };
+ };
+
+ virtualisation = {
+ spiceUSBRedirection.enable = true;
+ libvirtd = {
+ enable = true;
+ qemu = {
+ package = pkgs.qemu_kvm;
+ runAsRoot = true;
+ swtpm.enable = true;
+ ovmf = {
+ enable = true;
+ packages = [
+ (pkgs.OVMF.override {
+ secureBoot = true;
+ tpmSupport = true;
+ }).fd
+ ];
+ };
+ vhostUserPackages = with pkgs; [
+ virtiofsd
+ ];
+ };
+ };
+ kvmgt = {
+ enable = true;
+ vgpus = {
+ "i915-GVTg_V5_4" = {
+ uuid = [ "182a5376-ace2-47aa-bc00-ab50df01f774" ];
+ };
+ };
+ };
+ };
+
+ services."06cb-009a-fingerprint-sensor" = {
+ enable = true;
+ backend = "libfprint-tod";
+ calib-data-file = ../files/calib-data.bin;
+ };
+
+ system.stateVersion = "25.11";
+}
diff --git a/tundra/disk-config.nix b/tundra/disk-config.nix
new file mode 100644
--- /dev/null
+++ b/tundra/disk-config.nix
@@ -0,0 +1,72 @@
+{
+ disko.devices = {
+ disk = {
+ main = {
+ device = "/dev/nvme0n1";
+ type = "disk";
+ content = {
+ type = "gpt";
+ partitions = {
+ mbr = {
+ size = "1M";
+ type = "EF02";
+ };
+ swap = {
+ size = "16G";
+ content = {
+ type = "swap";
+ discardPolicy = "both";
+ resumeDevice = true;
+ };
+ };
+ boot = {
+ size = "2G";
+ content = {
+ type = "filesystem";
+ format = "ext2";
+ mountpoint = "/boot";
+ };
+ };
+ pool = {
+ size = "100%";
+ content = {
+ type = "zfs";
+ pool = "tundra";
+ };
+ };
+ };
+ };
+ };
+ };
+ zpool = {
+ tundra = {
+ type = "zpool";
+ rootFsOptions = {
+ compression = "zstd";
+ acltype = "posixacl";
+ xattr = "sa";
+ mountpoint = "none";
+ relatime = "on";
+ "com.sun:auto-snapshot" = "false";
+ };
+ options = {
+ autotrim = "on";
+ };
+ datasets = {
+ root = {
+ type = "zfs_fs";
+ mountpoint = "/";
+ };
+ home = {
+ type = "zfs_fs";
+ mountpoint = "/home";
+ };
+ windows = {
+ type = "zfs_volume";
+ size = "150G";
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/tundra/hardware.nix b/tundra/hardware.nix
new file mode 100644
--- /dev/null
+++ b/tundra/hardware.nix
@@ -0,0 +1,26 @@
+{
+ config,
+ lib,
+ modulesPath,
+ ...
+}:
+
+{
+ imports = [
+ (modulesPath + "/installer/scan/not-detected.nix")
+ ];
+
+ boot.initrd.availableKernelModules = [
+ "xhci_pci"
+ "nvme"
+ "usb_storage"
+ "sd_mod"
+ ];
+ boot.initrd.kernelModules = [ ];
+ boot.loader.grub.enable = true;
+ boot.kernelModules = [ "kvm-intel" ];
+ boot.extraModulePackages = [ ];
+
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+ hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}
diff --git a/tundra/home-overrides.nix b/tundra/home-overrides.nix
new file mode 100644
--- /dev/null
+++ b/tundra/home-overrides.nix
@@ -0,0 +1,10 @@
+{
+ lib,
+ ...
+}:
+{
+ programs.niri.settings = {
+ outputs."eDP-1".scale = lib.mkForce 1.0;
+ input.touchpad.enable = false;
+ };
+}
diff --git a/tundra/home.nix b/tundra/home.nix
new file mode 100644
--- /dev/null
+++ b/tundra/home.nix
@@ -0,0 +1,61 @@
+{
+ pkgs,
+ lib,
+ ...
+}:
+
+{
+ # TODO: make this not shit
+ imports =
+ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../modules/core)
+ ++ lib.fileset.toList (lib.fileset.fileFilter (file: file.hasExt "nix") ../modules/desktop)
+ ++ [
+ ../modules/wlsunset.nix
+ ./home-overrides.nix
+ ../modules/rclone.nix
+ ];
+
+ sops = {
+ defaultSopsFile = ../secrets/tundra.yaml;
+ age.keyFile = "/home/monke/.config/sops/age/keys.txt";
+ secrets = {
+ "nextcloud/url" = { };
+ "nextcloud/user" = { };
+ "nextcloud/pass" = { };
+ };
+ };
+
+ home = {
+ username = "monke";
+ homeDirectory = "/home/monke";
+
+ sessionVariables = {
+ EDITOR = "nvim";
+ NIXOS_OZONE_WL = 1;
+ QT_QPA_PLATFORM = "wayland-egl";
+ };
+
+ sessionPath = [
+ "$HOME/usr/bin"
+ ];
+ preferXdgDirectories = true;
+
+ stateVersion = "25.11";
+
+ packages = with pkgs; [
+ signal-desktop
+ gcc
+ gsettings-desktop-schemas
+ kicad
+ networkmanagerapplet
+ openscad
+ pwvucontrol
+ swaybg
+ tinymist
+ typst
+ wl-clipboard
+ ];
+ };
+
+ programs.home-manager.enable = true;
+}
diff --git a/tundra/programs.nix b/tundra/programs.nix
new file mode 100644
--- /dev/null
+++ b/tundra/programs.nix
@@ -0,0 +1,31 @@
+{
+ lib,
+ pkgs,
+ ...
+}:
+{
+ programs = {
+ zsh.enable = true;
+ niri.enable = true;
+ virt-manager.enable = true;
+ steam = {
+ enable = true;
+ remotePlay.openFirewall = true;
+ dedicatedServer.openFirewall = true;
+ localNetworkGameTransfers.openFirewall = true;
+ };
+ };
+ services = {
+ pipewire = {
+ enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ pulse.enable = true;
+ };
+ udisks2.enable = true;
+ };
+ environment.systemPackages = with pkgs; [
+ neovim
+ curl
+ ];
+}