ALWAYS Read @CONTRIBUTING.md when making changes.
For any Nix code or module task, use the writing-nix skill before making
edits.
- Home-First: Prefer Home Manager (
modules/home) for user-space configs (dotfiles, programs) over system modules. - Namespace Scoping: Always place options under
khanelinix.*. - Explicit Imports: Single-line
with lib;andwith pkgs;are acceptable. Avoid block-levelwith lib;. Useinherit (lib) ...or explicitlib.<fn>for larger scopes. - Modular & Composable: Split large modules (>200 lines) into sub-modules in a directory.
- Skill Usage (Nix Work): For any Nix code or module task, use the
writing-nixskill before making edits.
- Naming:
camelCasefor Nix variables/options,kebab-casefor files and directories. - Option Path:
khanelinix.{category}.{subcategory}.{name}. - Home Manager + System Access: HM modules use
osConfig ? {}to access the host system's configuration. - Conditionals: Prefer
lib.mkIffor entire configuration blocks. - PATH vs Store Paths: Prefer adding required tools to
home.packages/environment.systemPackagesso configs can use plain command names, instead of inlining store paths withlib.getExe/getExe'in shell aliases or config strings (unless a fixed store path is explicitly needed). - Secrets: Use
sops-nix. Never commit secrets in plaintext. Uselib.getFile "secrets/..."helpers. - Custom Helpers: Check
lib.khanelinixfor common helpers likeenabledanddisabled.
- In sandboxed agent environments, set
PRE_COMMIT_HOME=/tmp/pre-commitbeforegit commitif pre-commit cannot write to~/.local/cache/pre-commit.
{ config, lib, pkgs, osConfig ? {}, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.khanelinix.category.name;
in {
options.khanelinix.category.name.enable = mkEnableOption "Description";
config = mkIf cfg.enable {
# implementation
};
}