Compare commits

..

8 commits

Author SHA1 Message Date
fwastring
bba7fe79d8 updated some stuff 2026-05-02 12:06:25 +02:00
fwastring
1dd4440047 added lots 2026-04-27 14:46:44 +02:00
fwastring
14205e371f chagne hash 2026-04-25 16:35:32 +02:00
fwastring
c03fa07723 added some stuff 2026-04-06 20:37:39 +02:00
fwastring
39a1b68c8f added beets 2026-04-04 19:31:27 +02:00
fwastring
755a563d5c fixed nixvim 2026-04-04 19:31:04 +02:00
fwastring
d2985c8461 fixed lualine 2026-03-30 13:18:57 +02:00
fwastring
36ade9a42d updates 2026-03-30 09:34:05 +02:00
42 changed files with 1710 additions and 1337 deletions

View file

@ -4,6 +4,7 @@ keys:
- &server_macmini age1dql5lwetk39a9y8ummfgjx3aym02yn205lxk389k6q0tu9y3ff4s94l66t
- &server_legacy age1kf93dpuqhu0a90s49sszgw64mn32hwgrm8suv799ca4ngrkecpqs8ljzk8
- &server_core age1p3uxpjku9fkyvav56fgmq2cem50wg2dh34hdpp5nzqs6cerandaqvkrgxr
- &styrelsen age1cf97rf4gq7qad0rd5dcdtel2qq7uqcxvd7dpk257e3e0e0krv9esd7sc0d
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
@ -14,3 +15,4 @@ creation_rules:
- *server_macmini
- *server_legacy
- *server_core
- *styrelsen

364
flake.lock generated
View file

@ -20,11 +20,11 @@
]
},
"locked": {
"lastModified": 1774211390,
"narHash": "sha256-sTtAgCCaX8VNNZlQFACd3i1IQ+DB0Wf3COgiFS152ds=",
"lastModified": 1776876344,
"narHash": "sha256-Ubqb/agkuMJK+k19gjQgHux/eOYRc1sRGoOZOho8+VY=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "f62a4dbfa4e5584f14ad4c62afedf6e4b433cf70",
"rev": "648a13d0ee1e03a843b3e145b8ece15393058701",
"type": "github"
},
"original": {
@ -104,7 +104,9 @@
"bbk": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1760346178,
@ -123,14 +125,16 @@
},
"catppuccin": {
"inputs": {
"nixpkgs": "nixpkgs_2"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1774616169,
"narHash": "sha256-fP4bU3SOH5sefSl6EagqULFs+bXoo3h3VLQCCyJplo4=",
"lastModified": 1777637913,
"narHash": "sha256-IV0MJUCncmFUpcRRoHR11gK6VR+hpN/Vtaz91+dsPPE=",
"owner": "catppuccin",
"repo": "nix",
"rev": "e616c61cd9f7b05b32af266bc005fa266860dacf",
"rev": "a199649e9941490ab712aa891c144e305d165ef8",
"type": "github"
},
"original": {
@ -141,7 +145,9 @@
},
"confetti": {
"inputs": {
"nixpkgs": "nixpkgs_3"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1759854845,
@ -165,11 +171,11 @@
]
},
"locked": {
"lastModified": 1773889306,
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=",
"lastModified": 1777713215,
"narHash": "sha256-8GzXDOXckDWwST8TY5DbwYFjdvQLlP7K9CLSVx6iTTo=",
"owner": "nix-community",
"repo": "disko",
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347",
"rev": "63b4e7e6cf75307c1d26ac3762b886b5b0247267",
"type": "github"
},
"original": {
@ -181,11 +187,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1764873433,
"narHash": "sha256-1XPewtGMi+9wN9Ispoluxunw/RwozuTRVuuQOmxzt+A=",
"lastModified": 1775176642,
"narHash": "sha256-2veEED0Fg7Fsh81tvVDNYR6SzjqQxa7hbi18Jv4LWpM=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "f7ffd917ac0d253dbd6a3bf3da06888f57c69f92",
"rev": "179704030c5286c729b5b0522037d1d51341022c",
"type": "github"
},
"original": {
@ -211,6 +217,27 @@
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"hister",
"nixpkgs"
]
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"neovim-nightly-overlay",
@ -218,11 +245,11 @@
]
},
"locked": {
"lastModified": 1772408722,
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
"lastModified": 1777678872,
"narHash": "sha256-EPIFsulyon7Z1vLQq5Fk64GR8L7cQsT+IPhcsukVbgk=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
"rev": "5250617bffd85403b14dbf43c3870e7f255d2c16",
"type": "github"
},
"original": {
@ -239,11 +266,11 @@
]
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"type": "github"
},
"original": {
@ -260,11 +287,11 @@
]
},
"locked": {
"lastModified": 1767609335,
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "250481aafeb741edfe23d29195671c19b36b6dca",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"type": "github"
},
"original": {
@ -273,7 +300,7 @@
"type": "github"
}
},
"flake-parts_4": {
"flake-parts_5": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
@ -350,20 +377,18 @@
"gnome-shell": {
"flake": false,
"locked": {
"host": "gitlab.gnome.org",
"lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "gitlab"
"type": "github"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "gnome-49",
"repo": "gnome-shell",
"type": "gitlab"
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
}
},
"home-manager": {
@ -373,11 +398,11 @@
]
},
"locked": {
"lastModified": 1774647770,
"narHash": "sha256-UNNi14XiqRWWjO8ykbFwA5wRwx7EscsC+GItOVpuGjc=",
"lastModified": 1777679572,
"narHash": "sha256-egYNbRrkn+6SwTHinhdb6WUfzzdC3nXfCRqS321VylY=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "02371c05a04a2876cf92e2d67a259e8f87399068",
"rev": "9cb587ade2aa1b4a7257f0238d41072690b0ca4f",
"type": "github"
},
"original": {
@ -402,11 +427,11 @@
]
},
"locked": {
"lastModified": 1772461003,
"narHash": "sha256-pVICsV7FtcEeVwg5y/LFh3XFUkVJninm/P1j/JHzEbM=",
"lastModified": 1776511930,
"narHash": "sha256-fCpwFiTW0rT7oKJqr3cqHMnkwypSwQKpbtUEtxdkgrM=",
"owner": "hyprwm",
"repo": "hyprcursor",
"rev": "b62396457b9cfe2ebf24fe05404b09d2a40f8ed7",
"rev": "39435900785d0c560c6ae8777d29f28617d031ef",
"type": "github"
},
"original": {
@ -431,11 +456,11 @@
]
},
"locked": {
"lastModified": 1772461523,
"narHash": "sha256-mI6A51do+hEUzeJKk9YSWfVHdI/SEEIBi2tp5Whq5mI=",
"lastModified": 1776426399,
"narHash": "sha256-RUESLKNikIeEq9ymGJ6nmcDXiSFQpUW1IhJ245nL3xM=",
"owner": "hyprwm",
"repo": "hyprgraphics",
"rev": "7d63c04b4a2dd5e59ef943b4b143f46e713df804",
"rev": "68d064434787cf1ed4a2fe257c03c5f52f33cf84",
"type": "github"
},
"original": {
@ -455,17 +480,19 @@
"hyprutils": "hyprutils",
"hyprwayland-scanner": "hyprwayland-scanner",
"hyprwire": "hyprwire",
"nixpkgs": "nixpkgs_4",
"nixpkgs": [
"nixpkgs"
],
"pre-commit-hooks": "pre-commit-hooks",
"systems": "systems_2",
"xdph": "xdph"
},
"locked": {
"lastModified": 1774635054,
"narHash": "sha256-NVjEJ5u0VHKTc/A17kWDfXgFnBAsP2BOMNj+fAv58mM=",
"lastModified": 1777677995,
"narHash": "sha256-Q1fYHq1Gn79sQAkUDALR6dEC6l2WLkFyaB0cZLZnMQM=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "5dfb1033a433789021ab9f94b9044e6f32496211",
"rev": "c065e951d631a3aa3736b45f17b3556597f63c1a",
"type": "github"
},
"original": {
@ -507,11 +534,11 @@
]
},
"locked": {
"lastModified": 1772467975,
"narHash": "sha256-kipyuDBxrZq+beYpZqWzGvFWm4QbayW9agAvi94vDXY=",
"lastModified": 1776426575,
"narHash": "sha256-KI6nIfVihn/DPaeB5Et46Xg3dkNHrrEtUd5LBBVomB0=",
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"rev": "5e1c6b9025aaf4d578f3eff7c0eb1f0c197a9507",
"rev": "a968d211048e3ed538e47b84cb3649299578f19d",
"type": "github"
},
"original": {
@ -561,11 +588,11 @@
]
},
"locked": {
"lastModified": 1772459629,
"narHash": "sha256-/iwvNUYShmmnwmz/czEUh6+0eF5vCMv0xtDW0STPIuM=",
"lastModified": 1776426736,
"narHash": "sha256-rl7i4aY+9p8LysJp7o8uRWahCkpFznCgGHXszlTw7b0=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "7615ee388de18239a4ab1400946f3d0e498a8186",
"rev": "7833ff33b2e82d3406337b5dcf0d1cec595d83e9",
"type": "github"
},
"original": {
@ -638,11 +665,11 @@
]
},
"locked": {
"lastModified": 1774211405,
"narHash": "sha256-6KNwP4ojUzv3YBlZU5BqCpTrWHcix1Jo01BISsTT0xk=",
"lastModified": 1777492286,
"narHash": "sha256-PwuoEJQcjSKJNP5T55qhfDwIP0tw5zxEhfu8GDfKfeg=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "cb4e152dc72095a2af422956c6b689590572231a",
"rev": "ec5c0c709706bad5b82f667fd8758eae442577ce",
"type": "github"
},
"original": {
@ -663,11 +690,11 @@
]
},
"locked": {
"lastModified": 1772459835,
"narHash": "sha256-978jRz/y/9TKmZb/qD4lEYHCQGHpEXGqy+8X2lFZsak=",
"lastModified": 1777148232,
"narHash": "sha256-Uv0WZLhu89SafuSOmYDA7akrPt4wBRmsa1ucasO5aXg=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "0a692d4a645165eebd65f109146b8861e3a925e7",
"rev": "fec9cf1abcc1011e46f0a0986f46bf93c6bf8b92",
"type": "github"
},
"original": {
@ -692,11 +719,11 @@
]
},
"locked": {
"lastModified": 1773074819,
"narHash": "sha256-qRqYnXiKoJLRTcfaRukn7EifmST2IVBUMZOeZMAc5UA=",
"lastModified": 1776728575,
"narHash": "sha256-z9eGphrArEBpl1O/GCH0wlY6z4K9vA6yWh2gAS6qytU=",
"owner": "hyprwm",
"repo": "hyprwire",
"rev": "f68afd0e73687598cc2774804fedad76693046f0",
"rev": "f3a80888783702a39691b684d099e16b83ed4702",
"type": "github"
},
"original": {
@ -712,11 +739,11 @@
]
},
"locked": {
"lastModified": 1767599588,
"narHash": "sha256-T5eoG861JJdGj6swp4+icjzwtSB5TY4efy5FeYbgHeg=",
"lastModified": 1775123884,
"narHash": "sha256-HjvJ2bD0YvbTdOLo+s+Iw7Sx7IwobC3KP9HXYd0KCIE=",
"owner": "niksingh710",
"repo": "minimal-tmux-status",
"rev": "67e2f5205de1b46f99af1d92013fb38fec5b05d9",
"rev": "f3096808cfca41007eacc76a686004ab6a394a0e",
"type": "github"
},
"original": {
@ -727,16 +754,18 @@
},
"neovim-nightly-overlay": {
"inputs": {
"flake-parts": "flake-parts",
"flake-parts": "flake-parts_2",
"neovim-src": "neovim-src",
"nixpkgs": "nixpkgs_5"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1774656308,
"narHash": "sha256-k+L2Q5DtNGkPy+JgfhpTxpngdxy+FVz269iNfCYVy5E=",
"lastModified": 1777681657,
"narHash": "sha256-LaHz8tExvJg1JT0RJubPjWffBWUmhX5uCQnIIbEp8SM=",
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"rev": "114911d841b928b2b147511bec7121af310d7a23",
"rev": "69942be4a5ffc37cd83f568ab5d1955721021eb5",
"type": "github"
},
"original": {
@ -748,11 +777,11 @@
"neovim-src": {
"flake": false,
"locked": {
"lastModified": 1774652330,
"narHash": "sha256-dqlsjRaLgD87D8YaC8842bhYziuRQ2qvTDgQDKL1ttQ=",
"lastModified": 1777655539,
"narHash": "sha256-csYI4zuLVyrebqsvJilUkHe7GC4KHpl5pNzO+CiOPLE=",
"owner": "neovim",
"repo": "neovim",
"rev": "f027f41e2cfba7be8c4841cb1a036827375bbd73",
"rev": "085bb518c894a6b03aaf23ba81242c2c6126bea8",
"type": "github"
},
"original": {
@ -763,16 +792,16 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1774386573,
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
"lastModified": 1777428379,
"narHash": "sha256-ypxFOeDz+CqADEQNL72haqGjvZQdBR5Vc7pyx2JDttI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
"rev": "755f5aa91337890c432639c60b6064bb7fe67769",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
@ -808,116 +837,20 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1773821835,
"narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1759733170,
"narHash": "sha256-TXnlsVb5Z8HXZ6mZoeOAIwxmvGHp1g4Dw89eLvIwKVI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8913c168d1c56dc49a7718685968f38752171c3b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1774106199,
"narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1774273680,
"narHash": "sha256-a++tZ1RQsDb1I0NHrFwdGuRlR5TORvCEUksM459wKUA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fdc7b8f7b30fdbedec91b71ed82f36e1637483ed",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1774386573,
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 1774386573,
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvim": {
"inputs": {
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts_3",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_3"
},
"locked": {
"lastModified": 1774612943,
"narHash": "sha256-hRhq5cpDyBm/ZQyuzI+/YzQEVt35d/M6ko7ADfodw9s=",
"lastModified": 1777236345,
"narHash": "sha256-ALOqlq7bE30lsX4rA76hXeQ2aLLEpb44hS+D1+jWS88=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "2b9f8e1d659d1c7664e1b85ab1620c219672696c",
"rev": "a67d9cd6ff725a763afe88727aac73208ded3bf4",
"type": "github"
},
"original": {
@ -938,11 +871,11 @@
]
},
"locked": {
"lastModified": 1767810917,
"narHash": "sha256-ZKqhk772+v/bujjhla9VABwcvz+hB2IaRyeLT6CFnT0=",
"lastModified": 1775228139,
"narHash": "sha256-ebbeHmg+V7w8050bwQOuhmQHoLOEOfqKzM1KgCTexK4=",
"owner": "nix-community",
"repo": "NUR",
"rev": "dead29c804adc928d3a69dfe7f9f12d0eec1f1a4",
"rev": "601971b9c89e0304561977f2c28fa25e73aa7132",
"type": "github"
},
"original": {
@ -953,7 +886,9 @@
},
"powershell-es": {
"inputs": {
"nixpkgs": "nixpkgs_7"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1771417904,
@ -980,11 +915,11 @@
]
},
"locked": {
"lastModified": 1774104215,
"narHash": "sha256-EAtviqz0sEAxdHS4crqu7JGR5oI3BwaqG0mw7CmXkO8=",
"lastModified": 1776796298,
"narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "f799ae951fde0627157f40aec28dec27b22076d0",
"rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad",
"type": "github"
},
"original": {
@ -999,11 +934,12 @@
"catppuccin": "catppuccin",
"confetti": "confetti",
"disko": "disko",
"hister": "hister",
"home-manager": "home-manager",
"hyprland": "hyprland",
"minimal-tmux": "minimal-tmux",
"neovim-nightly-overlay": "neovim-nightly-overlay",
"nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs",
"nixpkgs-azure-cli": "nixpkgs-azure-cli",
"nixvim": "nixvim",
"powershell-es": "powershell-es",
@ -1041,11 +977,11 @@
]
},
"locked": {
"lastModified": 1774303811,
"narHash": "sha256-fhG4JAcLgjKwt+XHbjs8brpWnyKUfU4LikLm3s0Q/ic=",
"lastModified": 1777338324,
"narHash": "sha256-bc+ZZCmOTNq86/svGnw0tVpH7vJaLYvGLLKFYP08Q8E=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "614e256310e0a4f8a9ccae3fa80c11844fba7042",
"rev": "8eaee5c45428b28b8c47a83e4c09dccec5f279b5",
"type": "github"
},
"original": {
@ -1061,25 +997,24 @@
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_3",
"flake-parts": "flake-parts_4",
"gnome-shell": "gnome-shell",
"nixpkgs": [
"nixpkgs"
],
"nur": "nur",
"systems": "systems_4",
"tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux",
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1774124764,
"narHash": "sha256-Poz9WTjiRlqZIf197CrMMJfTifZhrZpbHFv0eU1Nhtg=",
"lastModified": 1777580129,
"narHash": "sha256-6buSTzDtHYCJP1JNAIZCmgNcOs76oN03j+21CxdijVo=",
"owner": "nix-community",
"repo": "stylix",
"rev": "e31c79f571c5595a155f84b9d77ce53a84745494",
"rev": "20ff51f523e2dd67e5f31a321719d30708c1b771",
"type": "github"
},
"original": {
@ -1148,23 +1083,6 @@
"type": "github"
}
},
"tinted-foot": {
"flake": false,
"locked": {
"lastModified": 1726913040,
"narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
}
},
"tinted-kitty": {
"flake": false,
"locked": {
@ -1184,11 +1102,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1767710407,
"narHash": "sha256-+W1EB79Jl0/gm4JqmO0Nuc5C7hRdp4vfsV/VdzI+des=",
"lastModified": 1772661346,
"narHash": "sha256-4eu3LqB9tPqe0Vaqxd4wkZiBbthLbpb7llcoE/p5HT0=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "2800e2b8ac90f678d7e4acebe4fa253f602e05b2",
"rev": "13b5b0c299982bb361039601e2d72587d6846294",
"type": "github"
},
"original": {
@ -1200,11 +1118,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1767489635,
"narHash": "sha256-e6nnFnWXKBCJjCv4QG4bbcouJ6y3yeT70V9MofL32lU=",
"lastModified": 1772934010,
"narHash": "sha256-x+6+4UvaG+RBRQ6UaX+o6DjEg28u4eqhVRM9kpgJGjQ=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "3c32729ccae99be44fe8a125d20be06f8d7d8184",
"rev": "c3529673a5ab6e1b6830f618c45d9ce1bcdd829d",
"type": "github"
},
"original": {
@ -1216,11 +1134,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1767488740,
"narHash": "sha256-wVOj0qyil8m+ouSsVZcNjl5ZR+1GdOOAooAatQXHbuU=",
"lastModified": 1772909925,
"narHash": "sha256-jx/5+pgYR0noHa3hk2esin18VMbnPSvWPL5bBjfTIAU=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "11abb0b282ad3786a2aae088d3a01c60916f2e40",
"rev": "b4d3a1b3bcbd090937ef609a0a3b37237af974df",
"type": "github"
},
"original": {
@ -1231,7 +1149,7 @@
},
"typsite": {
"inputs": {
"flake-parts": "flake-parts_4",
"flake-parts": "flake-parts_5",
"nixpkgs": [
"nixpkgs"
],
@ -1258,11 +1176,11 @@
]
},
"locked": {
"lastModified": 1774688817,
"narHash": "sha256-Jmc51QARSI/Mpp4FH2sq2UAA+rag4XMwkr4c2IB4nvc=",
"lastModified": 1777128769,
"narHash": "sha256-DP+KayU1TFjUo9ZY0TNvalNP8HzZsOhxPKRTd34G0mk=",
"ref": "simplify-static-html",
"rev": "4a05531e4478c6376146d6f5daffe5e3734fb1cb",
"revCount": 31,
"rev": "b168d315f718fa69d69630f2db741d12edb1ec2a",
"revCount": 36,
"type": "git",
"url": "ssh://git@github.com/fwastring/wedding.git"
},
@ -1300,11 +1218,11 @@
]
},
"locked": {
"lastModified": 1773601989,
"narHash": "sha256-2tJf/CQoHApoIudxHeJye+0Ii7scR0Yyi7pNiWk0Hn8=",
"lastModified": 1777035886,
"narHash": "sha256-m1TNuBoSXUBSKhD9UVMkU90M0wFTPTfvIOOltO8IM8A=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "a9b862d1aa000a676d310cc62d249f7ad726233d",
"rev": "ecfcdcc781f48821d83e1e2a0e30d7beca0eeb5e",
"type": "github"
},
"original": {

View file

@ -3,8 +3,11 @@
inputs = {
# Nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-azure-cli.url = "github:NixOS/nixpkgs/nixos-24.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
stylix = {
url = "github:nix-community/stylix";
inputs.nixpkgs.follows = "nixpkgs";
@ -17,16 +20,10 @@
url = "github:Glomzzz/typsite";
inputs.nixpkgs.follows = "nixpkgs";
};
catppuccin.url = "github:catppuccin/nix";
confetti.url = "git+https://git.wastring.com/fw/confetti?ref=main";
powershell-es.url = "git+https://git.wastring.com/fw/powershell-es?ref=main";
bbk.url = "git+https://git.wastring.com/fw/bbk?ref=main";
wedding.url = "git+ssh://git@github.com/fwastring/wedding.git?ref=simplify-static-html";
wedding.inputs.nixpkgs.follows = "nixpkgs";
neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
hyprland.url = "github:hyprwm/Hyprland";
catppuccin = {
url = "github:catppuccin/nix";
inputs.nixpkgs.follows = "nixpkgs";
};
minimal-tmux = {
url = "github:niksingh710/minimal-tmux-status";
inputs.nixpkgs.follows = "nixpkgs";
@ -35,8 +32,35 @@
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs";
};
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
confetti = {
url = "git+https://git.wastring.com/fw/confetti?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
powershell-es = {
url = "git+https://git.wastring.com/fw/powershell-es?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
bbk = {
url = "git+https://git.wastring.com/fw/bbk?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
wedding = {
url = "git+ssh://git@github.com/fwastring/wedding.git?ref=simplify-static-html";
inputs.nixpkgs.follows = "nixpkgs";
};
neovim-nightly-overlay = {
url = "github:nix-community/neovim-nightly-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprland = {
url = "github:hyprwm/Hyprland";
inputs.nixpkgs.follows = "nixpkgs";
};
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs-azure-cli.url = "github:NixOS/nixpkgs/nixos-24.11";
};
outputs =
@ -48,7 +72,7 @@
sops-nix,
catppuccin,
confetti,
powershell-es,
hister,
bbk,
nixvim,
disko,
@ -133,6 +157,7 @@
sops-nix.nixosModules.sops
catppuccin.nixosModules.catppuccin
confetti.nixosModules.default
hister.nixosModules.default
# bbk.nixosModules.default
nixvim.nixosModules.default
];

View file

@ -0,0 +1,20 @@
loki.relabel "journal" {
forward_to = []
rule {
source_labels = ["__journal__systemd_unit"]
target_label = "unit"
}
}
loki.source.journal "read" {
forward_to = [loki.write.endpoint.receiver]
relabel_rules = loki.relabel.journal.rules
labels = {component = "macmini"}
}
loki.write "endpoint" {
endpoint {
url ="http://192.168.1.143:3100/loki/api/v1/push"
}
}

View file

@ -0,0 +1,83 @@
# This is your system's configuration file.
# Use this to configure your system environment (it replaces /etc/nixos/configuration.nix)
{
inputs,
lib,
config,
pkgs,
myhostname,
...
}:
let
modulesDirectory = ../../moduler;
in
{
# You can import other NixOS modules here
imports = [
./hardware-configuration.nix
(modulesDirectory + /services/base)
../../moduler/users.nix
../../moduler/services/monitoring
];
alloy = {
enable = true;
configPath = ./alloy-systemd.yaml;
};
nixpkgs.config.permittedInsecurePackages = [
"broadcom-sta-6.30.223.271-59-6.12.58"
];
nix.settings = {
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
];
};
security.sudo.wheelNeedsPassword = false;
users.users.root.openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDALsdpwvC0w/Aj+1fWtzJyyWoUrGkdh8o2thVHeQQBNo0D7cmVberYmi4Cv9gWGX6PaElrnOl0KRdGyro2wxOYokSxgk2VgWW67BFITAQAbKyG2NhXXPbhb4jccDo7WH7TtOG8IofuJTPRu1Duda6k4RN0I0CkyAN6LGX+zy49cq0qKf9ijXYhCDYNih3+Fu/ig0aW/SYmsVoUl2VFTWdI5x5/wLvIjTEZhmAtYIeYADaLnom356cFrUysZa++FUujQAz3Ow236BvP95XZdTsqvfWNZFNIpC9VYF72JeIDCs5wDIr0GFmanF2On1nar+jJpoOE8SdHt357p5g/PqXV5TisN2xQRkqVwO9tWtMl4sF84jA4ULnY2gQWv9jErMxymUQ1IwuPUzDDlbRHCtfexAtkBy7wv6xslKAzG1QahvF/btNs5Caj3LN31rgAuxyooCbKGKTeBP3kHPKcz1iupgidfbO/QqVXBRQJTEdGyAKa8hVmLQZZPC/XUhxESAk= fw@fw-nix"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8ku8iCb7tXd/tfxYDW+Tj8K9kpfrYZciYUZ6tBpO80inm4EImtfyEeJTuqDWMKov2BftUKs8brNeTBCXUEvU1P0+cpOP9RtYA5tfBXf3su+iVSswJJStIxNboXHrEGKdJJRNsTv/9agshDSUBy6G5TI1cXhv/updornfA4fwOMqOmtlYEn6XCRnsrO6NBLc/uLckdbF75HOsoLvezRvuqTLjpapjaUKGVPrgNXiclIKHmuOx71kgD4FX3rSz9FgKjnfu3a7DBbrHsf/g+N9PjNF1muN9UOV6nK3WwiO9BMWi7NpAWfzJOeZg9chqzI+U6CcsqYVeESgL41so+dnv3 fw@laptop"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP34dnsZSnWdDvd+3BXDwcw7wP0PjPEx2eCdBQJyGD6O fw@laptop"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII60tdNsG0z9q2jHmoTKvkeLQE6OF0bmTsDX1bpqpoG7 fw@jobb"
];
# Restic
users.users.restic = {
isNormalUser = true;
createHome = true;
home = "/home/restic";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP34dnsZSnWdDvd+3BXDwcw7wP0PjPEx2eCdBQJyGD6O fw@laptop"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII60tdNsG0z9q2jHmoTKvkeLQE6OF0bmTsDX1bpqpoG7 fw@jobb"
];
};
# Where repos will live (you can choose a different path/disk)
systemd.tmpfiles.rules = [
"d /srv/restic 0750 restic restic -"
];
networking.firewall.allowedUDPPorts = [
22000
21027
];
services = {
openssh = {
enable = true;
allowSFTP = true;
};
};
security.rtkit.enable = true;
networking.hostName = myhostname;
services.xserver.dpi = 100;
system.stateVersion = "24.11";
}

View file

@ -0,0 +1,39 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "ohci_pci" "ehci_pci" "ahci" "firewire_ohci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "wl" ];
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/1c7e7116-3486-45a8-90c0-d3deea8e96b0";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/B70D-941F";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp3s0b1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -12,7 +12,14 @@ in
{
imports = [
./hardware-configuration.nix
(modulesDirectory + /features/standard)
(modulesDirectory + /users.nix)
(modulesDirectory + /git.nix)
(modulesDirectory + /network.nix)
(modulesDirectory + /programs.nix)
(modulesDirectory + /system.nix)
(modulesDirectory + /dev.nix)
(modulesDirectory + /sound.nix)
(modulesDirectory + /programs/kubernetes-tools.nix)
(modulesDirectory + /services/base)
@ -23,8 +30,6 @@ in
];
kubernetes-tools.enable = true;
features.profile = "desktop";
networking.hostName = myhostname;
security.pki.certificateFiles = [
@ -66,9 +71,120 @@ in
group = "users";
mode = "0400";
};
sops.secrets.jira_token = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.opencode_atlassian_env = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.google_oauth_client_id_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.google_oauth_client_secret_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.user_google_email_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.mssql_server_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.mssql_database_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.mssql_user_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.mssql_password_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.vault_addr_core = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.vault_token_core = {
owner = "fw";
group = "users";
mode = "0400";
};
environment.systemPackages = [ pkgs.cifs-utils ];
# Ollama service for running local LLMs
services.ollama = {
enable = true;
package = pkgs.ollama-rocm; # AMD GPU support
# Optional: specify host and port if you want to access from other machines
# host = "0.0.0.0";
# port = 11434;
};
services.hister = {
enable = true;
# Optional: Set via Nix options (takes precedence over config file)
# port = 4433;
dataDir = "/var/lib/hister"; # NixOS Recommend: "/var/lib/hister"
# Home-Manager Recommend: "~/.local/share/hister"
# Darwin Recommend: "~/Library/Application Support/hister"
# Optional (NixOS only): open `port` in the system firewall.
# Setting `port` alone no longer mutates the firewall.
# openFirewall = true;
# Optional: Use existing YAML config file
# configPath = /path/to/config.yml;
# Optional: Inject secrets (e.g. HISTER__APP__ACCESS_TOKEN) via a
# systemd EnvironmentFile instead of placing them in the world-readable
# Nix store. Honored by the NixOS module and the Linux home-manager
# user service; ignored on launchd (Darwin).
# environmentFile = "/run/secrets/hister.env";
# Optional: Inline configuration (rendered to YAML and passed via HISTER_CONFIG)
# Note: Only one of configPath or settings can be used.
# Accepts any key the server accepts — see the upstream `app`, `server`,
# `indexer`, `crawler`, `hotkeys`, `extractors`, and
# `sensitive_content_patterns` blocks.
settings = {
app = {
search_url = "https://google.com/search?q={query}";
log_level = "info";
};
server = {
address = "127.0.0.1:4433";
database = "db.sqlite3";
};
hotkeys = {
"/" = "focus_search_input";
"enter" = "open_result";
"alt+enter" = "open_result_in_new_tab";
"alt+j" = "select_next_result";
"alt+k" = "select_previous_result";
"alt+o" = "open_query_in_search_engine";
};
};
};
systemd.services.fleet-osquery = {
description = "osquery enrolled to Fleet";
wantedBy = [ "multi-user.target" ];
@ -116,6 +232,20 @@ in
];
};
fileSystems."/mnt/testdb/C" = {
device = "//192.168.0.203/C$";
fsType = "cifs";
options =
let
automount_opts =
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,"
+ "x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
in
[
"${automount_opts},credentials=${toString config.sops.secrets.build-service.path},vers=3.0"
];
};
fileSystems."/mnt/elastic-internal/C" = {
device = "//192.168.0.204/C$";
fsType = "cifs";
@ -186,8 +316,19 @@ in
];
};
home-manager.extraSpecialArgs = { inherit inputs pkgs; };
home-manager.extraSpecialArgs = {
inherit inputs pkgs myhostname;
};
home-manager.users.fw = {
opencode.mcpEnabled = {
az = false;
k8s = true;
github = true;
jira = false;
google = true;
mssql = true;
vault = false;
};
imports = [
./../../moduler/home.nix
./../../moduler/programs/waybar

View file

@ -0,0 +1,124 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{
inputs,
pkgs,
myhostname,
...
}:
let
theme = "mocha";
modulesDirectory = ../../moduler;
in
{
imports = [
./hardware-configuration.nix
(modulesDirectory + /users.nix)
(modulesDirectory + /git.nix)
(modulesDirectory + /network.nix)
(modulesDirectory + /programs.nix)
(modulesDirectory + /system.nix)
(modulesDirectory + /dev.nix)
(modulesDirectory + /sound.nix)
(modulesDirectory + /services/base)
(modulesDirectory + /programs/hyprland)
(modulesDirectory + /programs/nixvim)
];
networking.networkmanager = {
enable = true;
plugins = with pkgs; [
networkmanager-openvpn
];
};
stylix = {
enable = true;
base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-${theme}.yaml";
};
nixvim = {
enable = true;
theme = theme;
};
hyprland = {
enable = true;
theme = theme;
};
home-manager.extraSpecialArgs = {
inherit inputs pkgs myhostname;
};
home-manager.users.fw = {
imports = [
./../../moduler/home.nix
./../../moduler/programs/waybar
inputs.catppuccin.homeModules.catppuccin
];
waybar = {
enable = true;
profile = "laptop";
theme = theme;
};
gtk = {
enable = true;
iconTheme = {
name = "oomox-gruvbox-dark";
package = pkgs.gruvbox-dark-icons-gtk;
};
};
kitty = {
enable = true;
theme = theme;
};
fish = {
theme = theme;
};
k9s = {
enable = true;
theme = theme;
};
oh-my-posh = {
enable = true;
theme = theme;
};
catppuccin = {
librewolf = {
enable = true;
flavor = theme;
accent = "peach";
};
};
programs.ranger.enable = true;
stylix.targets = {
lazygit.enable = false;
fish.enable = false;
kitty.enable = false;
waybar.enable = false;
tmux.enable = false;
k9s.enable = false;
};
};
security.sudo.wheelNeedsPassword = false;
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII60tdNsG0z9q2jHmoTKvkeLQE6OF0bmTsDX1bpqpoG7 fw@jobb"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpJBGPIfPB1BwSG7aoKqwfccyZSaU7J3xpJ8behMp9N fw@core"
];
services.upower = {
enable = true;
};
boot.kernelPackages = pkgs.linuxPackages_latest;
networking.hostName = myhostname;
system.stateVersion = "25.05";
}

View file

@ -0,0 +1,18 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,35 @@
{ lib, ... }:
{
disko.devices = {
disk = {
main = {
device = lib.mkDefault "/dev/sda";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "1G";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}

View file

@ -13,7 +13,10 @@ in
{
imports = [
./hardware-configuration.nix
(modulesDirectory + /features/standard)
(modulesDirectory + /users.nix)
(modulesDirectory + /network.nix)
(modulesDirectory + /system.nix)
(modulesDirectory + /services/base)
(modulesDirectory + /services/webcam-rtsp)
@ -23,8 +26,6 @@ in
enable = true;
};
features.profile = "camera";
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [

View file

@ -0,0 +1,18 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -48,7 +48,8 @@ in
# You can import other NixOS modules here
imports = [
./hardware-configuration.nix
(modulesDirectory + /features/standard)
(modulesDirectory + /users.nix)
(modulesDirectory + /kitchenowl.nix)
# (modulesDirectory + /radicale.nix)
(modulesDirectory + /vaultwarden.nix)
@ -72,8 +73,6 @@ in
];
sops.defaultSopsFile = ../../secrets/sops.yaml;
features.profile = "server";
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.gandi_key = {
path = "/run/secrets/gandi_key";

View file

@ -16,7 +16,14 @@ in
{
imports = [
./hardware-configuration.nix
(modulesDirectory + /features/standard)
(modulesDirectory + /users.nix)
(modulesDirectory + /git.nix)
(modulesDirectory + /network.nix)
(modulesDirectory + /programs.nix)
(modulesDirectory + /system.nix)
(modulesDirectory + /dev.nix)
(modulesDirectory + /sound.nix)
(modulesDirectory + /services/base)
@ -25,9 +32,15 @@ in
(modulesDirectory + /programs/nixvim)
];
kubernetes-tools.enable = true;
features.profile = "laptop";
virtualisation.virtualbox = {
host = {
enable = true;
};
};
users.extraGroups.vboxusers.members = [ "fw" ];
kubernetes-tools.enable = true;
networking.networkmanager = {
enable = true;
};
@ -39,18 +52,47 @@ in
base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-${theme}.yaml";
};
nixvim = {
enable = true;
theme = theme;
};
sops.defaultSopsFile = ../../secrets/sops.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.google_oauth_client_id_styrelsen = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.google_oauth_client_secret_styrelsen = {
owner = "fw";
group = "users";
mode = "0400";
};
sops.secrets.user_google_email_styrelsen = {
owner = "fw";
group = "users";
mode = "0400";
};
hyprland = {
enable = true;
theme = theme;
};
home-manager.extraSpecialArgs = { inherit inputs pkgs; };
home-manager.extraSpecialArgs = {
inherit inputs pkgs myhostname;
};
home-manager.users.fw = {
opencode.mcpEnabled = {
az = false;
k8s = false;
github = false;
jira = false;
google = true;
mssql = false;
};
imports = [
./../../moduler/home.nix
./../../moduler/programs/waybar
@ -61,13 +103,13 @@ in
profile = "laptop";
theme = theme;
};
gtk = {
enable = true;
iconTheme = {
name = "oomox-gruvbox-dark";
package = pkgs.gruvbox-dark-icons-gtk;
};
};
# gtk = {
# enable = false;
# iconTheme = {
# name = "oomox-gruvbox-dark";
# package = pkgs.gruvbox-dark-icons-gtk;
# };
# };
kitty = {
enable = true;
theme = theme;

View file

@ -0,0 +1,35 @@
{ lib, ... }:
{
disko.devices = {
disk = {
main = {
device = lib.mkDefault "/dev/nvme0n1";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "1G";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}

View file

@ -1,8 +1,32 @@
{ lib, ... }:
{
imports = [
./programs/dev
];
inputs,
pkgs,
...
}:
let
azPkgs = inputs.nixpkgs-azure-cli.legacyPackages.${pkgs.stdenv.hostPlatform.system};
in
{
features.dev.enable = lib.mkDefault true;
environment.systemPackages = with pkgs; [
nixfmt-rfc-style
lazydocker
gh
awscli
minio-client
opentofu
python3
dive
(azPkgs.azure-cli.withExtensions (
with azPkgs.azure-cli.extensions;
[
# aks-preview
# ssh
fzf
]
))
yq
jq
git
];
}

View file

@ -1,108 +0,0 @@
# Feature Profiles
This directory provides a profile + overrides model for host configuration.
## Imports
Use this in host `imports`:
```nix
(modulesDirectory + /features/standard)
```
`features/standard` imports:
- `features` profile module
- `services/users`
- `services/network`
- `services/system`
- `services/sound`
- `programs/base`
- `programs/git`
- `programs/dev`
## Profile Selection
Set one profile per host:
```nix
features.profile = "desktop";
```
Supported values:
- `custom`
- `desktop`
- `laptop`
- `server`
- `camera`
Profiles set `mkDefault` values, so you can override any option per host.
## Common Overrides
### Base packages
```nix
features.base = {
enable = true;
preset = "minimal";
packages.captureEnable = true;
};
```
### Dev tools
```nix
features.dev = {
enable = true;
preset = "minimal";
cloud.aws.enable = false;
cloud.azure.enable = false;
};
```
### Network
```nix
features.network = {
enable = true;
netbird.enable = false;
tooling.enable = false;
};
```
### Sound/Bluetooth
```nix
features.sound = {
enable = true;
bluetooth.enable = false;
};
```
### Git defaults
```nix
features.git = {
enable = true;
userName = "myuser";
userEmail = "me@example.com";
};
```
### Users
```nix
features.users = {
enable = true;
name = "fw";
fullName = "Fredrik Wastring";
extraGroups = [ "wheel" "networkmanager" ];
};
```
## Notes
- If you only import `features/default.nix`, profile defaults are applied only for options that exist in imported modules.
- `features/standard` is the easiest option for hosts that should expose all common feature knobs.

View file

@ -1,81 +0,0 @@
{
lib,
config,
options,
...
}:
with lib;
let
profile = config.features.profile;
has = path: lib.hasAttrByPath path options;
setIf = path: value: lib.optionalAttrs (has path) (lib.setAttrByPath path value);
in
{
options.features.profile = mkOption {
type = types.enum [
"custom"
"desktop"
"laptop"
"server"
"camera"
];
default = "custom";
description = "Host feature profile. Use custom for fully explicit per-feature settings.";
};
config = mkMerge [
(mkIf (profile == "desktop") (mkMerge [
(setIf [ "features" "base" "enable" ] (mkDefault true))
(setIf [ "features" "base" "preset" ] (mkDefault "full"))
(setIf [ "features" "git" "enable" ] (mkDefault true))
(setIf [ "features" "dev" "enable" ] (mkDefault true))
(setIf [ "features" "dev" "preset" ] (mkDefault "full"))
(setIf [ "features" "users" "enable" ] (mkDefault true))
(setIf [ "features" "network" "enable" ] (mkDefault true))
(setIf [ "features" "network" "tooling" "enable" ] (mkDefault true))
(setIf [ "features" "system" "enable" ] (mkDefault true))
(setIf [ "features" "system" "preset" ] (mkDefault "desktop"))
(setIf [ "features" "sound" "enable" ] (mkDefault true))
]))
(mkIf (profile == "laptop") (mkMerge [
(setIf [ "features" "base" "enable" ] (mkDefault true))
(setIf [ "features" "base" "preset" ] (mkDefault "standard"))
(setIf [ "features" "git" "enable" ] (mkDefault true))
(setIf [ "features" "dev" "enable" ] (mkDefault true))
(setIf [ "features" "dev" "preset" ] (mkDefault "standard"))
(setIf [ "features" "users" "enable" ] (mkDefault true))
(setIf [ "features" "network" "enable" ] (mkDefault true))
(setIf [ "features" "network" "tooling" "enable" ] (mkDefault true))
(setIf [ "features" "system" "enable" ] (mkDefault true))
(setIf [ "features" "system" "preset" ] (mkDefault "desktop"))
(setIf [ "features" "sound" "enable" ] (mkDefault true))
]))
(mkIf (profile == "server") (mkMerge [
(setIf [ "features" "users" "enable" ] (mkDefault true))
(setIf [ "features" "network" "enable" ] (mkDefault true))
(setIf [ "features" "network" "netbird" "enable" ] (mkDefault false))
(setIf [ "features" "network" "tooling" "enable" ] (mkDefault false))
(setIf [ "features" "system" "enable" ] (mkDefault true))
(setIf [ "features" "system" "preset" ] (mkDefault "minimal"))
(setIf [ "features" "base" "enable" ] (mkDefault false))
(setIf [ "features" "git" "enable" ] (mkDefault false))
(setIf [ "features" "dev" "enable" ] (mkDefault false))
(setIf [ "features" "sound" "enable" ] (mkDefault false))
]))
(mkIf (profile == "camera") (mkMerge [
(setIf [ "features" "users" "enable" ] (mkDefault true))
(setIf [ "features" "network" "enable" ] (mkDefault true))
(setIf [ "features" "network" "netbird" "enable" ] (mkDefault false))
(setIf [ "features" "network" "tooling" "enable" ] (mkDefault false))
(setIf [ "features" "system" "enable" ] (mkDefault true))
(setIf [ "features" "system" "preset" ] (mkDefault "minimal"))
(setIf [ "features" "base" "enable" ] (mkDefault false))
(setIf [ "features" "git" "enable" ] (mkDefault false))
(setIf [ "features" "dev" "enable" ] (mkDefault false))
(setIf [ "features" "sound" "enable" ] (mkDefault false))
]))
];
}

View file

@ -1,13 +0,0 @@
{ ... }:
{
imports = [
../default.nix
../../services/users
../../services/network
../../services/system
../../services/sound
../../programs/base
../../programs/git
../../programs/dev
];
}

View file

@ -75,27 +75,7 @@ in
ls = "eza -l";
lg = "lazygit";
ka = "kubectl apply -f";
t = "timew";
a = "nix develop; opencode";
todo = "jira issue list -a 'Fredrik Wastring' -s ~Done -s ~Closed -s ~Released --plain";
cam = "jira issue create && jira issue assign && jira issue move";
e = "kubectx";
s = {
setCursor = "%";
expansion = "cha https://search.wastring.com/search?q=%";
};
tw = {
setCursor = "%";
expansion = "typst watch % --open zathura /tmp/zathura.pdf";
};
c = {
setCursor = "%";
expansion = "ssh 'fw:%@gateway.internalifacts.se' -p 2222";
};
dl = {
setCursor = "&";
expansion = "yt-dlp -o \"~/videor/%(title)s - %(uploader)s\" \"&\"";
};
e = "nvim";
};
interactiveShellInit =
let
@ -105,7 +85,32 @@ in
fish_vi_key_bindings
set fish_greeting
set FLAKE_DIR "/home/fw/nix"
set JIRA_API_TOKEN ATATT3xFfGF0_fkpGB1ne-QOSJzFVG0yH31j2CRtdNqbePCyEm9enpnA2uA3go75_GQwZPFX_IO9tf10ALJWvDLjsuHl8MSOUkNd703Vqr4uuGLAbHY73Z_b9fDJVrfodTrGAN9sZ5Sp75opCVkXB7MVXSAIvlWimRdwe-tqDPH4vhwY9Hqcs6M=0510D6CD
set -l host_name (hostname)
function load_secret --argument-names env_name preferred_secret fallback_secret
if test -r "/run/secrets/$preferred_secret"
set -gx $env_name (string trim (cat "/run/secrets/$preferred_secret"))
else if test -r "/run/secrets/$fallback_secret"
set -gx $env_name (string trim (cat "/run/secrets/$fallback_secret"))
end
end
if test -r /run/secrets/jira_token
set -gx JIRA_API_TOKEN (string trim (cat /run/secrets/jira_token))
end
load_secret GOOGLE_OAUTH_CLIENT_ID "google_oauth_client_id_$host_name" google_oauth_client_id
load_secret GOOGLE_OAUTH_CLIENT_SECRET "google_oauth_client_secret_$host_name" google_oauth_client_secret
load_secret USER_GOOGLE_EMAIL "user_google_email_$host_name" user_google_email
load_secret MSSQL_SERVER "mssql_server_$host_name" mssql_server
load_secret MSSQL_DATABASE "mssql_database_$host_name" mssql_database
load_secret MSSQL_USER "mssql_user_$host_name" mssql_user
load_secret MSSQL_PASSWORD "mssql_password_$host_name" mssql_password
load_secret MSSQL_PORT "mssql_port_$host_name" mssql_port
load_secret MSSQL_ENCRYPT "mssql_encrypt_$host_name" mssql_encrypt
load_secret MSSQL_WINDOWS_AUTH "mssql_windows_auth_$host_name" mssql_windows_auth
load_secret VAULT_ADDR "vault_addr_$host_name" vault_addr
load_secret VAULT_TOKEN "vault_token_$host_name" vault_token
load_secret VAULT_NAMESPACE "vault_namespace_$host_name" vault_namespace
set -gx GITHUB_PERSONAL_ACCESS_TOKEN (cat /run/secrets/github_token)
set -gx GITHUB_HOST "https://github.com"
set -gx GRAFANA_SERVICE_ACCOUNT_TOKEN (cat /run/secrets/grafana_token)
@ -117,6 +122,40 @@ in
gh completion -s fish > ~/.config/fish/completions/gh.fish
set -gx PATH $PATH $HOME/scripts
set -gx PATH $PATH $HOME/.krew/bin
set -gx OPENCODE_DEFAULT_PROMPT_FILE "$HOME/.config/opencode/session-prompt.txt"
function oc
set -l passthrough_subcommands completion acp mcp attach debug providers auth agent upgrade uninstall serve web models stats export import github pr session plugin plug db
if test (count $argv) -gt 0
if string match -qr '^-' -- "$argv[1]"
command opencode $argv
return $status
end
for arg in $argv
if test "$arg" = "--prompt"
command opencode $argv
return $status
end
end
if contains -- "$argv[1]" $passthrough_subcommands
command opencode $argv
return $status
end
end
if test -r "$OPENCODE_DEFAULT_PROMPT_FILE"
set -l session_prompt (string collect < "$OPENCODE_DEFAULT_PROMPT_FILE")
command opencode --prompt "$session_prompt" $argv
else
command opencode $argv
end
end
complete -e -c oc
complete -c oc -w opencode
if not set -q SSH_AUTH_SOCK
@ -126,6 +165,7 @@ in
end
set -Ux FZF_DEFAULT_OPTS "${fzfOpts}"
functions -e load_secret
'';
};
};

View file

@ -1,8 +1,16 @@
{ lib, ... }:
{ pkgs, lib, ... }:
{
imports = [
./programs/git
];
features.git.enable = lib.mkDefault true;
programs.git = {
enable = true;
config = {
user = {
name = "fwastring";
email = "fredrik@wastring.com";
};
pull = {
rebase = true;
};
url."git@github.com:".insteadOf = "https://github.com/";
};
};
}

View file

@ -6,7 +6,25 @@
myhostname,
...
}:
let
inherit (lib) mkOption types;
googleWorkspaceStateDir = "/home/fw/.local/share/google-workspace-mcp/${myhostname}";
in
{
options.opencode.mcpEnabled = mkOption {
type = types.attrsOf types.bool;
default = {
az = false;
k8s = true;
github = true;
jira = true;
google = false;
mssql = false;
vault = false;
};
description = "Per-host MCP enablement flags for OpenCode servers.";
};
imports = [
../moduler/tmux.nix
../moduler/fish.nix
@ -23,8 +41,188 @@
../moduler/programs/k9s
];
config = {
programs.home-manager.enable = true;
programs.fish.enable = true;
programs.opencode = {
enable = true;
enableMcpIntegration = false;
settings = {
"$schema" = "https://opencode.ai/config.json";
theme = lib.mkForce "catppuccin";
plugin = [ "@ex-machina/opencode-anthropic-auth" ];
provider = {
ollama = {
npm = "@ai-sdk/openai-compatible";
options = {
baseURL = "http://localhost:11434/v1";
};
models = {
# Only include models that support function calling (tools)
"gemma2:latest" = {};
"llama3.1:8b" = {};
"qwen2.5-coder:14b" = {};
"qwen2.5-coder:32b" = {};
# Note: deepseek-coder models and codellama:13b don't support tools
};
};
};
mcp = {
az = {
type = "local";
enabled = config.opencode.mcpEnabled.az or false;
command = [
"docker"
"run"
"-i"
"--rm"
"--env-file"
"/home/fw/.azure/credentials"
"mcr.microsoft.com/azure-sdk/azure-mcp:latest"
];
};
k8s = {
type = "local";
enabled = config.opencode.mcpEnabled.k8s or false;
command = [
"docker"
"run"
"--rm"
"-i"
"--user"
"1000:100"
"-v"
"/home/fw/.kube:/kube:ro"
"ghcr.io/containers/kubernetes-mcp-server:latest"
"--kubeconfig"
"/kube/config"
];
};
github = {
type = "local";
enabled = config.opencode.mcpEnabled.github or false;
command = [
"docker"
"run"
"-i"
"--rm"
"-e"
"GITHUB_PERSONAL_ACCESS_TOKEN"
"ghcr.io/github/github-mcp-server"
];
};
jira = {
type = "local";
enabled = config.opencode.mcpEnabled.jira or false;
command = [
"docker"
"run"
"-i"
"--rm"
"--env-file"
"/home/fw/.config/opencode/.env.local"
"ghcr.io/sooperset/mcp-atlassian:latest"
];
};
google = {
type = "local";
command = [
"docker"
"run"
"-i"
"--rm"
"--network"
"host"
"--user"
"1000:100"
"-v"
"${googleWorkspaceStateDir}:/home/app/.google_workspace_mcp"
"-e"
"GOOGLE_OAUTH_CLIENT_ID"
"-e"
"GOOGLE_OAUTH_CLIENT_SECRET"
"-e"
"USER_GOOGLE_EMAIL"
"-e"
"OAUTHLIB_INSECURE_TRANSPORT=1"
"--entrypoint"
"/app/.venv/bin/python"
"ghcr.io/taylorwilsdon/google_workspace_mcp:latest"
"/app/main.py"
"--single-user"
];
enabled = config.opencode.mcpEnabled.google or false;
};
mssql = {
type = "local";
command = [
"nix"
"shell"
"nixpkgs#uv"
"nixpkgs#freetds"
"-c"
"uvx"
"--from"
"git+https://github.com/RichardHan/mssql_mcp_server.git@77b0c6a9771e3f83a54c03dad42f1a53e0a20d0e"
"mssql_mcp_server"
];
enabled = config.opencode.mcpEnabled.mssql or false;
};
vault = {
type = "local";
command = [
"docker"
"run"
"-i"
"--rm"
"-e"
"VAULT_ADDR"
"-e"
"VAULT_TOKEN"
"-e"
"VAULT_NAMESPACE"
"hashicorp/vault-mcp-server"
];
enabled = config.opencode.mcpEnabled.vault or false;
};
};
};
};
home.activation.opencodeAtlassianEnv = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
mkdir -p "$HOME/.config/opencode"
if [ -r /run/secrets/opencode_atlassian_env ]; then
ln -sf /run/secrets/opencode_atlassian_env "$HOME/.config/opencode/.env.local"
fi
'';
home.activation.googleWorkspaceMcpState = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
mkdir -p "${googleWorkspaceStateDir}"
'';
home.file.".config/opencode/session-prompt.txt".text = ''
Session instructions for this entire chat:
1) Tooling / binaries
- Always use Nix for binaries and tool execution.
- Prefer `nix shell nixpkgs#<tool> -c <command>` (or `nix develop -c <command>` if the repo already defines a dev shell).
- Do not run tools directly from global/system installs unless I explicitly ask.
2) Daily note logging
- Track general work notes in: /home/fw/knowledge/notes/daily
- Use today's daily note file (create it if missing) and keep it updated as work progresses.
- Add short, timestamped entries for meaningful actions/decisions.
3) Schedule updates
- In today's daily note, maintain a "Schedule" section/tab and keep it current with what we are actively doing.
- When tasks change, update Schedule first, then continue implementation.
- Keep Schedule concise and action-oriented.
4) Working style
- Don't ask for confirmation on normal steps; proceed with sensible defaults.
- Only ask when blocked, destructive, or security-sensitive.
'';
programs.alacritty = {
enable = true;
# theme = "catppuccin_${theme}";
@ -45,4 +243,5 @@
home.stateVersion = "25.05";
systemd.user.startServices = "sd-switch";
};
}

View file

@ -1,8 +1,34 @@
{ lib, ... }:
# This is your system's configuration file.
# Use this to configure your system environment (it replaces /etc/nixos/configuration.nix)
{
inputs,
lib,
config,
pkgs,
...
}:
{
imports = [
./services/network
];
features.network.enable = lib.mkDefault true;
services.netbird = {
enable = true;
ui.enable = true;
};
systemd.services.tailscaled = {
after = [ "netbird.service" "network-online.target" ];
wants = [ "netbird.service" "network-online.target" ];
};
environment.systemPackages = with pkgs; [
# networkmanager
dnsutils
nmap
ipcalc
# iperf3
# networkmanagerapplet
# (octodns.withProviders (ps: [
# octodns-providers.gandi
# ]))
];
}

View file

@ -1,8 +1,147 @@
{ lib, ... }:
{
imports = [
./programs/base
inputs,
lib,
config,
pkgs,
...
}:
{
services.autofs.enable = false;
services.udev = {
extraRules = ''
KERNEL=="ttyACM0", MODE:="666"
ACTION=="add", KERNEL=="sd[a-e][0-9]", ENV{ID_FS_UUID}=="3039-3932", RUN+="${pkgs.systemd}/bin/systemd-mount --no-block -A -G -o gid=users,fmask=113,dmask=002 /dev/%k /mnt/sdcard"
ACTION=="add", KERNEL=="sd[a-e]", ENV{ID_FS_UUID}=="66BA-4EBA", RUN+="${pkgs.systemd}/bin/systemd-mount --no-block -A -G -o gid=users,fmask=113,dmask=002 /dev/%k /mnt/kobo"
KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"
'';
packages = with pkgs; [
vial
via
];
};
home-manager.users.fw = {
xdg.mimeApps = {
enable = true;
defaultApplications = {
"text/html" = "librewolf.desktop";
"x-scheme-handler/http" = "librewolf.desktop";
"x-scheme-handler/https" = "librewolf.desktop";
"x-scheme-handler/about" = "librewolf.desktop";
"x-scheme-handler/unknown" = "librewolf.desktop";
"text/plain" = "nvim.desktop";
"text/markdown" = "nvim.desktop";
"text/x-markdown" = "nvim.desktop";
"application/json" = "nvim.desktop";
"application/x-ndjson" = "nvim.desktop";
"application/x-yaml" = "nvim.desktop";
"text/yaml" = "nvim.desktop";
"text/x-shellscript" = "nvim.desktop";
"text/x-python" = "nvim.desktop";
"text/x-csrc" = "nvim.desktop";
"text/x-c++src" = "nvim.desktop";
"application/x-sql" = "nvim.desktop";
"text/xml" = "nvim.desktop";
"application/xml" = "nvim.desktop";
"application/pdf" = "org.gnome.Evince.desktop";
"image/jpeg" = "feh.desktop";
"image/png" = "feh.desktop";
"image/gif" = "feh.desktop";
"image/webp" = "feh.desktop";
"image/tiff" = "feh.desktop";
"image/bmp" = "feh.desktop";
"image/svg+xml" = "feh.desktop";
};
};
};
environment.sessionVariables.DEFAULT_BROWSER = "${pkgs.librewolf}/bin/librewolf";
features.base.enable = lib.mkDefault true;
environment.systemPackages = with pkgs; [
# GUI
feishin
vscode
signal-desktop
thunderbird
discord
slack
evince
spotify
firefox
ipcalc
vial
via
remmina
brightnessctl
speedcrunch
wf-recorder
slurp
lagrange
jujutsu
rclone
quickemu
virt-viewer
go-passbolt-cli
wf-recorder
slurp
bitwarden-desktop
jira-cli-go
chromium
vault
dbeaver-bin
(
let
base = pkgs.appimageTools.defaultFhsEnvArgs;
in
pkgs.buildFHSEnv (
base
// {
name = "fhs";
targetPkgs =
pkgs:
# pkgs.buildFHSUserEnv provides only a minimal FHS environment,
# lacking many basic packages needed by most software.
# Therefore, we need to add them manually.
#
# pkgs.appimageTools provides basic packages required by most software.
(base.targetPkgs pkgs)
++ (with pkgs; [
pkg-config
ncurses
icu
# Feel free to add more packages here if needed.
]);
profile = "export FHS=1";
runScript = "bash";
extraOutputsToInstall = [ "dev" ];
}
)
)
# TUI
# nodejs
claude-code
# Browsers
librewolf
# Displaying
zathura
feh
mpv
# System
pavucontrol
pulseaudio
devour
caligula
ptouch-print
# Transforms
yt-dlp
imagemagick
pandoc
pinta
pastel
ffmpeg
# darktable
];
}

View file

@ -1,245 +0,0 @@
{
lib,
config,
pkgs,
...
}:
with lib;
let
fhsEnv =
let
base = pkgs.appimageTools.defaultFhsEnvArgs;
in
pkgs.buildFHSEnv (
base
// {
name = "fhs";
targetPkgs =
pkgs:
(base.targetPkgs pkgs)
++ (with pkgs; [
pkg-config
ncurses
icu
]);
profile = "export FHS=1";
runScript = "bash";
extraOutputsToInstall = [ "dev" ];
}
);
in
{
options.features.base = {
enable = mkEnableOption "enable shared base programs";
preset = mkOption {
type = types.enum [
"minimal"
"standard"
"full"
];
default = "standard";
description = "Preset for desktop package groups.";
};
udevEnable = mkOption {
type = types.bool;
default = true;
description = "Enable custom udev rules and device packages.";
};
mimeEnable = mkOption {
type = types.bool;
default = true;
description = "Enable Home Manager MIME defaults.";
};
packages = {
communicationEnable = mkOption {
type = types.bool;
default = true;
description = "Install communication desktop apps.";
};
mediaEnable = mkOption {
type = types.bool;
default = true;
description = "Install media apps.";
};
browsersEnable = mkOption {
type = types.bool;
default = true;
description = "Install browsers.";
};
captureEnable = mkOption {
type = types.bool;
default = true;
description = "Install screen capture tools.";
};
creativeEnable = mkOption {
type = types.bool;
default = true;
description = "Install conversion/creative tools.";
};
devDesktopEnable = mkOption {
type = types.bool;
default = true;
description = "Install desktop dev helper tools and VMs.";
};
dbeaverEnable = mkOption {
type = types.bool;
default = true;
description = "Install dbeaver and FHS shell.";
};
};
};
config = mkMerge [
(mkIf (config.features.base.preset == "minimal") {
features.base.packages.communicationEnable = mkDefault false;
features.base.packages.mediaEnable = mkDefault false;
features.base.packages.browsersEnable = mkDefault true;
features.base.packages.captureEnable = mkDefault false;
features.base.packages.creativeEnable = mkDefault false;
features.base.packages.devDesktopEnable = mkDefault false;
features.base.packages.dbeaverEnable = mkDefault false;
})
(mkIf (config.features.base.preset == "full") {
features.base.packages.communicationEnable = mkDefault true;
features.base.packages.mediaEnable = mkDefault true;
features.base.packages.browsersEnable = mkDefault true;
features.base.packages.captureEnable = mkDefault true;
features.base.packages.creativeEnable = mkDefault true;
features.base.packages.devDesktopEnable = mkDefault true;
features.base.packages.dbeaverEnable = mkDefault true;
})
(mkIf config.features.base.enable {
services.udev = mkIf config.features.base.udevEnable {
extraRules = ''
KERNEL=="ttyACM0", MODE:="666"
ACTION=="add", KERNEL=="sd[a-e][0-9]", ENV{ID_FS_UUID}=="3039-3932", RUN+="${pkgs.systemd}/bin/systemd-mount --no-block -A -G -o gid=users,fmask=113,dmask=002 /dev/%k /mnt/sdcard"
ACTION=="add", KERNEL=="sd[a-e]", ENV{ID_FS_UUID}=="66BA-4EBA", RUN+="${pkgs.systemd}/bin/systemd-mount --no-block -A -G -o gid=users,fmask=113,dmask=002 /dev/%k /mnt/kobo"
KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"
'';
packages = with pkgs; [
vial
via
];
};
home-manager.users.fw = mkIf config.features.base.mimeEnable {
xdg.mimeApps = {
enable = true;
defaultApplications = {
"text/html" = "librewolf.desktop";
"x-scheme-handler/http" = "librewolf.desktop";
"x-scheme-handler/https" = "librewolf.desktop";
"x-scheme-handler/about" = "librewolf.desktop";
"x-scheme-handler/unknown" = "librewolf.desktop";
"text/plain" = "nvim.desktop";
"text/markdown" = "nvim.desktop";
"text/x-markdown" = "nvim.desktop";
"application/json" = "nvim.desktop";
"application/x-ndjson" = "nvim.desktop";
"application/x-yaml" = "nvim.desktop";
"text/yaml" = "nvim.desktop";
"text/x-shellscript" = "nvim.desktop";
"text/x-python" = "nvim.desktop";
"text/x-csrc" = "nvim.desktop";
"text/x-c++src" = "nvim.desktop";
"application/x-sql" = "nvim.desktop";
"text/xml" = "nvim.desktop";
"application/xml" = "nvim.desktop";
"application/pdf" = "org.gnome.Evince.desktop";
"image/jpeg" = "feh.desktop";
"image/png" = "feh.desktop";
"image/gif" = "feh.desktop";
"image/webp" = "feh.desktop";
"image/tiff" = "feh.desktop";
"image/bmp" = "feh.desktop";
"image/svg+xml" = "feh.desktop";
};
};
};
environment.sessionVariables.DEFAULT_BROWSER = "${pkgs.librewolf}/bin/librewolf";
environment.systemPackages =
(with pkgs; [
codex
ipcalc
remmina
brightnessctl
speedcrunch
lagrange
jujutsu
rclone
zathura
feh
pavucontrol
pulseaudio
devour
caligula
ptouch-print
])
++ optionals config.features.base.packages.communicationEnable (
with pkgs;
[
signal-desktop
thunderbird
discord
slack
]
)
++ optionals config.features.base.packages.mediaEnable (
with pkgs;
[
feishin
spotify
mpv
]
)
++ optionals config.features.base.packages.browsersEnable (
with pkgs;
[
librewolf
firefox
]
)
++ optionals config.features.base.packages.captureEnable (
with pkgs;
[
wf-recorder
slurp
]
)
++ optionals config.features.base.packages.creativeEnable (
with pkgs;
[
yt-dlp
imagemagick
pandoc
pinta
pastel
ffmpeg
]
)
++ optionals config.features.base.packages.devDesktopEnable (
with pkgs;
[
vscode
opencode
quickemu
virt-viewer
go-passbolt-cli
bitwarden-desktop
bitwarden-cli
]
)
++ optionals config.features.base.packages.dbeaverEnable (
with pkgs;
[
dbeaver-bin
fhsEnv
]
);
})
];
}

View file

@ -15,6 +15,9 @@ let
move: yes
write: yes
paths:
default: $albumartist/$album ($year)/$track $title
fetchart:
auto: yes
@ -60,7 +63,8 @@ in
"BEETSCONFIG=${config.xdg.configHome}/beets/config.yaml"
];
};
Install = { WantedBy = [ "default.target" ]; };
Install = {
WantedBy = [ "default.target" ];
};
};
}

View file

@ -1,109 +0,0 @@
{
inputs,
pkgs,
lib,
config,
...
}:
let
azPkgs = inputs.nixpkgs-azure-cli.legacyPackages.${pkgs.stdenv.hostPlatform.system};
in
with lib;
{
options.features.dev = {
enable = mkEnableOption "enable development toolchain";
preset = mkOption {
type = types.enum [
"minimal"
"standard"
"full"
];
default = "standard";
description = "Preset for development package groups.";
};
cloud = {
aws.enable = mkOption {
type = types.bool;
default = true;
description = "Enable AWS CLI tools.";
};
azure.enable = mkOption {
type = types.bool;
default = true;
description = "Enable Azure CLI tools.";
};
minio.enable = mkOption {
type = types.bool;
default = true;
description = "Enable MinIO client.";
};
};
tools = {
docker.enable = mkOption {
type = types.bool;
default = true;
description = "Enable lazydocker.";
};
python.enable = mkOption {
type = types.bool;
default = true;
description = "Enable Python runtime package.";
};
opentofu.enable = mkOption {
type = types.bool;
default = true;
description = "Enable OpenTofu package.";
};
git.enable = mkOption {
type = types.bool;
default = true;
description = "Enable git package in dev toolchain.";
};
};
};
config = mkMerge [
(mkIf config.features.dev.enable {
environment.systemPackages =
(with pkgs; [
nixfmt-rfc-style
gh
yq
jq
])
++ optionals config.features.dev.tools.docker.enable (with pkgs; [ lazydocker ])
++ optionals config.features.dev.cloud.aws.enable (with pkgs; [ awscli ])
++ optionals config.features.dev.cloud.minio.enable (with pkgs; [ minio-client ])
++ optionals config.features.dev.tools.opentofu.enable (with pkgs; [ opentofu ])
++ optionals config.features.dev.tools.python.enable (with pkgs; [ python3 ])
++ optionals config.features.dev.cloud.azure.enable [
(azPkgs.azure-cli.withExtensions (
with azPkgs.azure-cli.extensions;
[
fzf
]
))
]
++ optionals config.features.dev.tools.git.enable (with pkgs; [ git ]);
})
(mkIf (config.features.dev.preset == "minimal") {
features.dev.cloud.aws.enable = mkDefault false;
features.dev.cloud.azure.enable = mkDefault false;
features.dev.cloud.minio.enable = mkDefault false;
features.dev.tools.docker.enable = mkDefault false;
features.dev.tools.opentofu.enable = mkDefault false;
features.dev.tools.python.enable = mkDefault false;
})
(mkIf (config.features.dev.preset == "full") {
features.dev.cloud.aws.enable = mkDefault true;
features.dev.cloud.azure.enable = mkDefault true;
features.dev.cloud.minio.enable = mkDefault true;
features.dev.tools.docker.enable = mkDefault true;
features.dev.tools.opentofu.enable = mkDefault true;
features.dev.tools.python.enable = mkDefault true;
features.dev.tools.git.enable = mkDefault true;
})
];
}

View file

@ -1,45 +0,0 @@
{ lib, config, ... }:
with lib;
{
options.features.git = {
enable = mkEnableOption "enable git defaults";
userName = mkOption {
type = types.str;
default = "fwastring";
description = "Default git user.name.";
};
userEmail = mkOption {
type = types.str;
default = "fredrik@wastring.com";
description = "Default git user.email.";
};
pullRebase = mkOption {
type = types.bool;
default = true;
description = "Enable pull.rebase by default.";
};
githubSshInsteadOfHttps = mkOption {
type = types.bool;
default = true;
description = "Use SSH for GitHub remotes when cloning with HTTPS URLs.";
};
};
config = mkIf config.features.git.enable {
programs.git = {
enable = true;
config = {
user = {
name = config.features.git.userName;
email = config.features.git.userEmail;
};
pull = {
rebase = config.features.git.pullRebase;
};
}
// optionalAttrs config.features.git.githubSshInsteadOfHttps {
url."git@github.com:".insteadOf = "https://github.com/";
};
};
};
}

View file

@ -285,10 +285,12 @@ with lib;
"$mod, l, movefocus, r"
"$mod, k, movefocus, u"
"$mod, j, movefocus, d"
"$mod, b, exec, pkill -INT .waybar-wrapped"
# Applications
"$mod, q, exec, ${pkgs.librewolf}/bin/librewolf"
"$mod, d, exec, ${pkgs.rofi}/bin/rofi -show drun -p 'Run: '"
", F19, exec, ${pkgs.rofi}/bin/rofi -show drun -p 'Run: '"
# Screencapture
"$mod SHIFT, s, exec, ${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp)\" - | ${pkgs.wl-clipboard}/bin/wl-copy -t image/png"

View file

@ -0,0 +1,50 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.neomd;
neomdPackage = pkgs.buildGoModule {
pname = "neomd";
version = "unstable-2026-04-06";
src = pkgs.fetchFromGitHub {
owner = "ssp-data";
repo = "neomd";
rev = "671a9dd66bb367e21be7777a6765635a99b7ab09";
hash = "sha256-9IVrp9GTwr5aFsBy7lPPRXYCaeYTkOuM+VEdK7Tf2+o=";
};
vendorHash = "sha256-cG5x23qA+AN5zwEjdx8uDBk9JjNpn/afzI0/aAJjqAU=";
subPackages = [ "cmd/neomd" ];
ldflags = [
"-s"
"-w"
];
meta = {
description = "Terminal email client for markdown and Neovim workflows";
homepage = "https://github.com/ssp-data/neomd";
license = lib.licenses.mit;
mainProgram = "neomd";
};
};
in
{
options.neomd = {
enable = lib.mkEnableOption "neomd terminal email client";
package = lib.mkOption {
type = lib.types.package;
default = neomdPackage;
description = "Package to install when neomd is enabled.";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
};
}

View file

@ -37,6 +37,7 @@ with lib;
telescope = true;
treesitter = true;
cmp = true;
lualine = { };
};
};
};
@ -55,10 +56,6 @@ with lib;
};
clipboard.register = "unnamedplus";
extraPlugins = with pkgs.vimPlugins; [
plenary-nvim
];
globals.mapleader = " ";
keymaps = [
@ -66,7 +63,7 @@ with lib;
{
mode = "n";
key = "<leader>f";
action = "<cmd>Telescope find_files<CR>";
action = "<cmd>Telescope find_files hidden=true<CR>";
}
{
mode = "n";
@ -239,7 +236,9 @@ with lib;
lualine = {
enable = true;
settings = {
options.theme = "catppuccin";
options.theme = {
__raw = "(function() local ok, cp = pcall(require, 'catppuccin.utils.lualine'); return ok and cp() or 'auto' end)()";
};
tabline = {
lualine_a = [ ];
lualine_b = [ ];
@ -251,31 +250,44 @@ with lib;
};
};
};
# avante = {
# enable = true;
# settings = {
# provider = "claude-code";
# acp_providers = {
# claude-code = {
# command = "npx";
# args = [ "@zed-industries/claude-code-acp" ];
# };
# };
# };
# };
treesitter = {
enable = true;
grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
bash
json
lua
make
markdown
helm
nix
regex
toml
vim
vimdoc
xml
yaml
];
};
# treesitter = {
# enable = true;
#
# grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
# bash
# json
# lua
# make
# markdown
# helm
# nix
# regex
# toml
# vim
# vimdoc
# xml
# yaml
# ];
# };
oil = {
enable = true;
settings = {
default_file_explorer = true;
columns = [ "icon" ];
view_options.show_hidden = true;
win_options = {
wrap = false;
signcolumn = "no";
@ -292,7 +304,117 @@ with lib;
lazygit.enable = true;
telescope.enable = true;
telescope = {
enable = true;
settings = {
defaults = {
mappings = {
i = {
"<CR>" = {
__raw = ''
function(prompt_bufnr)
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local picker = action_state.get_current_picker(prompt_bufnr)
local selections = picker:get_multi_selection()
if vim.tbl_isempty(selections) then
actions.select_default(prompt_bufnr)
return
end
local current = action_state.get_selected_entry()
actions.close(prompt_bufnr)
local seen = {}
local first = true
local function open_entry(entry)
local path = entry and (entry.path or entry.filename or entry.value)
if not path or seen[path] then
return
end
seen[path] = true
local escaped = vim.fn.fnameescape(path)
if first then
vim.cmd("edit " .. escaped)
first = false
else
vim.cmd("tabedit " .. escaped)
end
end
open_entry(current)
for _, entry in ipairs(selections) do
open_entry(entry)
end
end
'';
};
};
n = {
"<CR>" = {
__raw = ''
function(prompt_bufnr)
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local picker = action_state.get_current_picker(prompt_bufnr)
local selections = picker:get_multi_selection()
if vim.tbl_isempty(selections) then
actions.select_default(prompt_bufnr)
return
end
local current = action_state.get_selected_entry()
actions.close(prompt_bufnr)
local seen = {}
local first = true
local function open_entry(entry)
local path = entry and (entry.path or entry.filename or entry.value)
if not path or seen[path] then
return
end
seen[path] = true
local escaped = vim.fn.fnameescape(path)
if first then
vim.cmd("edit " .. escaped)
first = false
else
vim.cmd("tabedit " .. escaped)
end
end
open_entry(current)
for _, entry in ipairs(selections) do
open_entry(entry)
end
end
'';
};
};
};
vimgrep_arguments = [
"rg"
"--color=never"
"--no-heading"
"--with-filename"
"--line-number"
"--column"
"--smart-case"
"--hidden"
"--glob"
"!.git/*"
];
};
};
};
luasnip.enable = true;
cmp = {
@ -363,6 +485,9 @@ with lib;
};
};
};
extraPlugins = with pkgs.vimPlugins; [
plenary-nvim
];
enableMan = false;
autoCmd = [
{

View file

@ -59,6 +59,7 @@ let
"upower"
"custom/tailscale"
"custom/netbird"
"custom/bitwarden"
"network"
"clock"
]
@ -69,6 +70,7 @@ let
"bluetooth"
"custom/tailscale"
"custom/netbird"
"custom/bitwarden"
"network"
"clock"
];
@ -189,6 +191,20 @@ let
return-type = "json";
interval = 5;
};
"custom/bitwarden" = {
exec = "/home/fw/.config/waybar/scripts/bitwarden.sh --status";
on-click = "/home/fw/.config/waybar/scripts/bitwarden.sh --toggle";
exec-on-event = true;
format = "BW {icon} {text}";
format-icons = {
connected = "";
stopped = "";
};
tooltip = true;
return-type = "json";
interval = 5;
};
};
waybarStyle = ''
@ -238,7 +254,8 @@ let
#upower,
#network,
#custom-tailscale,
#custom-netbird {
#custom-netbird,
#custom-bitwarden {
background: @base;
border: none;
border-radius: 5px;
@ -305,6 +322,7 @@ let
#upower,
#custom-tailscale,
#custom-netbird,
#custom-bitwarden,
#network {
background: @peach;
color: @base;
@ -755,6 +773,68 @@ with lib;
'';
executable = true;
};
xdg.configFile."waybar/scripts/bitwarden.sh" = {
text = ''
#!${pkgs.bash}/bin/bash
PATH=${
lib.makeBinPath [
pkgs.coreutils
pkgs.procps
pkgs.bitwarden-desktop
]
}
BITWARDEN_SSH_SOCK="''${HOME}/.bitwarden-ssh-agent.sock"
is_socket_active() {
[[ -S "$BITWARDEN_SSH_SOCK" ]]
}
show_status() {
if is_socket_active; then
echo "{\"text\":\"\",\"class\":\"connected\",\"alt\":\"connected\",\"tooltip\":\"Bitwarden SSH agent socket is active: $BITWARDEN_SSH_SOCK\"}"
else
echo "{\"text\":\"\",\"class\":\"stopped\",\"alt\":\"stopped\",\"tooltip\":\"Bitwarden SSH agent socket is inactive: $BITWARDEN_SSH_SOCK\"}"
fi
}
open_bitwarden() {
bitwarden >/dev/null 2>&1 &
show_status
}
stop_bitwarden() {
pkill -x bitwarden >/dev/null 2>&1 || true
show_status
}
toggle_bitwarden() {
if is_socket_active; then
stop_bitwarden
else
open_bitwarden
fi
}
case "$1" in
--status)
show_status
;;
--open)
open_bitwarden
;;
--toggle)
toggle_bitwarden
;;
*)
echo "Usage: $0 {--status|--open|--toggle}"
exit 1
;;
esac
'';
executable = true;
};
};
# catppuccin.waybar = {
# enable = true;

View file

@ -1,69 +0,0 @@
{
lib,
config,
pkgs,
...
}:
with lib;
{
options.features.network = {
enable = mkEnableOption "enable network tooling and VPN services";
netbird = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable NetBird service.";
};
uiEnable = mkOption {
type = types.bool;
default = true;
description = "Enable NetBird UI component.";
};
};
tailscale = {
waitForNetbird = mkOption {
type = types.bool;
default = true;
description = "Add netbird ordering to tailscaled unit.";
};
};
tooling = {
enable = mkOption {
type = types.bool;
default = true;
description = "Install network troubleshooting CLI tools.";
};
packages = mkOption {
type = types.listOf types.package;
default = with pkgs; [
dnsutils
nmap
ipcalc
];
description = "Packages installed when network tooling is enabled.";
};
};
};
config = mkIf config.features.network.enable {
services.netbird = mkIf config.features.network.netbird.enable {
enable = true;
ui.enable = config.features.network.netbird.uiEnable;
};
systemd.services.tailscaled =
mkIf (config.features.network.tailscale.waitForNetbird && config.features.network.netbird.enable)
{
after = [
"netbird.service"
"network-online.target"
];
wants = [
"netbird.service"
"network-online.target"
];
};
environment.systemPackages = mkIf config.features.network.tooling.enable config.features.network.tooling.packages;
};
}

View file

@ -1,71 +0,0 @@
{ lib, config, ... }:
with lib;
{
options.features.sound = {
enable = mkEnableOption "enable sound and bluetooth stack";
pipewire = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable PipeWire audio stack.";
};
alsa32Bit = mkOption {
type = types.bool;
default = true;
description = "Enable 32-bit ALSA support.";
};
pulseCompat = mkOption {
type = types.bool;
default = true;
description = "Enable PulseAudio compatibility through PipeWire.";
};
};
bluetooth = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable Bluetooth subsystem.";
};
powerOnBoot = mkOption {
type = types.bool;
default = true;
description = "Power on Bluetooth at boot.";
};
disableHeadsetProfile = mkOption {
type = types.bool;
default = true;
description = "Disable headset profile for Bluetooth devices.";
};
bluemanEnable = mkOption {
type = types.bool;
default = true;
description = "Enable Blueman service.";
};
};
};
config = mkIf config.features.sound.enable {
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services = {
pipewire = {
enable = config.features.sound.pipewire.enable;
alsa.enable = config.features.sound.pipewire.enable;
alsa.support32Bit = config.features.sound.pipewire.alsa32Bit;
pulse.enable = config.features.sound.pipewire.pulseCompat;
};
blueman.enable = config.features.sound.bluetooth.bluemanEnable;
};
hardware = {
bluetooth = mkIf config.features.sound.bluetooth.enable {
enable = config.features.sound.bluetooth.enable;
powerOnBoot = config.features.sound.bluetooth.powerOnBoot;
settings = {
General = mkIf config.features.sound.bluetooth.disableHeadsetProfile {
Disable = "Headset";
};
};
};
};
};
}

View file

@ -1,78 +0,0 @@
{
pkgs,
lib,
config,
...
}:
with lib;
{
options.features.system = {
enable = mkEnableOption "enable shared system utilities";
preset = mkOption {
type = types.enum [
"minimal"
"desktop"
"ops"
];
default = "desktop";
description = "Package profile for shared system tooling.";
};
corePackages = mkOption {
type = types.listOf types.package;
default = with pkgs; [
sops
unzip
zip
wget
htop
procps
fastfetch
bc
fzf
eza
rsync
ripgrep
fd
];
description = "Always-installed core system packages.";
};
desktopPackages = mkOption {
type = types.listOf types.package;
default = with pkgs; [
bluez
bluez-tools
poppler-utils
alsa-utils
libnotify
hyprpicker
];
description = "Additional packages for desktop-oriented hosts.";
};
opsPackages = mkOption {
type = types.listOf types.package;
default = with pkgs; [
grc
lazygit
];
description = "Additional packages for operations-heavy hosts.";
};
extras = mkOption {
type = types.listOf types.package;
default = with pkgs; [
lolcat
fortune
cowsay
typst
];
description = "Additional optional packages for all presets except minimal.";
};
};
config = mkIf config.features.system.enable {
environment.systemPackages =
config.features.system.corePackages
++ optionals (config.features.system.preset != "minimal") config.features.system.extras
++ optionals (config.features.system.preset == "desktop") config.features.system.desktopPackages
++ optionals (config.features.system.preset == "ops") config.features.system.opsPackages;
};
}

View file

@ -1,62 +0,0 @@
{
config,
pkgs,
lib,
...
}:
with lib;
{
options.features.users = {
enable = mkEnableOption "enable default users";
name = mkOption {
type = types.str;
default = "fw";
description = "Primary user account name.";
};
fullName = mkOption {
type = types.str;
default = "Fredrik Wastring";
description = "Primary user full name.";
};
initialPassword = mkOption {
type = types.str;
default = "password";
description = "Initial password for the primary user.";
};
extraGroups = mkOption {
type = types.listOf types.str;
default = [
"networkmanager"
"wheel"
"audio"
"docker"
"input"
];
description = "Additional groups for the primary user.";
};
sshAuthorizedKeys = mkOption {
type = types.listOf types.str;
default = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpJBGPIfPB1BwSG7aoKqwfccyZSaU7J3xpJ8behMp9N fw@core"
];
description = "SSH authorized keys for the primary user.";
};
};
config = mkIf config.features.users.enable {
users = {
defaultUserShell = pkgs.bash;
users = {
${config.features.users.name} = {
initialPassword = config.features.users.initialPassword;
isNormalUser = true;
description = config.features.users.fullName;
extraGroups = config.features.users.extraGroups;
openssh.authorizedKeys = {
keys = config.features.users.sshAuthorizedKeys;
};
};
};
};
};
}

View file

@ -100,21 +100,6 @@ in
default = 24;
description = "VAAPI quality parameter (lower means better quality, higher CPU/bitrate).";
};
waitForRtsp = mkOption {
type = types.bool;
default = true;
description = "Wait for the RTSP destination to accept TCP connections before ffmpeg starts.";
};
waitForRtspTimeoutSec = mkOption {
type = types.int;
default = 30;
description = "Maximum seconds to wait for RTSP destination availability.";
};
waitForRtspIntervalSec = mkOption {
type = types.int;
default = 1;
description = "Seconds between RTSP availability checks.";
};
vaapiDriver = mkOption {
type = types.nullOr types.str;
default = null;
@ -224,13 +209,6 @@ in
"-rc_mode VBR -b:v ${toString streamCfg.bitrateKbps}k -maxrate ${toString maxrateKbps}k -bufsize ${toString bufsizeKbps}k"
else
"-rc_mode CQP -qp ${toString streamCfg.vaapiQp}";
rtspUrlMatch = builtins.match "rtsp://([^/:]+)(:([0-9]+))?/.*" streamCfg.rtspUrl;
rtspHost = if rtspUrlMatch != null then builtins.elemAt rtspUrlMatch 0 else "127.0.0.1";
rtspPort =
if rtspUrlMatch != null && builtins.elemAt rtspUrlMatch 2 != null then
builtins.elemAt rtspUrlMatch 2
else
"8554";
videoCodecArgs =
if streamCfg.useVaapi then
"-vaapi_device ${streamCfg.vaapiDevice} -vf format=nv12,hwupload -c:v h264_vaapi -profile:v main -level:v 4.1 ${vaapiRateControlArgs} -g ${
@ -252,22 +230,6 @@ in
Restart = "always";
RestartSec = "2";
Environment = optional (streamCfg.vaapiDriver != null) "LIBVA_DRIVER_NAME=${streamCfg.vaapiDriver}";
ExecStartPre = optional cfg.waitForRtsp (
pkgs.writeShellScript "wait-for-rtsp-${sanitizeName streamName}" ''
set -eu
retries=${toString cfg.waitForRtspTimeoutSec}
interval=${toString cfg.waitForRtspIntervalSec}
i=0
until ${pkgs.netcat-openbsd}/bin/nc -z -w1 ${rtspHost} ${rtspPort}; do
i=$((i + 1))
if [ "$i" -ge "$retries" ]; then
echo "Timed out waiting for RTSP server at ${rtspHost}:${rtspPort}" >&2
exit 1
fi
sleep "$interval"
done
''
);
ExecStart = "${pkgs.ffmpeg}/bin/ffmpeg -hide_banner -loglevel warning -f v4l2 -framerate ${toString streamCfg.framerate} -video_size ${streamCfg.videoSize} -i ${streamCfg.device} ${videoCodecArgs} -f rtsp -rtsp_transport tcp ${streamCfg.rtspUrl}";
};
}

View file

@ -1,8 +1,25 @@
{ lib, ... }:
{ pkgs, lib, ... }:
{
imports = [
./services/sound
];
features.sound.enable = lib.mkDefault true;
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services = {
pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
blueman.enable = true;
};
hardware = {
bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Disable = "Headset";
};
};
};
};
}

View file

@ -1,8 +1,39 @@
{ lib, ... }:
{
imports = [
./services/system
];
pkgs,
...
}:
{
features.system.enable = lib.mkDefault true;
environment.systemPackages = with pkgs; [
bluez
bluez-tools
poppler-utils
alsa-utils
sops
libnotify
unzip
zip
wget
htop
procps
grc
fastfetch
bc
fzf
eza
rsync
ripgrep
fd
lolcat
fortune
cowsay
lazygit
hyprpicker
typst
];
}

View file

@ -1,8 +1,31 @@
{ lib, ... }:
{
imports = [
./services/users
config,
pkgs,
...
}:
{
# sops.secrets.user-password = { };
users = {
defaultUserShell = pkgs.bash;
users = {
fw = {
# hashedPasswordFile = config.sops.secrets.user-password.path;
initialPassword = "password";
isNormalUser = true;
description = "Fredrik Wastring";
extraGroups = [
"networkmanager"
"wheel"
"audio"
"docker"
"input"
];
features.users.enable = lib.mkDefault true;
openssh.authorizedKeys = {
keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpJBGPIfPB1BwSG7aoKqwfccyZSaU7J3xpJ8behMp9N fw@core"
];
};
};
};
};
}

View file

@ -16,7 +16,8 @@ let
version = "source";
src = inputs.wedding;
subPackages = [ "internal/cmd/app" ];
vendorHash = "sha256-rxaikaR4UGXu2hIuR9ZbOnITBsCq5zEDAlwrhhRudoo=";
#vendorHash = "sha256-rxaikaR4UGXu2hIuR9ZbOnITBsCq5zEDAlwrhhRudoo=";
vendorHash = "sha256-9TAVoYShxqzeo2BUWEFmZ6PO4p9Q/BG4207ZEBmhq9I=";
env = {
CGO_ENABLED = 0;
};

View file

@ -15,54 +15,77 @@ fw-qemu: ENC[AES256_GCM,data:TxbilLf79+gieY3WbAGl175aTUVjIc6rlKfYTy8Usmw=,iv:WCv
github_token: ENC[AES256_GCM,data:E8j5K2U8UvTpZtsWIm55dvvSxmZjDY15lYeXGuKnPuq1fRyb5HolEQ==,iv:tqODZ4Y247D4DhmC3z7XEq/2K2JsU76p1hxYkYiql9E=,tag:iYithxJyO/GKvKwwh4BDlA==,type:str]
grafana_token: ENC[AES256_GCM,data:yAUqBV2/IF/wkyutHhf1Ui/xxRIt+SgsUk7QmdcnYa+x5KC8G1ifdcxJjPJvyQ==,iv:dGk6AfadwajDbFzTteCeyNIpwWRwdJbNwjGSlrmhaBU=,tag:svCcQo96PGFXu+MVsmn1HQ==,type:str]
fleet-enroll-secret: ENC[AES256_GCM,data:2DEmgzsYvWZas65HLE4PaxZ3h7L4Gw8esVirZYrzCik=,iv:9t6ET8QnPLIl0Pnn9r24btF7VUQnRr3ukRH0oVsgIrg=,tag:mQ0yxEhx72L71DB36cfMew==,type:str]
jira_token: ENC[AES256_GCM,data:gPSgsNp4XlM6cTzLCpsJpdByTOHQ9vWfosurrd+yzo9MAkTcm5BDXwRWl1aNN2OFZu4+GXNqOho1gegDCQhZQnFRYNACASqmhGk6/GCpSNUlVAExOhvSs8tUu+YZoBUVufWHn5sIsxNHGgiJnX5ZtX7sVhUOo5u+qbb49iHsSZ6WBwP9SDMpfqXkhgZAURTk7iu7VgbHt6D1BxQH2yDCXR7OuICC5D6lSjdKo4Vbdudmz07vM1b4DHfvtP15SJfl,iv:oV3ACNPpz4Zb3bt0oWlx9On71LoXt3ZO5QosSr5XB2k=,tag:Xr0Y/ugZbQ2BaQtUJOwIng==,type:str]
opencode_atlassian_env: ENC[AES256_GCM,data:v7uz9p4/H2WNzZA+I5+qnBRw4cyB4DNt/adBn0TS1bm9Gqk+UhnpjlXuP3mpxElXrAPmqT/rIvRGZp/YGiDWODH+B/WjtAaA/R+hFfOoP+m2unx2UM/a+UwC2EO+6ci+lKtNpT8FfobQxjuCdKWCmz0U54ijtfmyh73+lIzZoffs35fvxHwvchzM3zfCy/EHkR1jDUiKykX2VR1JiBZNa6PFp+SXZGvBlcjf8WjaryEpzIGv1plFftTQSo74OHPuUAC4kXrV9eCH4OJQ6JLyfOH+8tGstyyVWO9BtG7/fO5j830bBgvbqTsjZX+NvmTiaP4caC/sy7vseKkbgRzdUuAASLM3Pbqs9QnP6lFzye/QNdnlcwOOoNniXMbwynmSwtrz6w==,iv:DrArPdRddjxqMqU+38jvc1zCy2xVRmXOD7D9UQHQfgs=,tag:ZGCBxg28k1FMKwvu2r2Aqg==,type:str]
google_oauth_client_id_styrelsen: ENC[AES256_GCM,data:nSbWYSreyn5+Qbf3hOYrpIAC2Eilp/gukox/c0DmjRNBy0DVHY/sKhy60GIM6L98pypmBA00Prx0aq1q506l80l9tcAnUOOC,iv:SMiQafz+ifJU7fW31UMYSZv2gelm+ADxQoy2iJfms4g=,tag:/T/kZAfcu/Ve8BgEr9MnAg==,type:str]
google_oauth_client_secret_styrelsen: ENC[AES256_GCM,data:mMqnmusE6KPFH4lTqXg/mboslIiHrCTEnQuHGmMYZ0aN3sA=,iv:xVy1UFNfbuYimuqKza61GJdwkCZ/j3qiBCm8Esl7cPE=,tag:RmBgnRT5WmwL2YFbj+0tKQ==,type:str]
user_google_email_styrelsen: ENC[AES256_GCM,data:JRYtpeY2bGVu6gaAuMlZdlklW2UWIY9FXq2v,iv:BEtfCwloMEdJN2uTBwbq8ATRMW9XWtbR3DTtzH9/6Qw=,tag:shBSm2749ZnwLITAUMieWw==,type:str]
user_google_email_core: ENC[AES256_GCM,data:azALLFW243+0y46jHGMfMwjEBWbth2ufF2E=,iv:gX36/P4VG189/QwUUPhmtlali4Y7U3pU2mLtW5EZOTs=,tag:1LxA7QsqpVN8RnJvde3HiA==,type:str]
google_oauth_client_id_core: ENC[AES256_GCM,data:R0ZoHDm1McgIqYSilmujguQTwZAozESasbLK+VCz5xU4pogH78H0I/pLL900ZFNUFr3nwoRSv4bG/aFJbtSxwXkKfcMMIEG7,iv:3LA8fl6QJd3Jh9tqyphrddgqYTwLwqGL71bdipwMqhA=,tag:hNLEhlOsHi2VpQf1JI7wUg==,type:str]
google_oauth_client_secret_core: ENC[AES256_GCM,data:JcuMQqrSxRZKFhrZ5Y5JeUCFsOb8ralJ6Ult7fBIrDGNTCc=,iv:0KHy8+/q0V5hkGYgXdXlq6i/G8NuKvi/rNSV4ztoF+8=,tag:6ZHFUEQlLVIeY7gU13NpWQ==,type:str]
mssql_server_core: ENC[AES256_GCM,data:G4ozEwlBqTqx,iv:Glg+tr4yQoL5IXG4kAcVyvdz4bhyAaRamVO3BC5JERY=,tag:Srz3oCy3+3kB8QzytBjoyw==,type:str]
mssql_database_core: ENC[AES256_GCM,data:niPf8ne2,iv:7/c1HwaRAObJ1E83+Au4T1RyVh2U+IHLNjOo8sWlcds=,tag:0Yp+o1NQkZjIGTfoTXsCLw==,type:str]
mssql_user_core: ENC[AES256_GCM,data:EGo=,iv:dfRX5GJdnz24RIS4SRLCCcavQ8WttGJg32N8NPcN0Es=,tag:Zbu2LCm2EWEYfr3OKouYfA==,type:str]
mssql_password_core: ENC[AES256_GCM,data:72kkh7A02lt0Cf0X,iv:h6vZR2Kw7Md73vFqpMPxL+0XVLaymEHfRGMQb8lobmY=,tag:ynnd+YIeh5O5YuNcITqdgg==,type:str]
vault_addr_core: ENC[AES256_GCM,data:OQIGGCAJQknET1ARyMKn4ahy8f4ZlIljqhpNFFcpRA==,iv:kQI9VBHYrtaw1a6+diYmD4kncsMXRSW55yHY5K/waq0=,tag:zWsmzo2uSHsnJmzPvoZ8Gw==,type:str]
vault_token_core: ENC[AES256_GCM,data:3UPIIzCB6CKS1UN083NvOSMUlgiVvCh7nnxRcA==,iv:jxXYJbJJa3THKuynmPMv/quUSLn+VI8+sup4xfReEjQ=,tag:UTRBCpIqz5XHGSNBWl8I8g==,type:str]
sops:
age:
- recipient: age1jeyw96795qu52swmtkjqgr2w3g4vxc43ckc5r4hlwpje23ptnfwsheah0s
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1Y0lCZzc0QVlmR0ZyV3pm
VnJPSW0zRkFmSmlwWW5Hbjg4NkJKb0pVTjBzClRmUW1XTS9GWGR0RWpXYVdUUDFk
a2VjS0VGSnVrQnpkU2RrQnZ4UmNDOFEKLS0tICtkY0xBeWt1ZFFhWEV4SlRmNXBr
OXljbkIxM21mYklubWxvcmI3eW5oWTAKNaDUBT+mX+G9HrqC9Od4vtFu3Irfuy1s
7GszkEHf+/0IKO4VD26NdHnO6X0P1UOnEqcEHLessGiWBsVYjUw4Xg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLdzRUNHBGdmZtdldFNHQr
dFY3RGhwbWRoSDl5UVNJSU1Cb002YUJrcmh3Ck9CbVVSeVJxdVJRYkFLWHFpVW5P
TVRrb0NLMGZrY2xhRDdEZ1ZYU3NldFEKLS0tIFgyRGZ6aXlublo4NHRlbzhXeFhx
OEg2U1h0cTlWbFFyM0xpelIzdkRGQlUKVA+DDPt1vgHZTTHna7hb6gqUyaJqJM2P
KRzZqqzddcgR84PKb4kxstAvxDVKovg2rrCFPC7NM5bvnkVQi2cfqg==
-----END AGE ENCRYPTED FILE-----
- recipient: age106ml0ssx0p24dvfamp322myzka4wzeze9yhzyvtptp9c6fmmru6slswh2x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMcDMzMVVmNHcrSGlNd1JW
RjZhNFlqWUVBM3QyVHJKWEZVTG5PbFRzRVQ0Ck0xMnl0U0pOUnVRM0ZCdXo1TFpU
SlZKTFo1Qm16UGZ5U2pWT2twbjU4RTgKLS0tIFU5VUQ5WEY4dGNwM1ErckZHVkNp
VUMwRFNsODFCZzZZQlBUWGhDYmZCZDgKFSDgrl1lppb4cx+baBwdVt3fKFia+DvS
AvMwzqQD7/OJu5Yhai8ekiLEN4Y2r+DcK3Nb526vM64Bevk5frmJsg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZTjA2VkM2SUN0SzIzamNK
TUZyN2pvMmxaMWt3TFJmNktJbkVJcGsyekU4Ck90TVFUTFd5S3JIWTB5YVd2NVcr
YjdUNzNrcDZLOFNyS3BSY2M2RFlkZTAKLS0tIDBmTFUxVjUxejFxbGlTR2lxRmx3
R1d1eXZCa1FiNnBkcHRqYjd0S1h3OEEKNmB73xPvtK3K9SpUi9dtgLDyZZyj2Url
k7BePcC8tcUYeQyhYEUIaVl1JRCPbHtdoTSyKVqa8Mr3I6pvfrkWnw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1dql5lwetk39a9y8ummfgjx3aym02yn205lxk389k6q0tu9y3ff4s94l66t
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMRldCMlVXTytpZVpoS2dL
eXZNRkpMRkFvRlJGSHZiOExlMTBHdllRVFRFCnc3RTBCY2hLbU90ZkpqMFQ0azQ4
UGZzRlpsZnVDMS9PSlVrSFFiYlgvUEUKLS0tIEtYS1RZY203dXN4SlZ4UVEyZFR0
TGROZTBhSXhJSm5VUit6UHpaU1JzZGsK/u8n7h445lJvzOLF7XXtAe0g5rTslRiw
+Gm/7/p0+QLlx3T+on9WfXVnxgSxVxur3xiSFjNp4fl/NqI0MSnbRg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0c3cxQkVmTGpWMlR0QnBD
clFNbktaTjg5UUFabDFyRUNOZlFNQUZiaDJzClJWM0hycDl3RmM3cjNGMm10SlJ1
U3FKUmw0R3N5aHkzeXhkKzdySW5RZzgKLS0tIDh0RzNtNmRmU3FBNXRyeFdKaWJu
aGt5K1hoaEIwNXdJTW01TldSb2JFUjgKkyah1P6De1pBRLobnYB8lMj1sRaMsx5D
RIGn9Tws5Kj+VsgGenm24mMnLO48b4s+Y2XX8clydNaVB/Jf7B4d4A==
-----END AGE ENCRYPTED FILE-----
- recipient: age1kf93dpuqhu0a90s49sszgw64mn32hwgrm8suv799ca4ngrkecpqs8ljzk8
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhUHliOXhKcFBMY1ZyeHZa
MHJUblRhMlBabFlRSlVHZmgrd0hZYWFPcWhBCnRxa2lBQk81NG9DMkQySHdhUGZk
Skc2ZEZ0bVdUNlVBUEJ6SXIyaDJuV0UKLS0tIHpMRWY2ZURBbEs0WlVZV0ZkTnZC
NGFpK3RTZ0FEc05TVkJHNlVKbzZUbTgKM1kbK9d8apdQf80tREKBfv6Sm6q9Dv0N
WWtZJOyxEldsTyF0cBiK15e8dOu/195x2Z7gbr4gECRNZg/huKHFYg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvOTZQdyswVUt6Vi9yejlF
Z3I0VEcrdmVFbjFBSlJ5bHZWaVp0R2U5c0dnCkJFNVM5MVRrM3NXQ3JQTzFib3k4
eTA2cTg2UFZGWkV6OVpSVWMxQ1IzNE0KLS0tIEc5SzlhRXVzQWlGd0l6ckJ4WmJO
L1QvTjhTWE1QNmswemRhVkczSnZEeFkKpeBTGWFl2rkNkR5tG3mo18WFkVZP/vwj
q/xKcMB/5lenIyYAfTlWWE84kWkt0Gx+spWFUqMqoE9805CyF6V/Ew==
-----END AGE ENCRYPTED FILE-----
- recipient: age1p3uxpjku9fkyvav56fgmq2cem50wg2dh34hdpp5nzqs6cerandaqvkrgxr
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwdkhUbnV4VFphSEFrdm8w
d1A0K0x2RGlKZVNHUllZQ1Z0UlFNOFhHTEdnClhkM2RVdE1hMDhSeG93WEs2MHRi
Vk5CcmZCOTFzYmdSdXNNZFZDT3RqaTgKLS0tIGlhdndIcXUzbUhxWEZVUVVxM0Rn
dFZ3T3VUeHVnVThadHVQaVJCNkdZeDQK99L7CbBbklUUtanyFIOiCzO3hZP1mh3z
ZZhhr6BCcHBbqzLaRLbT27BTCoNuGsXxyzW6tpXYacYuITkcFq9bOQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBVmd3UlhXV3U2aGdlanVu
bVBtMWxSNlNZVCs3SkhUQjlydU1JaThhMHdFCmlSR1cyWVJ0dGFuRTBMSUxqRjU1
cE90NkFlTVJ4TjFnK1J0dkR5ZEhxMGsKLS0tIGJ3akZNL2txVGFqVEZxM2wwNnNy
ODk5Rm43TmRJd3NQZUFrLzFZcyttNEUKYRsuDmk9u7GnJIM/8PphpyW0ydIud9JK
7R5Rg5fuqN9NZxZHjv5qW2sWwsP3hBaCAT6RqlYEULj03b+5y+s4Hg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-17T09:44:56Z"
mac: ENC[AES256_GCM,data:MX3xARncq/j17K5gtmGRi9E4LEOFDeoinahJ0o0AxECjdQYUndtlIMe+0/BfL2GIemhNaiHsQydjE4TrORgl/RGMcHj/gYy9EvY/m0E7gtSoWpxN5FOdavCQ4jcgRRxYj1mDdTuaS7VksWd+9XZMJh7ScmHlMI8PWdnTessd6Mk=,iv:GxuMN1Vt2fEBs/WrD4BvJlUIiGiHppZfzHU8NRB/4DA=,tag:OnHU8MnyLtclBCWKwribAQ==,type:str]
- recipient: age1cf97rf4gq7qad0rd5dcdtel2qq7uqcxvd7dpk257e3e0e0krv9esd7sc0d
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2RnE5eng3aG1PY1ZNRnJJ
SUlpbDA1eXI3VTJoUEFVRnpPTGxjanh3M2pnClI0TzVmN3ZXTkxqb2piVDJjRjRP
V2lJeGVMVXFVd1lCVVdIQlpmOGRZbVUKLS0tIHhrODBOTlpuOFptbzB5YU9BSlV0
WnpOSEZhNG1MZ2ZhelN5d2grSVl0L1kKt8fWIXZMeQMXaD3WT6joRa0YEmjHc4FU
IIge9bmr548WkDDq7uu0fbhgimiqRdjt0KxG0NnwlWm5MzpTOaYlQw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-04-20T09:24:02Z"
mac: ENC[AES256_GCM,data:7JvoexmSi2+yUxXMZljxwSoekxgPgEJtq21yVfkm5PO6+IvbrVD0fiKzcup7N8G9prgBUPYPvQV69eF6zxMz/zg58FdFKZ8HejNCUGrEeQ9lNXgqy6llSSDd7hj7b/e2OEo0zKLPA4s5ZmqXtE/G/Fa1V9kF0xMOwhkHWvHL++k=,iv:9tNusL5mmHrJC2Rif79JVf5V9TawXul02gLPl2IchMo=,tag:xfpzVqIKc+BVFGPKl8ickQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.12.0
version: 3.12.2