Compare commits

...

3 Commits

123 changed files with 2550 additions and 3145 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 2.2 MiB

167
flake.lock generated
View File

@@ -64,6 +64,24 @@
} }
}, },
"flake-parts": { "flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1777988971,
"narHash": "sha256-qIoWPDs+0/8JecyYgE3gpKQxW/4bLW/gp45vow9ioCQ=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "0678d8986be1661af6bb555f3489f2fdfc31f6ff",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"nixvim", "nixvim",
@@ -84,7 +102,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_2": { "flake-parts_3": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"terranix", "terranix",
@@ -123,6 +141,30 @@
"type": "github" "type": "github"
} }
}, },
"hm-wrapper-modules": {
"inputs": {
"home-manager": [
"home-manager"
],
"nix-wrapper-modules": "nix-wrapper-modules",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1774554164,
"narHash": "sha256-HzYleaTR4n4wejE7nyTcq7F1Kp4Q5ow//k/y0fiHNs0=",
"owner": "sini",
"repo": "hm-wrapper-modules",
"rev": "b28ff211a8cce758a98e0db349c0f3dd77a13373",
"type": "github"
},
"original": {
"owner": "sini",
"repo": "hm-wrapper-modules",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -165,6 +207,21 @@
"type": "github" "type": "github"
} }
}, },
"import-tree": {
"locked": {
"lastModified": 1773693634,
"narHash": "sha256-BtZ2dtkBdSUnFPPFc+n0kcMbgaTxzFNPv2iaO326Ffg=",
"owner": "vic",
"repo": "import-tree",
"rev": "c41e7d58045f9057880b0d85e1152d6a4430dbf1",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "import-tree",
"type": "github"
}
},
"ixx": { "ixx": {
"inputs": { "inputs": {
"flake-utils": [ "flake-utils": [
@@ -193,6 +250,27 @@
"type": "github" "type": "github"
} }
}, },
"nix-wrapper-modules": {
"inputs": {
"nixpkgs": [
"hm-wrapper-modules",
"nixpkgs"
]
},
"locked": {
"lastModified": 1774538285,
"narHash": "sha256-KRDNQDEWjB2O5SRH/oUTzi34cNxlIT8sab0FK2uqZ2g=",
"owner": "BirdeeHub",
"repo": "nix-wrapper-modules",
"rev": "15d740b2bfc545189a569147da7718457c12758e",
"type": "github"
},
"original": {
"owner": "BirdeeHub",
"repo": "nix-wrapper-modules",
"type": "github"
}
},
"nixos-apple-silicon": { "nixos-apple-silicon": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
@@ -213,22 +291,6 @@
"type": "github" "type": "github"
} }
}, },
"nixos-unstable": {
"locked": {
"lastModified": 1768564909,
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1757745802, "lastModified": 1757745802,
@@ -245,6 +307,21 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-lib": {
"locked": {
"lastModified": 1777168982,
"narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1773628058, "lastModified": 1773628058,
@@ -295,23 +372,23 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1764517877, "lastModified": 1778274207,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=", "narHash": "sha256-I4puXmX1iovcCHZlRmztO3vW0mAbbRvq4F8wgIMQ1MM=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c", "rev": "b3da656039dc7a6240f27b2ef8cc6a3ef3bccae7",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixpkgs-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixvim": { "nixvim": {
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts_2",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
@@ -368,37 +445,21 @@
"url": "https://devimages-cdn.apple.com/design/resources/download/NY.dmg" "url": "https://devimages-cdn.apple.com/design/resources/download/NY.dmg"
} }
}, },
"proton-pass-cli": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1766050030,
"narHash": "sha256-+jAjk7HyJ4aBo+JQODETpFFtpaXnUakcNx7ckBKhUkY=",
"owner": "yuxqiu",
"repo": "proton-pass-cli-nix",
"rev": "db5bd21dfe19b31d62fb62a7441a4d4c35bdf747",
"type": "github"
},
"original": {
"owner": "yuxqiu",
"repo": "proton-pass-cli-nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"apple-fonts": "apple-fonts", "apple-fonts": "apple-fonts",
"firefox-addons": "firefox-addons", "firefox-addons": "firefox-addons",
"flake-parts": "flake-parts",
"hm-wrapper-modules": "hm-wrapper-modules",
"home-manager": "home-manager", "home-manager": "home-manager",
"import-tree": "import-tree",
"nixos-apple-silicon": "nixos-apple-silicon", "nixos-apple-silicon": "nixos-apple-silicon",
"nixos-unstable": "nixos-unstable",
"nixpkgs": "nixpkgs_3", "nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"nixvim": "nixvim", "nixvim": "nixvim",
"proton-pass-cli": "proton-pass-cli",
"sops-nix": "sops-nix", "sops-nix": "sops-nix",
"terranix": "terranix", "terranix": "terranix",
"wrapper-modules": "wrapper-modules",
"zen-browser": "zen-browser" "zen-browser": "zen-browser"
} }
}, },
@@ -553,7 +614,7 @@
}, },
"terranix": { "terranix": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_3",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
@@ -573,11 +634,29 @@
"type": "github" "type": "github"
} }
}, },
"wrapper-modules": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1778520701,
"narHash": "sha256-qEA/vR6fKwnW3lqwy7f+Ds1iPgdotKpksQIk6UZotlM=",
"owner": "BirdeeHub",
"repo": "nix-wrapper-modules",
"rev": "5660d8cada6c2c5eb6c034577f3893f579526804",
"type": "github"
},
"original": {
"owner": "BirdeeHub",
"repo": "nix-wrapper-modules",
"type": "github"
}
},
"zen-browser": { "zen-browser": {
"inputs": { "inputs": {
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"nixpkgs": [ "nixpkgs": [
"nixos-unstable" "nixpkgs-unstable"
] ]
}, },
"locked": { "locked": {

180
flake.nix
View File

@@ -6,7 +6,10 @@
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nixos-unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts";
import-tree.url = "github:vic/import-tree";
wrapper-modules.url = "github:BirdeeHub/nix-wrapper-modules";
nixos-apple-silicon.url = nixos-apple-silicon.url =
"github:nix-community/nixos-apple-silicon?ref=release-2025-11-18"; "github:nix-community/nixos-apple-silicon?ref=release-2025-11-18";
@@ -15,6 +18,9 @@
url = "github:nix-community/home-manager?ref=release-25.11"; url = "github:nix-community/home-manager?ref=release-25.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
hm-wrapper-modules.url = "github:sini/hm-wrapper-modules";
hm-wrapper-modules.inputs.nixpkgs.follows = "nixpkgs";
hm-wrapper-modules.inputs.home-manager.follows = "home-manager";
nixvim = { nixvim = {
url = "github:nix-community/nixvim?ref=nixos-25.11"; url = "github:nix-community/nixvim?ref=nixos-25.11";
@@ -35,7 +41,7 @@
url = "github:0xc000022070/zen-browser-flake"; url = "github:0xc000022070/zen-browser-flake";
# IMPORTANT: we're using "libgbm" and is only available in unstable so ensure # IMPORTANT: we're using "libgbm" and is only available in unstable so ensure
# to have it up-to-date or simply don't specify the nixpkgs input # to have it up-to-date or simply don't specify the nixpkgs input
inputs.nixpkgs.follows = "nixos-unstable"; inputs.nixpkgs.follows = "nixpkgs-unstable";
}; };
firefox-addons = { firefox-addons = {
@@ -44,116 +50,70 @@
}; };
apple-fonts.url= "github:Lyndeno/apple-fonts.nix"; apple-fonts.url= "github:Lyndeno/apple-fonts.nix";
proton-pass-cli.url = "github:yuxqiu/proton-pass-cli-nix";
}; };
outputs = { self, nixpkgs, nixpkgs-unstable, nixos-unstable, nixos-apple-silicon, home-manager
, nixvim, sops-nix, terranix, zen-browser, apple-fonts, proton-pass-cli, firefox-addons, ... }:
let
forAllSystems = function:
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed
(system: function nixpkgs.legacyPackages.${system});
in {
packages.aarch64-linux = outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs;} (inputs.import-tree ./modules);
let
system = "aarch64-linux";
pkgs = import nixpkgs-unstable { # outputs = { self, nixpkgs, nixpkgs-unstable, nixos-unstable, nixos-apple-silicon, home-manager
inherit system; # , nixvim, sops-nix, terranix, zen-browser, apple-fonts, proton-pass-cli, firefox-addons, ... }:
config = { # let
allowUnfree = true; # forAllSystems = function:
}; # nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed
}; # (system: function nixpkgs.legacyPackages.${system});
# in {
terraform = pkgs.terraform.withPlugins (p: [ #
p.pocketid # nixosConfigurations = {
p.local # max = let
]); # system = "aarch64-linux";
terraformConfiguration = terranix.lib.terranixConfiguration { # pkgs-unstable = import nixpkgs-unstable { inherit system; };
inherit system; # secrets = import ./secrets;
modules = [ ./infra/config.nix ]; # in nixpkgs.lib.nixosSystem {
}; # inherit system;
in { # specialArgs = { inherit pkgs-unstable secrets zen-browser apple-fonts proton-pass-cli; };
deploy = pkgs.writeShellScriptBin "deploy" '' # modules = [
echo Deploying Infrastructure... # ./host/max/default.nix
# nixos-apple-silicon.nixosModules.apple-silicon-support
export TF_VAR_pocketid_api_token=$(${pkgs.sops}/bin/sops -d --extract '["pocketid-api-token"]' secrets/secrets.yaml) # sops-nix.nixosModules.sops
# home-manager.nixosModules.home-manager
cd infra # {
# home-manager.useGlobalPkgs = true;
cp ${terraformConfiguration} config.tf.json # home-manager.useUserPackages = true;
# home-manager.extraSpecialArgs = { inherit secrets zen-browser firefox-addons system pkgs-unstable; };
${terraform}/bin/terraform init # home-manager.users.max = { config, pkgs, lib, ... }: {
${terraform}/bin/terraform apply # imports = [
# sops-nix.homeManagerModules.sops
rm -f config.tf.json # nixvim.homeModules.nixvim
# zen-browser.homeModules.beta
echo Done # ./host/max/home.nix # Import your home.nix here
# ];
echo Encrypting secrets # };
# }
cd ../secrets # ];
# };
${pkgs.sops}/bin/sops -e -i sops/oauth.yaml #
# ark = let
echo Done # system = "x86_64-linux";
''; # secrets = import ./secrets;
}; # in nixos-unstable.lib.nixosSystem {
# inherit system;
nixosConfigurations = { # specialArgs = { inherit secrets; };
max = let # modules = [
system = "aarch64-linux"; # ./host/ark/default.nix
pkgs-unstable = import nixpkgs-unstable { inherit system; }; # sops-nix.nixosModules.sops
secrets = import ./secrets; # ];
in nixpkgs.lib.nixosSystem { # };
inherit system; # };
specialArgs = { inherit pkgs-unstable secrets zen-browser apple-fonts proton-pass-cli; }; #
modules = [ # devShells = forAllSystems (pkgs: {
./host/max/default.nix # default = pkgs.mkShell {
nixos-apple-silicon.nixosModules.apple-silicon-support # packages = with pkgs; [
sops-nix.nixosModules.sops # age
home-manager.nixosModules.home-manager # ssh-to-age
{ # sops
home-manager.useGlobalPkgs = true; # just
home-manager.useUserPackages = true; # ];
home-manager.extraSpecialArgs = { inherit secrets zen-browser firefox-addons system pkgs-unstable; }; # };
home-manager.users.max = { config, pkgs, lib, ... }: { # });
imports = [ # };
sops-nix.homeManagerModules.sops
nixvim.homeModules.nixvim
zen-browser.homeModules.beta
./host/max/home.nix # Import your home.nix here
];
};
}
];
};
ark = let
system = "x86_64-linux";
secrets = import ./secrets;
in nixos-unstable.lib.nixosSystem {
inherit system;
specialArgs = { inherit secrets; };
modules = [
./host/ark/default.nix
sops-nix.nixosModules.sops
];
};
};
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
packages = with pkgs; [
age
ssh-to-age
sops
just
];
};
});
};
} }

View File

@@ -1,25 +0,0 @@
{ pkgs, pkgs-unstable, ... }:
let
scripts = import ./hyprland/scripts/default.nix { inherit pkgs; };
in
{
imports = [
(import ./hyprland/hyprland.nix { inherit pkgs scripts pkgs-unstable; })
(import ./hyprland/wallpaper.nix { inherit pkgs scripts; })
(import ./hyprland/hyprlock.nix { inherit pkgs scripts; })
(import ./hyprland/hypridle.nix { inherit pkgs scripts; })
./hyprland/notifications.nix
];
home.file.".config/waybar/config.jsonc".source = ./hyprland/waybar/config.jsonc;
home.file.".config/waybar/style.css".source = ./hyprland/waybar/style.css;
services.swayosd = {
enable = true;
};
home.file.".config/swayosd/style.css".source = ./hyprland/swayosd/style.css;
home.file.".config/walker/config.toml".source = ./hyprland/walker/config.toml;
}

View File

@@ -1,27 +0,0 @@
{ pkgs, scripts, ... }:
{
services.hypridle = {
enable = true;
settings = {
general = {
lock_cmd = "${scripts.lock}";
before_sleep_cmd = "${pkgs.systemd}/bin/loginctl lock-session"; # lock before suspend.
after_sleep_cmd = "${pkgs.hyprland}/bin/hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
inhibit_sleep = 3; # wait until screen is locked
};
listener = [
{
timeout = 60 * 5; # 5min
on-timeout = "${pkgs.systemd}/bin/loginctl lock-session"; # lock screen when timeout has passed
}
{
timeout = 60 * 5.5; # 5.5min
on-timeout = "${pkgs.hyprland}/bin/hyprctl dispatch dpms off"; # screen off when timeout has passed
on-resume = "${pkgs.hyprland}/bin/hyprctl dispatch dpms on && brightnessctl -r"; # screen on when activity is detected
}
];
};
};
}

View File

@@ -1,353 +0,0 @@
{ pkgs, pkgs-unstable, scripts, ... }:
{
imports = [
./hyprland/performance.nix
];
wayland.windowManager.hyprland = {
enable = true;
systemd.enable = false;
plugins = with pkgs; [
(hyprlandPlugins.mkHyprlandPlugin {
pluginName = "hyprselect";
version = "0.1";
src = fetchFromGitHub {
owner = "jmanc3";
repo = "hyprselect";
rev = "f9651b5fd64c730ee164a6fee6a08d0398dcbe0a";
hash = "sha256-tY8EdfsjlUOuQ9v/POqpyLlkRO5wqEVSE9UeHfXuaGk=";
};
inherit (hyprland) nativeBuildInputs;
meta = with lib; {
homepage = "https://github.com/jmanc3/hyprselect";
description = "A plugin that adds a completely useless desktop selection box to Hyprland";
license = licenses.unlicense;
platforms = platforms.linux;
};
})
hyprlandPlugins.hyprscrolling
hyprlandPlugins.hyprbars
];
settings = {
source = [
"~/.config/koonos/current/performance/hyprland.conf"
];
"$terminal" = "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.alacritty}/bin/alacritty";
"$fileManager" = "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.pcmanfm}/bin/pcmanfm";
"$browser" = "${pkgs.uwsm}/bin/uwsm-app -- zen-beta";
"$menu" = "${pkgs.walker}/bin/walker";
"$player" = "${pkgs.playerctl}/bin/playerctl";
monitor = [
"eDP-1,preferred,1721x1080,auto"
"HDMI-A-1,preferred,1450x0,auto"
];
exec-once = [
"${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.hypridle}/bin/hypridle"
"${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.waybar}/bin/waybar"
"${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.hyprpaper}/bin/hyprpaper"
"sleep 2 && pw-play --volume=0 ~/Downloads/empty.wav"
];
env = [
"HYPRCURSOR_THEME,macOS"
"HYPRCURSOR_SIZE,20"
];
# env = [
# "XCURSOR_SIZE,20"
# "XCURSOR_THEME,macOS"
# ];
general = {
gaps_in = 0;
gaps_out = 0;
border_size = 2;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
# Set to true enable resizing windows by clicking and dragging on borders and gaps
resize_on_border = true;
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
allow_tearing = false;
layout = "scrolling";
};
decoration = {
# rounding = 10
# rounding_power = 2
# Change transparency of focused and unfocused windows
active_opacity = 1.0;
inactive_opacity = 1.0;
shadow = {
# enabled = false;
range = 4;
render_power = 3;
color = "rgba(1a1a1aee)";
};
# https://wiki.hyprland.org/Configuring/Variables/#blur
blur = {
# enabled = false;
size = 3;
passes = 1;
vibrancy = 0.1696;
};
};
# https://wiki.hyprland.org/Configuring/Variables/#animations
animations = {
enabled = true;
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = [
"easeOutQuint,0.23,1,0.32,1"
"easeInOutCubic,0.65,0.05,0.36,1"
"linear,0,0,1,1"
"almostLinear,0.5,0.5,0.75,1.0"
"quick,0.15,0,0.1,1"
];
animation = [
"global, 1, 10, default"
"border, 0, 5.39, easeOutQuint"
"windows, 1, 4.79, easeOutQuint"
"windowsIn, 1, 4.1, easeOutQuint, popin 87%"
"windowsOut, 1, 1.49, linear, popin 87%"
"fadeIn, 1, 1.73, almostLinear"
"fadeOut, 1, 1.46, almostLinear"
"fade, 1, 3.03, quick"
"layers, 1, 3.81, easeOutQuint"
"layersIn, 1, 4, easeOutQuint, fade"
"layersOut, 1, 1.5, linear, fade"
"fadeLayersIn, 1, 1.79, almostLinear"
"fadeLayersOut, 1, 1.39, almostLinear"
"workspaces, 0, 1.94, almostLinear, fade"
"workspacesIn, 0, 1.21, almostLinear, fade"
"workspacesOut, 0, 1.94, almostLinear, fade"
];
};
dwindle = {
pseudotile = true; # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true; # You probably want this
};
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
master = {
new_status = "master";
};
# https://wiki.hyprland.org/Configuring/Variables/#misc
misc = {
force_default_wallpaper = 0; # Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = true;
disable_splash_rendering = true;
};
#############
### INPUT ###
#############
# https://wiki.hyprland.org/Configuring/Variables/#input
input = {
kb_layout = "us";
# kb_variant =
# kb_model =
kb_options = "caps:swapescape";
# kb_rules =
follow_mouse = 1;
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
repeat_rate = 35;
repeat_delay = 300;
touchpad = {
natural_scroll = true;
tap-to-click = false;
clickfinger_behavior = true;
};
};
# https://wiki.hyprland.org/Configuring/Variables/#gestures
# gestures = {
# workspace_swipe = true;
# };
# See https://wiki.hyprland.org/Configuring/Keywords/
"$mainMod" = "SUPER"; # Sets "Windows" key as main modifier
bind = [
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
"$mainMod, return, exec, $terminal"
"$mainMod, W, killactive,"
# bind = $mainMod, M, exit,
"$mainMod, E, exec, $fileManager"
"$mainMod, B, exec, $browser"
"$mainMod, M, exec, $terminal -e ${pkgs-unstable.gurk-rs}/bin/gurk"
"$mainMod, P, exec, $terminal -e ${pkgs.ncmpcpp}/bin/ncmpcpp"
"$mainMod SHIFT, B, exec, $terminal -e \"$EDITOR\" /home/max/bible.txt -R"
"$mainMod SHIFT, R, exec, ${pkgs.hyprshot}/bin/hyprshot -m region --clipboard-only"
# "$mainMod, V, togglefloating,"
"$mainMod, space, exec, $menu"
# "$mainMod, P, pseudo, # dwindle"
"$mainMod, F, fullscreen"
# bind = $mainMod, J, togglesplit, # dwindle
"$mainMod SHIFT, Q, exec, ${scripts.lock}"
# Move focus with mainMod + arrow keys
"$mainMod, H, movefocus, l"
"$mainMod, L, movefocus, r"
"$mainMod, K, movefocus, u"
"$mainMod, J, movefocus, d"
# Swap window with mainMod + shift + arrow keys
"$mainMod SHIFT, H, swapwindow, l"
"$mainMod SHIFT, L, swapwindow, r"
"$mainMod SHIFT, K, swapwindow, u"
"$mainMod SHIFT, J, swapwindow, d"
# "$mainMod ALT, H, resizeactive, -40 0"
# "$mainMod ALT, L, resizeactive, 40 0"
# Switch workspaces with mainMod + [0-9]
"$mainMod, 1, workspace, 1"
"$mainMod, 2, workspace, 2"
"$mainMod, 3, workspace, 3"
"$mainMod, 4, workspace, 4"
"$mainMod, 5, workspace, 5"
"$mainMod, 6, workspace, 6"
"$mainMod, 7, workspace, 7"
"$mainMod, 8, workspace, 8"
"$mainMod, 9, workspace, 9"
"$mainMod, 0, workspace, 10"
# Move active window to a workspace with mainMod + SHIFT + [0-9]
"$mainMod SHIFT, 1, movetoworkspace, 1"
"$mainMod SHIFT, 2, movetoworkspace, 2"
"$mainMod SHIFT, 3, movetoworkspace, 3"
"$mainMod SHIFT, 4, movetoworkspace, 4"
"$mainMod SHIFT, 5, movetoworkspace, 5"
"$mainMod SHIFT, 6, movetoworkspace, 6"
"$mainMod SHIFT, 7, movetoworkspace, 7"
"$mainMod SHIFT, 8, movetoworkspace, 8"
"$mainMod SHIFT, 9, movetoworkspace, 9"
"$mainMod SHIFT, 0, movetoworkspace, 10"
# Example special workspace (scratchpad)
"$mainMod, S, togglespecialworkspace, magic"
"$mainMod SHIFT, S, movetoworkspace, special:magic"
# Scroll through existing workspaces with mainMod + scroll
# "$mainMod, mouse_down, workspace, e+1"
# "$mainMod, mouse_up, workspace, e-1"
", Prior, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x40"
", Next, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x41"
];
bindr = [
", Prior, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x80"
", Next, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x81"
];
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
];
"$osdclient" = "swayosd-client --monitor \"$(hyprctl monitors -j | ${pkgs.jq}/bin/jq -r '.[] | select(.focused == true).name')\"";
bindel = [
# Laptop multimedia keys for volume and LCD brightness
# bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
# bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
",XF86AudioRaiseVolume, exec, $osdclient --output-volume=raise"
",XF86AudioLowerVolume, exec, $osdclient --output-volume=lower"
",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
# bindel = ,XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+
# bindel = ,XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%-
",XF86MonBrightnessUp, exec, $osdclient --brightness=raise"
",XF86MonBrightnessDown, exec, $osdclient --brightness=lower"
];
bindl = [
# Requires playerctl
", XF86AudioNext, exec, $player next"
", XF86AudioPause, exec, $player play-pause"
", XF86AudioPlay, exec, $player play-pause"
", XF86AudioPrev, exec, $player previous"
];
bindd = [
"$mainMod, C, Universal copy, sendshortcut, CTRL, Insert,"
"$mainMod, V, Universal paste, sendshortcut, SHIFT, Insert,"
"$mainMod, X, Universal cut, sendshortcut, CTRL, X,"
"$mainMod, A, Universal select all, sendshortcut, CTRL, A,"
"$mainMod, T, Universal new tab, sendshortcut, CTRL, T,"
"$mainMod ALT, H, Universal left, sendshortcut, , Left,"
"$mainMod ALT, J, Universal down, sendshortcut, , Down,"
"$mainMod ALT, K, Universal up, sendshortcut, , Up,"
"$mainMod ALT, L, Universal right, sendshortcut, , Right,"
"$mainMod SHIFT ALT, H, Universal left, sendshortcut, SHIFT, Left,"
"$mainMod SHIFT ALT, J, Universal down, sendshortcut, SHIFT, Down,"
"$mainMod SHIFT ALT, K, Universal up, sendshortcut, SHIFT, Up,"
"$mainMod SHIFT ALT, L, Universal right, sendshortcut, SHIFT, Right,"
];
windowrule = [
# Just dash of opacity by default
"opacity 0.97 0.9, class:.*"
# Ignore maximize requests from apps. You'll probably like this.
"suppressevent maximize, class:.*"
# Fix some dragging issues with XWayland
"nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0"
];
plugin = {
hyprselect = {
"col.main" = "rgba(ffffff25)";
"col.border" = "rgba(ffffff88)";
fade_time_ms = 165.0;
border_size = 1.0;
};
hyprscrolling = {
fullscreen_on_one_column = true;
};
hyprbars = {
enabled = false;
};
};
};
};
}

View File

@@ -1,37 +0,0 @@
{ pkgs, lib, ... }:
let
normal = {
decoration = {
blur.enabled = true;
shadow.enabled = true;
};
misc.vfr = false;
};
battery-saver = {
decoration = {
blur.enabled = false;
shadow.enabled = false;
};
misc.vfr = true;
};
normal-file = pkgs.writeText "hyprland.conf.normal" (lib.hm.generators.toHyprconf { attrs = normal; });
battery-saver-file = pkgs.writeText "hyprland.conf.battery" (lib.hm.generators.toHyprconf { attrs = battery-saver; });
switchScript = pkgs.writeShellScriptBin "switch-config" ''
TARGET="$HOME/.config/koonos/current/performance/hyprland.conf"
if [ "$(readlink "$TARGET")" = "${normal-file}" ]; then
ln -sf ${battery-saver-file} "$TARGET"
echo "Switched to battery saver"
else
ln -sf ${normal-file} "$TARGET"
echo "Switched to normal mode"
fi
'';
in
{
home.file.".config/koonos/current/performance/hyprland.conf".source = normal-file;
home.packages = [ switchScript ];
}

View File

@@ -1,58 +0,0 @@
{ ... }:
{
programs.hyprlock = {
enable = true;
settings = {
"$color" = "rgba(26,27,38,1.0)";
"$inner_color" = "rgba(26,27,38,0.8)";
"$outer_color" = "rgba(205,214,244,1.0)";
"$font_color" = "rgba(205,214,244,1.0)";
"$check_color" = "rgba(68, 157, 171, 1.0)";
general = {
ignore_empty_input = true;
};
background = {
monitor = "";
color = "$color";
# path = "~/Downloads/wallpaper.png";
blur_passes = 3;
};
animations = {
enabled = true;
};
input-field = {
monitor = "";
size = "650, 100";
position = "0, 0";
halign = "center";
valign = "center";
inner_color = "$inner_color";
outer_color = "$outer_color";
outline_thickness = 4;
font_family = "JetBrainsMono Nerd Font";
font_color = "$font_color";
placeholder_text = "Enter Password";
check_color = "$check_color";
fail_text = "<i>$FAIL ($ATTEMPTS)</i>";
rounding = 0;
shadow_passes = 0;
fade_on_empty = false;
};
auth = {
"fingerprint:enabled" = true;
};
};
};
}

View File

@@ -1,31 +0,0 @@
{
services.swaync = {
enable = true;
settings = {
notification-window-width = 350;
};
# Taken from:
# https://github.com/ErikReider/SwayNotificationCenter/blob/2083415ee6441acc272f46f8a43ebccae215f69a/data/style/style.scss#L4
style = ''
:root {
--cc-bg: rgba(46, 46, 46, 0.7);
--noti-border-color: rgba(255, 255, 255, 0.15);
--noti-bg: 48, 48, 48;
--noti-bg-alpha: 1;
--border-radius: 0;
--font-size-body: 13px;
--font-size-summary: 14px;
}
.close-button {
min-width: 18px;
min-height: 18px;
}
'';
};
}

View File

@@ -1,7 +0,0 @@
{ pkgs }:
{
lock =
pkgs.writeShellScript "koonos-lock-screen" ''
${pkgs.hyprlock}/bin/hyprlock
'';
}

View File

@@ -1,19 +0,0 @@
{ ... }:
let
wallpaper = builtins.toString ../../../../../assets/wallpaper.jpg;
in
{
services.hyprpaper = {
enable = true;
settings = {
spash = false;
preload = [ wallpaper ];
wallpaper = [
"eDP-1,${wallpaper}"
"HDMI-A-1,${wallpaper}"
];
};
};
}

View File

@@ -1,16 +0,0 @@
{ ... }: {
programs.plasma = {
enable = true;
workspace = { wallpaper = "/home/max/bg.jpg"; };
kwin = { virtualDesktops = { number = 4; }; };
input = {
keyboard = {
options = [ "caps:escape" ];
layouts = [ { layout = "us"; } { layout = "cn"; } ];
};
};
};
}

View File

@@ -1,78 +0,0 @@
{ config, lib, pkgs, ... }: {
imports = [
./hardware-configuration.nix
./options.nix
../common/core/default.nix
./user.nix
./sops.nix
./service/audio.nix
./service/auth.nix
./service/docs.nix
./service/git.nix
./service/home.nix
./service/photos.nix
./service/radicale.nix
./service/wakapi.nix
# ./service/elytra.nix
./service/money.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "ark";
networking.nameservers = [ "8.8.8.8" "1.1.1.1" ];
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
extraUpFlags = [ "--accept-dns=false" ];
};
oauth.name = "KoonFamily";
oauth.secrets = import ./oauth-secrets.nix;
security.sudo.wheelNeedsPassword = false;
services.cloudflared = {
enable = true;
tunnels = {
"91d31395-fbc7-45a1-ae13-148957b32ecd" = {
credentialsFile = config.sops.secrets.tunnel-credentials.path;
ingress = {
"auth.koon.us" = "http://localhost:1411";
"photos.koon.us" = "http://localhost:2283";
"home.koon.us" = "http://localhost:8123";
"docs.koon.us" = "http://localhost:3004";
"git.koon.us" = "http://localhost:3000";
"ssh.koon.us" = "ssh://localhost:2222";
"audio.koon.us" = "http://localhost:8021";
"radicale.koon.us" = "http://localhost:5232";
"waka.koon.us" = "http://localhost:3006";
# "ride.koon.us" = "http://localhost:3007";
# "ride-api.koon.us" = "http://localhost:8080";
"money.koon.us" = "http://localhost:3160";
"zero.koon.us" = "http://localhost:4848";
"money-api.koon.us" = "http://localhost:3161";
};
default = "http_status:404";
};
};
};
fileSystems."/mnt/hdd" = {
device = "/dev/sdb";
fsType = "ext4";
};
services.openssh.enable = true;
networking.firewall.allowedTCPPorts = [ 8123 22 ];
system.stateVersion = "25.05"; # Did you read the comment?
}

View File

@@ -1,7 +0,0 @@
{ lib, ... }: {
options.oauth = {
name = lib.mkOption { type = lib.types.str; };
secrets = lib.mkOption { type = lib.types.attrs; };
};
}

View File

@@ -1,6 +0,0 @@
{ ... }: {
services.audiobookshelf = {
enable = true;
port = 8021;
};
}

View File

@@ -1,19 +0,0 @@
{ config, pkgs, ... }: {
services.pocket-id = {
enable = true;
settings = {
APP_URL = "https://auth.koon.us";
TRUST_PROXY = true;
ANALYTICS_DISABLED = true;
UI_CONFIG_DISABLED = true;
APP_NAME = config.oauth.name;
};
credentials = {
ENCRYPTION_KEY = config.sops.secrets."pocket-id-encryption-key".path;
};
};
}

View File

@@ -1,75 +0,0 @@
{ config, lib, pkgs, ... }: {
nixpkgs.config.allowUnfree = true;
services.outline = {
enable = true;
publicUrl = "https://docs.koon.us";
port = 3004;
forceHttps = true;
storage.storageType = "local";
logo = "https://i.imgur.com/fKJ1I63.png";
oidcAuthentication = {
authUrl = "https://auth.koon.us/authorize";
tokenUrl = "https://auth.koon.us/api/oidc/token";
userinfoUrl = "https://auth.koon.us/api/oidc/userinfo";
clientId = "";
clientSecretFile = config.sops.secrets."docs/clientSecret".path;
scopes = [ "openid" "email" "profile" ];
usernameClaim = "preferred_username";
displayName = config.oauth.name;
};
};
systemd.services.outline = {
script =
let
localPostgresqlUrl = "postgres://localhost/outline?host=/run/postgresql";
cfg = config.services.outline;
in lib.mkForce ''
export SECRET_KEY="$(head -n1 ${lib.escapeShellArg cfg.secretKeyFile})"
export UTILS_SECRET="$(head -n1 ${lib.escapeShellArg cfg.utilsSecretFile})"
${lib.optionalString (cfg.storage.storageType == "s3") ''
export AWS_SECRET_ACCESS_KEY="$(head -n1 ${lib.escapeShellArg cfg.storage.secretKeyFile})"
''}
${lib.optionalString (cfg.slackAuthentication != null) ''
export SLACK_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.slackAuthentication.secretFile})"
''}
${lib.optionalString (cfg.googleAuthentication != null) ''
export GOOGLE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.googleAuthentication.clientSecretFile})"
''}
${lib.optionalString (cfg.azureAuthentication != null) ''
export AZURE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.azureAuthentication.clientSecretFile})"
''}
${lib.optionalString (cfg.oidcAuthentication != null) ''
export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})"
export OIDC_CLIENT_ID="$(cat ${config.sops.secrets."docs/clientId".path})"
''}
${lib.optionalString (cfg.sslKeyFile != null) ''
export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})"
''}
${lib.optionalString (cfg.sslCertFile != null) ''
export SSL_CERT="$(head -n1 ${lib.escapeShellArg cfg.sslCertFile})"
''}
${lib.optionalString (cfg.slackIntegration != null) ''
export SLACK_VERIFICATION_TOKEN="$(head -n1 ${lib.escapeShellArg cfg.slackIntegration.verificationTokenFile})"
''}
${lib.optionalString (cfg.smtp != null) ''
export SMTP_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.smtp.passwordFile})"
''}
${
if (cfg.databaseUrl == "local") then
''
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
export PGSSLMODE=disable
''
else
''
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
''
}
${cfg.package}/bin/outline-server
'';
};
}

View File

@@ -1,112 +0,0 @@
{ secrets, config, pkgs, elytrarides, ... }:
{
users.users.elytra-web = {
isSystemUser = true;
group = "elytra-web";
description = "Elytra Rides web service user";
};
users.users.backend = {
isSystemUser = true;
home = "/var/lib/elytra-backend";
createHome = true;
group = "backend";
};
users.groups.elytra-web = {};
users.groups.backend = {};
systemd.services.elytra-web = {
description = "Elytra Rides Next.js Web Application";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = {
PORT = "3007";
HOST = "127.0.0.1";
NODE_ENV = "production";
};
serviceConfig = {
Type = "simple";
User = "elytra-web";
Group = "elytra-web";
WorkingDirectory = "${pkgs.web}/lib/node_modules/web";
ExecStart =
"${pkgs.nodejs}/bin/node ${pkgs.web}/lib/node_modules/web/node_modules/next/dist/bin/next start";
EnvironmentFile = config.sops.secrets."elytra-frontend-env".path;
Restart = "on-failure";
RestartSec = 10;
# Security hardening
NoNewPrivileges = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
StateDirectory = "elytra-web";
StateDirectoryMode = "0750";
StandardOutput = "journal";
StandardError = "journal";
SyslogIdentifier = "elytra-web";
};
};
services.postgresql = {
enable = true;
ensureDatabases = [ "backend" ];
ensureUsers = [
{
name = "backend";
ensureDBOwnership = true;
}
];
};
services.redis = {
enable = true;
};
nixpkgs.overlays = [
(final: prev: {
web = elytrarides.packages.${pkgs.system}.web.overrideAttrs (old: {
buildPhase = ''
export NEXT_PUBLIC_GOOGLE_MAPS_API_KEY="${config.environment.sessionVariables.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}"
${old.buildPhase or "runHook preBuild; npm run build --if-present; runHook postBuild"}
'';
});
})
];
environment.sessionVariables.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY = secrets.ark.elytra.google-maps-api-key;
systemd.services.elytra-backend = {
description = "Elytra Rides Backend Service";
after = [ "network.target" "postgresql.service" ];
wants = [ "network-online.target" ];
serviceConfig = {
ExecStart = "${elytrarides.packages.${pkgs.system}.backend}/bin/nujade_backend";
ExecStartPre = [
"${pkgs.diesel-cli}/bin/diesel --database-url=\"postgresql:///backend?user=backend\" migration run --migration-dir=${elytrarides.packages.${pkgs.system}.backend}/migrations"
];
Restart = "always";
RestartSec = 5;
User = "backend";
WorkingDirectory = "/var/lib/elytra-backend";
Environment = "RUST_LOG=info";
EnvironmentFile = config.sops.secrets."elytra-backend-env".path;
};
environment = {
DATABASE_URL="postgresql:///backend?user=backend";
};
wantedBy = [ "multi-user.target" ];
};
}

View File

@@ -1,189 +0,0 @@
{ lib, config, pkgs, ... }: {
services.openssh = {
enable = true;
# hostKeys = [
# { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
# { path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; bits = 4096; }
# ];
settings = {
# explicitly allow post-quantum KEX
KexAlgorithms = [
"mlkem768x25519-sha256"
"sntrup761x25519-sha512"
"curve25519-sha256"
];
};
};
services.gitea = {
enable = true;
user = "git";
group = "git";
database = {
user = "git";
name = "git";
type = "postgres";
};
settings = {
server = {
DOMAIN = "git.koon.us";
ROOT_URL = "https://git.koon.us";
HTTP_PORT = 3000;
LANDING_PAGE = "/max";
SSH_DOMAIN = "ssh.koon.us";
SSH_PORT = 2222;
START_SSH_SERVER = true;
};
oauth2_client = {
ACCOUNT_LINKING = "auto";
ENABLE_AUTO_REGISTRATION = true;
UPDATE_AVATAR = true;
USERNAME = "email";
};
service = {
DISABLE_REGISTRATION = true;
ENABLE_PASSWORD_SIGNIN_FORM = false;
ENABLE_PASSKEY_AUTHENTICATION = false;
SHOW_MILESTONES_DASHBOARD_PAGE = false;
};
"service.explore" = {
DISABLE_USERS_PAGE = true;
DISABLE_ORGANIZATIONS_PAGE = true;
DISABLE_CODE_PAGE = true;
};
};
};
users.users.git = {
isSystemUser = true;
group = "git";
home = "/var/lib/gitea";
description = "Git server (Gitea)";
createHome = true;
};
users.groups.git = { };
systemd.services.gitea = {
serviceConfig = {
RestartSec = "60"; # Retry every minute
};
preStart = let
exe = lib.getExe config.services.gitea.package;
clientIdPath = config.sops.secrets."git/clientId".path;
clientSecretPath = config.sops.secrets."git/clientSecret".path;
args = lib.escapeShellArgs (lib.concatLists [
[ "--name" config.oauth.name ]
[ "--provider" "openidConnect" ]
# [ "--key" config.oauth.secrets.git.clientId ]
[
"--auto-discover-url"
"https://auth.koon.us/.well-known/openid-configuration"
]
[ "--scopes" "email" ]
[ "--scopes" "profile" ]
[ "--group-claim-name" "groups" ]
[ "--admin-group" "admin" ]
[ "--skip-local-2fa" ]
]);
in lib.mkAfter ''
CLIENT_ID=$(cat ${clientIdPath})
CLIENT_SECRET=$(cat ${clientSecretPath})
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${config.oauth.name}' | cut -f1)
if [[ -z "$provider_id" ]]; then
${exe} admin auth add-oauth ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET"
else
${exe} admin auth update-oauth --id "$provider_id" ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET"
fi
mkdir -p /var/lib/gitea/custom/public/assets/img/
ln -sf ${
./git/assets/img/logo.svg
} /var/lib/gitea/custom/public/assets/img/logo.svg
ln -sf ${
./git/assets/img/favicon.svg
} /var/lib/gitea/custom/public/assets/img/favicon.svg
mkdir -p /var/lib/gitea/custom/templates/base/
ln -sf ${
./git/templates/base/head_navbar.tmpl
} /var/lib/gitea/custom/templates/base/head_navbar.tmpl
ln -sf ${
./git/templates/base/footer_content.tmpl
} /var/lib/gitea/custom/templates/base/footer_content.tmpl
mkdir -p /var/lib/gitea/custom/templates/custom/
ln -sf ${
./git/templates/custom/header.tmpl
} /var/lib/gitea/custom/templates/custom/header.tmpl
'';
};
services.restic.backups = {
git-local = {
repository = "/mnt/hdd/restic/git";
passwordFile = config.sops.secrets.restic-password.path;
initialize = true;
paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ];
backupPrepareCommand = ''
mkdir -p /var/backup/git
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \
--clean \
--if-exists \
--dbname=git > /var/backup/git/postgres.sql
'';
backupCleanupCommand = ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea
'';
};
git-remote = {
repository = "rest:http://m1:8000/git";
passwordFile = config.sops.secrets.restic-password.path;
initialize = true;
paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ];
backupPrepareCommand = ''
mkdir -p /var/backup/git
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \
--clean \
--if-exists \
--dbname=git > /var/backup/git/postgres.sql
'';
backupCleanupCommand = ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea
'';
};
};
environment.systemPackages = with pkgs;
let
scripts = with pkgs; {
restore_git_pg = writeShellScriptBin "restore_git_pg" ''
${pkgs.sudo}/bin/sudo -u postgres psql --dbname=git < /var/backup/git/postgres.sql
'';
restore_git = writeShellScriptBin "restore_git" ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea
${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/git restore latest --target /
${scripts.restore_git_pg}/bin/restore_git_pg
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea
'';
};
in [ scripts.restore_git_pg scripts.restore_git ];
}

View File

@@ -1,28 +0,0 @@
{ pkgs, ... }: {
virtualisation.oci-containers = let
hass_config = pkgs.writeText "configuration.yaml" ''
# Discovery
default_config:
# Web Server configuration
http:
server_host: 127.0.0.1
use_x_forwarded_for: true
trusted_proxies: 127.0.0.1
'';
in {
backend = "podman";
containers.homeassistant = {
volumes = [
"home-assistant:/config"
# "/data/docker/hass:/config"
"${hass_config}:/config/configuration.yaml"
# "/run/secrets/home-assistant:/config/secrets.yaml"
];
environment.TZ = "America/New_York";
image =
"ghcr.io/home-assistant/home-assistant:stable"; # Warning: if the tag does not change, the image will not be updated
extraOptions = [ "--network=host" ];
};
};
}

View File

@@ -1,199 +0,0 @@
{ pkgs, config, ... }:
let
src = pkgs.fetchgit {
url = "https://git.koon.us/max/money.git";
hash = "sha256-TPUeYuffR8U0M3Wnc3yGmqDhEjWIhRRFaKDkhTBsNG8=";
};
expoWeb = pkgs.stdenv.mkDerivation (finalAttrs: {
pname = "expo-web";
version = "1.0.0";
src = src;
pnpm = pkgs.pnpm_10;
nativeBuildInputs = [
pkgs.nodejs
finalAttrs.pnpm.configHook
];
pnpmDeps = finalAttrs.pnpm.fetchDeps {
inherit (finalAttrs) pname version src;
fetcherVersion = 2;
hash = "sha256-x2zCFeMU0VfkVRILrLReEOFNrcd7aJp57v4fMGBE2dI=";
};
pnpmInstallFlags = [ "--frozen-lockfile" ];
buildPhase = ''
runHook preBuild
pnpm run build
runHook postBuild
'';
installPhase = ''
mkdir -p $out
cp -r dist/* $out/
'';
});
api = pkgs.stdenv.mkDerivation (finalAttrs: {
pname = "koon-money-api";
version = "1.0.1";
src = src;
pnpm = pkgs.pnpm_10;
nativeBuildInputs = [
pkgs.nodejs
finalAttrs.pnpm.configHook
pkgs.python3 # Required for node-gyp
pkgs.nodePackages.node-gyp # For building native modules
pkgs.pkg-config
pkgs.gnumake
pkgs.gcc
];
buildInputs = [
pkgs.sqlite
pkgs.sqlite.dev
pkgs.readline
pkgs.ncurses
pkgs.libbsd
];
pnpmDeps = finalAttrs.pnpm.fetchDeps {
inherit (finalAttrs) pname version src;
fetcherVersion = 2;
hash = "sha256-x2zCFeMU0VfkVRILrLReEOFNrcd7aJp57v4fMGBE2dI=";
};
NIX_CFLAGS_COMPILE = "-D_GNU_SOURCE";
pnpmInstallFlags = [ "--frozen-lockfile" ];
buildPhase = ''
runHook preBuild
cd node_modules/@rocicorp/zero-sqlite3
node-gyp rebuild --build-from-source
cd -
runHook postBuild
'';
installPhase = ''
mkdir -p $out
cp -r . $out/
'';
});
api-port = "3161";
in
{
services.nginx = {
enable = true;
virtualHosts."money.koon.us" = {
root = "${expoWeb}";
listen = [
{ addr = "127.0.0.1"; port = 3160; }
];
locations."/" = {
tryFiles = "$uri /index.html";
};
};
};
virtualisation.oci-containers = {
backend = "podman";
containers = {
zero = {
image = "rocicorp/zero:0.23.2025101600";
ports = ["127.0.0.1:4848:4848"];
volumes = [ "/run/postgresql:/run/postgresql" ];
environment = {
ZERO_UPSTREAM_DB = "postgresql://postgres@127.0.0.1/money";
ZERO_REPLICA_FILE = "/tmp/zync-replica.db";
ZERO_GET_QUERIES_URL = "http://localhost:${api-port}/api/zero/get-queries";
ZERO_GET_QUERIES_FORWARD_COOKIES = "true";
ZERO_MUTATE_URL = "http://localhost:${api-port}/api/zero/mutate";
ZERO_MUTATE_FORWARD_COOKIES = "true";
};
extraOptions = [ "--network=host" ];
};
};
};
services.postgresql = {
enable = true;
ensureDatabases = [ "money" ];
ensureUsers = [
{
name = "money";
ensureDBOwnership = true;
}
];
authentication = ''
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
'';
settings = {
wal_level = "logical";
};
};
systemd.services.money-api = {
description = "Money API";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = {
ZERO_UPSTREAM_DB = "postgresql://postgres@127.0.0.1/money";
PORT = api-port;
NODE_ENV = "production";
BETTER_AUTH_SECRET = "burger";
DEBUG = "*";
NODE_OPTIONS = "--trace-warnings --trace-uncaught";
OAUTH_DISCOVERY_URL = "https://auth.koon.us/.well-known/openid-configuration";
PLAID_ENV = "production";
};
serviceConfig = {
Type = "simple";
User = "money";
Group = "money";
WorkingDirectory = "${api}/shared";
ExecStartPre = "${api}/node_modules/.bin/drizzle-kit push --config=${api}/shared/drizzle.config.ts";
ExecStart = pkgs.writeShellScript "money-api-start" ''
set -euo pipefail
export OAUTH_CLIENT_ID="$(cat ${config.sops.secrets."money/clientId".path})"
export OAUTH_CLIENT_SECRET="$(cat ${config.sops.secrets."money/clientSecret".path})"
exec ${api}/node_modules/.bin/tsx ${api}/api/src/index.ts
'';
EnvironmentFile = config.sops.secrets."money-env".path;
Restart = "on-failure";
RestartSec = 10;
SyslogIdentifier = "money-api";
StandardOutput = "journal";
StandardError = "journal";
};
};
users.users.money = {
isSystemUser = true;
home = "/var/lib/money";
createHome = true;
group = "money";
};
users.groups.money = {};
}

View File

@@ -1,117 +0,0 @@
{ lib, config, pkgs, ... }: {
sops = {
templates = {
"immich-config.json" = {
content = builtins.toJSON {
passwordLogin.enabled = false;
# We will do this ourselves
backup.database.enabled = false;
oauth = {
enabled = true;
autoLaunch = true;
autoRegister = true;
buttonText =
lib.strings.concatStrings [ "Login To " config.oauth.name ];
clientId = config.sops.placeholder."photos/clientId";
clientSecret = config.sops.placeholder."photos/clientSecret";
issuerUrl = "https://auth.koon.us/.well-known/openid-configuration";
};
};
owner = config.users.users.immich.name;
mode = "0400";
restartUnits = [ "immich-server.service" "pocket-id.service" ];
};
};
};
services.immich = {
enable = true;
port = 2283;
environment.IMMICH_CONFIG_FILE = config.sops.templates."immich-config.json".path;
accelerationDevices = null;
machine-learning.environment = {
HF_XET_CACHE = "/var/cache/immich/huggingface-xet";
};
};
users.users.immich = {
home = "/var/lib/immich";
createHome = true;
extraGroups = [ "video" "render" ];
};
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [ intel-media-driver ];
};
environment.sessionVariables = { LIBVA_DRIVER_NAME = "iHD"; };
services.restic.backups = {
immich-local = {
repository = "/mnt/hdd/restic/immich";
passwordFile = config.sops.secrets.restic-password.path;
initialize = true;
paths = [ "/var/lib/immich/upload" "/var/backup/immich" ];
backupPrepareCommand = ''
mkdir -p /var/backup/immich
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \
--clean \
--if-exists \
--dbname=immich > /var/backup/immich/postgres.sql
'';
backupCleanupCommand = ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning
'';
};
immich-remote = {
repository = "rest:http://m1:8000/immich";
passwordFile = config.sops.secrets.restic-password.path;
initialize = true;
paths = [ "/var/lib/immich/upload" "/var/backup/immich" ];
backupPrepareCommand = ''
mkdir -p /var/backup/immich
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \
--clean \
--if-exists \
--dbname=immich > /var/backup/immich/postgres.sql
'';
backupCleanupCommand = ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning
'';
};
};
environment.systemPackages = with pkgs;
let
scripts = with pkgs; {
restore_immich_pg = writeShellScriptBin "restore_immich_pg" ''
${pkgs.sudo}/bin/sudo -u postgres psql --dbname=immich < /var/backup/immich/postgres.sql
'';
restore_immich = writeShellScriptBin "restore_immich" ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning
${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/immich restore latest --target /
${scripts.restore_immich_pg}/bin/restore_immich_pg
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning
'';
};
in [ scripts.restore_immich_pg scripts.restore_immich ];
}

View File

@@ -1,9 +0,0 @@
{ ... }: {
services.radicale = {
enable = true;
settings = {
auth.type = "none";
server.hosts = [ "0.0.0.0:5232" ];
};
};
}

View File

@@ -1,50 +0,0 @@
{ config, ... }:
{
nixpkgs.overlays = [
(final: prev: let
version = "2.15.0";
in {
wakapi = (prev.buildGoModule.override { go = prev.go_1_25; }) {
pname = "wakapi";
version = version;
src = final.fetchFromGitHub {
owner = "k2on";
repo = "wakapi";
rev = "koon-fork";
hash = "sha256-FYGtoJmbqUD02/JKvON1RqpjkrDkAOkfPwMAUZ2MSE4=";
};
vendorHash = "sha256-912x6LwitYXdjWpP75Xoc56JXadeLQZuESSyLoaJcU0=";
excludedPackages = [ "scripts" ];
postPatch = ''echo ${version} > version.txt'';
ldflags = [ "-s" "-w" ];
passthru = {
nixos = prev.nixosTests.wakapi;
updateScript = prev.nix-update-script { };
};
meta = prev.wakapi.meta // {
version = version;
mainProgram = "wakapi";
};
};
})
];
services.wakapi = {
enable = true;
passwordSaltFile = config.sops.secrets."waka-password-salt".path;
settings = {
server.port = 3006;
app.avatar_url_template = "https://auth.koon.us/api/users/fbffa48a-faf7-4230-a89f-0da184f5948c/profile-picture.png";
};
};
}

View File

@@ -1,69 +0,0 @@
{ config, ... }:
{
sops = {
defaultSopsFile = ../../secrets/sops/host/ark/default.yaml;
validateSopsFiles = false;
age.keyFile = if builtins.pathExists /var/lib/sops-nix/key.txt then
"/var/lib/sops-nix/key.txt"
else
"/home/admin/.config/sops/age/keys.txt" # temp decrypt key
;
secrets = {
"host_age_key" = {
path = "/var/lib/sops-nix/key.txt";
};
"restic-password" = {};
"tunnel-credentials" = {};
"admin-password" = {};
"pocket-id-encryption-key" = {
owner = config.services.pocket-id.user;
};
"waka-password-salt" = {
owner = config.users.users.wakapi.name;
};
"money-env" = {
owner = config.users.users.money.name;
};
"photos/clientId" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
};
"photos/clientSecret" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
};
"git/clientId" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
owner = config.services.gitea.user;
};
"git/clientSecret" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
owner = config.services.gitea.user;
};
"docs/clientId" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
owner = config.services.outline.user;
};
"docs/clientSecret" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
owner = config.services.outline.user;
};
"money/clientId" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
owner = config.users.users.money.name;
};
"money/clientSecret" = {
sopsFile = ../../secrets/sops/host/ark/oauth.yaml;
owner = config.users.users.money.name;
};
};
};
}

View File

@@ -1,12 +0,0 @@
{ pkgs, config, ... }: {
sops.secrets.admin-password.neededForUsers = true;
users.mutableUsers = false;
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ];
hashedPasswordFile = config.sops.secrets.admin-password.path;
packages = with pkgs; [ tree vim tmux restic ];
};
}

View File

@@ -1,7 +0,0 @@
{ ... }: {
time.timeZone = "America/New_York";
# security.sudo.wheelNeedsPassword = false;
nix.settings.experimental-features = [ "nix-command" "flakes" ];
}

View File

@@ -1,68 +0,0 @@
{ lib, ... }: {
programs.chromium = {
enable = true;
};
programs.firefox = let
lock-false = {
Value = false;
Status = "locked";
};
lock-true = {
Value = true;
Status = "locked";
};
lock-empty-string = {
Value = "";
Status = "locked";
};
in {
enable = true;
policies = {
DisableTelemetry = true;
DisableFirefoxStudies = true;
DontCheckDefaultBrowser = true;
DisablePocket = true;
DisableAccounts = true;
Preferences = {
"extensions.pocket.enabled" = lock-false;
"browser.topsites.contile.enabled" = lock-false;
"browser.newtabpage.pinned" = lock-empty-string;
"browser.newtabpage.activity-stream.showSponsored" = lock-false;
"browser.newtabpage.activity-stream.system.showSponsored" = lock-false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = lock-false;
};
ExtensionSettings = {
"uBlock0@raymondhill.net" = {
install_url =
"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi";
installation_mode = "force_installed";
};
"{446900e4-71c2-419f-a6a7-df9c091e268b}" = {
install_url =
"https://addons.mozilla.org/firefox/downloads/latest/bitwarden-password-manager/latest.xpi";
installation_mode = "force_installed";
};
"{d7742d87-e61d-4b78-b8a1-b469842139fa}" = {
install_url =
"https://addons.mozilla.org/firefox/downloads/latest/vimium-ff/latest.xpi";
installation_mode = "force_installed";
};
"myallychou@gmail.com" = {
install_url =
"https://addons.mozilla.org/firefox/downloads/latest/youtube-recommended-videos/latest.xpi";
installation_mode = "force_installed";
};
};
UserMessaging = {
UrlbarInterventions = false;
SkipOnboarding = true;
};
};
};
}

View File

@@ -1,6 +0,0 @@
{ ... }:
{
services.displayManager.cosmic-greeter.enable = true;
services.desktopManager.cosmic.enable = true;
}

View File

@@ -1,17 +0,0 @@
{ ... }:
{
imports = [
./hyprland/cursor.nix
./hyprland/packages.nix
./hyprland/greeter.nix
./hyprland/hyprlock.nix
];
programs.hyprland = {
enable = true;
withUWSM = true;
xwayland.enable = true;
};
programs.ydotool.enable = true;
}

View File

@@ -1,10 +0,0 @@
{ pkgs, lib, ... }:
{
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
"apple_cursor"
];
environment.systemPackages = with pkgs; [
apple-cursor
];
}

View File

@@ -1,12 +0,0 @@
{ pkgs, ... }:
{
services.greetd = {
enable = true;
settings = {
default_session = {
command = "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd 'uwsm start hyprland-uwsm.desktop'";
user = "greeter";
};
};
};
}

View File

@@ -1,4 +0,0 @@
{ ... }:
{
security.pam.services.hyprlock = {};
}

View File

@@ -1,22 +0,0 @@
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
hyprpaper
hypridle
hyprpicker
hyprsunset
hyprshot
waybar
walker
swayosd
playerctl
brightnessctl
wl-clipboard
wdisplays
bluetui
kdePackages.dolphin
];
}

View File

@@ -1,29 +0,0 @@
{ pkgs, ... }: {
services = {
desktopManager.plasma6.enable = true;
displayManager.sddm.enable = true;
displayManager.sddm.wayland.enable = true;
};
environment.systemPackages = with pkgs; [
kdePackages.discover # Optional: Install if you use Flatpak or fwupd firmware update sevice
kdePackages.kcalc # Calculator
kdePackages.kcharselect # Tool to select and copy special characters from all installed fonts
kdePackages.kcolorchooser # A small utility to select a color
kdePackages.kolourpaint # Easy-to-use paint program
kdePackages.ksystemlog # KDE SystemLog Application
kdePackages.sddm-kcm # Configuration module for SDDM
kdiff3 # Compares and merges 2 or 3 files or directories
kdePackages.isoimagewriter # Optional: Program to write hybrid ISO files onto USB disks
kdePackages.partitionmanager # Optional Manage the disk devices, partitions and file systems on your computer
kdePackages.merkuro
kdePackages.korganizer
kdePackages.kdepim-addons
hardinfo2 # System information and benchmarks for Linux systems
haruna # Open source video player built with Qt/QML and libmpv
wayland-utils # Wayland utilities
wl-clipboard # Command-line copy/paste utilities for Wayland
];
}

View File

@@ -1 +0,0 @@
{ ... }: { programs.thunderbird.enable = true; }

View File

@@ -1,29 +0,0 @@
{ pkgs, apple-fonts, ... }: {
fonts = {
fontconfig.defaultFonts = {
sansSerif = [ "SF Pro" ];
serif = [ "SF Pro" ];
monospace = [ "JetBrainsMono Nerd Font" ];
emoji = [ "Apple Color Emoji" ];
};
packages = with pkgs; [
monocraft
noto-fonts-cjk-sans
nerd-fonts.jetbrains-mono
(apple-fonts.packages.${pkgs.system}.sf-pro)
(stdenv.mkDerivation {
name = "apple-color-emoji";
src = fetchurl {
url =
"https://github.com/samuelngs/apple-emoji-linux/releases/download/v17.4/AppleColorEmoji.ttf";
sha256 = "1wahjmbfm1xgm58madvl21451a04gxham5vz67gqz1cvpi0cjva8";
};
dontUnpack = true;
installPhase = ''
install -Dm644 $src $out/share/fonts/truetype/AppleColorEmoji.ttf
'';
})
];
};
}

View File

@@ -1,15 +0,0 @@
{ pkgs, ... }: {
i18n.defaultLocale = "en_US.UTF-8";
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" "zh_CN.UTF-8/UTF-8" ];
i18n.inputMethod = {
enable = true;
type = "fcitx5";
fcitx5.addons = with pkgs; [
# fcitx5-gtk # alternatively, kdePackages.fcitx5-qt
kdePackages.fcitx5-qt # alternatively, kdePackages.fcitx5-qt
qt6Packages.fcitx5-chinese-addons # table input method support
fcitx5-nord # a color theme
];
};
}

View File

@@ -1,32 +0,0 @@
{ pkgs, proton-pass-cli, config, ... }:
let
cache-path = "$HOME/.cache/pass";
proton-pass = pkgs.writeShellScriptBin "pass-cli" ''
export PROTON_PASS_KEY_PROVIDER="env"
export PROTON_PASS_ENCRYPTION_KEY="${config.sops.secrets.proton_key.path}"
exec ${proton-pass-cli.packages.${pkgs.system}.default}/bin/pass-cli "$@"
'';
pass-sync = pkgs.writeShellScriptBin "pass-sync" ''
mkdir -p "${cache-path}"
vaults=$(${proton-pass}/bin/pass-cli vault list --output json | ${pkgs.jq}/bin/jq '.vaults[].name' -r)
for vault in $vaults; do
${proton-pass}/bin/pass-cli item list $vault --filter-state active --output json | ${pkgs.jq}/bin/jq '.items[].content.title' -r > "${cache-path}/$vault"
done
'';
pass-fzf = pkgs.writeShellScriptBin "pass-fzf" ''
selected=$(for f in ~/.cache/pass/*; do while IFS= read -r line; do echo "$(basename "$f"): $line"; done < "$f"; done | fzf)
vault=$(echo "$selected" | cut -d':' -f1)
item=$(echo "$selected" | cut -d':' -f2- | sed 's/^ //')
${proton-pass}/bin/pass-cli item view --vault-name "$vault" --item-title "$item" --output json | ${pkgs.jq}/bin/jq '.item.content.content.Login.password' | ${pkgs.wl-clipboard}/bin/wl-copy
'';
in {
environment.systemPackages = [
proton-pass
pass-sync
pass-fzf
];
}

View File

@@ -1,20 +0,0 @@
{ ... }:
{
services.syncthing = {
enable = true;
openDefaultPorts = true;
settings = {
devices = {
"phone" = { id = "DBTMZ3P-VONFNYH-LDDNIO3-ZZ2TKO5-QFVV5D4-W4FMV67-HUTIJQB-UHNF3QM"; };
};
folders = {
"Music" = {
path = "/home/max/media/music";
devices = [ "phone" ];
};
};
};
};
}

View File

@@ -1,32 +0,0 @@
{ lib, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
yubioath-flutter # gui
yubikey-manager # `ykman`
pam_u2f # yubikey with sudo
];
services.pcscd.enable = true;
services.udev.packages = [ pkgs.yubikey-personalization ];
services.yubikey-agent.enable = true;
security.pam = {
sshAgentAuth.enable = true;
u2f = {
enable = true;
settings = {
cue = true;
authFile = "/home/max/.config/Yubico/u2f_keys";
};
};
services = {
login.u2fAuth = true;
sudo = {
u2fAuth = true;
sshAgentAuth = true;
};
};
};
}

View File

@@ -1,146 +0,0 @@
{ pkgs, pkgs-unstable, ... }:
{
imports = [
./hardware-configuration.nix
../common/core/default.nix
./user.nix
./work.nix
./sops.nix
./tailscale.nix
../common/optional/desktop/hyprland.nix
../common/optional/font.nix
../common/optional/yubikey.nix
../common/optional/browser.nix
../common/optional/locale.nix
../common/optional/email.nix
../common/optional/proton.nix
../common/optional/syncthing.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
boot.m1n1CustomLogo = ../../assets/logo.png;
hardware = {
asahi = {
peripheralFirmwareDirectory = ./firmware;
setupAsahiSound = true;
};
};
hardware.opengl = {
enable = true;
extraPackages = with pkgs; [
mesa.opencl
];
};
services.upower.enable = true;
services.logind.settings.Login.HandlePowerKey = "ignore";
networking.networkmanager = {
enable = true;
plugins = with pkgs; [
networkmanager-openconnect
];
};
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
environment.variables = {
XDG_DATA_HOME = "/home/max/.local/share";
GSK_RENDERER = "ngl";
EDITOR = "nvim";
};
environment.sessionVariables.NIXOS_OZONE_WL = "1";
programs.kdeconnect.enable = true;
environment.systemPackages = with pkgs; [
networkmanager
vim
git
wget
file
just
libreoffice-qt
pkgs-unstable.signal-desktop
pkgs-unstable.gurk-rs
gnupg
(pass.withExtensions (exts: [ exts.pass-otp ]))
pinentry-curses
pinentry-qt
fzf
zip
jq
ffmpeg
ripgrep
unzip
zbar
tt
sc-im
libqalculate
librespeed-cli
gparted
tea
cloudflared
# gcc
prismlauncher
gimp
inkscape
# arm support
pkgs-unstable.sparrow
(writeShellScriptBin "radio" ''
list="
WIOP http://s4.yesstreaming.net:7119/;audio.mp3
FamilyAlter https://usa17.fastcast4u.com/proxy/roloffev?mp=/1
"
choice=$(echo "$list" | awk '{print $1}' | ${fzf}/bin/fzf)
if [[ -n "$choice" ]]; then
url=$(echo "$list" | awk -v name="$choice" '$1==name {print $2}')
${mpg123}/bin/mpg123 "$url"
fi
'')
(pkgs.writeShellScriptBin "battery-graph" ''
${pkgs.coreutils}/bin/tail -n 20 /var/lib/upower/history-charge-bq40z651-69-F8Y3262H468Q1LTA1.dat | ${pkgs.coreutils}/bin/cut -f1,2 | RUBYOPT='-W0' ${pkgs.youplot}/bin/uplot line -w 70
'')
(pkgs.writeShellScriptBin "ocr-clip" ''
${pkgs.grimblast}/bin/grimblast -f save area - | ${pkgs.tesseract}/bin/tesseract stdin stdout | ${pkgs.wl-clipboard}/bin/wl-copy
'')
];
programs.zsh.enable = true;
programs.gnupg.agent = {
enable = true;
pinentryPackage = pkgs.pinentry-qt;
enableSSHSupport = true;
};
system.stateVersion = "25.05";
}

View File

@@ -1,28 +0,0 @@
{ ... }:
{
imports = [
./home/sops.nix
./home/ssh.nix
./home/git.nix
./home/browser.nix
./home/image-viewer.nix
../../home/common/optional/desktop/hyprland.nix
./home/nvim.nix
./home/terminal.nix
./home/zathura.nix
./home/music.nix
];
gtk = {
enable = true;
colorScheme = "dark";
};
home.username = "max";
home.homeDirectory = "/home/max";
home.stateVersion = "25.05";
}

View File

@@ -1,157 +0,0 @@
{ config, zen-browser, system, pkgs, firefox-addons, ... }:
{
xdg.mimeApps = let
value = let
browser = zen-browser.packages.${system}.beta; # or twilight
in
browser.meta.desktopFileName;
associations = builtins.listToAttrs (map (name: {
inherit name value;
}) [
"application/x-extension-shtml"
"application/x-extension-xhtml"
"application/x-extension-html"
"application/x-extension-xht"
"application/x-extension-htm"
"x-scheme-handler/unknown"
"x-scheme-handler/mailto"
"x-scheme-handler/chrome"
"x-scheme-handler/about"
"x-scheme-handler/https"
"x-scheme-handler/http"
"application/xhtml+xml"
"application/json"
"text/plain"
"text/html"
]);
in {
enable = true;
associations.added = associations;
defaultApplications = associations;
};
programs.zen-browser = {
enable = true;
policies = {
AutofillAddressEnabled = false;
AutofillCreditCardEnabled = false;
DisableAppUpdate = true;
DisableFeedbackCommands = true;
DisableFirefoxStudies = true;
DisablePocket = true;
DisableTelemetry = true;
DontCheckDefaultBrowser = true;
NoDefaultBookmarks = true;
OfferToSaveLogins = false;
EnableTrackingProtection = {
Value = true;
Locked = true;
Cryptomining = true;
Fingerprinting = true;
};
# ID's can be collected from this command:
# nix run github:tupakkatapa/mozid -- "https://addons.mozilla.org/en-US/firefox/addon/<example>/"
ExtensionSettings = {
# The default behaviour of ctrl+click, shift+click, cmd+click (on macOS) and middle-click when clicking on links is to open the link in a new tab (or new window in the case of shift).
# This behaviour is sometimes broken by silly developers.
"{18b670e2-67df-4b26-b9b0-34835d1f062a}" = {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/link-fixer/latest.xpi";
installation_mode = "force_installed";
};
};
};
profiles.default = let
containers = {
Personal = {
color = "yellow";
icon = "circle";
id = 1;
};
School = {
color = "red";
icon = "fruit";
id = 2;
};
Work = {
color = "blue";
icon = "briefcase";
id = 3;
};
};
spaces = {
Personal = {
id = "c6de089c-410d-4206-961d-ab11f988d40a";
icon = "";
container = containers."Personal".id;
position = 1000;
};
School = {
id = "78aabdad-8aae-4fe0-8ff0-2a0c6c4ccc24";
icon = "🍎";
container = containers."School".id;
position = 2000;
};
Work = {
id = "cdd10fab-4fc5-494b-9041-325e5759195b";
icon = "💼";
container = containers."Work".id;
position = 3000;
};
};
pins = {
# Personal Pins
"Proton Mail" = {
id = "d9942e0a-0997-418d-b357-91727300d184";
container = containers.Personal.id;
url = "https://mail.proton.me";
isEssential = true;
position = 1;
};
"Proton Calendar" = {
id = "6557e03f-c0ab-4656-ac94-acfb1fe19f3c";
container = containers.Personal.id;
url = "https://calendar.proton.me";
isEssential = true;
position = 2;
};
"YNAB" = {
id = "10cb5609-fcd5-4ed6-a48d-24eb22f2d624";
container = containers.Personal.id;
url = "https://app.ynab.com";
isEssential = true;
position = 3;
};
# # School Pins
# "Canvas" = {
# id = "cfbdc143-6a16-46d7-b33e-e9c964725e59";
# workspace = spaces.School.id;
# container = containers.School.id;
# url = "https://clemson.instructure.com/calendar";
# isEssential = true;
# position = 104;
# };
};
in {
containersForce = true;
spacesForce = true;
pinsForce = true;
inherit containers spaces pins;
# This is awesome :)
# https://nur.nix-community.org/repos/rycee/
extensions.packages = with firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [
ublock-origin
proton-pass
istilldontcareaboutcookies
better-canvas
darkreader
];
};
};
}

View File

@@ -1,6 +0,0 @@
.browserContainer > findbar {
top: 0 !important;
position: fixed !important;
width: 1000px !important;
right: 0 !important;
}

View File

@@ -1,31 +0,0 @@
{ lib, ... }:
let
publicGitEmail = "22125083+k2on@users.noreply.github.com";
publicKey = "/home/max/.ssh/id_maxkey.pub";
in
{
programs.git = {
enable = true;
settings = {
init.defaultBranch = "main";
push.autoSetupRemote = true;
commit.gpgsign = true;
gpg.format = "ssh";
user.name = "Max Koon";
user.email = publicGitEmail;
user.signing.key = publicKey;
gpg.ssh.allowedSignersFile = "/home/max/.ssh/allowed_signers";
};
signing = {
signByDefault = true;
key = publicKey;
};
};
home.file.".ssh/allowed_signers".text = ''
${publicGitEmail} ${lib.fileContents ../keys/id_maxkey.pub}
'';
}

View File

@@ -1,26 +0,0 @@
{ pkgs, ... }:
{
xdg.desktopEntries.imv = {
name = "imv";
exec = "${pkgs.imv}/bin/imv %F";
icon = "imv";
};
xdg.mimeApps = let
value = "imv.desktop";
associations = builtins.listToAttrs (map (name: {
inherit name value;
}) [
"image/png"
"image/jpeg"
"image/gif"
"image/bmp"
"image/webp"
]);
in {
enable = true;
associations.added = associations;
defaultApplications = associations;
};
}

View File

@@ -1,45 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
mpc
];
services.mpd = {
enable = true;
musicDirectory = "/home/max/media/music";
# extraConfig = ''
# audio_output {
# type "pipewire"
# name "pipewire"
# }
# '';
extraConfig = ''
audio_output {
type "alsa"
name "My ALSA"
mixer_type "hardware"
mixer_device "default"
mixer_control "PCM"
}
'';
};
services.mpd-mpris.enable = true;
programs.ncmpcpp = {
enable = true;
bindings = [
{ key = "j"; command = "scroll_down"; }
{ key = "k"; command = "scroll_up"; }
{ key = "h"; command = "previous_column"; }
{ key = "l"; command = "next_column"; }
{ key = "J"; command = [ "select_item" "scroll_down" ]; }
{ key = "K"; command = [ "select_item" "scroll_up" ]; }
];
};
}

View File

@@ -1,282 +0,0 @@
{ pkgs, ... }: {
programs.nixvim = {
enable = true;
colorschemes.tokyonight.enable = true;
globals = {
mapleader = " ";
maplocalleader = " ";
};
clipboard = {
providers.wl-copy.enable = true;
register = "unnamedplus";
};
opts = {
background = "dark";
relativenumber = true;
cursorline = true;
number = true;
tabstop = 2;
expandtab = true;
signcolumn = "yes";
updatetime = 250;
list = true;
listchars.__raw = "{ tab = '» ', trail = '·', nbsp = '' }";
};
extraConfigLua = ''
vim.g.transparent_enabled = true
require('transparent').setup({ exclude_groups = { "CursorLine" } })
require('stay-centered').setup({ enable = true })
require('mini.ai').setup()
'';
keymaps = [
{
mode = "n";
key = "<Esc>";
action = "<cmd>nohlsearch<CR>";
}
{
mode = "n";
key = "<leader>a";
action.__raw = "function() require'harpoon':list():add() end";
}
{
mode = "n";
key = "<C-e>";
action.__raw =
"function() require'harpoon'.ui:toggle_quick_menu(require'harpoon':list()) end";
}
{
mode = "n";
key = "<C-j>";
action.__raw = "function() require'harpoon':list():select(1) end";
}
{
mode = "n";
key = "<C-k>";
action.__raw = "function() require'harpoon':list():select(2) end";
}
{
mode = "n";
key = "<C-l>";
action.__raw = "function() require'harpoon':list():select(3) end";
}
{
mode = "n";
key = "<C-;>";
action.__raw = "function() require'harpoon':list():select(4) end";
}
{
mode = "n";
key = "<leader>b";
action = "<cmd>Neotree<CR>";
}
{
mode = "n";
key = "<leader>l";
action = "<cmd>Neotree reveal<CR>";
}
];
autoCmd = [
{
event = [ "BufWritePre" ];
pattern = "*";
command = "lua vim.lsp.buf.format()";
}
];
diagnostic.settings.virtual_text = true;
userCommands.W.command = "w";
plugins = {
web-devicons.enable = true;
sleuth.enable = true;
lastplace.enable = true;
gitsigns.enable = true;
highlight-colors.enable = true;
todo-comments.enable = true;
goyo.enable = true;
treesitter = {
enable = true;
settings = {
ensureInstalled =
[ "typescript" "rust" "php" "blade" "python" "nix" ];
highlight = { enable = true; };
indent = { enable = true; };
};
};
lsp = {
enable = true;
servers = {
tsgo.enable = true;
tailwindcss.enable = false;
biome.enable = false;
rust_analyzer = {
enable = true;
installCargo = true;
installRustc = true;
};
clangd.enable = true;
phpactor.enable = true;
pylsp.enable = true;
pyright.enable = true;
nixd.enable = true;
};
keymaps = {
extra = [
{
mode = "n";
key = "gd";
action.__raw = "require('telescope.builtin').lsp_definitions";
options = { desc = "LSP: [G]oto [D]efinition"; };
}
{
mode = "n";
key = "gr";
action.__raw = "require('telescope.builtin').lsp_references";
options = { desc = "LSP: [G]oto [R]eferences"; };
}
];
lspBuf = {
"<leader>." = {
mode = [ "n" "x" ];
action = "code_action";
desc = "Code action";
};
};
};
};
lazydev.enable = true;
luasnip.enable = true;
telescope = {
enable = true;
extensions = {
fzf-native.enable = true;
ui-select.enable = true;
};
keymaps = {
"<leader>sf" = {
mode = "n";
action = "find_files";
options = { desc = "[S]earch [F]iles"; };
};
"<leader>sk" = {
mode = "n";
action = "live_grep";
options = { desc = "[S]earch [S]tring"; };
};
};
settings = {
extensions.__raw =
"{ ['ui-select'] = { require('telescope.themes').get_dropdown() } }";
};
};
cmp = {
enable = true;
settings = {
snippet = {
expand = ''
function(args)
require('luasnip').lsp_expand(args.body)
end
'';
};
completion = { completeopt = "menu,menuone,noinsert"; };
formatting = {
format = ''require("nvim-highlight-colors").format'';
};
mapping = {
"<CR>" = "cmp.mapping.confirm { select = true }";
"<Tab>" = "cmp.mapping.select_next_item()";
"<S-Tab>" = "cmp.mapping.select_prev_item()";
"<Down>" = "cmp.mapping.select_next_item()";
"<Up>" = "cmp.mapping.select_prev_item()";
"<C-j>" = "cmp.mapping.select_next_item()";
"<C-k>" = "cmp.mapping.select_prev_item()";
};
sources = [
{
name = "lazydev";
group_index = 0;
}
{ name = "nvim_lsp"; }
{ name = "luasnip"; }
{ name = "path"; }
{ name = "nvim_lsp_signature_help"; }
];
};
};
harpoon = {
enable = true;
settings.settings = { save_on_toggle = true; };
};
neo-tree = {
enable = true;
settings = {
window.width = 25;
filesystem = {
filtered_items = {
visible = true;
};
};
};
};
wakatime.enable = true;
autoclose.enable = true;
ts-autotag.enable = true;
bullets.enable = true;
spider = {
enable = true;
settings = {
subwordMovement = true;
skipInsignificantPunctuation = false;
};
keymaps = {
motions = {
"w" = "w";
"e" = "e";
"b" = "b";
};
};
};
transparent.enable = true;
};
extraPlugins = with pkgs.vimPlugins; [
stay-centered-nvim
mini-ai
];
};
}

View File

@@ -1,19 +0,0 @@
{ ... }:
{
sops = {
age.keyFile = "/home/max/.config/sops/age/keys.txt";
defaultSopsFile = ../../../secrets/sops/host/max/default.yaml;
validateSopsFiles = false;
secrets = {
"ssh_keys/max" = {
path = "/home/max/.ssh/id_maxkey";
};
"waka_config" = {
path = "/home/max/.wakatime.cfg";
};
};
};
}

View File

@@ -1,45 +0,0 @@
{ ... }:
{
programs.ssh = {
enable = true;
extraConfig = ''
Host m1
HostName m1
User admin
Host surface
HostName surface
User admin
Host ark
HostName ark
User admin
Host pi
HostName 192.168.0.143
User admin
Host ssh.koon.us
HostName ssh.koon.us
ProxyCommand cloudflared access ssh --hostname %h
User git
AddKeysToAgent yes
'';
matchBlocks = {
"git" = {
host = "github.com";
user = "git";
identityFile = [
"~/.ssh/id_maxkey"
];
};
};
};
home.file = {
".ssh/id_maxkey.pub".source = ../keys/id_maxkey.pub;
};
}

View File

@@ -1,137 +0,0 @@
{ pkgs, config, ... }: {
programs.alacritty = {
enable = true;
theme = "tokyo_night";
settings = {
window = {
padding = { x = 14; y = 14; };
};
font = {
normal.family = "JetBrainsMono Nerd Font";
size = 10;
};
keyboard.bindings = [
{ key = "Insert"; mods = "Shift"; action = "Paste"; }
{ key = "Insert"; mods = "Control"; action = "Copy"; }
];
};
};
programs.lf = { enable = true; };
programs.tmux = {
enable = true;
mouse = true;
keyMode = "vi";
shell = "${pkgs.zsh}/bin/zsh";
extraConfig = ''
set -g status-style bg=default
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",alacritty:Tc"
'';
};
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion = {
enable = true;
};
syntaxHighlighting.enable = true;
dotDir = "${config.home.homeDirectory}/.config/zsh";
autocd = true;
initContent = ''
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*' menu select
fzf-project() {
selected=$(find ~/dev -mindepth 2 -maxdepth 2 | sed 's|/home/max/dev/||' | fzf --delimiter '/' --nth 2)
if [[ -n $selected ]]; then
cd ~/dev/$selected
zle reset-prompt
fi
zle redisplay
}
zle -N fzf-project
bindkey '^G' fzf-project
fzf-files() {
local selected
selected=$(${pkgs.ripgrep}/bin/rg --files | ${pkgs.fzf}/bin/fzf) || return
if [[ -n $selected ]]; then
BUFFER="v $selected"
print -s -- "$BUFFER"
zle accept-line
fi
}
zle -N fzf-files
bindkey '^V' fzf-files
open() {
xdg-open "$@" >/dev/null 2>&1 &
}
'';
envExtra = ''
export PER_DIRECTORY_HISTORY_TOGGLE="^H"
export HISTORY_BASE="$HOME/.local/share/directory_history"
'';
shellAliases = {
ll = "ls -alh";
v = "nvim";
vi = "nvim";
vim = "nvim";
p = "pnpm";
g = "pnpm run build && ~/dev/personal/genesis/packages/genesis/dist/bin.js";
ns = "nix-shell --run zsh -p";
tt = "tt -notheme -n 10";
bible = "nvim ~/bible.txt -R";
notes = "nvim ~/notes";
home = "sudo nvim /etc/nixos/home.nix";
wttr = "curl wttr.in/Clemson";
docx-to-pdf = "libreoffice --headless --convert-to pdf";
};
plugins = [
{
name = "vi-mode";
src = pkgs.zsh-vi-mode;
file = "share/zsh-vi-mode/zsh-vi-mode.plugin.zsh";
}
{
name = "per-directory-history";
src = pkgs.fetchFromGitHub {
owner = "jimhester";
repo = "per-directory-history";
rev = "95f06973e9f2ff0ff75f3cebd0a2ee5485e27834";
sha256 = "sha256-EV9QPBndwAWzdOcghDXrIIgP0oagVMOTyXzoyt8tXRo=";
};
}
];
};
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
silent = true;
};
programs.starship = { enable = true; };
}

View File

@@ -1,8 +0,0 @@
{ ... }: {
programs.zathura = {
enable = true;
options = {
selection-clipboard = "clipboard";
};
};
}

View File

@@ -1,29 +0,0 @@
{ config, lib, ... }:
{
sops = {
age.keyFile = if builtins.pathExists /var/lib/sops-nix/key.txt then
"/var/lib/sops-nix/key.txt"
else
"/home/max/.config/sops/age/keys.txt" # temp decrypt key
;
defaultSopsFile = ../../secrets/sops/host/max/default.yaml;
validateSopsFiles = false;
secrets = {
"host_age_key" = {
path = "/var/lib/sops-nix/key.txt";
};
"yubico/u2f_keys" = {
owner = config.users.users.max.name;
inherit (config.users.users.max) group;
path = "/home/max/.config/Yubico/u2f_keys";
};
"proton_key" = {};
};
};
environment.sessionVariables.PROTON_PASS_ENCRYPTION_KEY = config.sops.secrets.proton_key.path;
}

View File

@@ -1,16 +0,0 @@
{ pkgs, ... }:
{
services.tailscale.enable = true;
systemd.services.tailscale-restart = {
description = "Restart Tailscale after waking up";
after = [ "suspend.target" ];
wantedBy = [ "suspend.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.systemd}/bin/systemctl restart tailscaled.service";
};
};
}

View File

@@ -1,24 +0,0 @@
{ pkgs, config, ... }: {
sops.secrets.max-password.neededForUsers = true;
users.mutableUsers = false;
users.users.max = {
isNormalUser = true;
hashedPasswordFile = config.sops.secrets.max-password.path;
extraGroups = [ "wheel" "networkmanager" "video" "kvm" "docker" "ydotool" ];
packages = with pkgs; [ tree ];
shell = pkgs.zsh;
};
programs.adb.enable = true;
virtualisation.docker = {
enable = true;
rootless = {
enable = true;
setSocketVariable = true;
};
};
}

View File

@@ -1,31 +0,0 @@
{ config, secrets, ... }: {
services.openvpn.servers = {
ris = {
config = "config /etc/openvpn/ris/config.ovpn ";
updateResolvConf = true;
autoStart = false;
};
};
sops.secrets = {
"ris-vpn/key" = {
sopsFile = ../../secrets/sops/host/max/work.yaml;
owner = config.users.users.root.name;
inherit (config.users.users.root) group;
path = "/etc/openvpn/ris/vpnclient.rismedia.com.key";
};
};
environment.etc."openvpn/ris/config.ovpn" = {
text = secrets.work.ris.vpn.config;
};
environment.etc."openvpn/ris/vpnclient.rismedia.com.crt" = {
text = secrets.work.ris.vpn.crt;
};
networking.extraHosts = ''
${secrets.work.ris.extraHosts}
'';
}

View File

@@ -1,16 +0,0 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/local" {
version = "2.5.3"
hashes = [
"h1:6ADVoHtXiWFhClkKa1vnBycJxqnL0GjHMZAQipa4SEU=",
]
}
provider "registry.terraform.io/trozz/pocketid" {
version = "0.1.5"
hashes = [
"h1:egwnwPepmLF/OAE96D7RxGlsXYlUVZi3CuFhAH69iVE=",
]
}

View File

@@ -1,93 +0,0 @@
{
terraform = {
required_providers = {
pocketid = {
source = "trozz/pocketid";
};
};
};
provider.pocketid = {
base_url = "https://auth.koon.us";
api_token = "\${var.pocketid_api_token}";
};
variable.pocketid_api_token = {
type = "string";
sensitive = true;
description = "PocketID API token";
};
resource.pocketid_client.photos = {
name = "Photos";
callback_urls = [
"https://photos.koon.us/auth/login"
"https://photos.koon.us/user-settings"
"app.immich:///oauth-callback"
];
is_public = false;
pkce_enabled = false;
};
resource.pocketid_client.git = {
name = "Git";
callback_urls = [
"https://git.koon.us/user/oauth2/KoonFamily/callback"
];
is_public = false;
pkce_enabled = false;
};
resource.pocketid_client.docs = {
name = "Docs";
callback_urls = [
"https://docs.koon.us/*"
];
is_public = false;
pkce_enabled = false;
};
output = {
photos_client_id = {
value = "\${pocketid_client.photos.id}";
};
photos_client_secret = {
value = "\${pocketid_client.photos.client_secret}";
sensitive = true;
};
git_client_id = {
value = "\${pocketid_client.git.id}";
};
git_client_secret = {
value = "\${pocketid_client.git.client_secret}";
sensitive = true;
};
docs_client_id = {
value = "\${pocketid_client.docs.id}";
};
docs_client_secret = {
value = "\${pocketid_client.docs.client_secret}";
sensitive = true;
};
};
resource.local_file.oauth_config = {
filename = "\${path.module}/../secrets/sops/oauth.yaml";
content = ''
photos:
clientId: ''${pocketid_client.photos.id}
clientSecret: ''${pocketid_client.photos.client_secret}
git:
clientId: ''${pocketid_client.git.id}
clientSecret: ''${pocketid_client.git.client_secret}
docs:
clientId: ''${pocketid_client.docs.id}
clientSecret: ''${pocketid_client.docs.client_secret}
'';
file_permission = "0600";
};
}

View File

@@ -11,25 +11,32 @@ rebuild:
just add-secrets just add-secrets
git add . git add .
sudo nixos-rebuild switch --flake '.?submodules=1#max' sudo nixos-rebuild switch --flake '.?submodules=1#koonMax'
rebuild-boot: rebuild-boot:
just add-secrets just add-secrets
git add . git add .
sudo nixos-rebuild boot --flake '.?submodules=1#max' sudo nixos-rebuild boot --flake '.?submodules=1#koonMax'
rebuild-offline: rebuild-offline:
just add-secrets just add-secrets
git add . git add .
sudo nixos-rebuild switch --flake '.?submodules=1#max' --offline sudo nixos-rebuild switch --flake '.?submodules=1#koonMax' --offline
rebuild-ark: rebuild-ark:
just add-secrets just add-secrets
git add . git add .
nixos-rebuild --flake '.?submodules=1#ark' --build-host admin@192.168.1.192 --target-host admin@192.168.1.192 --use-remote-sudo --fast switch nixos-rebuild --flake '.?submodules=1#koonArk' --build-host ark --target-host ark --use-remote-sudo --fast switch
rebuild-ark-boot:
just add-secrets
git add .
nixos-rebuild --flake '.?submodules=1#koonArk' --build-host ark --target-host ark --use-remote-sudo --fast boot
push-secrets: push-secrets:
just add-secrets just add-secrets

View File

@@ -0,0 +1,21 @@
{ ... }: {
flake.homeModules.commonFeatureAlacritty = { ... }: {
programs.alacritty = {
enable = true;
theme = "tokyo_night";
settings = {
window = {
padding = { x = 14; y = 14; };
};
font = {
normal.family = "JetBrainsMono Nerd Font";
size = 10;
};
keyboard.bindings = [
{ key = "Insert"; mods = "Shift"; action = "Paste"; }
{ key = "Insert"; mods = "Control"; action = "Copy"; }
];
};
};
};
}

View File

@@ -0,0 +1,10 @@
{ ... }: {
flake.homeModules.commonFeatureDirenv = { ... }: {
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
silent = true;
};
};
}

View File

@@ -0,0 +1,5 @@
{ ... }: {
flake.homeModules.commonFeatureLf = { ... }: {
programs.lf = { enable = true; };
};
}

View File

@@ -0,0 +1,6 @@
{ ... }: {
flake.homeModules.commonFeatureStarship = { ... }: {
programs.starship.enable = true;
};
}

View File

@@ -0,0 +1,21 @@
{ ... }: {
flake.homeModules.commonFeatureTmux = { pkgs, ... }: {
programs.tmux = {
enable = true;
mouse = true;
keyMode = "vi";
shell = "${pkgs.zsh}/bin/zsh";
extraConfig = ''
set -g status-style bg=default
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",alacritty:Tc"
'';
};
};
}

View File

@@ -0,0 +1,92 @@
{ ... }: {
flake.homeModules.commonFeatureZsh = { pkgs, config, ... }: {
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion = {
enable = true;
};
syntaxHighlighting.enable = true;
dotDir = "${config.home.homeDirectory}/.config/zsh";
autocd = true;
initContent = ''
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*' menu select
fzf-project() {
selected=$(find ~/dev -mindepth 2 -maxdepth 2 | sed 's|/home/max/dev/||' | fzf --delimiter '/' --nth 2)
if [[ -n $selected ]]; then
cd ~/dev/$selected
zle reset-prompt
fi
zle redisplay
}
zle -N fzf-project
bindkey '^G' fzf-project
fzf-files() {
local selected
selected=$(${pkgs.ripgrep}/bin/rg --files | ${pkgs.fzf}/bin/fzf) || return
if [[ -n $selected ]]; then
BUFFER="v $selected"
print -s -- "$BUFFER"
zle accept-line
fi
}
zle -N fzf-files
bindkey '^V' fzf-files
open() {
xdg-open "$@" >/dev/null 2>&1 &
}
'';
envExtra = ''
export PER_DIRECTORY_HISTORY_TOGGLE="^H"
export HISTORY_BASE="$HOME/.local/share/directory_history"
'';
shellAliases = {
ll = "ls -alh";
v = "nvim";
vi = "nvim";
vim = "nvim";
p = "pnpm";
g = "pnpm run build && ~/dev/personal/genesis/packages/genesis/dist/bin.js";
ns = "nix-shell --run zsh -p";
tt = "tt -notheme -n 10";
bible = "nvim ~/bible.txt -R";
notes = "nvim ~/notes";
home = "sudo nvim /etc/nixos/home.nix";
wttr = "curl wttr.in/Clemson";
docx-to-pdf = "libreoffice --headless --convert-to pdf";
};
plugins = [
{
name = "vi-mode";
src = pkgs.zsh-vi-mode;
file = "share/zsh-vi-mode/zsh-vi-mode.plugin.zsh";
}
{
name = "per-directory-history";
src = pkgs.fetchFromGitHub {
owner = "jimhester";
repo = "per-directory-history";
rev = "95f06973e9f2ff0ff75f3cebd0a2ee5485e27834";
sha256 = "sha256-EV9QPBndwAWzdOcghDXrIIgP0oagVMOTyXzoyt8tXRo=";
};
}
];
};
};
}

View File

@@ -0,0 +1,6 @@
{ ... }: {
flake.nixosModules.commonFeatureEmail = { ... }: {
programs.thunderbird.enable = true;
};
}

View File

@@ -0,0 +1,32 @@
{ ... }: {
flake.nixosModules.commonFeatureFont = { pkgs, ... }: {
fonts = {
fontconfig.defaultFonts = {
sansSerif = [ "SF Pro" ];
serif = [ "SF Pro" ];
monospace = [ "JetBrainsMono Nerd Font" ];
emoji = [ "Apple Color Emoji" ];
};
packages = with pkgs; [
monocraft
noto-fonts-cjk-sans
nerd-fonts.jetbrains-mono
# (apple-fonts.packages.${pkgs.system}.sf-pro)
(stdenv.mkDerivation {
name = "apple-color-emoji";
src = fetchurl {
url =
"https://github.com/samuelngs/apple-emoji-linux/releases/download/v17.4/AppleColorEmoji.ttf";
sha256 = "1wahjmbfm1xgm58madvl21451a04gxham5vz67gqz1cvpi0cjva8";
};
dontUnpack = true;
installPhase = ''
install -Dm644 $src $out/share/fonts/truetype/AppleColorEmoji.ttf
'';
})
];
};
};
}

View File

@@ -0,0 +1,351 @@
{ ... }: {
flake.homeModules.commonFeatureHyprlandConfig = { pkgs, ... }: {
wayland.windowManager.hyprland = {
enable = true;
systemd.enable = false;
plugins = with pkgs; [
(hyprlandPlugins.mkHyprlandPlugin {
pluginName = "hyprselect";
version = "0.1";
src = fetchFromGitHub {
owner = "jmanc3";
repo = "hyprselect";
rev = "f9651b5fd64c730ee164a6fee6a08d0398dcbe0a";
hash = "sha256-tY8EdfsjlUOuQ9v/POqpyLlkRO5wqEVSE9UeHfXuaGk=";
};
inherit (hyprland) nativeBuildInputs;
meta = with lib; {
homepage = "https://github.com/jmanc3/hyprselect";
description = "A plugin that adds a completely useless desktop selection box to Hyprland";
license = licenses.unlicense;
platforms = platforms.linux;
};
})
hyprlandPlugins.hyprscrolling
# hyprlandPlugins.hyprbars
];
settings = {
# source = [
# "~/.config/koonos/current/performance/hyprland.conf"
# ];
"$terminal" = "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.alacritty}/bin/alacritty";
"$fileManager" = "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.pcmanfm}/bin/pcmanfm";
"$browser" = "${pkgs.uwsm}/bin/uwsm-app -- zen-beta";
"$menu" = "${pkgs.walker}/bin/walker";
"$player" = "${pkgs.playerctl}/bin/playerctl";
monitor = [
"eDP-1,preferred,1721x1080,auto"
"HDMI-A-1,preferred,1450x0,auto"
];
exec-once = [
"${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.hypridle}/bin/hypridle"
"${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.waybar}/bin/waybar"
"${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.hyprpaper}/bin/hyprpaper"
"sleep 2 && pw-play --volume=0 ~/Downloads/empty.wav"
];
env = [
"HYPRCURSOR_THEME,macOS"
"HYPRCURSOR_SIZE,20"
];
# env = [
# "XCURSOR_SIZE,20"
# "XCURSOR_THEME,macOS"
# ];
general = {
gaps_in = 0;
gaps_out = 0;
border_size = 2;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
# Set to true enable resizing windows by clicking and dragging on borders and gaps
resize_on_border = true;
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
allow_tearing = false;
layout = "master";
};
decoration = {
# rounding = 10
# rounding_power = 2
# Change transparency of focused and unfocused windows
active_opacity = 1.0;
inactive_opacity = 1.0;
shadow = {
# enabled = false;
range = 4;
render_power = 3;
color = "rgba(1a1a1aee)";
};
# https://wiki.hyprland.org/Configuring/Variables/#blur
blur = {
# enabled = false;
size = 3;
passes = 1;
vibrancy = 0.1696;
};
};
# https://wiki.hyprland.org/Configuring/Variables/#animations
animations = {
enabled = true;
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = [
"easeOutQuint,0.23,1,0.32,1"
"easeInOutCubic,0.65,0.05,0.36,1"
"linear,0,0,1,1"
"almostLinear,0.5,0.5,0.75,1.0"
"quick,0.15,0,0.1,1"
];
animation = [
"global, 1, 10, default"
"border, 0, 5.39, easeOutQuint"
"windows, 1, 4.79, easeOutQuint"
"windowsIn, 1, 4.1, easeOutQuint, popin 87%"
"windowsOut, 1, 1.49, linear, popin 87%"
"fadeIn, 1, 1.73, almostLinear"
"fadeOut, 1, 1.46, almostLinear"
"fade, 1, 3.03, quick"
"layers, 1, 3.81, easeOutQuint"
"layersIn, 1, 4, easeOutQuint, fade"
"layersOut, 1, 1.5, linear, fade"
"fadeLayersIn, 1, 1.79, almostLinear"
"fadeLayersOut, 1, 1.39, almostLinear"
"workspaces, 0, 1.94, almostLinear, fade"
"workspacesIn, 0, 1.21, almostLinear, fade"
"workspacesOut, 0, 1.94, almostLinear, fade"
];
};
dwindle = {
pseudotile = true; # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true; # You probably want this
};
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
master = {
new_status = "master";
};
# https://wiki.hyprland.org/Configuring/Variables/#misc
misc = {
force_default_wallpaper = 0; # Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = true;
disable_splash_rendering = true;
};
#############
### INPUT ###
#############
# https://wiki.hyprland.org/Configuring/Variables/#input
input = {
kb_layout = "us";
# kb_variant =
# kb_model =
kb_options = "caps:swapescape";
# kb_rules =
follow_mouse = 1;
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
repeat_rate = 35;
repeat_delay = 300;
touchpad = {
natural_scroll = true;
tap-to-click = false;
clickfinger_behavior = true;
};
};
# https://wiki.hyprland.org/Configuring/Variables/#gestures
# gestures = {
# workspace_swipe = true;
# };
# See https://wiki.hyprland.org/Configuring/Keywords/
"$mainMod" = "SUPER"; # Sets "Windows" key as main modifier
bind = [
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
"$mainMod, return, exec, $terminal"
"$mainMod, W, killactive,"
# bind = $mainMod, M, exit,
"$mainMod, E, exec, $fileManager"
"$mainMod, B, exec, $browser"
# "$mainMod, M, exec, $terminal -e ${pkgs-unstable.gurk-rs}/bin/gurk"
"$mainMod, P, exec, $terminal -e ${pkgs.ncmpcpp}/bin/ncmpcpp"
"$mainMod SHIFT, B, exec, $terminal -e \"$EDITOR\" /home/max/bible.txt -R"
"$mainMod SHIFT, R, exec, ${pkgs.hyprshot}/bin/hyprshot -m region --clipboard-only"
# "$mainMod, V, togglefloating,"
"$mainMod, space, exec, $menu"
# "$mainMod, P, pseudo, # dwindle"
"$mainMod, F, fullscreen"
# bind = $mainMod, J, togglesplit, # dwindle
"$mainMod SHIFT, Q, exec, ${pkgs.hyprlock}/bin/hyprlock"
# Move focus with mainMod + arrow keys
"$mainMod, H, movefocus, l"
"$mainMod, L, movefocus, r"
"$mainMod, K, movefocus, u"
"$mainMod, J, movefocus, d"
# Swap window with mainMod + shift + arrow keys
"$mainMod SHIFT, H, swapwindow, l"
"$mainMod SHIFT, L, swapwindow, r"
"$mainMod SHIFT, K, swapwindow, u"
"$mainMod SHIFT, J, swapwindow, d"
# "$mainMod ALT, H, resizeactive, -40 0"
# "$mainMod ALT, L, resizeactive, 40 0"
# Switch workspaces with mainMod + [0-9]
"$mainMod, 1, workspace, 1"
"$mainMod, 2, workspace, 2"
"$mainMod, 3, workspace, 3"
"$mainMod, 4, workspace, 4"
"$mainMod, 5, workspace, 5"
"$mainMod, 6, workspace, 6"
"$mainMod, 7, workspace, 7"
"$mainMod, 8, workspace, 8"
"$mainMod, 9, workspace, 9"
"$mainMod, 0, workspace, 10"
# Move active window to a workspace with mainMod + SHIFT + [0-9]
"$mainMod SHIFT, 1, movetoworkspace, 1"
"$mainMod SHIFT, 2, movetoworkspace, 2"
"$mainMod SHIFT, 3, movetoworkspace, 3"
"$mainMod SHIFT, 4, movetoworkspace, 4"
"$mainMod SHIFT, 5, movetoworkspace, 5"
"$mainMod SHIFT, 6, movetoworkspace, 6"
"$mainMod SHIFT, 7, movetoworkspace, 7"
"$mainMod SHIFT, 8, movetoworkspace, 8"
"$mainMod SHIFT, 9, movetoworkspace, 9"
"$mainMod SHIFT, 0, movetoworkspace, 10"
# Example special workspace (scratchpad)
"$mainMod, S, togglespecialworkspace, magic"
"$mainMod SHIFT, S, movetoworkspace, special:magic"
# Scroll through existing workspaces with mainMod + scroll
# "$mainMod, mouse_down, workspace, e+1"
# "$mainMod, mouse_up, workspace, e-1"
# ", Prior, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x40"
# ", Next, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x41"
];
# bindr = [
# ", Prior, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x80"
# ", Next, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x81"
# ];
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
];
"$osdclient" = "swayosd-client --monitor \"$(hyprctl monitors -j | ${pkgs.jq}/bin/jq -r '.[] | select(.focused == true).name')\"";
bindel = [
# Laptop multimedia keys for volume and LCD brightness
# bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
# bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
",XF86AudioRaiseVolume, exec, $osdclient --output-volume=raise"
",XF86AudioLowerVolume, exec, $osdclient --output-volume=lower"
",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
# bindel = ,XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+
# bindel = ,XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%-
",XF86MonBrightnessUp, exec, $osdclient --brightness=raise"
",XF86MonBrightnessDown, exec, $osdclient --brightness=lower"
];
bindl = [
# Requires playerctl
", XF86AudioNext, exec, $player next"
", XF86AudioPause, exec, $player play-pause" ", XF86AudioPlay, exec, $player play-pause"
", XF86AudioPrev, exec, $player previous"
];
bindd = [
"$mainMod, C, Universal copy, sendshortcut, CTRL, Insert,"
"$mainMod, V, Universal paste, sendshortcut, SHIFT, Insert,"
"$mainMod, X, Universal cut, sendshortcut, CTRL, X,"
"$mainMod, A, Universal select all, sendshortcut, CTRL, A,"
"$mainMod, T, Universal new tab, sendshortcut, CTRL, T,"
"$mainMod ALT, H, Universal left, sendshortcut, , Left,"
"$mainMod ALT, J, Universal down, sendshortcut, , Down,"
"$mainMod ALT, K, Universal up, sendshortcut, , Up,"
"$mainMod ALT, L, Universal right, sendshortcut, , Right,"
"$mainMod SHIFT ALT, H, Universal left, sendshortcut, SHIFT, Left,"
"$mainMod SHIFT ALT, J, Universal down, sendshortcut, SHIFT, Down,"
"$mainMod SHIFT ALT, K, Universal up, sendshortcut, SHIFT, Up,"
"$mainMod SHIFT ALT, L, Universal right, sendshortcut, SHIFT, Right,"
];
windowrule = [
# Just dash of opacity by default
"opacity 0.97 0.9, class:.*"
# Ignore maximize requests from apps. You'll probably like this.
"suppressevent maximize, class:.*"
# Fix some dragging issues with XWayland
"nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0"
];
plugin = {
hyprselect = {
"col.main" = "rgba(ffffff25)";
"col.border" = "rgba(ffffff88)";
fade_time_ms = 165.0;
border_size = 1.0;
};
hyprscrolling = {
fullscreen_on_one_column = true;
};
# hyprbars = {
# enabled = false;
# };
};
};
};
};
}

View File

@@ -0,0 +1,41 @@
{ self, inputs, ... }: {
flake.nixosModules.commonFeatureHyprland = { pkgs, ... }: {
programs.hyprland = {
enable = true;
withUWSM = true;
xwayland.enable = true;
};
services.greetd = {
enable = true;
settings = {
default_session = {
command = "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd 'uwsm start hyprland-uwsm.desktop'";
user = "greeter";
};
};
};
security.pam.services.hyprlock = {};
environment.systemPackages = with pkgs; [
hyprpaper
hypridle
hyprpicker
hyprsunset
hyprshot
waybar
walker
swayosd
playerctl
brightnessctl
wl-clipboard
wdisplays
bluetui
kdePackages.dolphin
];
};
}

View File

@@ -0,0 +1,29 @@
{ ... }: {
flake.homeModules.commonFeatureHypridle = { pkgs, ... }: {
services.hypridle = {
enable = true;
settings = {
general = {
lock_cmd = "${pkgs.hyprlock}/bin/hyprlock";
before_sleep_cmd = "${pkgs.systemd}/bin/loginctl lock-session"; # lock before suspend.
after_sleep_cmd = "${pkgs.hyprland}/bin/hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
inhibit_sleep = 3; # wait until screen is locked
};
listener = [
{
timeout = 60 * 5; # 5min
on-timeout = "${pkgs.systemd}/bin/loginctl lock-session"; # lock screen when timeout has passed
}
{
timeout = 60 * 5.5; # 5.5min
on-timeout = "${pkgs.hyprland}/bin/hyprctl dispatch dpms off"; # screen off when timeout has passed
on-resume = "${pkgs.hyprland}/bin/hyprctl dispatch dpms on && brightnessctl -r"; # screen on when activity is detected
}
];
};
};
};
}

View File

@@ -0,0 +1,59 @@
{ ... }: {
flake.homeModules.commonFeatureHyprlock = { ... }: {
programs.hyprlock = {
enable = true;
settings = {
"$color" = "rgba(26,27,38,1.0)";
"$inner_color" = "rgba(26,27,38,0.8)";
"$outer_color" = "rgba(205,214,244,1.0)";
"$font_color" = "rgba(205,214,244,1.0)";
"$check_color" = "rgba(68, 157, 171, 1.0)";
general = {
ignore_empty_input = true;
};
background = {
monitor = "";
color = "$color";
# path = "~/Downloads/wallpaper.png";
blur_passes = 3;
};
animations = {
enabled = true;
};
input-field = {
monitor = "";
size = "650, 100";
position = "0, 0";
halign = "center";
valign = "center";
inner_color = "$inner_color";
outer_color = "$outer_color";
outline_thickness = 4;
font_family = "JetBrainsMono Nerd Font";
font_color = "$font_color";
placeholder_text = "Enter Password";
check_color = "$check_color";
fail_text = "<i>$FAIL ($ATTEMPTS)</i>";
rounding = 0;
shadow_passes = 0;
fade_on_empty = false;
};
auth = {
"fingerprint:enabled" = true;
};
};
};
};
}

View File

@@ -0,0 +1,33 @@
{ ... }: {
flake.homeModules.commonFeatureNotifications = { ... }: {
services.swaync = {
enable = true;
settings = {
notification-window-width = 350;
};
# Taken from:
# https://github.com/ErikReider/SwayNotificationCenter/blob/2083415ee6441acc272f46f8a43ebccae215f69a/data/style/style.scss#L4
style = ''
:root {
--cc-bg: rgba(46, 46, 46, 0.7);
--noti-border-color: rgba(255, 255, 255, 0.15);
--noti-bg: 48, 48, 48;
--noti-bg-alpha: 1;
--border-radius: 0;
--font-size-body: 13px;
--font-size-summary: 14px;
}
.close-button {
min-width: 18px;
min-height: 18px;
}
'';
};
};
}

View File

@@ -0,0 +1,9 @@
{ ... }: {
flake.homeModules.commonFeatureOsd = { ... }: {
services.swayosd = {
enable = true;
};
home.file.".config/swayosd/style.css".source = ./swayosd/style.css;
};
}

View File

@@ -0,0 +1,5 @@
{ ... }: {
flake.homeModules.commonFeatureWalker = { ... }: {
home.file.".config/walker/config.toml".source = ./walker/config.toml;
};
}

View File

@@ -0,0 +1,21 @@
{ self, ... }: {
flake.homeModules.commonFeatureWallpaper = { ... }:
let
wallpaper = builtins.toString "${self}/assets/wallpaper.jpg";
in {
services.hyprpaper = {
enable = true;
settings = {
spash = false;
preload = [ wallpaper ];
wallpaper = [
"eDP-1,${wallpaper}"
"HDMI-A-1,${wallpaper}"
];
};
};
};
}

View File

@@ -0,0 +1,6 @@
{ ... }: {
flake.homeModules.commonFeatureWaybar = { ... }: {
home.file.".config/waybar/config.jsonc".source = ./waybar/config.jsonc;
home.file.".config/waybar/style.css".source = ./waybar/style.css;
};
}

View File

@@ -0,0 +1,27 @@
{ ... }: {
flake.homeModules.commonFeatureImageViewer = { pkgs, ... }: {
xdg.desktopEntries.imv = {
name = "imv";
exec = "${pkgs.imv}/bin/imv %F";
icon = "imv";
};
xdg.mimeApps = let
value = "imv.desktop";
associations = builtins.listToAttrs (map (name: {
inherit name value;
}) [
"image/png"
"image/jpeg"
"image/gif"
"image/bmp"
"image/webp"
]);
in {
enable = true;
associations.added = associations;
defaultApplications = associations;
};
};
}

View File

@@ -0,0 +1,7 @@
{ ... }: {
flake.nixosModules.commonFeatureLaptop = { ... }: {
services.upower.enable = true;
services.logind.settings.Login.HandlePowerKey = "ignore";
services.automatic-timezoned.enable = true;
};
}

View File

@@ -0,0 +1,16 @@
{ ... }: {
flake.nixosModules.commonFeatureLocale = { pkgs, ... }: {
i18n.defaultLocale = "en_US.UTF-8";
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" "zh_CN.UTF-8/UTF-8" ];
i18n.inputMethod = {
enable = true;
type = "fcitx5";
fcitx5.addons = with pkgs; [
# fcitx5-gtk # alternatively, kdePackages.fcitx5-qt
kdePackages.fcitx5-qt # alternatively, kdePackages.fcitx5-qt
qt6Packages.fcitx5-chinese-addons # table input method support
fcitx5-nord # a color theme
];
};
};
}

View File

@@ -0,0 +1,47 @@
{ ... }: {
flake.homeModules.commonFeatureMusic = { pkgs, ... }: {
home.packages = with pkgs; [
mpc
];
services.mpd = {
enable = true;
musicDirectory = "/home/max/media/music";
# extraConfig = ''
# audio_output {
# type "pipewire"
# name "pipewire"
# }
# '';
extraConfig = ''
audio_output {
type "alsa"
name "My ALSA"
mixer_type "hardware"
mixer_device "default"
mixer_control "PCM"
}
'';
};
services.mpd-mpris.enable = true;
programs.ncmpcpp = {
enable = true;
bindings = [
{ key = "j"; command = "scroll_down"; }
{ key = "k"; command = "scroll_up"; }
{ key = "h"; command = "previous_column"; }
{ key = "l"; command = "next_column"; }
{ key = "J"; command = [ "select_item" "scroll_down" ]; }
{ key = "K"; command = [ "select_item" "scroll_up" ]; }
];
};
};
}

View File

@@ -0,0 +1,11 @@
{ inputs, ... }: {
flake.nixosModules.commonUnstablePkgsOverlay = { ... }: {
nixpkgs.overlays = [
(final: prev: {
pkgs-unstable = import inputs.nixpkgs-unstable {
inherit (prev.stdenv.hostPlatform) system;
};
})
];
};
}

View File

@@ -0,0 +1,32 @@
{ ... }: {
flake.nixosModules.commonFeatureYubikey = { pkgs, ... }: {
environment.systemPackages = with pkgs; [
yubioath-flutter # gui
yubikey-manager # `ykman`
pam_u2f # yubikey with sudo
];
services.pcscd.enable = true;
services.udev.packages = [ pkgs.yubikey-personalization ];
services.yubikey-agent.enable = true;
security.pam = {
sshAgentAuth.enable = true;
u2f = {
enable = true;
settings = {
cue = true;
authFile = "/home/max/.config/Yubico/u2f_keys";
};
};
services = {
login.u2fAuth = true;
sudo = {
u2fAuth = true;
sshAgentAuth = true;
};
};
};
};
}

View File

@@ -0,0 +1,10 @@
{ ... }: {
flake.homeModules.commonFeatureZathura = { ... }: {
programs.zathura = {
enable = true;
options = {
selection-clipboard = "clipboard";
};
};
};
}

View File

@@ -0,0 +1,17 @@
{ ... }: {
flake.nixosModules.koonFeatureTailscale = { pkgs, ... }: {
services.tailscale.enable = true;
systemd.services.tailscale-restart = {
description = "Restart Tailscale after waking up";
after = [ "suspend.target" ];
wantedBy = [ "suspend.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.systemd}/bin/systemctl restart tailscaled.service";
};
};
};
}

View File

@@ -0,0 +1,77 @@
{ self, ... }: {
flake.nixosModules.koonArkConfiguration = { config, ... }: {
imports = [
./_hardware-configuration.nix
self.nixosModules.koonArkUser
self.nixosModules.koonArkSops
self.nixosModules.koonArkServiceAudio
self.nixosModules.koonArkServiceAuth
self.nixosModules.koonArkServiceGit
self.nixosModules.koonArkServiceHome
self.nixosModules.koonArkServicePhotos
self.nixosModules.koonArkServiceRadicale
self.nixosModules.koonArkServiceWakapi
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "ark";
networking.nameservers = [ "8.8.8.8" "1.1.1.1" ];
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
extraUpFlags = [ "--accept-dns=false" ];
};
# oauth.name = "KoonFamily";
# oauth.secrets = import ./oauth-secrets.nix;
security.sudo.wheelNeedsPassword = false;
services.cloudflared = {
enable = true;
tunnels = {
"91d31395-fbc7-45a1-ae13-148957b32ecd" = {
credentialsFile = config.sops.secrets.tunnel-credentials.path;
ingress = {
"auth.koon.us" = "http://localhost:1411";
"photos.koon.us" = "http://localhost:2283";
"home.koon.us" = "http://localhost:8123";
"docs.koon.us" = "http://localhost:3004";
"git.koon.us" = "http://localhost:3000";
"ssh.koon.us" = "ssh://localhost:2222";
"audio.koon.us" = "http://localhost:8021";
"radicale.koon.us" = "http://localhost:5232";
"waka.koon.us" = "http://localhost:3006";
# "ride.koon.us" = "http://localhost:3007";
# "ride-api.koon.us" = "http://localhost:8080";
"money.koon.us" = "http://localhost:3160";
"zero.koon.us" = "http://localhost:4848";
"money-api.koon.us" = "http://localhost:3161";
};
default = "http_status:404";
};
};
};
fileSystems."/mnt/hdd" = {
device = "/dev/sdb";
fsType = "ext4";
};
services.openssh.enable = true;
networking.firewall.allowedTCPPorts = [ 8123 22 ];
time.timeZone = "America/New_York";
nix.settings.experimental-features = [ "nix-command" "flakes" ];
system.stateVersion = "25.05"; # Did you read the comment?
};
}

View File

@@ -0,0 +1,8 @@
{ self, inputs, ... }: {
flake.nixosConfigurations.koonArk = inputs.nixpkgs-unstable.lib.nixosSystem {
modules = [
self.inputs.sops-nix.nixosModules.sops
self.nixosModules.koonArkConfiguration
];
};
}

View File

@@ -0,0 +1,8 @@
{ ... }: {
flake.nixosModules.koonArkServiceAudio = { ... }: {
services.audiobookshelf = {
enable = true;
port = 8021;
};
};
}

View File

@@ -0,0 +1,21 @@
{ ... }: {
flake.nixosModules.koonArkServiceAuth = { config, ... }: {
services.pocket-id = {
enable = true;
settings = {
APP_URL = "https://auth.koon.us";
TRUST_PROXY = true;
ANALYTICS_DISABLED = true;
UI_CONFIG_DISABLED = true;
APP_NAME = "KoonFamily";
};
credentials = {
ENCRYPTION_KEY = config.sops.secrets."pocket-id-encryption-key".path;
};
};
};
}

View File

@@ -0,0 +1,193 @@
{ ... }: {
flake.nixosModules.koonArkServiceGit = { config, lib, pkgs, ... }:
let
oauthName = "KoonFamily";
in {
services.openssh = {
enable = true;
# hostKeys = [
# { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
# { path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; bits = 4096; }
# ];
settings = {
# explicitly allow post-quantum KEX
KexAlgorithms = [
"mlkem768x25519-sha256"
"sntrup761x25519-sha512"
"curve25519-sha256"
];
};
};
services.gitea = {
enable = true;
user = "git";
group = "git";
database = {
user = "git";
name = "git";
type = "postgres";
};
settings = {
server = {
DOMAIN = "git.koon.us";
ROOT_URL = "https://git.koon.us";
HTTP_PORT = 3000;
LANDING_PAGE = "/max";
SSH_DOMAIN = "ssh.koon.us";
SSH_PORT = 2222;
START_SSH_SERVER = true;
};
oauth2_client = {
ACCOUNT_LINKING = "auto";
ENABLE_AUTO_REGISTRATION = true;
UPDATE_AVATAR = true;
USERNAME = "email";
};
service = {
DISABLE_REGISTRATION = true;
ENABLE_PASSWORD_SIGNIN_FORM = false;
ENABLE_PASSKEY_AUTHENTICATION = false;
SHOW_MILESTONES_DASHBOARD_PAGE = false;
};
"service.explore" = {
DISABLE_USERS_PAGE = true;
DISABLE_ORGANIZATIONS_PAGE = true;
DISABLE_CODE_PAGE = true;
};
};
};
users.users.git = {
isSystemUser = true;
group = "git";
home = "/var/lib/gitea";
description = "Git server (Gitea)";
createHome = true;
};
users.groups.git = { };
systemd.services.gitea = {
serviceConfig = {
RestartSec = "60"; # Retry every minute
};
preStart = let
exe = lib.getExe config.services.gitea.package;
clientIdPath = config.sops.secrets."oauth/git/clientId".path;
clientSecretPath = config.sops.secrets."oauth/git/clientSecret".path;
args = lib.escapeShellArgs (lib.concatLists [
[ "--name" oauthName ]
[ "--provider" "openidConnect" ]
# [ "--key" config.oauth.secrets.git.clientId ]
[
"--auto-discover-url"
"https://auth.koon.us/.well-known/openid-configuration"
]
[ "--scopes" "email" ]
[ "--scopes" "profile" ]
[ "--group-claim-name" "groups" ]
[ "--admin-group" "admin" ]
[ "--skip-local-2fa" ]
]);
in lib.mkAfter ''
CLIENT_ID=$(cat ${clientIdPath})
CLIENT_SECRET=$(cat ${clientSecretPath})
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${oauthName}' | cut -f1)
if [[ -z "$provider_id" ]]; then
${exe} admin auth add-oauth ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET"
else
${exe} admin auth update-oauth --id "$provider_id" ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET"
fi
mkdir -p /var/lib/gitea/custom/public/assets/img/
ln -sf ${
./git/assets/img/logo.svg
} /var/lib/gitea/custom/public/assets/img/logo.svg
ln -sf ${
./git/assets/img/favicon.svg
} /var/lib/gitea/custom/public/assets/img/favicon.svg
mkdir -p /var/lib/gitea/custom/templates/base/
ln -sf ${
./git/templates/base/head_navbar.tmpl
} /var/lib/gitea/custom/templates/base/head_navbar.tmpl
ln -sf ${
./git/templates/base/footer_content.tmpl
} /var/lib/gitea/custom/templates/base/footer_content.tmpl
mkdir -p /var/lib/gitea/custom/templates/custom/
ln -sf ${
./git/templates/custom/header.tmpl
} /var/lib/gitea/custom/templates/custom/header.tmpl
'';
};
services.restic.backups = {
git-local = {
repository = "/mnt/hdd/restic/git";
passwordFile = config.sops.secrets.restic-password.path;
initialize = true;
paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ];
backupPrepareCommand = ''
mkdir -p /var/backup/git
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \
--clean \
--if-exists \
--dbname=git > /var/backup/git/postgres.sql
'';
backupCleanupCommand = ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea
'';
};
git-remote = {
repository = "rest:http://m1:8000/git";
passwordFile = config.sops.secrets.restic-password.path;
initialize = true;
paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ];
backupPrepareCommand = ''
mkdir -p /var/backup/git
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \
--clean \
--if-exists \
--dbname=git > /var/backup/git/postgres.sql
'';
backupCleanupCommand = ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea
'';
};
};
environment.systemPackages = with pkgs;
let
scripts = with pkgs; {
restore_git_pg = writeShellScriptBin "restore_git_pg" ''
${pkgs.sudo}/bin/sudo -u postgres psql --dbname=git < /var/backup/git/postgres.sql
'';
restore_git = writeShellScriptBin "restore_git" ''
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea
${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/git restore latest --target /
${scripts.restore_git_pg}/bin/restore_git_pg
${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea
'';
};
in [ scripts.restore_git_pg scripts.restore_git ];
};
}

View File

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

View File

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

Some files were not shown because too many files have changed in this diff Show More