Compare commits

...

27 Commits

Author SHA1 Message Date
f3b32776f6 refactor: move ark into dentritic pattern 2026-05-21 22:50:15 -04:00
8043068885 refactor: move max into dentritic pattern 2026-05-21 11:26:17 -04:00
5e886ee875 feat: lsp change, pocketid key, hyprland changes 2026-04-12 01:22:21 -04:00
c46ccff5c9 feat: hypr changes, notifications, power button, vpn 2026-02-19 12:05:51 -05:00
7e6d382408 feat: add tailscale restart service, make wallpaper declarative, add
music player
2026-02-09 11:26:25 -05:00
15afc3d9d8 feat: add extension to fix links 2026-01-25 19:37:09 -05:00
5eb2d1c3e2 fix: music working 2026-01-21 07:59:38 -05:00
2adf1b010b feat: add music and zsh and zathura improvements 2026-01-20 12:40:15 -05:00
0d21f85c84 feat: perf hyprland switcher and new image viewer 2026-01-18 17:24:43 -05:00
23a642f6f7 feat: hyprland, neovim, zsh changes 2026-01-17 13:43:34 -05:00
01f32d795c chore: update flake 2026-01-07 06:03:08 -05:00
14a58df894 refactor: move to hyprland 2025-12-22 15:59:25 -05:00
b713f0f3d9 fix: warnings and update zen 2025-12-15 12:32:42 -05:00
53142c9e02 feat: add koon money 2025-10-20 17:43:36 -04:00
ab831218c9 feat: add zen browser 2025-10-09 17:26:47 -04:00
980c674a43 feat: elytra fix 2025-10-02 13:02:53 -04:00
92ea15f919 feat: add elytra 2025-09-26 09:46:57 -04:00
f3a34a5482 feat: add cjk font 2025-09-17 06:08:15 -04:00
d976cc9905 feat: shell stuff 2025-09-16 09:13:22 -04:00
0dba0b6943 feat: Koon fork of wakapi 2025-09-05 23:00:33 -04:00
3b81fd3293 feat: configure zathura with home manager 2025-09-02 09:11:59 -04:00
09385d2e45 feat: add git backup 2025-09-01 16:40:26 -04:00
b92b3e41f2 feat: add some programs and update unstable 2025-09-01 16:02:45 -04:00
6691dc2b53 fix: secrets 2025-08-19 14:58:40 -04:00
f194c9cfdc feat(max): add openconnect-sso 2025-08-18 20:13:16 -04:00
d5dce97512 feat(max): enable autosetupremote in git 2025-08-18 17:57:20 -04:00
39b0bdf6e1 feat(max): add radio script 2025-08-18 17:54:28 -04:00
104 changed files with 3323 additions and 1765 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

2
.gitignore vendored
View File

@@ -2,3 +2,5 @@
*.tfstate
*.tfstate.*
.direnv

BIN
assets/wallpaper.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

420
flake.lock generated
View File

@@ -1,5 +1,53 @@
{
"nodes": {
"apple-fonts": {
"inputs": {
"nixpkgs": "nixpkgs",
"ny": "ny",
"sf-arabic": "sf-arabic",
"sf-armenian": "sf-armenian",
"sf-compact": "sf-compact",
"sf-georgian": "sf-georgian",
"sf-hebrew": "sf-hebrew",
"sf-mono": "sf-mono",
"sf-pro": "sf-pro"
},
"locked": {
"lastModified": 1758228441,
"narHash": "sha256-3mA9oFuhJ1EHyhPd17g/EuJi4jDYPGhyxkEitdh3Kmc=",
"owner": "Lyndeno",
"repo": "apple-fonts.nix",
"rev": "aba9944f6606a69ebedf7bfb723316139eec3f72",
"type": "github"
},
"original": {
"owner": "Lyndeno",
"repo": "apple-fonts.nix",
"type": "github"
}
},
"firefox-addons": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"dir": "pkgs/firefox-addons",
"lastModified": 1767089190,
"narHash": "sha256-TaPGpx3KSx9pjmM4C9kdClz/2JlyHQQaprzBYPWowvg=",
"owner": "rycee",
"repo": "nur-expressions",
"rev": "bf40463eb8b5becdc657a2262be71d785bbb35ef",
"type": "gitlab"
},
"original": {
"dir": "pkgs/firefox-addons",
"owner": "rycee",
"repo": "nur-expressions",
"type": "gitlab"
}
},
"flake-compat": {
"locked": {
"lastModified": 1688025799,
@@ -16,6 +64,24 @@
}
},
"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": {
"nixpkgs-lib": [
"nixvim",
@@ -36,7 +102,7 @@
"type": "github"
}
},
"flake-parts_2": {
"flake-parts_3": {
"inputs": {
"nixpkgs-lib": [
"terranix",
@@ -75,6 +141,30 @@
"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": {
"inputs": {
"nixpkgs": [
@@ -82,20 +172,56 @@
]
},
"locked": {
"lastModified": 1753592768,
"narHash": "sha256-oV695RvbAE4+R9pcsT9shmp6zE/+IZe6evHWX63f2Qg=",
"lastModified": 1766292113,
"narHash": "sha256-sWTtmkQujRpjWYCnZc8LWdDiCzrRlSBPrGovkZpLkBI=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "fc3add429f21450359369af74c2375cb34a2d204",
"rev": "fdec8815a86db36f42fc9c8cb2931cd8485f5aed",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.05",
"ref": "release-25.11",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
"zen-browser",
"nixpkgs"
]
},
"locked": {
"lastModified": 1765682243,
"narHash": "sha256-yeCxFV/905Wr91yKt5zrVvK6O2CVXWRMSrxqlAZnLp0=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "58bf3ecb2d0bba7bdf363fc8a6c4d49b4d509d03",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"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": {
"inputs": {
"flake-utils": [
@@ -124,33 +250,54 @@
"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": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1748659443,
"narHash": "sha256-dav2hzyCmXZ3n6lEZrfZBG51+g6PUhkzRl3d6Ypd9x0=",
"lastModified": 1763596466,
"narHash": "sha256-CTSUc4Fk1lHMQZMJ5LczPDYGLq5UjXDFKLSpuA3mKmI=",
"owner": "nix-community",
"repo": "nixos-apple-silicon",
"rev": "3ddc251d2acce5019b0fa770e224d068610a34e4",
"rev": "73b7103c4e3996e3e20868d510b0e8797f279323",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-2025-05-30",
"ref": "release-2025-11-18",
"repo": "nixos-apple-silicon",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1748460289,
"narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=",
"lastModified": 1757745802,
"narHash": "sha256-hLEO2TPj55KcUFUU1vgtHE9UEIOjRcH/4QbmfHNF820=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102",
"rev": "c23193b943c6c689d70ee98ce3128239ed9e32d1",
"type": "github"
},
"original": {
@@ -160,25 +307,88 @@
"type": "github"
}
},
"nixpkgs_2": {
"nixpkgs-lib": {
"locked": {
"lastModified": 1754563854,
"narHash": "sha256-YzNTExe3kMY9lYs23mZR7jsVHe5TWnpwNrsPOpFs/b8=",
"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": {
"locked": {
"lastModified": 1773628058,
"narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "e728d7ae4bb6394bbd19eec52b7358526a44c414",
"rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.05",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1766070988,
"narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c6245e83d836d0433170a16eb185cefe0572f8b8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1766201043,
"narHash": "sha256-eplAP+rorKKd0gNjV3rA6+0WMzb1X1i16F5m5pASnjA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b3aad468604d3e488d627c0b43984eb60e75e782",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1778274207,
"narHash": "sha256-I4puXmX1iovcCHZlRmztO3vW0mAbbRvq4F8wgIMQ1MM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b3da656039dc7a6240f27b2ef8cc6a3ef3bccae7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvim": {
"inputs": {
"flake-parts": "flake-parts",
"flake-parts": "flake-parts_2",
"nixpkgs": [
"nixpkgs"
],
@@ -186,16 +396,16 @@
"systems": "systems_2"
},
"locked": {
"lastModified": 1754262585,
"narHash": "sha256-Yz5dJ0VzGRzSRHdHldsWQbuFYmtP3NWNreCvPfCi9CI=",
"lastModified": 1766256678,
"narHash": "sha256-LLpJEUFNrj6pO8hvkZMjuuBUeCrjJp/PnVSp2huR+ZA=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "ab1b5962e1ca90b42de47e1172e0d24ca80e6256",
"rev": "204a2f3d359e01fcf5af4433adc8cdbb434c9ded",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "nixos-25.05",
"ref": "nixos-25.11",
"repo": "nixvim",
"type": "github"
}
@@ -223,39 +433,118 @@
"type": "github"
}
},
"plasma-manager": {
"inputs": {
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"ny": {
"flake": false,
"locked": {
"lastModified": 1754501628,
"narHash": "sha256-FExJ54tVB5iu7Dh2tLcyCSWpaV+lmUzzWKZUkemwXvo=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "cca090f8115c4172b9aef6c5299ae784bdd5e133",
"type": "github"
"narHash": "sha256-3257NAH4qlan2YHVLpNRy7x8IJqR2pal3OzFo/ykqXs=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/NY.dmg"
},
"original": {
"owner": "nix-community",
"repo": "plasma-manager",
"type": "github"
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/NY.dmg"
}
},
"root": {
"inputs": {
"apple-fonts": "apple-fonts",
"firefox-addons": "firefox-addons",
"flake-parts": "flake-parts",
"hm-wrapper-modules": "hm-wrapper-modules",
"home-manager": "home-manager",
"import-tree": "import-tree",
"nixos-apple-silicon": "nixos-apple-silicon",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable",
"nixvim": "nixvim",
"plasma-manager": "plasma-manager",
"sops-nix": "sops-nix",
"terranix": "terranix",
"unstable": "unstable"
"wrapper-modules": "wrapper-modules",
"zen-browser": "zen-browser"
}
},
"sf-arabic": {
"flake": false,
"locked": {
"narHash": "sha256-/0gjRimqvZyE60xYxxPdlU+7Q2LJnnvtbmwOP0YmS9U=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Arabic.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Arabic.dmg"
}
},
"sf-armenian": {
"flake": false,
"locked": {
"narHash": "sha256-rRoDkbNMYkzOHZmQm96Zv80TZvRlAeoxkv4pMHP5nUg=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Armenian.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Armenian.dmg"
}
},
"sf-compact": {
"flake": false,
"locked": {
"narHash": "sha256-WeqT80cdK/XzTLSaJs5DHodzxoeAzwL/xTgdq0YwQbM=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg"
}
},
"sf-georgian": {
"flake": false,
"locked": {
"narHash": "sha256-IevVNOC28IiR45YfI3PsZzXLMRxuB5u7UiE53Zn6tRU=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Georgian.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Georgian.dmg"
}
},
"sf-hebrew": {
"flake": false,
"locked": {
"narHash": "sha256-Dw84kYwMpCtKKKqm8cZcQ9TZ7GayU5MO7W0LJw0Rcwk=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Hebrew.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Hebrew.dmg"
}
},
"sf-mono": {
"flake": false,
"locked": {
"narHash": "sha256-ICdHRFdNL7PM/fXJUzS7LgZxZiqcyIuCMHLze4En4vg=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Mono.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Mono.dmg"
}
},
"sf-pro": {
"flake": false,
"locked": {
"narHash": "sha256-vprahHpCUf9O8RualBrEuLEfuLfzI/2d8AQmwlCGPPk=",
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"
},
"original": {
"type": "file",
"url": "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"
}
},
"sops-nix": {
@@ -325,7 +614,7 @@
},
"terranix": {
"inputs": {
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts_3",
"nixpkgs": [
"nixpkgs"
],
@@ -345,19 +634,42 @@
"type": "github"
}
},
"unstable": {
"wrapper-modules": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1754498491,
"narHash": "sha256-erbiH2agUTD0Z30xcVSFcDHzkRvkRXOQ3lb887bcVrs=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c2ae88e026f9525daf89587f3cbee584b92b6134",
"lastModified": 1778520701,
"narHash": "sha256-qEA/vR6fKwnW3lqwy7f+Ds1iPgdotKpksQIk6UZotlM=",
"owner": "BirdeeHub",
"repo": "nix-wrapper-modules",
"rev": "5660d8cada6c2c5eb6c034577f3893f579526804",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"owner": "BirdeeHub",
"repo": "nix-wrapper-modules",
"type": "github"
}
},
"zen-browser": {
"inputs": {
"home-manager": "home-manager_2",
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1765764138,
"narHash": "sha256-Nb5y5xSDQLMeUYiA1bQkbmHffGm0d/XXWoJjFu8ovw0=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"rev": "bd8815d0a686267386268e7cc70315124e21362b",
"type": "github"
},
"original": {
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"type": "github"
}
}

186
flake.nix
View File

@@ -2,26 +2,28 @@
description = "Koon OS";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.05";
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.11";
unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-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 =
"github:nix-community/nixos-apple-silicon?ref=release-2025-05-30";
"github:nix-community/nixos-apple-silicon?ref=release-2025-11-18";
home-manager = {
url = "github:nix-community/home-manager?ref=release-25.05";
url = "github:nix-community/home-manager?ref=release-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
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 = {
url = "github:nix-community/nixvim?ref=nixos-25.05";
url = "github:nix-community/nixvim?ref=nixos-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
@@ -34,94 +36,84 @@
url = "github:terranix/terranix";
inputs.nixpkgs.follows = "nixpkgs";
};
zen-browser = {
url = "github:0xc000022070/zen-browser-flake";
# 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
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
firefox-addons = {
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
inputs.nixpkgs.follows = "nixpkgs";
};
apple-fonts.url= "github:Lyndeno/apple-fonts.nix";
};
outputs = { self, nixpkgs, unstable, nixos-apple-silicon, home-manager
, plasma-manager, nixvim, sops-nix, terranix, ... }: {
packages.aarch64-linux =
let
system = "aarch64-linux";
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs;} (inputs.import-tree ./modules);
pkgs = import unstable {
inherit system;
config = {
allowUnfree = true;
};
};
terraform = pkgs.terraform.withPlugins (p: [
p.pocketid
p.local
]);
terraformConfiguration = terranix.lib.terranixConfiguration {
inherit system;
modules = [ ./infra/config.nix ];
};
in {
deploy = pkgs.writeShellScriptBin "deploy" ''
echo Deploying Infrastructure...
export TF_VAR_pocketid_api_token=$(${pkgs.sops}/bin/sops -d --extract '["pocketid-api-token"]' secrets/secrets.yaml)
cd infra
cp ${terraformConfiguration} config.tf.json
${terraform}/bin/terraform init
${terraform}/bin/terraform apply
rm -f config.tf.json
echo Done
echo Encrypting secrets
cd ../secrets
${pkgs.sops}/bin/sops -e -i sops/oauth.yaml
echo Done
'';
};
nixosConfigurations = {
max = let
system = "aarch64-linux";
pkgs-unstable = import unstable { inherit system; };
secrets = import ./secrets;
in nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = { inherit pkgs-unstable secrets; };
modules = [
./host/max/default.nix
nixos-apple-silicon.nixosModules.apple-silicon-support
sops-nix.nixosModules.sops
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = { inherit secrets; };
home-manager.users.max = { config, pkgs, lib, ... }: {
imports = [
sops-nix.homeManagerModules.sops
nixvim.homeManagerModules.nixvim
plasma-manager.homeManagerModules.plasma-manager
./host/max/home.nix # Import your home.nix here
];
};
}
];
};
ark = let system = "x86_64-linux";
in unstable.lib.nixosSystem {
inherit system;
modules = [
./host/ark/default.nix
sops-nix.nixosModules.sops
];
};
};
};
# 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 {
#
# nixosConfigurations = {
# max = let
# system = "aarch64-linux";
# pkgs-unstable = import nixpkgs-unstable { inherit system; };
# secrets = import ./secrets;
# in nixpkgs.lib.nixosSystem {
# inherit system;
# specialArgs = { inherit pkgs-unstable secrets zen-browser apple-fonts proton-pass-cli; };
# modules = [
# ./host/max/default.nix
# nixos-apple-silicon.nixosModules.apple-silicon-support
# sops-nix.nixosModules.sops
# home-manager.nixosModules.home-manager
# {
# home-manager.useGlobalPkgs = true;
# 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,62 +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
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "ark"; # Define your hostname.
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";
};
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,14 +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;
};
};
}

View File

@@ -1,94 +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
'';
};
# systemd.services.outline = {
# serviceConfig = {
# # Load the client ID from the sops secret file
# ExecStartPre = let
# script = pkgs.writeShellScript "outline-set-oauth" ''
# CLIENT_ID=$(cat ${config.sops.secrets."docs/clientId".path})
# # Export as environment variable that Outline will use
# echo "OIDC_CLIENT_ID=$CLIENT_ID" >> $RUNTIME_DIRECTORY/env
# '';
# in "+${script}";
#
# # Load the environment file
# EnvironmentFile = "-/run/outline/env";
# };
#
# # Ensure sops secrets are available before starting
# after = [ "sops-nix.service" ];
# wants = [ "sops-nix.service" ];
# };
}

View File

@@ -1,111 +0,0 @@
{ lib, config, pkgs, ... }: {
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
'';
};
}

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,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,28 +0,0 @@
{ config, ... }:
{
nixpkgs.overlays = [
(final: prev: {
wakapi = prev.wakapi.overrideAttrs (oldAttrs: rec {
src = final.fetchFromGitHub {
owner = "k2on";
repo = "wakapi";
rev = "theming";
# hash = "";
hash = "sha256-mbQ2cA9tbuDA5OXEP+qVfsrBC90budAzWE7x4oN6ypY=";
};
# vendorHash = final.lib.fakeHash;
vendorHash = "sha256-lb6u9NQbB3bizIRbCRaB7Ngv9T5mAYtSl+g13gL7VEU=";
});
})
];
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,50 +0,0 @@
{ config, ... }:
{
sops = {
defaultSopsFile = ../../secrets/sops/host/ark/default.yaml;
validateSopsFiles = false;
age.keyFile = "/var/lib/sops-nix/key.txt";
secrets = {
"host_age_key" = {
path = "/var/lib/sops-nix/key.txt";
};
"restic-password" = {};
"tunnel-credentials" = {};
"admin-password" = {};
"waka-password-salt" = {
owner = config.users.users.wakapi.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;
};
};
};
}

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,9 +0,0 @@
{ inputs, ... }: {
time.timeZone = "America/New_York";
services.tailscale.enable = true;
# security.sudo.wheelNeedsPassword = false;
nix.settings.experimental-features = [ "nix-command" "flakes" ];
}

View File

@@ -1,63 +0,0 @@
{ lib, ... }: {
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,28 +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,18 +0,0 @@
{ pkgs, ... }: {
fonts.packages = with pkgs; [
monocraft
(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,14 +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 = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [
# fcitx5-gtk # alternatively, kdePackages.fcitx5-qt
kdePackages.fcitx5-qt # alternatively, kdePackages.fcitx5-qt
fcitx5-chinese-addons # table input method support
fcitx5-nord # a color theme
];
};
}

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,116 +0,0 @@
{ pkgs, config, pkgs-unstable, ... }: {
imports = [
./hardware-configuration.nix
../common/core/default.nix
./user.nix
./work.nix
./sops.nix
../common/optional/yubikey.nix
../common/optional/browser.nix
../common/optional/desktop.nix
../common/optional/fonts.nix
../common/optional/locale.nix
../common/optional/email.nix
./zero-cache.nix
];
services.zero-cache.enable = false;
# 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;
useExperimentalGPUDriver = true;
experimentalGPUInstallMode = "replace";
setupAsahiSound = true;
};
};
# networking.hostName = "nixos"; # Define your hostname.
# Pick only one of the below networking options.
networking.networkmanager.enable =
true; # Easiest to use and most distros use this by default.
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
environment.variables = {
XDG_DATA_HOME = "/home/max/.local/share";
GSK_RENDERER = "ngl";
EDITOR = "nvim";
};
programs.wireshark.enable = true;
programs.adb.enable = true;
programs.kdeconnect.enable = true;
environment.systemPackages = with pkgs; [
vim
git
wget
# mpc
gurk-rs
libreoffice-qt
# ncmpcpp
brave
signal-desktop
gnupg
(pass.withExtensions (exts: [ exts.pass-otp ]))
pinentry
pinentry-curses
pinentry-qt
zathura
fzf
ffmpeg
ripgrep
unzip
zbar
tt
sc-im
libqalculate
librespeed-cli
tea
kubectl
cloudflared
# gcc
prismlauncher
gimp
inkscape
wireshark
# arm support
pkgs-unstable.sparrow
];
programs.zsh.enable = true;
programs.gnupg.agent = {
enable = true;
pinentryPackage = pkgs.pinentry-qt;
enableSSHSupport = true;
};
system.stateVersion = "25.05";
}

View File

@@ -1,18 +0,0 @@
{ ... }:
{
imports = [
./home/sops.nix
./home/ssh.nix
./home/git.nix
./home/browser.nix
./home/desktop.nix
./home/nvim.nix
./home/terminal.nix
];
home.username = "max";
home.homeDirectory = "/home/max";
home.stateVersion = "25.05";
}

View File

@@ -1,57 +0,0 @@
{
programs.firefox = {
enable = true;
profiles = {
personal = {
id = 0;
name = "1. Personal";
isDefault = true;
settings = {
"browser.search.defaultenginename" = "ddg";
"browser.search.order.1" = "ddg";
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
};
search = {
force = true;
default = "ddg";
order = [ "ddg" "google" ];
};
userChrome = builtins.readFile ./browser/userChrome.css;
};
work = {
id = 1;
name = "2. Work";
settings = {
"browser.search.defaultenginename" = "ddg";
"browser.search.order.1" = "ddg";
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
};
search = {
force = true;
default = "ddg";
order = [ "ddg" "google" ];
};
userChrome = builtins.readFile ./browser/userChrome.css;
};
school = {
id = 2;
name = "3. School";
settings = {
"browser.search.defaultenginename" = "ddg";
"browser.search.order.1" = "ddg";
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
};
search = {
force = true;
default = "ddg";
order = [ "ddg" "google" ];
};
userChrome = builtins.readFile ./browser/userChrome.css;
};
};
};
}

View File

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

View File

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

View File

@@ -1,29 +0,0 @@
{ lib, ... }:
let
publicGitEmail = "22125083+k2on@users.noreply.github.com";
publicKey = "/home/max/.ssh/id_maxkey.pub";
in
{
programs.git = {
enable = true;
userName = "Max Koon";
userEmail = publicGitEmail;
extraConfig = {
init.defaultBranch = "main";
commit.gpgsign = true;
gpg.format = "ssh";
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,262 +0,0 @@
{ pkgs, ... }: {
programs.nixvim = {
enable = true;
colorschemes.one.enable = true;
globals = {
mapleader = " ";
maplocalleader = " ";
};
clipboard = {
providers.wl-copy.enable = true;
register = "unnamedplus";
};
opts = {
background = "light";
relativenumber = true;
cursorline = true;
number = true;
signcolumn = "yes";
updatetime = 250;
list = true;
listchars.__raw = "{ tab = '» ', trail = '·', nbsp = '' }";
};
extraConfigLua = ''
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>";
}
];
diagnostic.settings.virtual_text = true;
userCommands.W.command = "w";
plugins = {
sleuth.enable = true;
lastplace.enable = true;
gitsigns.enable = true;
highlight-colors.enable = true;
todo-comments.enable = true;
# smear-cursor.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 = {
ts_ls.enable = true;
rust_analyzer = {
enable = true;
installCargo = true;
installRustc = true;
};
clangd.enable = true;
tailwindcss.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;
extraOptions = {
filesystem = {
filtered_items = {
visible = true;
};
};
};
};
wakatime.enable = true;
autoclose.enable = true;
ts-autotag.enable = true;
spider = {
enable = true;
extraOptions = {
subwordMovement = true;
skipInsignificantPunctuation = false;
};
keymaps = {
motions = {
"w" = "w";
"e" = "e";
"b" = "b";
};
};
};
};
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,69 +0,0 @@
{ pkgs, ... }: {
programs.alacritty = {
enable = true;
theme = "one_light";
settings = {
font = {
normal.family = "Monocraft";
size = 10;
};
};
};
programs.lf = { enable = true; };
programs.tmux = {
enable = true;
mouse = true;
keyMode = "vi";
shell = "${pkgs.zsh}/bin/zsh";
extraConfig = ''
set -g status-style bg=white
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
'';
};
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion = {
enable = true;
highlight = "fg=#bbbbbb";
};
syntaxHighlighting.enable = true;
dotDir = ".config/zsh";
autocd = true;
# initExtra = builtins.readFile ./zsh-nix-shell.zsh;
shellAliases = {
ll = "ls -la --color";
v = "nvim";
vi = "nvim";
vim = "nvim";
k = "kubectl";
tt = "tt --theme one-light -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";
}];
};
programs.starship = { enable = true; };
}

View File

@@ -1,25 +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";
};
};
};
}

View File

@@ -1,13 +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" "wireshark" "kvm" ];
packages = with pkgs; [ tree ];
shell = pkgs.zsh;
};
}

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,84 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.zero-cache;
inherit (lib)
mkEnableOption
mkIf
;
litestream = pkgs.buildGoModule rec {
pname = "litestream-zero";
version = "0.3.13+z0.0.6";
src = pkgs.fetchFromGitHub {
owner = "rocicorp";
repo = "litestream";
rev = "zero@v0.0.6";
sha256 = "sha256-sBKmz2fBoYzYi1kUVeiugLBLPdqHc+fXCBkI8Cttakg=";
};
vendorHash = "sha256-PlfDJbhzbH/ZgtQ35KcB6HtPEDTDgss7Lv8BcKT/Dgg=";
ldflags = [
"-s"
"-w"
"-X main.Version=${version}"
# nix does not like to build with this
# "-extldflags '-static'"
];
doCheck = false;
tags = [
"osusergo"
"netgo"
"sqlite_omit_load_extension"
];
subPackages = [ "cmd/litestream" ];
};
zero-cache = pkgs.buildNpmPackage rec {
name = "zero-cache";
src = pkgs.fetchFromGitHub {
owner = "rocicorp";
repo = "mono";
rev = "zero/v0.23.2025081401";
hash = "sha256-NQcG/vnfUmle/6eNXXmnMqzNvniK8R/mO5RYdMX9pnE=";
};
npmDepsHash = "sha256-9vX9eODN8AfcLcMSjm6KzAAUmPIHfe2BILt0juya5us=";
makeCacheWritable = true;
npmFlags = [ "--legacy-peer-deps" ];
};
in
{
options = {
services.zero-cache = {
enable = mkEnableOption "Zero-cache, the server component of the Zero sync engine.";
};
};
config = mkIf cfg.enable {
systemd.services.zero-cache = {
description = "Zero Cache";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${zero-cache}/bin/zero-cache";
RemainAfterExit = true;
};
};
};
}

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,13 +11,32 @@ rebuild:
just add-secrets
git add .
sudo nixos-rebuild switch --flake '.?submodules=1#max'
sudo nixos-rebuild switch --flake '.?submodules=1#koonMax'
rebuild-boot:
just add-secrets
git add .
sudo nixos-rebuild boot --flake '.?submodules=1#koonMax'
rebuild-offline:
just add-secrets
git add .
sudo nixos-rebuild switch --flake '.?submodules=1#koonMax' --offline
rebuild-ark:
just add-secrets
git add .
nixos-rebuild --flake '.?submodules=1#ark' --build-host admin@100.98.252.15 --target-host admin@100.98.252.15 --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:
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,35 @@
@define-color background-color #1a1b26;
@define-color border-color #33354a;
@define-color label #a9b1d6;
@define-color image #a9b1d6;
@define-color progress #a9b1d6;
window {
border-radius: 999;
opacity: 0.97;
border: 1px solid @border-color;
padding: 0;
background-color: @background-color;
}
label {
font-family: 'JetBrainsMono Nerd Font';
font-size: 11pt;
color: @label;
}
image {
color: @image;
-gtk-icon-transform: scale(0.5);
}
progressbar {
border-radius: 999;
}
progress {
background-color: @progress;
}

View File

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

View File

@@ -0,0 +1,252 @@
app_launch_prefix = ""
terminal_title_flag = ""
locale = ""
close_when_open = false
theme = "default"
monitor = ""
hotreload_theme = false
as_window = false
timeout = 0
disable_click_to_close = false
force_keyboard_focus = false
[keys]
accept_typeahead = ["tab"]
trigger_labels = "lalt"
next = ["down"]
prev = ["up"]
close = ["esc"]
remove_from_history = ["shift backspace"]
resume_query = ["ctrl r"]
toggle_exact_search = ["ctrl m"]
[keys.activation_modifiers]
keep_open = "shift"
alternate = "alt"
[keys.ai]
clear_session = ["ctrl x"]
copy_last_response = ["ctrl c"]
resume_session = ["ctrl r"]
run_last_response = ["ctrl e"]
[events]
on_activate = ""
on_selection = ""
on_exit = ""
on_launch = ""
on_query_change = ""
[list]
dynamic_sub = true
keyboard_scroll_style = "emacs"
max_entries = 50
show_initial_entries = true
single_click = true
visibility_threshold = 20
placeholder = "No Results"
[search]
argument_delimiter = "#"
placeholder = "Search..."
delay = 0
resume_last_query = false
[activation_mode]
labels = "jkl;asdf"
[builtins.applications]
weight = 5
name = "applications"
placeholder = "Applications"
prioritize_new = true
hide_actions_with_empty_query = true
context_aware = true
refresh = true
show_sub_when_single = true
show_icon_when_single = true
show_generic = true
history = true
[builtins.applications.actions]
enabled = true
hide_category = false
hide_without_query = true
[builtins.bookmarks]
weight = 5
placeholder = "Bookmarks"
name = "bookmarks"
icon = "bookmark"
switcher_only = true
[[builtins.bookmarks.entries]]
label = "Walker"
url = "https://github.com/abenz1267/walker"
keywords = ["walker", "github"]
[builtins.xdph_picker]
hidden = true
weight = 5
placeholder = "Screen/Window Picker"
show_sub_when_single = true
name = "xdphpicker"
switcher_only = true
[builtins.ai]
weight = 5
placeholder = "AI"
name = "ai"
icon = "help-browser"
switcher_only = true
show_sub_when_single = true
[[builtins.ai.anthropic.prompts]]
model = "claude-3-7-sonnet-20250219"
temperature = 1
max_tokens = 1_000
label = "General Assistant"
prompt = "You are a helpful general assistant. Keep your answers short and precise."
[builtins.calc]
require_number = true
weight = 5
name = "calc"
icon = "accessories-calculator"
placeholder = "Calculator"
min_chars = 4
[builtins.windows]
weight = 5
icon = "view-restore"
name = "windows"
placeholder = "Windows"
show_icon_when_single = true
[builtins.clipboard]
always_put_new_on_top = true
exec = "wl-copy"
weight = 5
name = "clipboard"
avoid_line_breaks = true
placeholder = "Clipboard"
image_height = 300
max_entries = 10
switcher_only = true
[builtins.commands]
weight = 5
icon = "utilities-terminal"
switcher_only = true
name = "commands"
placeholder = "Commands"
[builtins.custom_commands]
weight = 5
icon = "utilities-terminal"
name = "custom_commands"
placeholder = "Custom Commands"
[builtins.emojis]
exec = "wl-copy"
weight = 5
name = "emojis"
placeholder = "Emojis"
switcher_only = true
history = true
typeahead = true
show_unqualified = false
[builtins.symbols]
after_copy = ""
weight = 5
name = "symbols"
placeholder = "Symbols"
switcher_only = true
history = true
typeahead = true
[builtins.finder]
use_fd = false
fd_flags = "--ignore-vcs --type file"
weight = 5
icon = "file"
name = "finder"
placeholder = "Finder"
switcher_only = true
ignore_gitignore = true
refresh = true
concurrency = 8
show_icon_when_single = true
preview_images = false
[builtins.runner]
eager_loading = true
weight = 5
icon = "utilities-terminal"
name = "runner"
placeholder = "Runner"
typeahead = true
history = true
generic_entry = false
refresh = true
use_fd = false
[builtins.ssh]
weight = 5
icon = "preferences-system-network"
name = "ssh"
placeholder = "SSH"
switcher_only = true
history = true
refresh = true
[builtins.switcher]
weight = 5
name = "switcher"
placeholder = "Switcher"
prefix = "/"
[builtins.websearch]
keep_selection = true
weight = 5
icon = "applications-internet"
name = "websearch"
placeholder = "Websearch"
[[builtins.websearch.entries]]
name = "Google"
url = "https://www.google.com/search?q=%TERM%"
[[builtins.websearch.entries]]
name = "DuckDuckGo"
url = "https://duckduckgo.com/?q=%TERM%"
switcher_only = true
[[builtins.websearch.entries]]
name = "Ecosia"
url = "https://www.ecosia.org/search?q=%TERM%"
switcher_only = true
[[builtins.websearch.entries]]
name = "Yandex"
url = "https://yandex.com/search/?text=%TERM%"
switcher_only = true
[builtins.dmenu]
hidden = true
weight = 5
name = "dmenu"
placeholder = "Dmenu"
switcher_only = true
show_icon_when_single = true
[builtins.translation]
delay = 1000
weight = 5
name = "translation"
icon = "accessories-dictionary"
placeholder = "Translation"
switcher_only = true
provider = "googlefree"

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,131 @@
{
"reload_style_on_change": true,
"layer": "top",
"position": "top",
"spacing": 0,
"height": 26,
"modules-left": ["custom/logo", "hyprland/workspaces"],
"modules-center": ["clock", "custom/screenrecording-indicator"],
"modules-right": [
"group/tray-expander",
"custom/countdown",
"bluetooth",
"network",
"pulseaudio",
"battery"
],
"hyprland/workspaces": {
"on-click": "activate",
"format": "{icon}",
"format-icons": {
"default": "",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"6": "6",
"7": "7",
"8": "8",
"9": "9",
"10": "0",
"active": ""
},
"persistent-workspaces": {
"1": [],
"2": [],
"3": [],
"4": []
}
},
"custom/logo": {
"format": "󰳭 ",
"on-click": "omarchy-menu",
"on-click-right": "xdg-terminal-exec",
"tooltip-format": ""
},
"custom/countdown": {
"exec": "echo $(( ($(date +%s) - $(date -d 'June 6, 2026' +%s)) / 86400 ))",
"format": "{} ",
"interval": 60
},
"clock": {
"format": "{:L%A %I:%M}",
"format-alt": "{:L%d %B W%V %Y}",
"tooltip": false,
"on-click-right": "omarchy-launch-floating-terminal-with-presentation omarchy-tz-select"
},
"network": {
"format-icons": ["󰤯", "󰤟", "󰤢", "󰤥", "󰤨"],
"format": "{icon}",
"format-wifi": "{icon}",
"format-ethernet": "󰀂",
"format-disconnected": "󰤮",
"tooltip-format-wifi": "{essid} ({frequency} GHz)\n⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}",
"tooltip-format-ethernet": "⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}",
"tooltip-format-disconnected": "Disconnected",
"interval": 3,
"spacing": 1,
"on-click": "omarchy-launch-wifi"
},
"battery": {
"format": "{capacity}% {icon}",
"format-discharging": "{icon}",
"format-charging": "{icon}",
"format-plugged": "",
"format-icons": {
"charging": ["󰢜", "󰂆", "󰂇", "󰂈", "󰢝", "󰂉", "󰢞", "󰂊", "󰂋", "󰂅"],
"default": ["󰁺", "󰁻", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹"]
},
"format-full": "󰂅",
"tooltip-format-discharging": "{power:>1.0f}W↓ {capacity}%",
"tooltip-format-charging": "{power:>1.0f}W↑ {capacity}%",
"interval": 5,
"on-click": "omarchy-menu power",
"states": {
"warning": 20,
"critical": 10
}
},
"bluetooth": {
"format": "",
"format-disabled": "󰂲",
"format-connected": "󰂱",
"format-no-controller": "",
"tooltip-format": "Devices connected: {num_connections}",
"on-click": "omarchy-launch-bluetooth"
},
"pulseaudio": {
"format": "{icon}",
"on-click": "omarchy-launch-or-focus-tui wiremix",
"on-click-right": "pamixer -t",
"tooltip-format": "Playing at {volume}%",
"scroll-step": 5,
"format-muted": "",
"format-icons": {
"default": ["", "", ""]
}
},
"group/tray-expander": {
"orientation": "inherit",
"drawer": {
"transition-duration": 600,
"children-class": "tray-group-item"
},
"modules": ["custom/expand-icon", "tray"]
},
"custom/expand-icon": {
"format": "",
"tooltip": false
},
"custom/screenrecording-indicator": {
"on-click": "omarchy-cmd-screenrecord",
"exec": "$OMARCHY_PATH/default/waybar/indicators/screen-recording.sh",
"signal": 8,
"return-type": "json"
},
"tray": {
"icon-size": 12,
"spacing": 17
}
}

View File

@@ -0,0 +1,84 @@
@define-color foreground #cdd6f4;
@define-color background #1a1b26;
* {
background-color: @background;
color: @foreground;
border: none;
border-radius: 0;
min-height: 0;
font-family: 'JetBrainsMono Nerd Font';
font-size: 12px;
}
.modules-left {
margin-left: 8px;
}
.modules-right {
margin-right: 8px;
}
#workspaces button {
all: initial;
padding: 0 6px;
margin: 0 1.5px;
min-width: 9px;
}
#workspaces button.empty {
opacity: 0.5;
}
#cpu,
#battery,
#pulseaudio,
#custom-omarchy,
#custom-screenrecording-indicator,
#custom-update {
min-width: 12px;
margin: 0 7.5px;
}
#tray {
margin-right: 16px;
}
#bluetooth {
margin-right: 17px;
}
#network {
margin-right: 13px;
}
#custom-expand-icon {
margin-right: 18px;
}
tooltip {
padding: 2px;
}
#custom-update {
font-size: 10px;
}
#clock {
margin-left: 8.75px;
}
.hidden {
opacity: 0;
}
#custom-screenrecording-indicator {
min-width: 12px;
margin-left: 8.75px;
font-size: 10px;
}
#custom-screenrecording-indicator.active {
color: #a55555;
}

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,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

View File

@@ -0,0 +1,38 @@
{ ... }: {
flake.nixosModules.koonArkServiceHome = { 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
sonos:
media_player:
hosts:
- 10.0.0.77
- 10.0.0.186
'';
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" ];
};
};
networking.firewall.allowedTCPPorts = [ 1400 ];
};
}

View File

@@ -0,0 +1,123 @@
{ ... }: {
flake.nixosModules.koonArkServicePhotos = { config, lib, pkgs, ... }:
let
oauthName = "KoonFamily";
in {
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 " oauthName ];
clientId = config.sops.placeholder."oauth/photos/clientId";
clientSecret = config.sops.placeholder."oauth/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

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

View File

@@ -0,0 +1,50 @@
{ ... }: {
flake.nixosModules.koonArkServiceWakapi = { 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

@@ -0,0 +1,34 @@
{ self, ... }: {
flake.nixosModules.koonArkSops = { config, ... }: {
sops = {
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
defaultSopsFile = "${self}/secrets/koon/ark/default.yaml";
validateSopsFiles = false;
secrets = {
"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;
};
"oauth/photos/clientId" = {};
"oauth/photos/clientSecret" = {};
"oauth/git/clientId" = {
owner = config.services.gitea.user;
};
"oauth/git/clientSecret" = {
owner = config.services.gitea.user;
};
};
};
};
}

View File

@@ -0,0 +1,13 @@
{ ... }: {
flake.nixosModules.koonArkUser = { 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

@@ -0,0 +1,184 @@
{ self, ... }: {
flake.homeModules.koonMaxBrowser = { pkgs, ... }: {
imports = [
self.inputs.zen-browser.homeModules.beta
];
xdg.mimeApps = let
value = let
browser = self.inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.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;
};
Preferences = {
"privacy.resistFingerprinting" = {
Value = true;
Status = "locked";
};
"privacy.resistFingerprinting.randomization.canvas.use_siphash" = {
Value = true;
Status = "locked";
};
"privacy.resistFingerprinting.randomization.daily_reset.enabled" = {
Value = true;
Status = "locked";
};
"privacy.resistFingerprinting.randomization.daily_reset.private.enabled" = {
Value = true;
Status = "locked";
};
"privacy.resistFingerprinting.block_mozAddonManager" = {
Value = true;
Status = "locked";
};
};
# 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 self.inputs.firefox-addons.packages.${pkgs.stdenv.hostPlatform.system}; [
ublock-origin
proton-pass
istilldontcareaboutcookies
darkreader
];
};
};
};
}

View File

@@ -0,0 +1,152 @@
{ self, ... }: {
flake.nixosModules.koonMaxConfiguration = { pkgs, lib, modulesPath, ... }: {
imports = [
./_hardware-configuration.nix
self.nixosModules.commonUnstablePkgsOverlay
self.nixosModules.commonFeatureEmail
self.nixosModules.commonFeatureFont
self.nixosModules.commonFeatureLocale
self.nixosModules.commonFeatureYubikey
self.nixosModules.commonFeatureHyprland
self.nixosModules.koonFeatureTailscale
self.nixosModules.koonMaxSops
self.nixosModules.koonMaxUser
self.nixosModules.koonMaxHomeManager
];
# 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;
};
graphics = {
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;
};
time.timeZone = "America/New_York";
nix.settings.experimental-features = [ "nix-command" "flakes" ];
system.stateVersion = "25.05";
};
}

View File

@@ -0,0 +1,10 @@
{ self, inputs, ... }: {
flake.nixosConfigurations.koonMax = inputs.nixpkgs.lib.nixosSystem {
modules = [
self.inputs.nixos-apple-silicon.nixosModules.apple-silicon-support
self.inputs.sops-nix.nixosModules.sops
self.inputs.home-manager.nixosModules.home-manager
self.nixosModules.koonMaxConfiguration
];
};
}

View File

@@ -0,0 +1,33 @@
{ ... }: {
flake.homeModules.koonMaxGit = { 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 ./id_maxkey.pub}
'';
};
}

View File

@@ -0,0 +1,288 @@
{ self, ... }: {
flake.homeModules.koonMaxNeovim = { pkgs, ... }: {
imports = [
self.inputs.nixvim.homeModules.nixvim
];
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

@@ -0,0 +1,38 @@
{ ... }: {
flake.homeModules.koonMaxSsh = { pkgs, ... }: {
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = {
"*" = {
addKeysToAgent = "yes";
};
"m1" = {
host = "m1";
user = "admin";
};
"ark" = {
host = "ark";
user = "admin";
};
"ssh.koon.us" = {
host = "ssh.koon.us";
user = "git";
proxyCommand = "${pkgs.cloudflared}/bin/cloudflared access ssh --hostname %h";
};
"git" = {
host = "github.com";
user = "git";
identityFile = [
"~/.ssh/id_maxkey"
];
};
};
};
home.file = {
".ssh/id_maxkey.pub".source = ./id_maxkey.pub;
};
};
}

View File

@@ -0,0 +1,54 @@
{ self, inputs, ... }: {
flake.nixosModules.koonMaxHomeManager = { ... }: {
imports = [
inputs.home-manager.nixosModules.home-manager
];
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = { inherit inputs self; };
users.max = {
imports = [ self.homeModules.koonMaxHome ];
};
};
};
flake.homeModules.koonMaxHome = { ... }: {
imports = [
self.homeModules.commonFeatureHyprlandConfig
self.homeModules.commonFeatureHypridle
self.homeModules.commonFeatureHyprlock
self.homeModules.commonFeatureNotifications
self.homeModules.commonFeatureOsd
self.homeModules.commonFeatureWalker
self.homeModules.commonFeatureWallpaper
self.homeModules.commonFeatureWaybar
self.homeModules.commonFeatureZathura
self.homeModules.commonFeatureAlacritty
self.homeModules.commonFeatureLf
self.homeModules.commonFeatureTmux
self.homeModules.commonFeatureStarship
self.homeModules.commonFeatureDirenv
self.homeModules.commonFeatureImageViewer
self.homeModules.commonFeatureMusic
self.homeModules.commonFeatureZsh
self.homeModules.koonMaxBrowser
self.homeModules.koonMaxNeovim
self.homeModules.koonMaxGit
self.homeModules.koonMaxSsh
];
gtk = {
enable = true;
colorScheme = "dark";
};
home.username = "max";
home.homeDirectory = "/home/max";
home.stateVersion = "25.05";
};
}

View File

@@ -0,0 +1,34 @@
{ self, ... }: {
flake.nixosModules.koonMaxSops = { config, ... }: {
sops = {
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
defaultSopsFile = "${self}/secrets/koon/max/default.yaml";
validateSopsFiles = false;
secrets = {
"yubico/u2f_keys" = {
owner = config.users.users.max.name;
inherit (config.users.users.max) group;
path = "/home/max/.config/Yubico/u2f_keys";
};
"ssh_keys/max" = {
owner = config.users.users.max.name;
inherit (config.users.users.max) group;
path = "/home/max/.ssh/id_maxkey";
mode = "0600";
};
"waka_config" = {
owner = config.users.users.max.name;
inherit (config.users.users.max) group;
path = "/home/max/.wakatime.cfg";
};
"proton_key" = {};
};
};
environment.sessionVariables.PROTON_PASS_ENCRYPTION_KEY = config.sops.secrets.proton_key.path;
};
}

View File

@@ -0,0 +1,31 @@
{ ... }: {
flake.nixosModules.koonMaxUser = { pkgs, config, ... }: {
sops.secrets.max-password.neededForUsers = true;
users.mutableUsers = true;
users.users.max = {
isNormalUser = true;
# hashedPasswordFile = config.sops.secrets.max-password.path;
password = "password";
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;
};
};
};
}

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