Conversation
Flake lock file updates:
• Updated input 'chaotic':
'github:chaotic-cx/nyx/4a5332e5a4eba9eac822b660c8c6acadc9501b48?narHash=sha256-qHwmBOx6RATjYkdoVzf%2BLN55DTBCAarTjs2ANNs7yzA%3D' (2025-08-26)
→ 'github:chaotic-cx/nyx/9e9e58125b4ba190658235106858f9733b25a1b4?narHash=sha256-lcHMwq0LVcS1mP9o0pq00Von8PsXMsFPPo3ZXGWa7DU%3D' (2025-08-31)
• Updated input 'chaotic/home-manager':
'github:nix-community/home-manager/9e3a33c0bcbc25619e540b9dfea372282f8a9740?narHash=sha256-J1i35r4HfNDdPpwL0vOBaZopQudAUVtartEerc1Jryc%3D' (2025-08-24)
→ 'github:nix-community/home-manager/77f348da3176dc68b20a73dab94852a417daf361?narHash=sha256-eiy0klFK5EVJLNilutR7grsZN/7Itj9DyD75eyOf83k%3D' (2025-08-27)
• Updated input 'chaotic/jovian':
'github:Jovian-Experiments/Jovian-NixOS/bcad5af8eb475df936f6cf2d04b076dc6784af95?narHash=sha256-j8ghatY34DbEnHe42r8VtAe05WyMUK%2Bd66uGKsfLbbk%3D' (2025-08-23)
→ 'github:Jovian-Experiments/Jovian-NixOS/9f6745bd704ab7f2617d41c2b02f4fd5f9ed0e89?narHash=sha256-bK5j5cwJgO5AZXlDl5AgISzpOv9YV1Fcv2nDr9RW/5o%3D' (2025-08-26)
• Updated input 'chaotic/nixpkgs':
'github:NixOS/nixpkgs/20075955deac2583bb12f07151c2df830ef346b4?narHash=sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs%2BStOp19xNsbqdOg%3D' (2025-08-19)
→ 'github:NixOS/nixpkgs/d7600c775f877cd87b4f5a831c28aa94137377aa?narHash=sha256-tlOn88coG5fzdyqz6R93SQL5Gpq%2Bm/DsWpekNFhqPQk%3D' (2025-08-30)
• Updated input 'chaotic/rust-overlay':
'github:oxalica/rust-overlay/88ceedecde53e809b4bf8b5fd10d181889d9bac7?narHash=sha256-lmEMhIIbjt8Wp1EYbNqCojuU9ygyDFv8Tu0X1k8qIMc%3D' (2025-08-24)
→ 'github:oxalica/rust-overlay/86e5140961c91a9ee1dde1c17d18a787d44ceef8?narHash=sha256-5UJRyxZ8QCm%2Bpgh5pNHXFJMmopMqHVraUhRA1g2AmA0%3D' (2025-08-29)
• Updated input 'hydenix':
'github:richen604/hydenix/9836f27996b1eee38a6da3a04ad783943941bbce?narHash=sha256-t6M3TU5%2B4ZzqUSEk%2BKBv0mREtQ3UiR933YNRkDMHWBM%3D' (2025-08-23)
→ 'github:richen604/hydenix/5f57152efaadcef47f7998fc56728783eaf1166e?narHash=sha256-4k6ImV1a4LItXdNfkgbh/Vj5gkBEUEvrhn2M5zKGEZ0%3D' (2025-08-28)
• Updated input 'hydenix/home-manager':
'github:nix-community/home-manager/c5d7e957397ecb7d48b99c928611c6e780db1b56?narHash=sha256-NLWIkn1qM0wxtZu/2NXRaujWJ4Y1PSZlc7h0y6pOzOQ%3D' (2025-08-05)
→ 'github:nix-community/home-manager/77f348da3176dc68b20a73dab94852a417daf361?narHash=sha256-eiy0klFK5EVJLNilutR7grsZN/7Itj9DyD75eyOf83k%3D' (2025-08-27)
• Added input 'hydenix/hyde-config':
'github:richen604/hyde-config/59dc0659e0cfb72552616553f5b2635cf40c2184?narHash=sha256-kn35QcO7OxZxcYyaZNxQ4tBsLdeSi1u2kbWdPg/pky0%3D' (2025-08-11)
• Added input 'hydenix/hyde-config/nixpkgs':
follows 'hydenix/hydenix-nixpkgs'
• Added input 'hydenix/hyde-ipc':
'github:richen604/hyde-ipc/016b6e7bd5959a18c2cefeb4a952098468f6bb8f?narHash=sha256-TsiA83Gd16VfIMatHa6o56Rvf7Vi2Lr/9ch9T6%2Bn/qg%3D' (2025-08-11)
• Added input 'hydenix/hyde-ipc/nixpkgs':
follows 'hydenix/hydenix-nixpkgs'
• Added input 'hydenix/hyde-ipc/rust-overlay':
'github:oxalica/rust-overlay/17c591a44e4eb77f05f27cd37e1cfc3f219c7fc4?narHash=sha256-tG6l0wiX8V8IvG4HFYY8IYN5vpNAxQ%2BUWunjjpE6SqU%3D' (2025-08-11)
• Added input 'hydenix/hyde-ipc/rust-overlay/nixpkgs':
'github:NixOS/nixpkgs/18dd725c29603f582cf1900e0d25f9f1063dbf11?narHash=sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38%3D' (2025-04-13)
• Added input 'hydenix/hydectl':
'github:richen604/hydectl/a19610347de2230175e5d8807584db65d0588134?narHash=sha256-TVLjDL4%2BSdoXJrNu5TLiUSDD73CdVWfAn3aE2c4aShg%3D' (2025-08-13)
• Added input 'hydenix/hydectl/nixpkgs':
follows 'hydenix/hydenix-nixpkgs'
• Updated input 'hydenix/hydenix-nixpkgs':
'github:nixos/nixpkgs/c539ae8d21e49776966d714f82fba33b1fca78bc?narHash=sha256-zcGClfkXh4pckf4aGOZ18GFv73n1xHbdMWl17cPLouE%3D' (2025-06-17)
→ 'github:nixos/nixpkgs/ddd1826f294a0ee5fdc198ab72c8306a0ea73aa9?narHash=sha256-Om8adB1lfkU7D33VpR%2B/haZ2gI5r3Q%2BZbIPzE5sYnwE%3D' (2025-08-27)
• Removed input 'hydenix/hypridle'
• Removed input 'hydenix/hypridle/hyprland-protocols'
• Removed input 'hydenix/hypridle/hyprland-protocols/nixpkgs'
• Removed input 'hydenix/hypridle/hyprland-protocols/systems'
• Removed input 'hydenix/hypridle/hyprlang'
• Removed input 'hydenix/hypridle/hyprlang/hyprutils'
• Removed input 'hydenix/hypridle/hyprlang/nixpkgs'
• Removed input 'hydenix/hypridle/hyprlang/systems'
• Removed input 'hydenix/hypridle/hyprutils'
• Removed input 'hydenix/hypridle/hyprutils/nixpkgs'
• Removed input 'hydenix/hypridle/hyprutils/systems'
• Removed input 'hydenix/hypridle/hyprwayland-scanner'
• Removed input 'hydenix/hypridle/hyprwayland-scanner/nixpkgs'
• Removed input 'hydenix/hypridle/hyprwayland-scanner/systems'
• Removed input 'hydenix/hypridle/nixpkgs'
• Removed input 'hydenix/hypridle/systems'
• Removed input 'hydenix/hyprland'
• Removed input 'hydenix/hyprland/aquamarine'
• Removed input 'hydenix/hyprland/aquamarine/hyprutils'
• Removed input 'hydenix/hyprland/aquamarine/hyprwayland-scanner'
• Removed input 'hydenix/hyprland/aquamarine/nixpkgs'
• Removed input 'hydenix/hyprland/aquamarine/systems'
• Removed input 'hydenix/hyprland/hyprcursor'
• Removed input 'hydenix/hyprland/hyprcursor/hyprlang'
• Removed input 'hydenix/hyprland/hyprcursor/nixpkgs'
• Removed input 'hydenix/hyprland/hyprcursor/systems'
• Removed input 'hydenix/hyprland/hyprgraphics'
• Removed input 'hydenix/hyprland/hyprgraphics/hyprutils'
• Removed input 'hydenix/hyprland/hyprgraphics/nixpkgs'
• Removed input 'hydenix/hyprland/hyprgraphics/systems'
• Removed input 'hydenix/hyprland/hyprland-protocols'
• Removed input 'hydenix/hyprland/hyprland-protocols/nixpkgs'
• Removed input 'hydenix/hyprland/hyprland-protocols/systems'
• Removed input 'hydenix/hyprland/hyprland-qtutils'
• Removed input 'hydenix/hyprland/hyprland-qtutils/hyprland-qt-support'
• Removed input 'hydenix/hyprland/hyprland-qtutils/hyprland-qt-support/hyprlang'
• Removed input 'hydenix/hyprland/hyprland-qtutils/hyprland-qt-support/nixpkgs'
• Removed input 'hydenix/hyprland/hyprland-qtutils/hyprland-qt-support/systems'
• Removed input 'hydenix/hyprland/hyprland-qtutils/hyprlang'
• Removed input 'hydenix/hyprland/hyprland-qtutils/hyprutils'
• Removed input 'hydenix/hyprland/hyprland-qtutils/nixpkgs'
• Removed input 'hydenix/hyprland/hyprland-qtutils/systems'
• Removed input 'hydenix/hyprland/hyprlang'
• Removed input 'hydenix/hyprland/hyprlang/hyprutils'
• Removed input 'hydenix/hyprland/hyprlang/nixpkgs'
• Removed input 'hydenix/hyprland/hyprlang/systems'
• Removed input 'hydenix/hyprland/hyprutils'
• Removed input 'hydenix/hyprland/hyprutils/nixpkgs'
• Removed input 'hydenix/hyprland/hyprutils/systems'
• Removed input 'hydenix/hyprland/hyprwayland-scanner'
• Removed input 'hydenix/hyprland/hyprwayland-scanner/nixpkgs'
• Removed input 'hydenix/hyprland/hyprwayland-scanner/systems'
• Removed input 'hydenix/hyprland/nixpkgs'
• Removed input 'hydenix/hyprland/pre-commit-hooks'
• Removed input 'hydenix/hyprland/pre-commit-hooks/flake-compat'
• Removed input 'hydenix/hyprland/pre-commit-hooks/gitignore'
• Removed input 'hydenix/hyprland/pre-commit-hooks/gitignore/nixpkgs'
• Removed input 'hydenix/hyprland/pre-commit-hooks/nixpkgs'
• Removed input 'hydenix/hyprland/systems'
• Removed input 'hydenix/hyprland/xdph'
• Removed input 'hydenix/hyprland/xdph/hyprland-protocols'
• Removed input 'hydenix/hyprland/xdph/hyprlang'
• Removed input 'hydenix/hyprland/xdph/hyprutils'
• Removed input 'hydenix/hyprland/xdph/hyprwayland-scanner'
• Removed input 'hydenix/hyprland/xdph/nixpkgs'
• Removed input 'hydenix/hyprland/xdph/systems'
• Added input 'hydenix/hyq':
'github:richen604/hyprquery/afe6da39cf94f3e24dcfd13abf88da6ea5d661ac?narHash=sha256-2G8YwNzELvklrYftaRAzNLZ2AbDtIrWzgRgnhReNnuk%3D' (2025-08-28)
• Added input 'hydenix/hyq/flake-utils':
'github:numtide/flake-utils/11707dc2f618dd54ca8739b309ec4fc024de578b?narHash=sha256-l0KFg5HjrsfsO/JpG%2Br7fRrqm12kzFHyUHqHCVpMMbI%3D' (2024-11-13)
• Added input 'hydenix/hyq/flake-utils/systems':
'github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e?narHash=sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768%3D' (2023-04-09)
• Added input 'hydenix/hyq/nixpkgs':
follows 'hydenix/hydenix-nixpkgs'
• Updated input 'hydenix/nix-index-database':
'github:nix-community/nix-index-database/b7fcd4e26d67fca48e77de9b0d0f954b18ae9562?narHash=sha256-YL71IEf2OugH3gmAsxQox6BJI0KOcHKtW2QqT/%2Bs2SA%3D' (2025-08-03)
→ 'github:nix-community/nix-index-database/52dec1cb33a614accb9e01307e17816be974d24d?narHash=sha256-rfTBWuTXi9/X7GhtF562FKNXKh2kvKb6dwI5lV1SjPE%3D' (2025-08-24)
• Updated input 'hydenix/nixos-hardware':
'github:NixOS/nixos-hardware/9368056b73efb46eb14fd4667b99e0f81b805f28?narHash=sha256-Ry1gd1BQrNVJJfT11cpVP0FY8XFMx4DJV2IDp01CH9w%3D' (2025-08-04)
→ 'github:NixOS/nixos-hardware/a65b650d6981e23edd1afa1f01eb942f19cdcbb7?narHash=sha256-9bHzrVbjAudbO8q4vYFBWlEkDam31fsz0J7GB8k4AsI%3D' (2025-08-26)
• Updated input 'nix-darwin/nixpkgs':
'github:NixOS/nixpkgs/84c256e42600cb0fdf25763b48d28df2f25a0c8b?narHash=sha256-ohMvsjtSVdT/bruXf5ClBh8ZYXRmD4krmjKrXhEvwMg%3D' (2025-08-25)
→ 'github:NixOS/nixpkgs/2f9173bde1d3fbf1ad26ff6d52f952f9e9da52ea?narHash=sha256-NnXFQu7g4LnvPIPfJmBuZF7LFy/fey2g2%2BLCzjQhTUk%3D' (2025-05-20)
• Updated input 'nix-gaming':
'github:fufexan/nix-gaming/00beb5274d213427a78794f719ed9e7505b091ec?narHash=sha256-gAdXP1w5ADA9ekT/gVCQMrGxLDVPKjfiMaoUT7xx4gY%3D' (2025-08-26)
→ 'github:fufexan/nix-gaming/4c92760b8d12d0d36e8e189d890d1c01a7ae646e?narHash=sha256-qLvZwPsuUUL2B/yqFJBeWmz6fdsloQyMAWK/6dYDXMU%3D' (2025-08-31)
• Updated input 'nix-gaming/nixpkgs':
'github:NixOS/nixpkgs/f937f8ecd1c70efd7e9f90ba13dfb400cf559de4?narHash=sha256-4/Jd%2BLkQ2ssw8luQVkqVs9spDBVE6h/u/hC/tzngsPo%3D' (2025-08-22)
→ 'github:NixOS/nixpkgs/a918bb3594dd243c2f8534b3be01b3cb4ed35fd1?narHash=sha256-ynQxPVN2FIPheUgTFhv01gYLbaiSOS7NgWJPm9LF9D0%3D' (2025-08-30)
• Updated input 'nix-index-database':
'github:nix-community/nix-index-database/52dec1cb33a614accb9e01307e17816be974d24d?narHash=sha256-rfTBWuTXi9/X7GhtF562FKNXKh2kvKb6dwI5lV1SjPE%3D' (2025-08-24)
→ 'github:nix-community/nix-index-database/3fe768e1f058961095b4a0d7a2ba15dc9736bdc6?narHash=sha256-/glV6VAq8Va3ghIbmhET3S1dzkbZqicsk5h%2BFtvwiPE%3D' (2025-08-31)
• Updated input 'nix-podman-stacks':
'github:Tarow/nix-podman-stacks/f6ca61cf048c97a4ad96f4e5026f0ac25928d751?narHash=sha256-gNOnFFVO7%2BAKFcnygvY8lwbqWegLpb49kZSZyOljBFo%3D' (2025-08-26)
→ 'github:Tarow/nix-podman-stacks/b84320f19bb906644be85aeab717dcf4870df2e6?narHash=sha256-iNfoqZyShPzXcARe6lMXR9OM/b3uykgpEtyD983hH8Q%3D' (2025-08-31)
• Updated input 'nixpkgs':
'github:nixos/nixpkgs/3b9f00d7a7bf68acd4c4abb9d43695afb04e03a5?narHash=sha256-XexyKZpf46cMiO5Vbj%2BdWSAXOnr285GHsMch8FBoHbc%3D' (2025-08-25)
→ 'github:nixos/nixpkgs/d7600c775f877cd87b4f5a831c28aa94137377aa?narHash=sha256-tlOn88coG5fzdyqz6R93SQL5Gpq%2Bm/DsWpekNFhqPQk%3D' (2025-08-30)
• Updated input 'nixpkgs-stable':
'github:nixos/nixpkgs/4a55998176831003c7a4dc14bb47dfb03e46d4cf?narHash=sha256-7SN8kh2y29uMqWfqxoC591nUwDfFitBPwx4AMweo9Yc%3D' (2025-08-27)
→ 'github:nixos/nixpkgs/5eb9271c6e5096d5bb9af338448efc30b11b84f0?narHash=sha256-CxUlNyB2SRKv7Q7vMn1osVk9yqkxehwLvalcO4O/XN8%3D' (2025-08-31)
…dd new modules for hayase, scalar, and wrkflw
- Added image editing support with Krita. - Introduced OpenShot video editor for video editing. - Implemented a multimedia player configuration with support for various clients including MPV, VLC, and Jellyfin. - Added Rambox for organizing web services into workspaces. - Introduced remote desktop client options with Parsec and RustDesk. - Added OBS Studio for video recording and streaming with necessary plugins. - Enhanced the app launcher with Kando and official themes. - Implemented Ianny for break reminders with customizable presets and notifications. - Added power mode toggle script for performance management. - Introduced random theme and wallpaper application on boot. - Updated Hydenix desktop configuration to support new features and validate hostnames. - Added Syncthing and various media services to Cedar host configuration.
…dules for improved functionality
…move obsolete configurations
…ed tasks and add new settings
…and ecosystem; remove obsolete entries
📝 WalkthroughSummary by CodeRabbit
WalkthroughRemoves CI workflows; overhauls flake.nix to a script-driven multi-host deployment and adds a new Cedar host. Broad refactor/renames across Home Manager and system modules, introducing new modules (media servers, utilities, virtualization, safety), deleting legacy ones, updating host configs (oak/pine), and adding scripts and services. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev
participant RB as rb (deploy script)
participant Map as hostConfigs
participant Nix as nixos-rebuild
participant Host as Target Host
Dev->>RB: rb [host|all] [--remote-build|--local-build|--build-host X] [args...]
RB->>Map: resolve target(s)
loop for each target
RB->>Nix: nixos-rebuild --flake .#<host> [args...]
alt remote-build or build-host
Nix->>Host: build/deploy via SSH
else local-build
Nix->>Nix: local build then switch
end
end
RB-->>Dev: exit status per host
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120+ minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Pull Request Overview
This pull request introduces significant organizational restructuring to the modules system, adds new services and packages, and establishes better modularization with improved configuration flexibility. The changes focus on migrating from old naming conventions to a more structured approach, adding several new wrapper packages, and enhancing the server infrastructure with multiple service integrations.
- Restructured module organization with better separation of concerns between dev, server, hardware, and virtualisation components
- Added numerous new service modules for communication, media, storage, and development environments
- Introduced custom package wrappers for applications like Portmaster, Scalar, and Hayase
Reviewed Changes
Copilot reviewed 117 out of 119 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/wrapper/*.nix | New package wrappers for wrkflw, scalar, safing/portmaster, and hayase applications |
| modules/system/hosts/*/default.nix | Updated host configurations to use new module structure and added portmaster service |
| modules/system/hosts/fern/vfio/* | Removed legacy VFIO and virtualization scripts and configurations |
| modules/system/common/server/* | New server modules for communication, media, storage, and development services |
| modules/system/common/virtualisation/* | Restructured virtualization modules with better abstraction |
| modules/system/common/dev/* | Reorganized development modules under languages and tools subdirectories |
| modules/system/common/hardware/powersave/* | Enhanced power management with new benchmark and tuning scripts |
| modules/system/common/*.nix | Updated imports and module structure throughout the common system |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 159
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (17)
modules/system/common/hardware/powersave/default.nix (1)
212-226: TLP and auto-cpufreq conflict; don’t enable both.These tools both manage CPU scaling/governors and will fight. Disable auto-cpufreq by default here.
- services.auto-cpufreq = { - enable = true; + services.auto-cpufreq = { + enable = false;modules/hm/common/games/mangohud.nix (2)
59-59: Avoid null in INI settings; it will fail coercionUse empty string or conditionally include the key; null will error during INI generation.
Minimal fix:
- cpu_text = if cfg.cpu_text != "" then cfg.cpu_text else null; + cpu_text = if cfg.cpu_text != "" then cfg.cpu_text else "";Better (conditional keys):
- settings = { + settings = + { # ...unchanged keys... - cpu_text = if cfg.cpu_text != "" then cfg.cpu_text else null; # ...unchanged keys... - gpu_text = if cfg.gpu_text != "" then cfg.gpu_text else ""; } + // lib.optionalAttrs (cfg.cpu_text != "") { cpu_text = cfg.cpu_text; } + // lib.optionalAttrs (cfg.gpu_text != "") { gpu_text = cfg.gpu_text; };
73-73: Make cpu_text/gpu_text handling consistentBoth should follow the same conditional pattern to avoid surprising config.
Apply the “Better (conditional keys)” approach from the previous comment for both keys.
modules/system/common/dev/environments.nix (1)
21-34: Trim nix-ld libraries to lib outputs to reduce closure sizeSeveral entries (e.g., curl, util-linux) pull bins. Prefer lib.getLib to include only libraries.
- libraries = with pkgs; [ - stdenv.cc.cc - openssl - curl - glib - util-linux - glibc - icu - libunwind - libuuid - zlib - ]; + libraries = with pkgs; [ + (lib.getLib stdenv.cc.cc) + (lib.getLib openssl) + (lib.getLib curl) + (lib.getLib glib) + (lib.getLib util-linux) + glibc + (lib.getLib icu) + (lib.getLib libunwind) + libuuid + (lib.getLib zlib) + ];modules/hm/common/dev/languages/node.nix (1)
64-75: Global installs: ensure the bin dir is on PATH and prefix is honoredCreating the directory isn’t enough. Add PATH entry and NPM_CONFIG_PREFIX.
home.activation = lib.mkIf cfg.allowGlobalInstalls { createNpmGlobalDir = lib.hm.dag.entryAfter ["writeBoundary"] '' mkdir -p "${npmGlobalPath}/bin" ''; }; + home.sessionVariables = lib.mkIf cfg.allowGlobalInstalls { + NPM_CONFIG_PREFIX = npmGlobalPath; + }; + home.sessionPath = lib.mkIf cfg.allowGlobalInstalls [ "${npmGlobalPath}/bin" ];Also applies to: 54-58
modules/hm/common/dev/languages/python.nix (1)
10-12: Dynamic attribute access is invalid; use builtins.getAttr
pkgs.${pythonAttr}andpythonPkgs.${pkg}won’t evaluate. Usebuiltins.getAttr:- pythonPkg = pkgs.${pythonAttr}; + pythonPkg = builtins.getAttr pythonAttr pkgs; pythonPkgsAttr = "${pythonAttr}Packages"; - pythonPkgs = pkgs.${pythonPkgsAttr}; + pythonPkgs = builtins.getAttr pythonPkgsAttr pkgs; @@ - extraPkgsMapped = map (pkg: pythonPkgs.${pkg}) cfg.extraPackages; + extraPkgsMapped = map (pkgName: builtins.getAttr pkgName pythonPkgs) cfg.extraPackages;Also applies to: 15-16
modules/hm/common/network/tunnel.nix (5)
39-43: Fix Home Manager file option misuse (target.recursive is invalid).
home.filedoes not supporttarget.recursive. Userecursive(top-level) and set a strict mode for secrets.Apply:
home.file.".cloudflared/token" = { source = cfg.cloudflare.tokenPath; - target.recursive = true; + # token is a single file; no recursion needed + mode = "0600"; };
46-50: Same HM option bug for ngrok config.
target.recursiveshould berecursive(or omitted if sourcing a file).Apply:
home.file.".config/ngrok/ngrok.yml" = { source = cfg.ngrok.configPath; - target.recursive = true; + # config is a file; recursion not needed + # recursive = false; # optional (default) };
16-18: Avoid npx; call the packaged binary directly.
nodePackages.localtunnelinstalls a CLI; relying onnpximplicitly requires npm/node on PATH.Use the installed binary:
localtunnel = { - ltn = "npx localtunnel --port ${toString cfg.localtunnel.port}"; - ltn-custom = "npx localtunnel --port"; + ltn = "localtunnel --port ${toString cfg.localtunnel.port}"; + ltn-custom = "localtunnel --port"; };If the binary name is
ltin your channel, switch toltaccordingly.
20-21: Cloudflared alias likely non-functional.
cloudflared tunnel --config <file>alone won’t run a tunnel. Typically you needrun,create, or--url.Prefer:
- cft = "cloudflared tunnel --config ${cfg.cloudflare.configPath}"; + cft = "cloudflared --config ${cfg.cloudflare.configPath} tunnel run";Optionally add a second alias for ad-hoc:
cloudflared tunnel --url http://localhost:${toString cfg.localtunnel.port}.
37-43: Harden token handling.Set restrictive perms and avoid copying secrets into the store (already OK since
sourcepoints to a file on disk). Ensure the token path exists and is readable.Add a mode and an assertion:
cloudflareTokenConfig = lib.mkIf (builtins.elem "cloudflare" cfg.services && cfg.cloudflare.tokenPath != null) { home.sessionVariables.CLOUDFLARE_TOKEN_FILE = cfg.cloudflare.tokenPath; home.file.".cloudflared/token" = { source = cfg.cloudflare.tokenPath; + mode = "0600"; }; + assertions = [{ + assertion = builtins.pathExists cfg.cloudflare.tokenPath; + message = "CLOUDFLARE tokenPath does not exist: ${cfg.cloudflare.tokenPath}"; + }]; };modules/hm/common/dev/tools/cli.nix (1)
13-15: Slight simplification.Use
lib.mapAttrsToList+builtins.elemto avoid building nulls.Example:
cliPackages = map (tool: cliToPackage.${tool}) (builtins.filter (t: builtins.hasAttr t cliToPackage) cfg.cli);modules/hm/common/dev/tools/nix.nix (1)
22-28: Prefer HM’s nix-index integration over manual sourcing.Manual
source ${pkgs.nix-index}/etc/profile.d/command-not-found.shis brittle; use first-class options.Apply:
- programs.direnv = { + programs.direnv = { enable = true; silent = true; nix-direnv.enable = true; enableZshIntegration = true; }; - - programs.zsh = { - initExtra = lib.mkAfter '' - source ${pkgs.nix-index}/etc/profile.d/command-not-found.sh - ''; - }; + programs.nix-index = { + enable = true; + enableZshIntegration = true; + };modules/system/common/server/storage/syncthing.nix (3)
40-41: Do not use lib.cleanSource for runtime dataDir; points into the Nix store.
lib.cleanSourceproduces a store path and is wrong for Syncthing’s mutable data. Use the real filesystem path.Apply:
- dataDir = lib.cleanSource "${cfg.dirSync}/${cfg.subDir}"; # default location for new folders + dataDir = "${cfg.dirSync}/${cfg.subDir}"; # default location for new folders
22-32: Unsafe defaults for dirSync/subDir.
dirSync = "/"risks writing config under/.config/syncthingand defaulting data to/. Set a sane user-scoped default and guard against/.Apply:
- dirSync = lib.mkOption { + dirSync = lib.mkOption { type = lib.types.str; - default = "/"; + default = "/home/${vars.user}"; description = "Directory containing sync principal"; }; @@ - subDir = lib.mkOption { + subDir = lib.mkOption { type = lib.types.str; default = ""; description = "Directory containing sync sub"; };Add assertion:
assertions = [{ assertion = cfg.dirSync != "/"; message = "syncthing.dirSync must not be '/'"; }];
45-54: Overriding systemd service directly may fight the module.Prefer
services.syncthing.*options unless a specific unit knob is missing.Drop the
systemd.services.syncthingblock unless you need non-default restart behavior.flake.nix (1)
55-59: Unused binding (isoConfig).
isoConfigis defined but never used. Remove or expose it underpackages.${system}(e.g.,installer-iso).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
flake.lockis excluded by!**/*.lock
📒 Files selected for processing (107)
.github/workflows/flake-check.yml(0 hunks).github/workflows/lint-commits.yml(0 hunks)TODO.md(1 hunks)flake.nix(2 hunks)hosts/cedar/default.nix(1 hunks)hosts/cedar/hardware-configuration.nix(1 hunks)hosts/oak/default.nix(6 hunks)hosts/oak/hardware-configuration.nix(2 hunks)hosts/pine/default.nix(3 hunks)hosts/pine/hardware-configuration.nix(1 hunks)info.txt(1 hunks)modules/hm/common/communication/mail.nix(2 hunks)modules/hm/common/communication/mail/bluemail.nix(0 hunks)modules/hm/common/communication/matrix.nix(1 hunks)modules/hm/common/default.nix(1 hunks)modules/hm/common/dev/editor/android-studio.nix(0 hunks)modules/hm/common/dev/editor/dbeaver.nix(0 hunks)modules/hm/common/dev/editor/jetbrains.nix(0 hunks)modules/hm/common/dev/editor/vs-code.nix(0 hunks)modules/hm/common/dev/environments/containers.nix(1 hunks)modules/hm/common/dev/environments/editor.nix(1 hunks)modules/hm/common/dev/global-tools/act-github.nix(0 hunks)modules/hm/common/dev/languages/dotnet.nix(2 hunks)modules/hm/common/dev/languages/node.nix(3 hunks)modules/hm/common/dev/languages/python.nix(4 hunks)modules/hm/common/dev/languages/rust.nix(2 hunks)modules/hm/common/dev/node/pm2.nix(0 hunks)modules/hm/common/dev/tools/cli.nix(2 hunks)modules/hm/common/dev/tools/git-action.nix(1 hunks)modules/hm/common/dev/tools/gitleaks.nix(1 hunks)modules/hm/common/dev/tools/nix.nix(1 hunks)modules/hm/common/dev/tools/prisma.nix(1 hunks)modules/hm/common/documentation/default.nix(2 hunks)modules/hm/common/documentation/obsidian.nix(3 hunks)modules/hm/common/emulator/default.nix(0 hunks)modules/hm/common/extra/ignore-file-retriever.nix(0 hunks)modules/hm/common/extra/shader-cache-cleanup.nix(1 hunks)modules/hm/common/extra/syncthing-ignore.nix(1 hunks)modules/hm/common/games/games.nix(2 hunks)modules/hm/common/games/mangohud.nix(1 hunks)modules/hm/common/multimedia/editing/image.nix(1 hunks)modules/hm/common/multimedia/editing/video.nix(1 hunks)modules/hm/common/multimedia/gimp.nix(0 hunks)modules/hm/common/multimedia/mpv.nix(0 hunks)modules/hm/common/multimedia/parsec.nix(0 hunks)modules/hm/common/multimedia/player.nix(1 hunks)modules/hm/common/multimedia/rambox.nix(1 hunks)modules/hm/common/multimedia/remote-desktop.nix(1 hunks)modules/hm/common/multimedia/stremio.nix(0 hunks)modules/hm/common/network/tunnel.nix(1 hunks)modules/hm/common/shell/btop.nix(0 hunks)modules/hm/common/shell/disk-usage.nix(0 hunks)modules/hm/common/shell/fzf.nix(0 hunks)modules/hm/common/shell/navi.nix(0 hunks)modules/hm/common/shell/ranger.nix(0 hunks)modules/hm/common/shell/starship.nix(0 hunks)modules/hm/common/shell/tools.nix(1 hunks)modules/hm/common/utilities/app-launcher.nix(1 hunks)modules/hm/common/utilities/safety/config.json(1 hunks)modules/hm/common/utilities/safety/ianny.nix(1 hunks)modules/hm/common/utilities/scalar.nix(1 hunks)modules/hm/desktops/configHydenix.nix(2 hunks)modules/hm/desktops/hydenix.nix(4 hunks)modules/hm/desktops/powermode-toggle.sh(1 hunks)modules/hm/desktops/random-theme.sh(1 hunks)modules/hm/hosts/cedar/default.nix(1 hunks)modules/hm/hosts/oak/default.nix(1 hunks)modules/system/common/default.nix(1 hunks)modules/system/common/dev/environments.nix(1 hunks)modules/system/common/dev/languages/flutter.nix(3 hunks)modules/system/common/dev/languages/php.nix(1 hunks)modules/system/common/dev/tools/flatpak.nix(1 hunks)modules/system/common/games.nix(2 hunks)modules/system/common/hardware/powersave/default.nix(9 hunks)modules/system/common/hardware/powersave/power-benchmark.sh(1 hunks)modules/system/common/hardware/powersave/power-tuning.sh(1 hunks)modules/system/common/networks/print/print.nix(0 hunks)modules/system/common/networks/vpn.nix(1 hunks)modules/system/common/nix/default.nix(1 hunks)modules/system/common/nix/nix-garbage.nix(2 hunks)modules/system/common/nix/polkit.nix(2 hunks)modules/system/common/server/communication/agents.nix(1 hunks)modules/system/common/server/communication/deskflow.nix(1 hunks)modules/system/common/server/communication/matrix.nix(1 hunks)modules/system/common/server/communication/ntfy-sh.nix(1 hunks)modules/system/common/server/dev/vs-code.nix(1 hunks)modules/system/common/server/games/sunshine.nix(1 hunks)modules/system/common/server/meal.nix(1 hunks)modules/system/common/server/media/multimedia.nix(1 hunks)modules/system/common/server/media/paperless.nix(1 hunks)modules/system/common/server/media/photoprism.nix(1 hunks)modules/system/common/server/password-manager/vaultwarden.nix(1 hunks)modules/system/common/server/print.nix(1 hunks)modules/system/common/server/storage/gitea.nix(1 hunks)modules/system/common/server/storage/syncthing.nix(1 hunks)modules/system/common/virtualisation/containers.nix(0 hunks)modules/system/common/virtualisation/default.nix(1 hunks)modules/system/common/virtualisation/ollama.nix(1 hunks)modules/system/hosts/cedar/default.nix(1 hunks)modules/system/hosts/fern/default.nix(0 hunks)modules/system/hosts/fern/plex.nix(0 hunks)modules/system/hosts/fern/sunshine.nix(0 hunks)modules/system/hosts/fern/vfio/default.nix(0 hunks)modules/system/hosts/fern/vfio/scripts/99-vendor-reset.rules(0 hunks)modules/system/hosts/fern/vfio/scripts/lg.sh(0 hunks)modules/system/hosts/fern/vfio/scripts/rdp.sh(0 hunks)modules/system/hosts/fern/vfio/scripts/start-vfio.sh(0 hunks)
⛔ Files not processed due to max files limit (10)
- modules/system/hosts/fern/vfio/scripts/stop-vfio.sh
- modules/system/hosts/fern/vfio/scripts/vfio.sh
- modules/system/hosts/fern/vfio/scripts/vm.sh
- modules/system/hosts/fern/vfio/scripts/win11.xml
- modules/system/hosts/oak/default.nix
- modules/wrapper/hayase.nix
- modules/wrapper/safing/module.nix
- modules/wrapper/safing/package.nix
- modules/wrapper/scalar.nix
- modules/wrapper/wrkflw.nix
💤 Files with no reviewable changes (31)
- modules/hm/common/dev/editor/dbeaver.nix
- modules/system/hosts/fern/vfio/scripts/rdp.sh
- .github/workflows/flake-check.yml
- modules/hm/common/shell/navi.nix
- modules/hm/common/multimedia/mpv.nix
- modules/system/hosts/fern/vfio/scripts/lg.sh
- modules/hm/common/dev/editor/vs-code.nix
- modules/system/hosts/fern/plex.nix
- modules/hm/common/multimedia/gimp.nix
- modules/hm/common/shell/starship.nix
- modules/system/common/networks/print/print.nix
- modules/hm/common/shell/btop.nix
- modules/hm/common/communication/mail/bluemail.nix
- modules/hm/common/multimedia/stremio.nix
- modules/system/hosts/fern/vfio/scripts/start-vfio.sh
- .github/workflows/lint-commits.yml
- modules/hm/common/dev/editor/android-studio.nix
- modules/hm/common/dev/editor/jetbrains.nix
- modules/hm/common/dev/global-tools/act-github.nix
- modules/system/hosts/fern/vfio/scripts/99-vendor-reset.rules
- modules/system/hosts/fern/default.nix
- modules/hm/common/dev/node/pm2.nix
- modules/hm/common/shell/disk-usage.nix
- modules/hm/common/emulator/default.nix
- modules/hm/common/shell/fzf.nix
- modules/hm/common/shell/ranger.nix
- modules/system/common/virtualisation/containers.nix
- modules/hm/common/multimedia/parsec.nix
- modules/hm/common/extra/ignore-file-retriever.nix
- modules/system/hosts/fern/sunshine.nix
- modules/system/hosts/fern/vfio/default.nix
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-05-27T21:08:03.407Z
Learnt from: ClementBobin
PR: ClementBobin/flakeHypr#2
File: modules/hm/common/dev/python.nix:141-142
Timestamp: 2025-05-27T21:08:03.407Z
Learning: In modules/hm/common/dev/python.nix, using both `force = true` and `mutable = true` for shell.nix files is intentional - it creates a pattern where the template is regenerated from config on each activation (force) but allows temporary user modifications between activations (mutable).
Applied to files:
modules/hm/common/games/mangohud.nixmodules/hm/hosts/oak/default.nix
🧬 Code graph analysis (2)
modules/system/common/hardware/powersave/power-tuning.sh (1)
modules/system/common/hardware/powersave/power-benchmark.sh (3)
log(14-16)show_help(182-202)main(204-239)
modules/system/common/hardware/powersave/power-benchmark.sh (1)
modules/system/common/hardware/powersave/power-tuning.sh (3)
log(11-13)show_help(247-281)main(283-323)
🪛 Shellcheck (0.10.0)
modules/hm/desktops/random-theme.sh
[warning] 33-33: SPECIFIED_THEME appears unused. Verify use (or export if used externally).
(SC2034)
modules/system/common/hardware/powersave/power-tuning.sh
[warning] 31-31: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 32-32: Declare and assign separately to avoid masking return values.
(SC2155)
[style] 107-107: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
(SC2002)
[warning] 133-133: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 138-138: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 157-157: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 240-240: Declare and assign separately to avoid masking return values.
(SC2155)
modules/system/common/hardware/powersave/power-benchmark.sh
[warning] 42-42: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 43-43: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 79-79: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 111-111: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 112-112: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 113-113: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 129-129: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 130-130: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 131-131: Declare and assign separately to avoid masking return values.
(SC2155)
🔇 Additional comments (86)
modules/hm/common/shell/tools.nix (3)
31-46: btop settings look correct and map to upstream config keys.The chosen defaults are sensible; no issues spotted.
19-23: programs.navi.enableZshIntegration is a valid option; snippet is correct.
17-47: No duplicate program configurations detected; consolidation is safe.modules/hm/common/utilities/scalar.nix (1)
7-7: Preferpkgs.callPackageand drop unusedconfigarg
modules/wrapper/scalar.nixexportsscalarApp = scalar-appand contains no use ofconfig→ removeconfigfrom the import.- Switch to dependency injection via
callPackagefor clarity:scalarApp = pkgs.callPackage ../../../wrapper/scalar.nix { inherit lib; }modules/system/common/server/password-manager/vaultwarden.nix (1)
1-10: LGTM: module skeleton and option wiring are sound.The
cfgbinding and the mapping intoservices.vaultwardenfollow a clear, consistent pattern.modules/hm/common/dev/environments/editor.nix (2)
61-64: Unfree allowance already configured
allowUnfree = trueis set in each host’s config (hosts/pine/default.nix, hosts/cedar/default.nix, hosts/oak/default.nix, hosts/fern/default.nix). No changes needed.
56-59: Confirmprograms.jetbrains-remote.idestype (modules/hm/common/dev/environments/editor.nix:56–59)
I didn’t find the module definition locally—please verify in the nixpkgs module thatidesexpects derivations (not string names).modules/hm/common/utilities/app-launcher.nix (2)
80-87: Simplify attrset construction with genAttrsClearer and avoids intermediate list allocations.
- installThemes = themes: - lib.listToAttrs (map (name: - lib.nameValuePair ".config/kando/menu-themes/${name}" { - source = fetchOfficialTheme name; - recursive = true; - } - ) themes); + installThemes = themes: + lib.genAttrs themes (name: { + source = fetchOfficialTheme name; + recursive = true; + });Likely an incorrect or invalid review comment.
102-105: Remove unnecessary assertion for pkgs.kando
kandowas merged into nixpkgs by PR #337555 on Oct 27 2024 and is included in the 25.05 release (github.com, mynixos.com)Likely an incorrect or invalid review comment.
modules/system/common/games.nix (1)
8-8: Dropping steam from clientToPackage is fine—verify steam-run/steamcmd needsSince programs.steam.enable installs Steam, this is OK. If you rely on steam-run or steamcmd (e.g., for tools or servers), add them explicitly.
modules/system/common/nix/polkit.nix (1)
1-1: Signature update OKAdding pkgs to the module args is appropriate given the new package usage.
info.txt (1)
100-106: Verify tarow.podman options and derive hostUid
- Manual check required: unable to locate
options.*tarow.podmanin module definitions (confirm correct field name:hostIP4AddressvshostIPv4Address).- Replace hard-coded
hostUid = 1000with
hostUid = config.users.users.${config.home.username}.uid or 1000;
at lines 100–106 and 109–112 in info.txtmodules/hm/common/dev/languages/node.nix (1)
38-41: Verify Node.js version 22 availability
Run:nix eval --raw .#homeConfigurations.$USER@$HOST.pkgs.nodejs_22.pnameConfirm that
nodejs_22is provided by your pinned nixpkgs; if it’s missing, add a fallback or adjust the default.modules/system/common/server/communication/agents.nix (1)
25-26: Option names are camelCase & correct The correct options are services.glpiAgent.enable (mynixos.com) and services.fusionInventory.enable (mynixos.com); the current code matches these names.Likely an incorrect or invalid review comment.
modules/hm/common/multimedia/editing/image.nix (1)
11-15: LGTM – minimal, correct HM toggle for Krita.The option wiring and conditional package inclusion look good.
modules/hm/common/multimedia/editing/video.nix (1)
1-16: No old option path references found. Ran searches for bothmodules.hm.multimedia.openshot-qtandopenshot-qt; only the new usage in video.nix appears.modules/system/common/nix/default.nix (1)
30-47: Verify grub-reboot with entry titles vs IDs
The environment script couldn’t find/boot/grub/grub.cfg; please manually confirm on your target machine whethergrub-rebootaccepts the display title or requires the menuentry ID. For example:grep -E 'menuentry .* --id' /boot/grub/grub.cfg | sed -E 's/.*--id ['"'"'](.*?)['"'"'].*/\1/' sudo grub-reboot '<menuentry-id>'modules/system/common/server/dev/vs-code.nix (1)
42-51: Validate option names against current NixOS moduleConfirm that services.code-server supports extraEnvironment/extraArguments on your nixpkgs pin; if not, map via services.code-server.serviceConfig.Environment and services.code-server.extraArgs.
I can adjust the module once you confirm the exact option names in nixpkgs-25.05.
modules/system/common/dev/languages/flutter.nix (1)
50-56: Minor: prefer mkIf for androidSdk inclusion (already good), keep as-isThe optional inclusion pattern is correct and efficient.
modules/system/common/networks/vpn.nix (1)
1-1: Ensurevarsis provided viaspecialArgsNo occurrences of
specialArgs = { inherit vars; }(orextraSpecialArgs) were found in yourflake.nix,hosts/, ormodules/entry points. Manually verify that any NixOS/Home Manager configurations importingmodules/system/common/networks/vpn.nixpassspecialArgs = { inherit vars; }and confirm
vars.useris defined for each host.modules/hm/common/default.nix (1)
26-27: No duplicate imports:modules/hm/common/documentation/default.nixdefines only the basemodules.hm.documentationmodule and does not re-exportobsidian.nix, so importing both./documentation/obsidian.nixand./documentationyields distinct modules as intended.Likely an incorrect or invalid review comment.
modules/hm/common/dev/languages/python.nix (2)
20-23: Guard onconfig.hydenix.hm.enableis project-specificIf
hydenix.hm.enableis absent on some hosts, this path may break expectations (missing interpreter). Ensure it’s defined whereverversionsincludes "312", or add a safer fallback.
91-91: Verify existence ofvirtualenvAutoSwitchoptionI didn’t find any declarations or references to
python.virtualenvAutoSwitchin our HM modules beyond its single use (you only have the one match in python.nix), nor does it appear in NixOS’s officialprograms.zsh.preztooptions. Please confirm that thepython.virtualenvAutoSwitchattribute is actually supported by the underlying Prezto module; otherwise switch to enabling the Python module via:programs.zsh.prezto.modules = [ "python" ]; # and configure any extra init commands with programs.zsh.initExtramodules/system/common/virtualisation/default.nix (1)
15-21: “virtualbox” as an emulator implies host setup; clarify or split.If “emulators” is intended for userland tools only, split VirtualBox to
enginesor add a doc note that picking it will also enable the host module (see suggested config above).Do you want “virtualbox” treated like an engine (host enable) or purely as a package? I can align docs and behavior accordingly.
modules/hm/common/documentation/obsidian.nix (1)
60-61: Default projectsDir path changed; verify vault path consistency.Ensure
${defaultObsiPath}/obsidian/home/content/Projectsmatches the actual vault structure (you also sethome.sessionVariables.OBSIDIAN_VAULT = "${defaultObsiPath}/obsidian").Do you want me to add a sanity check that creates the theme dir and projects dir under the same vault root if missing?
modules/hm/common/network/tunnel.nix (1)
56-56: Behavior change: no tunnel enabled by default.network.tunnel.servicesnow defaults to[]. Only thecedarhost explicitly enables["localtunnel"]; update any other hosts that rely on tunnels with anetwork.tunnel.servicesoverride.modules/hm/common/dev/tools/cli.nix (2)
8-10: Verify package attributes exist in pinned nixpkgs.
nodePackages.vercelandgraphite-clican drift across channels.If needed, replace with maintained derivations or pin overlays.
4-4: Rename complete; nomodules.hm.dev.global-toolsreferences remain
Search confirms all callers updated tomodules.hm.dev.tools.*.modules/hm/common/dev/tools/nix.nix (1)
13-21: Package set looks good.The chosen tools cover common Nix dev workflows.
modules/hm/common/dev/tools/prisma.nix (2)
17-23: Engine paths: confirm correctness against current nixpkgs.Engine filenames can change between versions; if they drift, Prisma CLI fails at runtime.
If needed, gate by platform or derive from
${pkgs.prisma-engines}outputs.
7-9: Rename complete: nodev.node.prismareferences remain. Search confirmed all configs and modules now usetools.prisma.modules/system/common/server/storage/syncthing.nix (1)
13-20: API rename looks consistent.New path under
modules.system.server.storage.syncthingis clear and matches server/storage taxonomy.hosts/oak/hardware-configuration.nix (1)
4-4:varsis already passed viaspecialArgs; no changes needed.modules/hm/common/dev/tools/gitleaks.nix (1)
1-14: LGTM: clean, toggleable install of gitleaksMatches the established HM pattern; guarded enable and package injection look good.
modules/hm/hosts/cedar/default.nix (5)
39-42: Localtunnel exposure: validate port and service interactionEnsure 8080 doesn’t collide with other dev services and that the tunnel module is idempotent across host restarts.
43-47: LGTM: Syncthing ignore defaultsSensible excludes; startup enabled.
32-37: wrkflw mapping verified
The"wrkflw"entry ingit-action.packagesis correctly resolved bymodules/hm/common/dev/tools/git-action.nixto the package defined inmodules/wrapper/wrkflw.nix. No changes needed.
17-23: Container option types align with definitions All provided options (engine,enableSocket,hostUid,tui.enable,overrideAliases) match their declared types inmodules/hm/common/dev/environments/containers.nix.
24-31: No changes needed:dotnet.extraPackagesexpects string names
The option is defined as alistOf strand mapped againstpkgs.<name>, so supplying["dotnet-ef"]is correct.hosts/pine/hardware-configuration.nix (1)
6-9: LGTM: qemu-guest import is appropriate for PineMatches common virtualized host pattern.
modules/system/hosts/cedar/default.nix (1)
21-23: Syncthing path/use checksConfirm the effective path resolves to /home/${vars.user}/Documents and that Syncthing runs as the owning user (UID/GID) to avoid permission issues. Consider pinning the service user/group here if your common module doesn’t.
modules/system/common/default.nix (1)
24-43: Ignore duplicate import suggestion
modules/system/common/virtualisation/default.nix does not reference ollama.nix, so the explicit import isn’t redundant.Likely an incorrect or invalid review comment.
hosts/cedar/hardware-configuration.nix (2)
7-9: QEMU guest profile import LGTMBaseline looks correct for a VM guest. Ensure NIC name (e.g., ens18) matches if you switch to explicit per-interface DHCP later.
16-20: Filesystem/checksConfirm the UUID and fsType match the target disk; consider adding a separate /var/lib (or persistence) if Cedar will host stateful services.
modules/hm/common/dev/tools/git-action.nix (2)
17-21: Clean implementation of conditional package installationThe use of
lib.optionalwithlib.elemfor conditional package inclusion is well-structured and follows NixOS best practices.
6-6: wrkflw wrapper path resolves correctlyThe relative import
../../../../wrapper/wrkflw.nixinmodules/hm/common/dev/tools/git-action.nixresolves tomodules/wrapper/wrkflw.nix, which exists in the repository.modules/system/common/virtualisation/ollama.nix (2)
8-43: Well-structured Ollama module implementationThe module follows NixOS best practices with proper option definitions, sensible defaults, and clean service configuration. The integration between the Ollama server and its GUI frontend is properly handled.
39-39: Ensure Ollama service binds to localhost
The module only sets services.ollama.port; verify that the generated systemd service includes a--host 127.0.0.1(or equivalent) flag—if not, update modules/system/common/virtualisation/ollama.nix to restrict the Ollama daemon to localhost.modules/hm/common/multimedia/player.nix (2)
49-51: Good use of mpv scriptsThe configuration properly uses the
uoscscript frompkgs.mpvScripts, which is the recommended way to install mpv scripts in NixOS.
7-7: No action needed: thehayase.nixwrapper path is correct
The filemodules/wrapper/hayase.nixexists and is properly referenced by../../../wrapper/hayase.nixfrommodules/hm/common/multimedia/player.nix.modules/system/common/server/print.nix (1)
44-51: Clarify firewall behavior for non-local listen addresses.If
listenAddressesincludes non-local interfaces, opening the firewall exposes CUPS on the LAN.Review desired exposure. If not intended, set
openFirewall = falseor restrictlistenAddressesto localhost only. I can add an option to auto-deriveopenFirewallfromlistenAddressesif you want.modules/system/common/server/media/photoprism.nix (1)
35-43: Module wiring looks correct.
mkIfgating and direct mapping toservices.photoprismare clean.hosts/cedar/default.nix (4)
47-67: Home Manager wiring looks good.Global pkgs, extraSpecialArgs, and host/user imports are set up cleanly.
69-81: Hydenix host block is explicit and conservative.Clear disables for optional features; fine as a baseline.
83-89: Useboot.loader.grub.deviceswithlib.mkDefaultinstead of hardcoding/dev/sda.
Replace thedeviceattribute as shown and add per-host overrides to list the correct device(s) (e.g./dev/vda,/dev/nvme0n1) in your hardware config:- boot.loader = { - grub = { - device = lib.mkForce "/dev/sda"; - efiSupport = lib.mkForce false; - }; - efi.canTouchEfiVariables = lib.mkForce false; - }; + boot.loader = { + grub = { + # Use devices list; override per-host via vars or hardware-configuration. + devices = lib.mkDefault [ "/dev/sda" ]; + efiSupport = lib.mkForce false; + }; + efi.canTouchEfiVariables = lib.mkForce false; + };Verify the actual disk names on this host (e.g. via
lsblkor/dev/disk/by-id) and update thedeviceslist accordingly.
29-45: Imports and hydenix modules validated—no action required
hardware-configuration.nix and modules/system/hosts/cedar exist; inputs.hydenix.lib.nixOsModules and inputs.hydenix.inputs.home-manager.nixosModules.home-manager align with the flake inputs.modules/system/common/server/media/paperless.nix (2)
11-21: Minor: usetypes.pathconsistently fordataDir/mediaDir.You already do here; good alignment.
47-61: Verify exporter options in upstream nixpkgs 25.05
Ensure thatservices.paperless.exporter.directoryandservices.paperless.exporter.onCalendarare defined and match upstream in your target nixpkgs release.modules/system/common/server/communication/ntfy-sh.nix (1)
36-38: Replacenotify-clientwith the correct Nix package for ntfy CLI- environment.systemPackages = lib.mkIf cfg.gui.enable (with pkgs; [ - notify-client - ]); + environment.systemPackages = lib.mkIf cfg.gui.enable [ pkgs.ntfy ];Ensure that
pkgs.ntfyexists in your nixpkgs channel—if your channel only providesntfy-sh, substitutepkgs.ntfy-shinstead.modules/system/common/server/communication/matrix.nix (2)
165-167: Confirm firewall exposure is intendedYou open 80/443 but bind Synapse only on loopback. This is fine behind nginx; ensure no direct 8008 exposure is required.
117-122: No change: dedicated metrics listener is valid
Synapse supports a standalone listener withtype = "metrics"for Prometheus scraping (second method in the metrics how-to) (matrix-org.github.io)Likely an incorrect or invalid review comment.
modules/system/common/server/media/multimedia.nix (1)
217-223: Double-check Bazarr option nameNixOS may expose
services.bazarr.port(notlistenPort). Verify the correct attr for your nixpkgs revision to avoid a no-op.If needed:
- listenPort = cfg.bazarr.listenPort; + port = cfg.bazarr.listenPort;Likely an incorrect or invalid review comment.
modules/hm/common/extra/syncthing-ignore.nix (2)
82-87: Security concern: Command injection vulnerability in XML extraction fallbackThe fallback grep/sed approach is vulnerable to malicious input in the XML file that could inject shell commands through specially crafted attribute values.
The fallback method using grep and sed is inherently unsafe. Consider either:
- Making xmlstarlet a required dependency
- Using a safer XML parsing approach (e.g., Python with xml.etree)
Apply this diff to make xmlstarlet required:
# Use xmlstarlet to extract folder paths if command -v ${pkgs.xmlstarlet}/bin/xmlstarlet &> /dev/null; then ${pkgs.xmlstarlet}/bin/xmlstarlet sel -t -m "//folder" -v "@path" -n "$config_file" 2>/dev/null else - # Fallback: use grep and sed (less reliable but works) - grep -o 'path="[^"]*"' "$config_file" | sed 's/path="//;s/"$//' + echo "Error: xmlstarlet is required for safe XML parsing" >&2 + return 1 fiLikely an incorrect or invalid review comment.
115-115: Variable interpolation issue in shell scriptThe Nix string interpolation for
cfg.excludedDirsoccurs at build time, but the script expects it to be evaluated at runtime. This will cause the script to fail.The build-time interpolation needs to be fixed:
- local FIND_CMD="${buildFindCommand "\$TARGET_DIR" cfg.excludedDirs}" + local FIND_CMD='${buildFindCommand "$TARGET_DIR" cfg.excludedDirs}'Likely an incorrect or invalid review comment.
modules/hm/common/dev/environments/containers.nix (1)
45-51: Verify Podman socket UID alignment
Could not find other Podman socket configurations in the codebase; ensure that/run/user/${toString cfg.hostUid}/podman/podman.sockmatches the systemd-user’s actual runtime directory and ownership. If UIDs diverge, consider switching to%t/podman/podman.sock.modules/hm/hosts/oak/default.nix (4)
41-47: Confirm container engine wiring for rootless Podman.
enableSocket = true,hostUid = 1001, and alias overrides can clash with user UID and lingering daemon setups. Verify the effective UID on oak and that services use rootless sockets (XDG_RUNTIME_DIR). If UID differs, make it configurable.
18-24: Policy/UX check on enabled apps.
- Games/media/comm choices look fine; just confirm each module exists and guards arch-specific or license-gated apps (e.g.,
mangohud,rambox,bluemail) behind platform checks to avoid evaluation failures on non-Linux or missing channels.Also applies to: 25-32, 33-37, 67-72
73-80: Unknown module surface (ianny).Ensure
utilities.safety.iannyis provided by your HM modules and has sane defaults; otherwise Nix will fail at option resolution.
81-84: LGTM: syncthing ignore set is sensible.Common large/ephemeral dirs excluded. Nice.
modules/hm/desktops/hydenix.nix (3)
80-86: Assertions look good.Hostname validation and non-empty theme list are clear and actionable.
23-24: nix-index home module import: verify path.
inputs.nix-index-database.homeModules.nix-indexis correct in recent versions; confirm the input exposeshomeModules.nix-indexfor your pinned commit.
176-183: Script deployment is correct; ensure it’s referenced.
powermode-toggle.shandrandom-theme.share installed; verifyconfigHydenix.exec-onceactually calls them when the flags are enabled.TODO.md (2)
12-12: LGTM! Completed task aligned with PR changes.The bluemail task completion is consistent with the overall project restructuring in this PR.
18-18: LGTM! Flutter task completion matches module reorganization.The Flutter task completion aligns with the broader development language module restructuring under
modules/*/dev/languages/*seen throughout this PR.modules/hm/common/dev/languages/rust.nix (3)
4-4: LGTM! Config path updated correctly for namespace reorganization.The configuration path has been properly updated from
config.modules.hm.dev.rusttoconfig.modules.hm.dev.languages.rust, aligning with the broader development language module restructuring.
14-14: LGTM! Option path updated consistently.The options path has been correctly updated from
options.modules.hm.dev.rusttooptions.modules.hm.dev.languages.rust, maintaining consistency with the configuration path change.
4-14: No remaining references to the old Rust module path
A repository-wide search confirms there are zero usages ofmodules.hm.dev.rust; all imports now point tomodules.hm.dev.languages.rust(e.g.,modules/hm/common/default.niximports./dev/languages/rust.nix).modules/hm/common/dev/languages/dotnet.nix (3)
4-4: LGTM! Config binding updated for namespace reorganization.The configuration binding has been properly updated from
config.modules.hm.dev.dotnettoconfig.modules.hm.dev.languages.dotnet, aligning with the development language module restructuring.
17-17: LGTM! Options path updated consistently.The options path has been correctly updated from
options.modules.hm.dev.dotnettooptions.modules.hm.dev.languages.dotnet, maintaining consistency with the configuration path change.
4-17: No remaining references to the old dotnet module path. All instances ofmodules.hm.dev.dotnethave been removed and replaced withmodules.hm.dev.languages.dotnet, and the import inmodules/hm/common/default.nixis correctly pointing to./dev/languages/dotnet.nix.modules/system/common/dev/languages/php.nix (3)
4-4: LGTM! Config path updated for namespace reorganization.The configuration path has been properly updated from
config.modules.system.dev.phptoconfig.modules.system.dev.languages.php, aligning with the development language module restructuring.
7-7: LGTM! Options path updated consistently.The options path has been correctly updated from
options.modules.system.dev.phptooptions.modules.system.dev.languages.php, maintaining consistency with the configuration path change.
4-7: No remaining references to old PHP module path. All occurrences ofmodules.system.dev.phphave been removed and imports now usemodules.system.dev.languages.php([script output]).modules/system/common/dev/tools/flatpak.nix (3)
9-9: LGTM! Config path updated for tools namespace reorganization.The configuration path has been properly updated from
config.modules.system.dev.flatpaktoconfig.modules.system.dev.tools.flatpak, aligning with the development tools module restructuring.
12-12: LGTM! Options path updated consistently.The options path has been correctly updated from
options.modules.system.dev.flatpaktooptions.modules.system.dev.tools.flatpak, maintaining consistency with the configuration path change.
9-12: No remainingmodules.system.dev.flatpakreferences
All instances of the old flatpak module path have been removed and imports now usemodules.system.dev.tools.flatpakwith the file atmodules/system/common/dev/tools/flatpak.nix.
| return 1 | ||
| fi | ||
|
|
||
| available_policies=$(cat /sys/module/pcie_aspm/parameters/policy | tr -d '[]') |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
ShellCheck SC2002: avoid useless cat.
Minor efficiency/readability tweak.
- available_policies=$(cat /sys/module/pcie_aspm/parameters/policy | tr -d '[]')
+ available_policies=$(tr -d '[]' < /sys/module/pcie_aspm/parameters/policy)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| available_policies=$(cat /sys/module/pcie_aspm/parameters/policy | tr -d '[]') | |
| available_policies=$(tr -d '[]' < /sys/module/pcie_aspm/parameters/policy) |
🧰 Tools
🪛 Shellcheck (0.10.0)
[style] 107-107: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
(SC2002)
🤖 Prompt for AI Agents
In modules/system/common/hardware/powersave/power-tuning.sh around line 107, the
use of "cat" to feed /sys/module/pcie_aspm/parameters/policy into tr is
unnecessary; change it so tr reads the file directly via input redirection
(i.e., call tr -d '[]' with the policy file as its input) to remove the useless
cat and improve efficiency/readability.
| "governor") | ||
| set_cpu_governor "${2:-}" | ||
| ;; |
There was a problem hiding this comment.
Argument validation: require governor name.
Avoid calling with empty string.
- "governor")
- set_cpu_governor "${2:-}"
+ "governor")
+ if [[ -z "${2:-}" ]]; then
+ log "Error: governor name required"; exit 1
+ fi
+ set_cpu_governor "${2}"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "governor") | |
| set_cpu_governor "${2:-}" | |
| ;; | |
| "governor") | |
| if [[ -z "${2:-}" ]]; then | |
| log "Error: governor name required"; exit 1 | |
| fi | |
| set_cpu_governor "${2}" | |
| ;; |
🤖 Prompt for AI Agents
In modules/system/common/hardware/powersave/power-tuning.sh around lines 292 to
294, the "governor" branch calls set_cpu_governor with "${2:-}" which allows an
empty string; validate that a governor name was provided (e.g., check that "$2"
is non-empty or test "$#" -ge 2), and if missing print a clear error/usage
message and exit or return a non-zero status instead of invoking
set_cpu_governor; if provided, call set_cpu_governor with the validated value.
| gc = { | ||
| automatic = true; | ||
| automatic = lib.mkForce cfg.autoGarbageCollection; | ||
| dates = cfg.dates; | ||
| options = "--delete-older-than ${cfg.optionDate}"; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid mkForce; prefer mkDefault (or plain assignment) to keep modules composable.
lib.mkForce prevents host- or role-level overrides of nix.gc.automatic. Use mkDefault so site-specific configs can still take precedence, or assign directly if you truly want this module to win only by import order.
- automatic = lib.mkForce cfg.autoGarbageCollection;
+ automatic = lib.mkDefault cfg.autoGarbageCollection;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| gc = { | |
| automatic = true; | |
| automatic = lib.mkForce cfg.autoGarbageCollection; | |
| dates = cfg.dates; | |
| options = "--delete-older-than ${cfg.optionDate}"; | |
| }; | |
| gc = { | |
| automatic = lib.mkDefault cfg.autoGarbageCollection; | |
| dates = cfg.dates; | |
| options = "--delete-older-than ${cfg.optionDate}"; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/common/nix/nix-garbage.nix around lines 41 to 45, the use of
lib.mkForce for gc.automatic prevents higher-level/site overrides; change
lib.mkForce cfg.autoGarbageCollection to lib.mkDefault cfg.autoGarbageCollection
so host/role configs can override, or alternatively assign automatic =
cfg.autoGarbageCollection directly if you intend import-order-only behavior;
keep the rest of the gc attributes (dates and options) unchanged.
| settings = lib.mkOption { | ||
| type = lib.types.attrsOf lib.types.anything; | ||
| default = {}; | ||
| description = "Custom settings for photoprism configuration"; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Fix copy/paste in description and tighten the option type.
- Replace “photoprism” with “Vaultwarden”.
- Prefer a stricter type for settings to catch invalid values earlier.
- settings = lib.mkOption {
- type = lib.types.attrsOf lib.types.anything;
- default = {};
- description = "Custom settings for photoprism configuration";
- };
+ settings = lib.mkOption {
+ type = with lib.types; attrsOf (oneOf [ str int bool ]);
+ default = {};
+ description = "Custom settings for Vaultwarden configuration (maps to services.vaultwarden.config).";
+ };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| settings = lib.mkOption { | |
| type = lib.types.attrsOf lib.types.anything; | |
| default = {}; | |
| description = "Custom settings for photoprism configuration"; | |
| }; | |
| settings = lib.mkOption { | |
| type = with lib.types; attrsOf (oneOf [ str int bool ]); | |
| default = {}; | |
| description = "Custom settings for Vaultwarden configuration (maps to services.vaultwarden.config)."; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/common/server/password-manager/vaultwarden.nix around lines 18
to 22, the option description incorrectly references "photoprism" and the type
is too permissive; update the description to "Custom settings for Vaultwarden
configuration" and tighten the option type from lib.types.attrsOf
lib.types.anything to lib.types.attrsOf lib.types.any so values cannot be
arbitrary (e.g. functions) while still allowing attribute sets, ensuring invalid
value types are caught earlier.
| config = { | ||
| services.vaultwarden = { | ||
| enable = cfg.enable; | ||
| backupDir = cfg.backupDir; | ||
| config = cfg.settings; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
Backups will fail unless the backupDir exists; create it via tmpfiles when enabled.
services.vaultwarden.backupDir isn’t created automatically; the backup unit errors out if the directory is missing. Add a tmpfiles rule gated by cfg.enable. (discourse.nixos.org)
- config = {
- services.vaultwarden = {
- enable = cfg.enable;
- backupDir = cfg.backupDir;
- config = cfg.settings;
- };
- };
+ config = lib.mkMerge [
+ {
+ services.vaultwarden = {
+ enable = cfg.enable;
+ backupDir = cfg.backupDir;
+ config = cfg.settings;
+ };
+ }
+ (lib.mkIf cfg.enable {
+ # Ensure backup directory exists with correct ownership.
+ systemd.tmpfiles.rules = [
+ "d ${cfg.backupDir} 0750 ${config.services.vaultwarden.user or \"vaultwarden\"} ${config.services.vaultwarden.group or \"vaultwarden\"} - -"
+ ];
+ })
+ ];For reference, using services.vaultwarden.config is the correct knob for environment-style settings. (discourse.nixos.org)
🤖 Prompt for AI Agents
In modules/system/common/server/password-manager/vaultwarden.nix around lines 25
to 31, backups will fail if services.vaultwarden.backupDir does not exist; add a
tmpfiles rule gated by cfg.enable that creates cfg.backupDir with appropriate
ownership and permissions before the service starts. Modify the module to append
a systemd.tmpfiles.rules entry (only when cfg.enable is true) that ensures the
directory path from cfg.backupDir is created at boot with the correct
owner/group and mode so the Vaultwarden backup systemd unit won’t error out.
| # It should match the UID of the user running the tarow.podman service. | ||
| # If you are not sure, you can find it by running `id -u` in the terminal. | ||
| hostUid = 1000; | ||
| externalStorageBaseDir = "${config.home.homeDirectory}/podman-stoorage"; |
There was a problem hiding this comment.
Typo: “podman-stoorage”
Fix the path to avoid creating a wrong directory.
- externalStorageBaseDir = "${config.home.homeDirectory}/podman-stoorage";
+ externalStorageBaseDir = "${config.home.homeDirectory}/podman-storage";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| externalStorageBaseDir = "${config.home.homeDirectory}/podman-stoorage"; | |
| externalStorageBaseDir = "${config.home.homeDirectory}/podman-storage"; |
🤖 Prompt for AI Agents
In info.txt around line 107, the externalStorageBaseDir path contains a typo
"podman-stoorage"; update the string to the correct directory name (e.g.,
"podman-storage") so the path reads
"${config.home.homeDirectory}/podman-storage" to avoid creating an incorrectly
named directory.
| clientsToPackage = with pkgs; { | ||
| element = [ ]; | ||
| nheko = [ ]; | ||
| }; | ||
|
|
||
| # Get packages for enabled clients | ||
| clientPackages = lib.concatMap (client: clientsToPackage.${client} or []) cfg.clients; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Clarify installation path: rely on HM program modules or home.packages (avoid duplication)
Element/Nheko HM modules typically install packages when enabled. Keeping clientsToPackage empty makes home.packages a no-op. Either (a) remove clientsToPackage/clientPackages/home.packages and rely solely on programs., or (b) populate the mapping and drop programs. to avoid double installation.
Would you like me to adjust to option (a) and strip the no-op home.packages?
🤖 Prompt for AI Agents
In modules/hm/common/communication/matrix.nix around lines 7 to 13, the
clientsToPackage/clientPackages/home.packages block is effectively a no-op and
duplicates installation behavior provided by programs.element/programs.nheko;
remove the clientsToPackage and clientPackages definitions and any references to
home.packages in this module so package installation is handled solely by the HM
program modules (option (a): strip the no-op home.packages).
| type = lib.types.listOf (lib.types.enum (lib.attrNames clientsToPackage)); | ||
| default = []; | ||
| description = "List of clients to install"; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Improve option docs with examples and default behavior
Add examples and note that enabling a client toggles programs..enable.
description = "List of clients to install";
+ example = [ "element" "nheko" ];
+ defaultText = "[] (no clients enabled)";Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
modules/hm/common/communication/matrix.nix around lines 18 to 22: the option
description for the clients list is too terse; update the description string to
include one or two short usage examples (e.g., ["element" "nheko"]) and
explicitly state the default (empty list) and that enabling a client here
effectively toggles programs.<client>.enable in their respective package
definitions; keep the default = [] unchanged and ensure the description
clarifies that adding a client in this list will enable
programs.<client>.enable.
| config = { | ||
| home.packages = clientPackages; | ||
|
|
||
| programs = { | ||
| element-desktop.enable = lib.elem "element" cfg.clients; | ||
| nheko.enable = lib.elem "nheko" cfg.clients; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Deduplicate packages in case of overlaps
If keeping clientPackages, ensure uniqueness.
- home.packages = clientPackages;
+ home.packages = lib.unique clientPackages;🤖 Prompt for AI Agents
In modules/hm/common/communication/matrix.nix around lines 24-31, the
home.packages assignment may contain duplicate entries from clientPackages; wrap
or replace it with a de-duplicated list (e.g. use Nix's
builtins.removeDuplicates or an equivalent lib helper) so home.packages =
builtins.removeDuplicates clientPackages (or deduplicate at the point where
clientPackages is constructed) to ensure uniqueness.
| { | ||
| ... | ||
| }: | ||
| { inputs, lib, config, ... }: |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Confirm inputs is threaded to HM modules
You import inputs.nix-podman-stacks.homeModules.nps here; ensure HM gets inputs via extraSpecialArgs = { inherit inputs; }.
Also applies to: 57-58
🏁 Script executed:
#!/bin/bash
# Check Home Manager wiring passes `inputs`.
rg -nP -C3 'homeConfigurations|homeManagerUsers' flake.nix | rg -nP -C2 'extraSpecialArgs\s*=\s*\{[^}]*inputs' || trueLength of output: 119
🏁 Script executed:
#!/bin/bash
# Search for Home Manager configuration blocks in flake.nix and extraSpecialArgs usage across the repo.
rg -n -C5 'homeManagerConfigurations' flake.nix
rg -n -C5 'homeConfigurations' flake.nix
rg -n -C5 'extraSpecialArgs' .Length of output: 2134
🏁 Script executed:
#!/bin/bash
# Check how Home Manager modules are imported in flake.nix and where common/default.nix is used
rg -n 'nix-podman-stacks.homeModules.nps' flake.nix
rg -n 'homeModules' -C3 flake.nix
rg -n 'modules/hm/common/default.nix' -C3 flake.nix
rg -n 'modules/hm' -C3 flake.nixLength of output: 170
Pass inputs into Home Manager outputs
Your flake.nix’s homeConfigurations and homeManagerUsers blocks omit
extraSpecialArgs = { inherit inputs; };Add that to both blocks so modules (e.g. inputs.nix-podman-stacks.homeModules.nps and modules/hm/common/default.nix) receive the inputs argument.
🤖 Prompt for AI Agents
In modules/hm/common/default.nix around line 1, the Home Manager modules expect
an `inputs` argument but your flake's `homeConfigurations` and
`homeManagerUsers` blocks don't pass it; edit your flake.nix and add
`extraSpecialArgs = { inherit inputs; };` to both the `homeConfigurations` and
`homeManagerUsers` blocks so modules like
`inputs.nix-podman-stacks.homeModules.nps` and `modules/hm/common/default.nix`
receive the `inputs` argument.
| options.modules.system.server.dev.vs-code = { | ||
| enable = lib.mkEnableOption "Enable VS Code server"; | ||
|
|
||
| port = lib.mkOption { | ||
| type = lib.types.port; | ||
| default = 3000; | ||
| description = "Port for the VS Code server to listen on."; | ||
| }; | ||
| host = lib.mkOption { | ||
| type = lib.types.str; | ||
| default = "localhost"; | ||
| description = "Host for the VS Code server to bind to."; | ||
| }; | ||
| extraPackages = lib.mkOption { | ||
| type = lib.types.listOf lib.types.package; | ||
| default = []; | ||
| description = "Additional packages to install for the VS Code server."; | ||
| }; | ||
| extraEnvironment = lib.mkOption { | ||
| type = lib.types.attrsOf lib.types.str; | ||
| default = {}; | ||
| description = "Additional environment variables for the VS Code server."; | ||
| }; | ||
| extraArguments = lib.mkOption { | ||
| type = lib.types.listOf lib.types.str; | ||
| default = []; | ||
| description = "Additional command line arguments for the VS Code server."; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add security-related options (auth) and firewall control
Expose auth and openFirewall so hosts don’t accidentally run unauthenticated or inaccessible servers.
options.modules.system.server.dev.vs-code = {
enable = lib.mkEnableOption "Enable VS Code server";
@@
extraArguments = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = "Additional command line arguments for the VS Code server.";
};
+ auth = lib.mkOption {
+ type = lib.types.enum [ "password" "none" ];
+ default = "password";
+ description = "Authentication mode for code-server. Use 'none' only behind a trusted reverse proxy.";
+ };
+ hashedPasswordFile = lib.mkOption {
+ type = with lib.types; nullOr path;
+ default = null;
+ description = "Path to a file containing the bcrypt-hashed password for code-server.";
+ };
+ openFirewall = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Open the firewall on the configured port.";
+ };
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| options.modules.system.server.dev.vs-code = { | |
| enable = lib.mkEnableOption "Enable VS Code server"; | |
| port = lib.mkOption { | |
| type = lib.types.port; | |
| default = 3000; | |
| description = "Port for the VS Code server to listen on."; | |
| }; | |
| host = lib.mkOption { | |
| type = lib.types.str; | |
| default = "localhost"; | |
| description = "Host for the VS Code server to bind to."; | |
| }; | |
| extraPackages = lib.mkOption { | |
| type = lib.types.listOf lib.types.package; | |
| default = []; | |
| description = "Additional packages to install for the VS Code server."; | |
| }; | |
| extraEnvironment = lib.mkOption { | |
| type = lib.types.attrsOf lib.types.str; | |
| default = {}; | |
| description = "Additional environment variables for the VS Code server."; | |
| }; | |
| extraArguments = lib.mkOption { | |
| type = lib.types.listOf lib.types.str; | |
| default = []; | |
| description = "Additional command line arguments for the VS Code server."; | |
| }; | |
| }; | |
| options.modules.system.server.dev.vs-code = { | |
| enable = lib.mkEnableOption "Enable VS Code server"; | |
| port = lib.mkOption { | |
| type = lib.types.port; | |
| default = 3000; | |
| description = "Port for the VS Code server to listen on."; | |
| }; | |
| host = lib.mkOption { | |
| type = lib.types.str; | |
| default = "localhost"; | |
| description = "Host for the VS Code server to bind to."; | |
| }; | |
| extraPackages = lib.mkOption { | |
| type = lib.types.listOf lib.types.package; | |
| default = []; | |
| description = "Additional packages to install for the VS Code server."; | |
| }; | |
| extraEnvironment = lib.mkOption { | |
| type = lib.types.attrsOf lib.types.str; | |
| default = {}; | |
| description = "Additional environment variables for the VS Code server."; | |
| }; | |
| extraArguments = lib.mkOption { | |
| type = lib.types.listOf lib.types.str; | |
| default = []; | |
| description = "Additional command line arguments for the VS Code server."; | |
| }; | |
| auth = lib.mkOption { | |
| type = lib.types.enum [ "password" "none" ]; | |
| default = "password"; | |
| description = "Authentication mode for code-server. Use 'none' only behind a trusted reverse proxy."; | |
| }; | |
| hashedPasswordFile = lib.mkOption { | |
| type = with lib.types; nullOr path; | |
| default = null; | |
| description = "Path to a file containing the bcrypt-hashed password for code-server."; | |
| }; | |
| openFirewall = lib.mkOption { | |
| type = lib.types.bool; | |
| default = false; | |
| description = "Open the firewall on the configured port."; | |
| }; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/common/server/dev/vs-code.nix around lines 12 to 40, the
module currently lacks options to control authentication and firewall exposure;
add an auth stanza and an openFirewall option so instances are not accidentally
unauthenticated or publicly accessible. Add auth = { enable = lib.mkEnableOption
"Require authentication for VS Code server"; providers = lib.mkOption { type =
lib.types.listOf lib.types.str; default = []; description = "Authentication
providers (e.g. password, oidc)"; }; extraSettings = lib.mkOption { type =
lib.types.attrsOf lib.types.str; default = {}; description = "Provider-specific
auth settings"; }; }; and add openFirewall = lib.mkOption { type =
lib.types.bool; default = false; description = "If true, open the required port
in the firewall for VS Code server"; }; ensure descriptions match style of
surrounding options and wire these options into the service definition where the
server is started and firewall rules are generated.
| config = { | ||
| services.code-server = { | ||
| enable = cfg.enable; | ||
| port = cfg.port; | ||
| host = cfg.host; | ||
| extraPackages = cfg.extraPackages; | ||
| extraEnvironment = cfg.extraEnvironment; | ||
| extraArguments = cfg.extraArguments; | ||
| user = "${vars.user}"; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Guard config with mkIf; set auth/password and firewall
Avoid evaluating service attrs when disabled; wire new security options.
- config = {
+ config = lib.mkIf cfg.enable {
services.code-server = {
- enable = cfg.enable;
+ enable = true;
port = cfg.port;
host = cfg.host;
+ auth = cfg.auth;
+ hashedPasswordFile = cfg.hashedPasswordFile;
extraPackages = cfg.extraPackages;
extraEnvironment = cfg.extraEnvironment;
extraArguments = cfg.extraArguments;
user = "${vars.user}";
};
+ networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| config = { | |
| services.code-server = { | |
| enable = cfg.enable; | |
| port = cfg.port; | |
| host = cfg.host; | |
| extraPackages = cfg.extraPackages; | |
| extraEnvironment = cfg.extraEnvironment; | |
| extraArguments = cfg.extraArguments; | |
| user = "${vars.user}"; | |
| }; | |
| }; | |
| config = lib.mkIf cfg.enable { | |
| services.code-server = { | |
| enable = true; | |
| port = cfg.port; | |
| host = cfg.host; | |
| auth = cfg.auth; | |
| hashedPasswordFile = cfg.hashedPasswordFile; | |
| extraPackages = cfg.extraPackages; | |
| extraEnvironment = cfg.extraEnvironment; | |
| extraArguments = cfg.extraArguments; | |
| user = "${vars.user}"; | |
| }; | |
| networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ]; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/common/server/dev/vs-code.nix around lines 42–52, guard the
service attrs with lib.mkIf so the code-server attrs aren't evaluated when
disabled, and wire the new security options: wrap the services.code-server block
with lib.mkIf cfg.enable, add auth = cfg.auth or "password" and supply the
password via cfg.password or cfg.passwordFile (whichever your module exposes),
and expose the port to the firewall only when enabled by adding
networking.firewall.allowedTCPPorts = lib.mkIf cfg.enable [ cfg.port ]; ensure
you reference cfg.* for values and avoid evaluating any expressions when
cfg.enable is false.
| # Get packages for enabled emulators | ||
| baseEmulatorPackages = lib.concatMap (emulator: emulatorToPackage.${emulator} or []) cfg.emulators; | ||
|
|
||
| # Additional packages based on configuration | ||
| additionalPackages = with pkgs; [] | ||
| ++ lib.optionals cfg.wine.enable [ (winePackages.${cfg.wine.version} or pkgs.wine-stable) winetricks ] | ||
| ++ lib.optionals cfg.proton.enable protonPackages | ||
| ++ lib.optionals (lib.elem "podman" cfg.engines) [ podman-compose ] | ||
| ++ lib.optionals (lib.elem "docker" cfg.engines) [ docker-compose ]; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Guard unknown emulator keys and tighten package resolution.
You already type-check cfg.emulators, so or [] is redundant. Minor, but simplifies.
- baseEmulatorPackages = lib.concatMap (emulator: emulatorToPackage.${emulator} or []) cfg.emulators;
+ baseEmulatorPackages = lib.concatMap (emulator: emulatorToPackage.${emulator}) cfg.emulators;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Get packages for enabled emulators | |
| baseEmulatorPackages = lib.concatMap (emulator: emulatorToPackage.${emulator} or []) cfg.emulators; | |
| # Additional packages based on configuration | |
| additionalPackages = with pkgs; [] | |
| ++ lib.optionals cfg.wine.enable [ (winePackages.${cfg.wine.version} or pkgs.wine-stable) winetricks ] | |
| ++ lib.optionals cfg.proton.enable protonPackages | |
| ++ lib.optionals (lib.elem "podman" cfg.engines) [ podman-compose ] | |
| ++ lib.optionals (lib.elem "docker" cfg.engines) [ docker-compose ]; | |
| # Get packages for enabled emulators | |
| baseEmulatorPackages = lib.concatMap (emulator: emulatorToPackage.${emulator}) cfg.emulators; |
🤖 Prompt for AI Agents
In modules/system/common/virtualisation/default.nix around lines 38 to 46, the
current concatMap uses "emulatorToPackage.${emulator} or []" which redundantly
compensates for cfg.emulators already being type-checked and yields a loose
package lookup; replace that lookup with a guarded attribute-path lookup (e.g.
use lib.attrByPath or lib.getAttr with a default empty list) so unknown emulator
keys are explicitly handled and package resolution is tightened, and remove the
redundant "or []" fallback from the concatMap call.
| additionalPackages = with pkgs; [] | ||
| ++ lib.optionals cfg.wine.enable [ (winePackages.${cfg.wine.version} or pkgs.wine-stable) winetricks ] | ||
| ++ lib.optionals cfg.proton.enable protonPackages | ||
| ++ lib.optionals (lib.elem "podman" cfg.engines) [ podman-compose ] | ||
| ++ lib.optionals (lib.elem "docker" cfg.engines) [ docker-compose ]; | ||
| in { |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Prefer Compose v2 (docker compose) over docker-compose (v1).
Nixpkgs increasingly defaults to the v2 plugin via the Docker package. Consider not installing docker-compose and rely on docker compose, or explicitly use docker-compose-v2 if needed.
- ++ lib.optionals (lib.elem "docker" cfg.engines) [ docker-compose ];
+ # Prefer docker compose v2 plugin; drop v1 python docker-compose
+ ++ lib.optionals (lib.elem "docker" cfg.engines) []If you do need a separate package, switch to docker-compose-v2 and document it.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| additionalPackages = with pkgs; [] | |
| ++ lib.optionals cfg.wine.enable [ (winePackages.${cfg.wine.version} or pkgs.wine-stable) winetricks ] | |
| ++ lib.optionals cfg.proton.enable protonPackages | |
| ++ lib.optionals (lib.elem "podman" cfg.engines) [ podman-compose ] | |
| ++ lib.optionals (lib.elem "docker" cfg.engines) [ docker-compose ]; | |
| in { | |
| additionalPackages = with pkgs; [] | |
| + lib.optionals cfg.wine.enable [ (winePackages.${cfg.wine.version} or pkgs.wine-stable) winetricks ] | |
| + lib.optionals cfg.proton.enable protonPackages | |
| + lib.optionals (lib.elem "podman" cfg.engines) [ podman-compose ] | |
| # Prefer docker compose v2 plugin; drop v1 python docker-compose | |
| + lib.optionals (lib.elem "docker" cfg.engines) [] | |
| ; | |
| in { |
🤖 Prompt for AI Agents
In modules/system/common/virtualisation/default.nix around lines 42 to 47, the
current additionalPackages installs the legacy docker-compose (v1); change this
to prefer Compose v2 by either removing docker-compose and relying on the Docker
package's built-in `docker compose` plugin, or replace the explicit package with
`docker-compose-v2` (or the appropriate nixpkgs name for the v2 plugin) in the
lib.optionals list; also add a brief comment documenting the choice (rely on
Docker plugin vs install docker-compose-v2) so future maintainers understand why
v1 is avoided.
| users.users.${vars.user}.extraGroups = ["kvm" "input"] | ||
| ++ lib.optionals (lib.elem "libvirtd" cfg.engines) ["libvirtd"] | ||
| ++ lib.optionals (lib.elem "docker" cfg.engines) ["docker"] | ||
| ++ lib.optionals (lib.elem "podman" cfg.engines) ["podman"] | ||
| ++ lib.optionals (lib.elem "lxd" cfg.engines) ["lxd"]; | ||
| }) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add vboxusers group when VirtualBox is selected.
VirtualBox requires membership in vboxusers.
users.users.${vars.user}.extraGroups = ["kvm" "input"]
++ lib.optionals (lib.elem "libvirtd" cfg.engines) ["libvirtd"]
++ lib.optionals (lib.elem "docker" cfg.engines) ["docker"]
++ lib.optionals (lib.elem "podman" cfg.engines) ["podman"]
- ++ lib.optionals (lib.elem "lxd" cfg.engines) ["lxd"];
+ ++ lib.optionals (lib.elem "lxd" cfg.engines) ["lxd"]
+ ++ lib.optionals (lib.elem "virtualbox" cfg.emulators) ["vboxusers"];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| users.users.${vars.user}.extraGroups = ["kvm" "input"] | |
| ++ lib.optionals (lib.elem "libvirtd" cfg.engines) ["libvirtd"] | |
| ++ lib.optionals (lib.elem "docker" cfg.engines) ["docker"] | |
| ++ lib.optionals (lib.elem "podman" cfg.engines) ["podman"] | |
| ++ lib.optionals (lib.elem "lxd" cfg.engines) ["lxd"]; | |
| }) | |
| users.users.${vars.user}.extraGroups = ["kvm" "input"] | |
| + lib.optionals (lib.elem "libvirtd" cfg.engines) ["libvirtd"] | |
| + lib.optionals (lib.elem "docker" cfg.engines) ["docker"] | |
| + lib.optionals (lib.elem "podman" cfg.engines) ["podman"] | |
| + lib.optionals (lib.elem "lxd" cfg.engines) ["lxd"] | |
| + lib.optionals (lib.elem "virtualbox" cfg.emulators) ["vboxusers"]; | |
| }) |
🤖 Prompt for AI Agents
In modules/system/common/virtualisation/default.nix around lines 94 to 99, the
users.users.${vars.user}.extraGroups list does not add the vboxusers group when
VirtualBox is selected; update the concatenation to include ++ lib.optionals
(lib.elem "virtualbox" cfg.engines) ["vboxusers"] so that when "virtualbox" is
present in cfg.engines the vboxusers group is appended (place it alongside the
existing lib.optionals entries for libvirtd/docker/podman/lxd).
| permittedInsecurePackages = [ | ||
| "qtwebengine-5.15.19" | ||
| ]; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Duplicated insecure-packages config + security risk
You repeat permittedInsecurePackages in both pkgs and userPkgs. DRY it and document why qtwebengine-5.15.19 is required, plus a reminder to remove ASAP.
Apply:
let
- pkgs = import inputs.hydenix.inputs.hydenix-nixpkgs {
+ commonNixpkgsConfig = {
+ android_sdk.accept_license = true;
+ allowUnfree = true;
+ permittedInsecurePackages = [ "qtwebengine-5.15.19" ];
+ };
+ pkgs = import inputs.hydenix.inputs.hydenix-nixpkgs {
inherit (inputs.hydenix.lib) system;
- config = {
- android_sdk.accept_license = true;
- allowUnfree = true;
- permittedInsecurePackages = [
- "qtwebengine-5.15.19"
- ];
- };
+ config = commonNixpkgsConfig;
overlays = [
inputs.hydenix.lib.overlays
(final: prev: {
userPkgs = import inputs.nixpkgs {
inherit (inputs.hydenix.lib) system;
- config = {
- android_sdk.accept_license = true;
- allowUnfree = true;
- permittedInsecurePackages = [
- "qtwebengine-5.15.19"
- ];
- };
+ config = commonNixpkgsConfig;
};
})
];
};Also applies to: 25-27
🤖 Prompt for AI Agents
In hosts/oak/default.nix around lines 13-16 (and also lines 25-27), you
currently duplicate permittedInsecurePackages in both pkgs and userPkgs;
refactor by extracting a single permittedInsecurePackages list (e.g., top-level
let-bound or shared attribute) and reference that variable from both pkgs and
userPkgs to DRY the config, remove the duplicated entries, and add a short
inline comment above the shared list explaining why "qtwebengine-5.15.19" is
required and a TODO/reminder to remove it ASAP once a safer alternative or
upgrade is available.
| ]; | ||
|
|
||
| boot.kernelParams = [ "video=HDMI-A-1:e" ]; | ||
| #boot.kernelParams = [ "video=HDMI-A-1:e" ]; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Kernel param kept commented
If HDMI force-enable is obsolete, drop it. If needed, gate it by host/hardware profile to avoid leaking stale tuning.
🤖 Prompt for AI Agents
In hosts/oak/default.nix around line 58, the commented-out kernel param
"#boot.kernelParams = [ "video=HDMI-A-1:e" ];" is either stale or should be
applied only for specific hardware; either remove the commented line entirely if
the HDMI force-enable is no longer needed, or reintroduce it behind a
host/hardware conditional so it only applies for machines that require HDMI
forcing (e.g., add it to boot.kernelParams when the host profile or detected
GPU/monitor matches the affected hardware). Ensure the change is implemented by
editing the host's Nix expression to conditionally extend boot.kernelParams
based on the host/hardware profile and commit the updated host.nix.
| hardware.nvidia = { | ||
| prime.amdgpuBusId = lib.mkForce "PCI:36:0:0"; | ||
| }; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Incomplete PRIME config (missing nvidiaBusId)
Setting only amdgpuBusId is usually insufficient; PRIME expects both amdgpuBusId and nvidiaBusId (and an offload/sync mode). Wrong IDs break graphics.
Apply:
hardware.nvidia = {
- prime.amdgpuBusId = lib.mkForce "PCI:36:0:0";
+ prime = {
+ amdgpuBusId = lib.mkForce "PCI:36:0:0";
+ nvidiaBusId = lib.mkForce "PCI:NN:0:0"; # TODO: replace with actual
+ # offload.enable = true; # or: sync.enable = true;
+ };
};Run to audit PRIME settings across the repo and catch missing IDs:
🏁 Script executed:
#!/bin/bash
rg -nP -C2 'hardware\.nvidia\.prime\.(amdgpuBusId|nvidiaBusId|offload\.enable|sync\.enable)'Length of output: 94
🏁 Script executed:
#!/bin/bash
# Audit PRIME config keys across all Nix files
rg -nP -C2 'prime\.(amdgpuBusId|nvidiaBusId|offload\.enable|sync\.enable)' --glob '*.nix'Length of output: 300
Add missing NVIDIA PRIME fields
In hosts/oak/default.nix, PRIME must include both bus IDs and a mode; update accordingly:
hardware.nvidia = {
- prime.amdgpuBusId = lib.mkForce "PCI:36:0:0";
+ prime = {
+ amdgpuBusId = lib.mkForce "PCI:36:0:0";
+ nvidiaBusId = lib.mkForce "<PCI:NN:0:0>"; # replace with actual NVIDIA bus ID
+ sync.enable = true; # or: offload.enable = true
+ };
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| hardware.nvidia = { | |
| prime.amdgpuBusId = lib.mkForce "PCI:36:0:0"; | |
| }; | |
| hardware.nvidia = { | |
| prime = { | |
| amdgpuBusId = lib.mkForce "PCI:36:0:0"; | |
| nvidiaBusId = lib.mkForce "<PCI:NN:0:0>"; # replace with actual NVIDIA bus ID | |
| sync.enable = true; # or: offload.enable = true | |
| }; | |
| }; |
🤖 Prompt for AI Agents
In hosts/oak/default.nix around lines 103 to 105, the hardware.nvidia.prime
block only sets amdgpuBusId; add the missing nvidiaBusId field with the correct
PCI bus ID for the NVIDIA GPU and set the prime mode (e.g. mode = "nvidia" or
"hybrid" per your intended behavior). Ensure both bus IDs use lib.mkForce like
the existing entry and that the mode string matches NixOS expected values.
| fileSystems."/home/${vars.user}/mnt" = { | ||
| device = "/dev/disk/by-uuid/cd70c50f-c6c2-49c1-935a-854ba3e8c153"; | ||
| fsType = "ext4"; | ||
| options = [ "defaults" "noatime" "discard" "nofail" "errors=remount-ro" ]; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Home-scoped mount: add automount and ensure mountpoint ownership
Mounting at /home/${vars.user}/mnt can race with home dir creation and default to root:root ownership. Use systemd automount and create the directory with proper owner.
Apply options tweak:
- options = [ "defaults" "noatime" "discard" "nofail" "errors=remount-ro" ];
+ options = [
+ "defaults" "noatime" "discard" "nofail" "errors=remount-ro"
+ "x-systemd.automount" "x-systemd.idle-timeout=300"
+ ];And in a host module (not this generated file), create the mountpoint:
# hosts/oak/default.nix (snippet)
systemd.tmpfiles.rules = [
"d /home/${vars.user}/mnt 0750 ${vars.user} users -"
];| inputs.hydenix.lib.nixOsModules | ||
| ./hardware-configuration.nix | ||
| ../../modules/system/hosts/pine | ||
| ../../modules/system/hosts/cedar |
There was a problem hiding this comment.
Host configuration mismatch: pine imports cedar modules
The file hosts/pine/default.nix imports ../../modules/system/hosts/cedar instead of a pine-specific module. This appears to be a configuration error where the pine host is using cedar's configuration.
This should likely be:
- ../../modules/system/hosts/cedar
+ ../../modules/system/hosts/pineUnless this is intentional (converting pine to cedar), in which case the file should be renamed or removed to avoid confusion.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ../../modules/system/hosts/cedar | |
| ../../modules/system/hosts/pine |
🤖 Prompt for AI Agents
In hosts/pine/default.nix around line 32, the file imports
../../modules/system/hosts/cedar which is incorrect for the pine host; replace
that import with the pine-specific module (e.g. ../../modules/system/hosts/pine)
ensuring the target module exists and exports the expected configuration; if the
intent was to make pine identical to cedar instead, rename or remove this file
and/or document the intentional reuse to avoid confusion.
| (lib.mkIf (cfg.emulators != []) { | ||
| environment.systemPackages = baseEmulatorPackages; | ||
| }) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Enable VirtualBox host when selected in emulators.
Installing the package alone isn’t enough; the kernel modules must be enabled.
(lib.mkIf (cfg.emulators != []) {
environment.systemPackages = baseEmulatorPackages;
})
+ (lib.mkIf (lib.elem "virtualbox" cfg.emulators) {
+ virtualisation.virtualbox.host.enable = true;
+ })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| (lib.mkIf (cfg.emulators != []) { | |
| environment.systemPackages = baseEmulatorPackages; | |
| }) | |
| (lib.mkIf (cfg.emulators != []) { | |
| environment.systemPackages = baseEmulatorPackages; | |
| }) | |
| (lib.mkIf (lib.elem "virtualbox" cfg.emulators) { | |
| virtualisation.virtualbox.host.enable = true; | |
| }) |
🤖 Prompt for AI Agents
modules/system/common/virtualisation/default.nix lines 145-147: currently you
only add emulator packages when cfg.emulators is non-empty; you must also enable
the VirtualBox host when "virtualbox" is selected so kernel modules are loaded.
Update the nix expression to detect membership (e.g. lib.elem "virtualbox"
cfg.emulators) and, inside a conditional (lib.mkIf or lib.optionalAttrs), set
virtualisation.virtualbox.host.enable = true so the kernel modules and host
support are activated whenever VirtualBox is in cfg.emulators.
| @@ -0,0 +1,43 @@ | |||
| { config, lib, pkgs, vars, ... }: | |||
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Unused vars parameter
The vars parameter is imported but never used in this module.
-{ config, lib, pkgs, vars, ... }:
+{ config, lib, pkgs, ... }:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { config, lib, pkgs, vars, ... }: | |
| { config, lib, pkgs, ... }: |
🤖 Prompt for AI Agents
In modules/system/common/virtualisation/ollama.nix around lines 1 to 1, the
function signature includes an unused vars parameter; remove vars from the
parameter list ({ config, lib, pkgs, ... } instead of { config, lib, pkgs, vars,
... }) so the module signature matches actual usage and eliminates the unused
variable warning.
| media = { | ||
| multimedia = { | ||
| enable = true; | ||
| jellyfin.enable = true; | ||
| sonarr.enable = true; | ||
| radarr.enable = true; | ||
| prowlarr.enable = true; | ||
| bazarr.enable = true; | ||
| jellyseerr.enable = true; | ||
| }; | ||
| paperless.enable = true; | ||
| photoprism.enable = true; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
ARR stack likely needs a download client
You enable Sonarr/Radarr/Prowlarr/Bazarr/Jellyseerr but no download client (e.g., qBittorrent/Transmission). Add one and persist download/metadata paths to avoid churn.
🤖 Prompt for AI Agents
In modules/system/hosts/cedar/default.nix around lines 26-38, the ARR stack
services (sonarr, radarr, prowlarr, bazarr, jellyseerr) are enabled but no
download client or persistent download/config paths are provided; add and enable
a download client (e.g., qbittorrent or transmission) under multimedia, enable
it (multimedia.qbittorrent.enable = true or multimedia.transmission.enable =
true), and configure persistent mounts for download and metadata/config
directories (map host paths to the container/service config and downloads
folders) so downloads and metadata survive restarts and avoid churn.
| communication = { | ||
| ntfy-sh.enable = true; | ||
| matrix-synapse.enable = true; | ||
| agents = ["qemu"]; | ||
| }; | ||
| meal.clients = ["mealie"]; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Matrix/ntfy: secure defaults
For Matrix, ensure registration is disabled or gated and set proper server_name/registration secrets. For ntfy, validate auth/topics policy. Also open only required firewall ports.
🤖 Prompt for AI Agents
modules/system/hosts/cedar/default.nix lines 39-45: the Matrix and ntfy blocks
use insecure defaults—disable or gate user registration for synapse, set
explicit server_name and a
registration_shared_secret/registration_shared_secret_file (or equivalent) so
automated registrations are prevented, and configure synapse to require
invitation/SSO/gating for account creation; for ntfy, enable and enforce
authentication and a topics ACL/policy so only authorized clients can
publish/subscribe; finally tighten the firewall rules to expose only the
required ports (Matrix client port and federation port only as needed, ntfy only
on TLS port if used) and verify the services still function after applying these
secure settings.
| services.portmaster = { | ||
| enable = true; | ||
| devmode.enable = true; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Portmaster devmode should not be on in prod
Dev mode weakens protections. Disable by default and enable only when debugging.
Apply:
- services.portmaster = {
- enable = true;
- devmode.enable = true;
- };
+ services.portmaster = {
+ enable = true;
+ devmode.enable = false;
+ };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| services.portmaster = { | |
| enable = true; | |
| devmode.enable = true; | |
| }; | |
| services.portmaster = { | |
| enable = true; | |
| devmode.enable = false; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/hosts/cedar/default.nix around lines 48 to 51, the Portmaster
devmode is enabled which weakens protections in production; change
devmode.enable to false (or remove the devmode block entirely) so dev mode is
disabled by default and only toggled on explicitly for debugging, and update any
module documentation or comments to note that devmode must be enabled only
during debugging with appropriate justification.
| nix-podman-stacks = { | ||
| url = "github:Tarow/nix-podman-stacks"; | ||
| inputs.nixpkgs.follows = "nixpkgs"; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Dead input?
nix-podman-stacks is added but not referenced in this flake. If intentional for future use, add a TODO; otherwise drop it to speed evals.
🤖 Prompt for AI Agents
In flake.nix around lines 21 to 24, the input "nix-podman-stacks" is declared
but never used; either remove the unused input to speed flake evaluation or keep
it but add an explicit in-file TODO comment and a short explanation (or a
visible reference like adding it to outputs/defaultPackage or a top-level
comment) so reviewers know it is intentionally reserved for future use; apply
the chosen change and run a flake check to verify there are no unused-input
warnings.
| # Host configuration mapping | ||
| hostConfigs = { | ||
| fern = { hostname = "fern"; ip = "fern"; }; | ||
| oak = { hostname = "oak"; ip = "oak"; }; | ||
| pine = { hostname = "pine"; ip = "pine"; }; | ||
| cedar = { hostname = "cedar"; ip = "cedar"; }; | ||
| }; |
There was a problem hiding this comment.
Bash can’t see this Nix attrset; remove or inline mapping.
hostConfigs is a Nix value and isn’t exported into the rb shell. Later references like hostConfigs[$host] will be empty/unbound. Drop this and let the script derive targets from $host.
- # Host configuration mapping
- hostConfigs = {
- fern = { hostname = "fern"; ip = "fern"; };
- oak = { hostname = "oak"; ip = "oak"; };
- pine = { hostname = "pine"; ip = "pine"; };
- cedar = { hostname = "cedar"; ip = "cedar"; };
- };
+ # SSH target equals hostname; adjust rb if per-host SSH names are needed.Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In flake.nix around lines 63 to 69, the hostConfigs Nix attrset is declared but
not exported to the runtime shell so bash access like hostConfigs[$host] will be
empty; remove this attrset and instead compute/inline the mapping in the shell
script by deriving targets directly from the $host variable (e.g., use a shell
case or associative array defined inside the script or compute host-specific
values from $host when the script runs) so the script no longer depends on a
Nix-only value.
| packages.${system} = { | ||
| cedar-vm = mkVm "cedar"; | ||
| fern-vm = mkVm "fern"; | ||
| oak-vm = mkVm "oak"; | ||
|
|
||
| build-iso = isoConfig.build-iso; | ||
| burn-iso = isoConfig.burn-iso; | ||
| fern = self.nixosConfigurations.fern.config.system.build.toplevel; | ||
| oak = self.nixosConfigurations.oak.config.system.build.toplevel; | ||
| cedar = self.nixosConfigurations.cedar.config.system.build.toplevel; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Parity: expose pine VM and toplevel like other hosts.
pine is in nixosConfigurations but missing from packages.${system}.
cedar-vm = mkVm "cedar";
fern-vm = mkVm "fern";
oak-vm = mkVm "oak";
+ pine-vm = mkVm "pine";
@@
- fern = self.nixosConfigurations.fern.config.system.build.toplevel;
- oak = self.nixosConfigurations.oak.config.system.build.toplevel;
- cedar = self.nixosConfigurations.cedar.config.system.build.toplevel;
+ fern = self.nixosConfigurations.fern.config.system.build.toplevel;
+ oak = self.nixosConfigurations.oak.config.system.build.toplevel;
+ pine = self.nixosConfigurations.pine.config.system.build.toplevel;
+ cedar = self.nixosConfigurations.cedar.config.system.build.toplevel;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| packages.${system} = { | |
| cedar-vm = mkVm "cedar"; | |
| fern-vm = mkVm "fern"; | |
| oak-vm = mkVm "oak"; | |
| build-iso = isoConfig.build-iso; | |
| burn-iso = isoConfig.burn-iso; | |
| fern = self.nixosConfigurations.fern.config.system.build.toplevel; | |
| oak = self.nixosConfigurations.oak.config.system.build.toplevel; | |
| cedar = self.nixosConfigurations.cedar.config.system.build.toplevel; | |
| packages.${system} = { | |
| cedar-vm = mkVm "cedar"; | |
| fern-vm = mkVm "fern"; | |
| oak-vm = mkVm "oak"; | |
| pine-vm = mkVm "pine"; | |
| fern = self.nixosConfigurations.fern.config.system.build.toplevel; | |
| oak = self.nixosConfigurations.oak.config.system.build.toplevel; | |
| pine = self.nixosConfigurations.pine.config.system.build.toplevel; | |
| cedar = self.nixosConfigurations.cedar.config.system.build.toplevel; |
🤖 Prompt for AI Agents
In flake.nix around lines 80 to 88, the pine host is present in
nixosConfigurations but not exported under packages.${system}; add pine-vm =
mkVm "pine"; and pine =
self.nixosConfigurations.pine.config.system.build.toplevel following the same
pattern as cedar/fern/oak so the pine VM and its toplevel are exposed in
packages.${system}.
| rb = pkgs.writeShellScriptBin "rb" '' | ||
| set -euo pipefail | ||
|
|
||
| host=$1 | ||
| shift # Remove the first argument (hostname) | ||
|
|
||
| # Parse additional flags | ||
| build_host="" | ||
| extra_args=() | ||
|
|
||
| while [[ $# -gt 0 ]]; do | ||
| case "$1" in | ||
| --build-host=*) | ||
| build_host="''${1#*=}" | ||
| shift | ||
| ;; | ||
| --build-host) | ||
| build_host="$2" | ||
| shift 2 | ||
| ;; | ||
| --remote-build) | ||
| build_host="''${hostConfigs[$host]:-$host}" | ||
| shift | ||
| ;; | ||
| --local-build) | ||
| build_host="localhost" | ||
| shift | ||
| ;; | ||
| *) | ||
| extra_args+=("$1") | ||
| shift | ||
| ;; | ||
| esac | ||
| done | ||
|
|
||
| # Get host configuration | ||
| case "$host" in | ||
| "oak") | ||
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#oak ;; | ||
| "fern") | ||
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#fern ;; | ||
| "pine") | ||
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#pine ;; | ||
| "all") | ||
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#oak | ||
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#fern | ||
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#pine | ||
| ;; | ||
| *) echo "Usage: rb [oak|fern|pine|all]" >&2; exit 1 ;; | ||
| "oak"|"fern"|"pine"|"cedar") | ||
| target_host="''${hostConfigs[$host]}" | ||
| ;; | ||
| "all") | ||
| # Deploy to all hosts sequentially | ||
| echo "Deploying to all hosts..." | ||
| for h in oak fern pine cedar; do | ||
| echo "=== Deploying to $h ===" | ||
| ${pkgs.nix}/bin/nixos-rebuild switch \ | ||
| --flake ".#$h" \ | ||
| --target-host "$h" \ | ||
| --sudo \ | ||
| "''${extra_args[@]}" | ||
| done | ||
| exit 0 | ||
| ;; | ||
| *) | ||
| echo "Usage: rb [oak|fern|pine|cedar|all] [OPTIONS] [-- nixos-rebuild-args]" | ||
| echo "" | ||
| echo "Options:" | ||
| echo " --build-host=HOST Build on specified host" | ||
| echo " --remote-build Build on target host (default)" | ||
| echo " --local-build Build on local machine" | ||
| echo " -- nixos-rebuild-args Additional arguments to nixos-rebuild" | ||
| echo "" | ||
| echo "Examples:" | ||
| echo " rb cedar # Build on cedar, deploy to cedar" | ||
| echo " rb cedar --local-build # Build locally, deploy to cedar" | ||
| echo " rb cedar --build-host=fern # Build on fern, deploy to cedar" | ||
| echo " rb cedar -- --show-trace # Pass --show-trace to nixos-rebuild" | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| # Build the nixos-rebuild command | ||
| cmd=( | ||
| ${pkgs.nix}/bin/nixos-rebuild | ||
| switch | ||
| --flake ".#$host" | ||
| --target-host "$target_host" | ||
| --sudo | ||
| ) | ||
|
|
||
| # Add build-host if specified | ||
| if [[ -n "$build_host" ]]; then | ||
| cmd+=(--build-host "$build_host") | ||
| fi | ||
|
|
||
| # Add extra arguments | ||
| cmd+=("''${extra_args[@]}") | ||
|
|
||
| echo "Running: ''${cmd[@]}" | ||
| "''${cmd[@]}" | ||
| ''; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
rb: wrong nixos-rebuild path, unreachable host map, missing remote sudo, and brittle flake path.
${pkgs.nix}/bin/nixos-rebuildis wrong; use${pkgs.nixos-rebuild}/bin/nixos-rebuild.hostConfigs[$host]never exists in bash.- Use
--use-remote-sudofor remote target. - Bake the flake path (
self.outPath) sorbworks outside repo root. - Validate
$1and handleallwithout losing extra args.
- rb = pkgs.writeShellScriptBin "rb" ''
- set -euo pipefail
-
- host=$1
- shift # Remove the first argument (hostname)
-
- # Parse additional flags
- build_host=""
- extra_args=()
-
- while [[ $# -gt 0 ]]; do
- case "$1" in
- --build-host=*)
- build_host="''${1#*=}"
- shift
- ;;
- --build-host)
- build_host="$2"
- shift 2
- ;;
- --remote-build)
- build_host="''${hostConfigs[$host]:-$host}"
- shift
- ;;
- --local-build)
- build_host="localhost"
- shift
- ;;
- *)
- extra_args+=("$1")
- shift
- ;;
- esac
- done
-
- # Get host configuration
- case "$host" in
- "oak"|"fern"|"pine"|"cedar")
- target_host="''${hostConfigs[$host]}"
- ;;
- "all")
- # Deploy to all hosts sequentially
- echo "Deploying to all hosts..."
- for h in oak fern pine cedar; do
- echo "=== Deploying to $h ==="
- ${pkgs.nix}/bin/nixos-rebuild switch \
- --flake ".#$h" \
- --target-host "$h" \
- --sudo \
- "''${extra_args[@]}"
- done
- exit 0
- ;;
- *)
- echo "Usage: rb [oak|fern|pine|cedar|all] [OPTIONS] [-- nixos-rebuild-args]"
- echo ""
- echo "Options:"
- echo " --build-host=HOST Build on specified host"
- echo " --remote-build Build on target host (default)"
- echo " --local-build Build on local machine"
- echo " -- nixos-rebuild-args Additional arguments to nixos-rebuild"
- echo ""
- echo "Examples:"
- echo " rb cedar # Build on cedar, deploy to cedar"
- echo " rb cedar --local-build # Build locally, deploy to cedar"
- echo " rb cedar --build-host=fern # Build on fern, deploy to cedar"
- echo " rb cedar -- --show-trace # Pass --show-trace to nixos-rebuild"
- exit 1
- ;;
- esac
-
- # Build the nixos-rebuild command
- cmd=(
- ${pkgs.nix}/bin/nixos-rebuild
- switch
- --flake ".#$host"
- --target-host "$target_host"
- --sudo
- )
-
- # Add build-host if specified
- if [[ -n "$build_host" ]]; then
- cmd+=(--build-host "$build_host")
- fi
-
- # Add extra arguments
- cmd+=("''${extra_args[@]}")
-
- echo "Running: ''${cmd[@]}"
- "''${cmd[@]}"
- '';
+ rb = pkgs.writeShellScriptBin "rb" ''
+ set -euo pipefail
+ FLAKE="${inputs.self.outPath}"
+
+ if [[ $# -lt 1 ]]; then
+ echo "Usage: rb [oak|fern|pine|cedar|all] [OPTIONS] [-- nixos-rebuild-args]" >&2
+ exit 1
+ fi
+
+ host=$1
+ shift || true
+
+ build_host=""
+ extra_args=()
+ remote_build=false
+
+ while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --build-host=*) build_host="''${1#*=}"; shift ;;
+ --build-host) build_host="$2"; shift 2 ;;
+ --remote-build) remote_build=true; shift ;;
+ --local-build) build_host="localhost"; shift ;;
+ *) extra_args+=("$1"); shift ;;
+ esac
+ done
+
+ if [[ "$host" == "all" ]]; then
+ for h in oak fern pine cedar; do
+ echo "=== Deploying to $h ==="
+ ${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \
+ --flake "$FLAKE#$h" \
+ --target-host "$h" \
+ --use-remote-sudo \
+ "''${extra_args[@]}"
+ done
+ exit 0
+ fi
+
+ case "$host" in oak|fern|pine|cedar) ;; *)
+ echo "Unknown host: $host" >&2; exit 1 ;; esac
+
+ target_host="$host"
+ if [[ "$remote_build" == true && -z "$build_host" ]]; then
+ build_host="$host"
+ fi
+
+ cmd=(
+ ${pkgs.nixos-rebuild}/bin/nixos-rebuild
+ switch
+ --flake "$FLAKE#$host"
+ --target-host "$target_host"
+ --use-remote-sudo
+ )
+ if [[ -n "$build_host" ]]; then
+ cmd+=(--build-host "$build_host")
+ fi
+ cmd+=("''${extra_args[@]}")
+ echo "Running: ''${cmd[@]}"
+ "''${cmd[@]}"
+ '';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| rb = pkgs.writeShellScriptBin "rb" '' | |
| set -euo pipefail | |
| host=$1 | |
| shift # Remove the first argument (hostname) | |
| # Parse additional flags | |
| build_host="" | |
| extra_args=() | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --build-host=*) | |
| build_host="''${1#*=}" | |
| shift | |
| ;; | |
| --build-host) | |
| build_host="$2" | |
| shift 2 | |
| ;; | |
| --remote-build) | |
| build_host="''${hostConfigs[$host]:-$host}" | |
| shift | |
| ;; | |
| --local-build) | |
| build_host="localhost" | |
| shift | |
| ;; | |
| *) | |
| extra_args+=("$1") | |
| shift | |
| ;; | |
| esac | |
| done | |
| # Get host configuration | |
| case "$host" in | |
| "oak") | |
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#oak ;; | |
| "fern") | |
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#fern ;; | |
| "pine") | |
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#pine ;; | |
| "all") | |
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#oak | |
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#fern | |
| ${pkgs.deploy-rs}/bin/deploy --skip-checks .#pine | |
| ;; | |
| *) echo "Usage: rb [oak|fern|pine|all]" >&2; exit 1 ;; | |
| "oak"|"fern"|"pine"|"cedar") | |
| target_host="''${hostConfigs[$host]}" | |
| ;; | |
| "all") | |
| # Deploy to all hosts sequentially | |
| echo "Deploying to all hosts..." | |
| for h in oak fern pine cedar; do | |
| echo "=== Deploying to $h ===" | |
| ${pkgs.nix}/bin/nixos-rebuild switch \ | |
| --flake ".#$h" \ | |
| --target-host "$h" \ | |
| --sudo \ | |
| "''${extra_args[@]}" | |
| done | |
| exit 0 | |
| ;; | |
| *) | |
| echo "Usage: rb [oak|fern|pine|cedar|all] [OPTIONS] [-- nixos-rebuild-args]" | |
| echo "" | |
| echo "Options:" | |
| echo " --build-host=HOST Build on specified host" | |
| echo " --remote-build Build on target host (default)" | |
| echo " --local-build Build on local machine" | |
| echo " -- nixos-rebuild-args Additional arguments to nixos-rebuild" | |
| echo "" | |
| echo "Examples:" | |
| echo " rb cedar # Build on cedar, deploy to cedar" | |
| echo " rb cedar --local-build # Build locally, deploy to cedar" | |
| echo " rb cedar --build-host=fern # Build on fern, deploy to cedar" | |
| echo " rb cedar -- --show-trace # Pass --show-trace to nixos-rebuild" | |
| exit 1 | |
| ;; | |
| esac | |
| # Build the nixos-rebuild command | |
| cmd=( | |
| ${pkgs.nix}/bin/nixos-rebuild | |
| switch | |
| --flake ".#$host" | |
| --target-host "$target_host" | |
| --sudo | |
| ) | |
| # Add build-host if specified | |
| if [[ -n "$build_host" ]]; then | |
| cmd+=(--build-host "$build_host") | |
| fi | |
| # Add extra arguments | |
| cmd+=("''${extra_args[@]}") | |
| echo "Running: ''${cmd[@]}" | |
| "''${cmd[@]}" | |
| ''; | |
| rb = pkgs.writeShellScriptBin "rb" '' | |
| set -euo pipefail | |
| FLAKE="${inputs.self.outPath}" | |
| if [[ $# -lt 1 ]]; then | |
| echo "Usage: rb [oak|fern|pine|cedar|all] [OPTIONS] [-- nixos-rebuild-args]" >&2 | |
| exit 1 | |
| fi | |
| host=$1 | |
| shift || true | |
| build_host="" | |
| extra_args=() | |
| remote_build=false | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --build-host=*) build_host="''${1#*=}"; shift ;; | |
| --build-host) build_host="$2"; shift 2 ;; | |
| --remote-build) remote_build=true; shift ;; | |
| --local-build) build_host="localhost"; shift ;; | |
| *) extra_args+=("$1"); shift ;; | |
| esac | |
| done | |
| if [[ "$host" == "all" ]]; then | |
| for h in oak fern pine cedar; do | |
| echo "=== Deploying to $h ===" | |
| ${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \ | |
| --flake "$FLAKE#$h" \ | |
| --target-host "$h" \ | |
| --use-remote-sudo \ | |
| "''${extra_args[@]}" | |
| done | |
| exit 0 | |
| fi | |
| case "$host" in oak|fern|pine|cedar) ;; *) | |
| echo "Unknown host: $host" >&2; exit 1 ;; esac | |
| target_host="$host" | |
| if [[ "$remote_build" == true && -z "$build_host" ]]; then | |
| build_host="$host" | |
| fi | |
| cmd=( | |
| ${pkgs.nixos-rebuild}/bin/nixos-rebuild | |
| switch | |
| --flake "$FLAKE#$host" | |
| --target-host "$target_host" | |
| --use-remote-sudo | |
| ) | |
| if [[ -n "$build_host" ]]; then | |
| cmd+=(--build-host "$build_host") | |
| fi | |
| cmd+=("''${extra_args[@]}") | |
| echo "Running: ''${cmd[@]}" | |
| "''${cmd[@]}" | |
| ''; |
🤖 Prompt for AI Agents
In flake.nix around lines 90–180, the rb script has multiple issues: replace
${pkgs.nix}/bin/nixos-rebuild with ${pkgs.nixos-rebuild}/bin/nixos-rebuild;
ensure hostConfigs is a defined bash associative array (declare -A
hostConfigs=([...])) and reference it properly as "${hostConfigs[$host]:-}"
(don’t rely on an undefined variable); use the --use-remote-sudo flag instead of
--sudo for remote targets; bake the flake path by using a pinned flake variable
(e.g. self.outPath or pass a baked FLake_PATH) and use --flake "$BAKED_FLAKE#$h"
so rb works outside the repo root; validate that $1 exists at the top (print
usage and exit if missing) and don’t shift the hostname before parsing so the
special case "all" can be detected while preserving extra_args (or capture host
into a variable without shifting) so iterating over all hosts retains extra_args
when calling nixos-rebuild.
| devShells.${system}.default = pkgs.mkShell { | ||
| buildInputs = [ | ||
| self.packages.${system}.rb | ||
| self.packages.${system}.deploy-remote | ||
| self.packages.${system}.deploy-local | ||
| self.packages.${system}.deploy-cross | ||
| pkgs.nix | ||
| ]; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Dev shell is missing nixos-rebuild.
Include pkgs.nixos-rebuild so the shell matches the script’s dependency.
buildInputs = [
self.packages.${system}.rb
self.packages.${system}.deploy-remote
self.packages.${system}.deploy-local
self.packages.${system}.deploy-cross
pkgs.nix
+ pkgs.nixos-rebuild
];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| devShells.${system}.default = pkgs.mkShell { | |
| buildInputs = [ | |
| self.packages.${system}.rb | |
| self.packages.${system}.deploy-remote | |
| self.packages.${system}.deploy-local | |
| self.packages.${system}.deploy-cross | |
| pkgs.nix | |
| ]; | |
| devShells.${system}.default = pkgs.mkShell { | |
| buildInputs = [ | |
| self.packages.${system}.rb | |
| self.packages.${system}.deploy-remote | |
| self.packages.${system}.deploy-local | |
| self.packages.${system}.deploy-cross | |
| pkgs.nix | |
| pkgs.nixos-rebuild | |
| ]; | |
| }; |
🤖 Prompt for AI Agents
In flake.nix around lines 206 to 214, the devShell's buildInputs is missing
pkgs.nixos-rebuild; update the buildInputs array to include pkgs.nixos-rebuild
(e.g., add pkgs.nixos-rebuild alongside pkgs.nix) so the development shell
provides the nixos-rebuild binary required by the script.
| settings = lib.mkOption { | ||
| type = lib.types.attrsOf lib.types.anything; | ||
| default = {}; | ||
| description = "Custom settings for photoprism configuration"; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Prefer types.unspecified for free-form settings (matches Paperless).
This avoids over-permissive anything and keeps modules consistent.
- settings = lib.mkOption {
- type = lib.types.attrsOf lib.types.anything;
+ settings = lib.mkOption {
+ type = lib.types.attrsOf lib.types.unspecified;
default = {};
description = "Custom settings for photoprism configuration";
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| settings = lib.mkOption { | |
| type = lib.types.attrsOf lib.types.anything; | |
| default = {}; | |
| description = "Custom settings for photoprism configuration"; | |
| }; | |
| settings = lib.mkOption { | |
| type = lib.types.attrsOf lib.types.unspecified; | |
| default = {}; | |
| description = "Custom settings for photoprism configuration"; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/common/server/media/photoprism.nix around lines 23 to 27, the
option `type = lib.types.attrsOf lib.types.anything;` is using the overly
permissive `anything`; update it to use `lib.types.attrsOf
lib.types.unspecified` so the setting remains free-form but aligns with other
modules (like Paperless) and avoids using `anything`. Keep the rest of the
option (default and description) unchanged.
| port = lib.mkOption { | ||
| type = lib.types.port; | ||
| default = 2342; | ||
| description = "Port for the photoprism web interface"; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add an opt-in firewall switch.
Opening the port should be explicit. Add openFirewall and only open the port when requested.
port = lib.mkOption {
type = lib.types.port;
default = 2342;
description = "Port for the photoprism web interface";
};
+ openFirewall = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Open the firewall for the Photoprism port.";
+ };
};
- config = lib.mkIf cfg.enable {
- services.photoprism = {
- enable = true;
- port = cfg.port;
- originalsPath = cfg.originalsPath;
- storagePath = cfg.storagePath;
- settings = cfg.settings;
- };
- };
+ config = lib.mkIf cfg.enable {
+ services.photoprism = {
+ enable = true;
+ port = cfg.port;
+ originalsPath = cfg.originalsPath;
+ storagePath = cfg.storagePath;
+ settings = cfg.settings;
+ };
+ networking.firewall = lib.mkIf cfg.openFirewall {
+ allowedTCPPorts = [ cfg.port ];
+ };
+ };Also applies to: 35-43
| services.printing = { | ||
| enable = cfg.enable; | ||
| drivers = lib.mkIf cfg.enable cfg.drivers; | ||
| listenAddresses = cfg.listenAddresses; | ||
| allowFrom = cfg.allowFrom; | ||
| logLevel = cfg.logLevel; | ||
| openFirewall = cfg.openFirewall; | ||
| webInterface = cfg.webInterface; | ||
| }; | ||
|
|
||
| services.avahi.enable = cfg.browsed.enable; | ||
|
|
There was a problem hiding this comment.
Wire CUPS Browsed properly (not just Avahi).
browsed.enable should control services.printing.browsed.enable; Avahi alone isn’t sufficient.
config = {
services.printing = {
enable = cfg.enable;
drivers = lib.mkIf cfg.enable cfg.drivers;
listenAddresses = cfg.listenAddresses;
allowFrom = cfg.allowFrom;
logLevel = cfg.logLevel;
openFirewall = cfg.openFirewall;
webInterface = cfg.webInterface;
};
- services.avahi.enable = cfg.browsed.enable;
+ services.printing.browsed.enable = cfg.browsed.enable;
+ services.avahi.enable = cfg.browsed.enable;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| services.printing = { | |
| enable = cfg.enable; | |
| drivers = lib.mkIf cfg.enable cfg.drivers; | |
| listenAddresses = cfg.listenAddresses; | |
| allowFrom = cfg.allowFrom; | |
| logLevel = cfg.logLevel; | |
| openFirewall = cfg.openFirewall; | |
| webInterface = cfg.webInterface; | |
| }; | |
| services.avahi.enable = cfg.browsed.enable; | |
| services.printing = { | |
| enable = cfg.enable; | |
| drivers = lib.mkIf cfg.enable cfg.drivers; | |
| listenAddresses = cfg.listenAddresses; | |
| allowFrom = cfg.allowFrom; | |
| logLevel = cfg.logLevel; | |
| openFirewall = cfg.openFirewall; | |
| webInterface = cfg.webInterface; | |
| }; | |
| services.printing.browsed.enable = cfg.browsed.enable; | |
| services.avahi.enable = cfg.browsed.enable; |
🤖 Prompt for AI Agents
In modules/system/common/server/print.nix around lines 75 to 86, the
configuration sets services.avahi.enable from cfg.browsed.enable but fails to
wire CUPS Browsed; add services.printing.browsed.enable = cfg.browsed.enable so
the cups-browsed option is controlled by cfg.browsed.enable (keep existing
services.avahi.enable line), and ensure proper indentation and placement inside
the services.printing block so browsed toggles with the printing service.
|
|
||
| services.avahi.enable = cfg.browsed.enable; | ||
|
|
||
| users.users.${vars.user}.extraGroups = [ "lp" "lpadmin" ]; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Gate user group changes behind enable (and avoid errors if user var is unset).
Prevents unintended group mods when printing is disabled or vars.user is missing.
- users.users.${vars.user}.extraGroups = [ "lp" "lpadmin" ];
+ users.users = lib.mkIf (cfg.enable && (vars ? user)) {
+ ${vars.user}.extraGroups = [ "lp" "lpadmin" ];
+ };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| users.users.${vars.user}.extraGroups = [ "lp" "lpadmin" ]; | |
| users.users = lib.mkIf (cfg.enable && (vars ? user)) { | |
| ${vars.user}.extraGroups = [ "lp" "lpadmin" ]; | |
| }; |
🤖 Prompt for AI Agents
In modules/system/common/server/print.nix around line 87, the line that
unconditionally sets users.users.${vars.user}.extraGroups = [ "lp" "lpadmin" ];
must be guarded so group changes only happen when printing is enabled and when
vars.user is defined; change this to only assign the extraGroups attribute when
both the printing enable flag is true and vars.user is non-empty (e.g. wrap the
attribute in a conditional or merge an optional attrset), and ensure you don't
reference ${vars.user} if it is unset to avoid evaluation errors.
| - [x] Matrix Server | ||
| - [x] Deskflow | ||
| - [x] ping module | ||
| - [x] db module | ||
| - [x] nginx module |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify new completed tasks correspond to actual implementations.
The newly marked completed tasks should have corresponding implementations in the codebase:
- Matrix Server: Should correspond to
modules/system/common/server/communication/matrix.nix - Deskflow: Should correspond to
modules/system/common/server/communication/deskflow.nix - nginx, db, ping modules: Should have corresponding module files
🏁 Script executed:
#!/bin/bash
# Description: Verify that the completed TODO items have corresponding module implementations
echo "=== Checking for Matrix Server module ==="
fd -t f "matrix.nix" modules/
echo "=== Checking for Deskflow module ==="
fd -t f "deskflow.nix" modules/
echo "=== Checking for nginx module references ==="
rg -n "nginx" modules/ | head -10
echo "=== Checking for database/db module ==="
fd -t f -e nix modules/ | xargs rg -l "database|db" | head -5
echo "=== Checking for ping module ==="
fd -t f "ping.nix" modules/ || rg -n "ping" modules/ | head -5Length of output: 1278
Implement missing ping, db, and nginx modules
No modules/**/ping.nix, db.nix, or nginx.nix files were found under modules/; please add the corresponding module implementations or update the TODO entries accordingly.
🤖 Prompt for AI Agents
In TODO.md around lines 23 to 27, the checklist marks "ping module", "db
module", and "nginx module" as done but there are no corresponding files under
modules/ (e.g., modules/**/ping.nix, db.nix, nginx.nix); either add the missing
module implementations with appropriate exports and configuration (create
modules/<service>/ping.nix, modules/db.nix, modules/nginx.nix following existing
module patterns) or update the TODO to uncheck or remove those entries and
include a short note about where/when they will be added.
|
🎉 This PR is included in version 1.3.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Description
This pull request makes significant changes to the NixOS flake and host configuration, focusing on simplifying deployment workflows, updating input sources, and adding support for a new host (
cedar). The main improvements are the removal of legacy GitHub workflows, migration away fromdeploy-rsin favor of custom deployment scripts, updates to input versions, and the addition of configuration files for thecedarhost. There are also fixes and minor improvements to existing host configurations.Deployment and Workflow Simplification
.github/workflows/flake-check.yml,.github/workflows/lint-commits.yml). [1] [2]deploy-rsto a custom deployment script (rb) and helper scripts (deploy-remote,deploy-local,deploy-cross), providing flexible and user-friendly deployment options for NixOS hosts. This also includes removal of related deploy-rs configuration and checks. (flake.nix)Host and Input Updates
cedarhost, including its configuration and hardware files (hosts/cedar/default.nix,hosts/cedar/hardware-configuration.nix). [1] [2]flake.nix: bumpednixpkgs-stabletorelease-25.05, pinnedhydenixto versionv4.9.0, and replaceddeploy-rsandnix-darwinwithnix-podman-stacks.Host Configuration Improvements
oak, added a mount for/home/${vars.user}/mnt, and minor hardware tweaks. (hosts/oak/default.nix,hosts/oak/hardware-configuration.nix) [1] [2] [3] [4]pinehost to use the new module and configuration structure, aligning it withcedar. (hosts/pine/default.nix) [1] [2]Project Management
TODO.mdto mark several tasks as completed, reflecting recent progress.Type of change
Checklist