Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN
12 KiB
DankMaterialShell (niri) Profile Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add a my.profiles.dank NixOS profile that runs DankMaterialShell (DMS) on the niri Wayland compositor as a login session parallel to KDE on mibook, backed by a new opt-in my.profiles.home-manager module.
Architecture: Three flake inputs (home-manager, niri = niri-flake, dank = DankMaterialShell) are added to flake.nix. A my.profiles.home-manager module unconditionally imports the home-manager NixOS module and, when enabled, sets global HM settings. A my.profiles.dank module enables my.profiles.home-manager as a dependency, turns on niri (system session) + the DMS nixosModule (daemons/packages), and configures home-manager.users.finn with the DMS + niri-flake HM modules for keybinds/spawn. mibook enables dank.
Tech Stack: Nix flakes, flake-parts, NixOS modules, home-manager (as NixOS module), niri-flake, DankMaterialShell flake, quickshell (from pkgs.unstable).
Global Constraints
- Do not modify
machines/configuration.nix.inputsandselfare already threaded into every module via_module.args; consume them as module arguments. - Base channel is pinned
nixpkgs/nixos-26.05;pkgs.unstableoverlay is available everywhere. quickshell must come frompkgs.unstable.quickshell(needs ≥ 0.3.0). - home-manager scoped to user
finnonly;home.stateVersion = "26.05". - Follow the existing profile pattern exactly:
let cfg = config.my.profiles.<name>; in { options.my.profiles.<name>.enable = lib.mkEnableOption "..."; config = lib.mkIf cfg.enable { ... }; }. - Format every new/edited
.nixfile withnixfmt-rfc-stylebefore committing. - Commit messages end with the repo's trailer lines (Co-Authored-By + Claude-Session) as seen in recent history.
- KDE (
my.profiles.kde-desktop) stays enabled on mibook; do not remove it.
Task 1: Add flake inputs
Files:
- Modify:
flake.nix:4-15(theinputs = { ... }block)
Interfaces:
-
Produces: flake inputs
inputs.home-manager,inputs.niri,inputs.dank, reachable from any NixOS module (via the existing_module.args.inputs = self.inputs). Later tasks consumeinputs.home-manager.nixosModules.home-manager,inputs.niri.homeModules.niri,inputs.dank.nixosModules.dank-material-shell,inputs.dank.homeModules.dank-material-shell,inputs.dank.homeModules.niri. -
Step 1: Add the three inputs
In flake.nix, inside the inputs = { ... } block, after the nixos-generators entry and before the closing };, add:
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
niri.url = "github:sodiboo/niri-flake";
dank.url = "github:AvengeMedia/DankMaterialShell";
- Step 2: Resolve the lock file
Run: nix flake lock
Expected: completes without error; flake.lock gains home-manager, niri, niri-flake-transitive, and dank (DankMaterialShell) nodes. If it reports a bad URL, re-check the github:owner/repo strings.
- Step 3: Verify inputs expose the expected outputs
Run: nix eval --raw '.#nixosConfigurations.mibook.pkgs.system' first to confirm the flake still evaluates (expected: x86_64-linux).
Then run: nix flake show 'github:AvengeMedia/DankMaterialShell' --allow-import-from-derivation 2>/dev/null | grep -E 'dank-material-shell|nixosModules|homeModules'
Expected: output lists nixosModules.dank-material-shell and homeModules.dank-material-shell and homeModules.niri. If the niri output name differs (e.g. dankMaterialShell.niri), note the actual name — Task 3 Step 1 must use whatever this shows.
- Step 4: Format and commit
nixfmt-rfc-style flake.nix
git add flake.nix flake.lock
git commit -m "chore: add home-manager, niri-flake, and DankMaterialShell flake inputs
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN"
Task 2: my.profiles.home-manager module
Files:
- Create:
modules/environments/home-manager/default.nix - Modify:
modules/environments/default.nix(add./home-managertoimports)
Interfaces:
-
Consumes:
inputs.home-manager.nixosModules.home-manager(Task 1). -
Produces: option
my.profiles.home-manager.enable. When enabled, setshome-manager.useGlobalPkgs = true,home-manager.useUserPackages = true,home-manager.extraSpecialArgs = { inherit inputs self; }. Also makes thehome-manager.users.<name>option available (from the unconditional import) so Task 3 can populatehome-manager.users.finn. -
Step 1: Create the module
Create modules/environments/home-manager/default.nix:
{
config,
lib,
inputs,
self,
...
}:
let
cfg = config.my.profiles.home-manager;
in
{
imports = [ inputs.home-manager.nixosModules.home-manager ];
options.my.profiles.home-manager.enable =
lib.mkEnableOption "home-manager integration";
config = lib.mkIf cfg.enable {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = { inherit inputs self; };
};
}
- Step 2: Register the module
In modules/environments/default.nix, add ./home-manager to the imports list (place it after ./hyprland):
./hyprland
./home-manager
- Step 3: Verify it evaluates disabled (no behavior change)
Run: nix build '.#nixosConfigurations.mibook.config.system.build.toplevel' --dry-run
Expected: evaluates and shows a build plan with no errors. Because my.profiles.home-manager.enable defaults to false, importing the HM module must not change the build outcome.
- Step 4: Verify the option exists and defaults false
Run: nix eval '.#nixosConfigurations.mibook.config.my.profiles.home-manager.enable'
Expected: false
- Step 5: Format and commit
nixfmt-rfc-style modules/environments/home-manager/default.nix modules/environments/default.nix
git add modules/environments/home-manager/default.nix modules/environments/default.nix
git commit -m "feat(home-manager): add opt-in my.profiles.home-manager module
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN"
Task 3: my.profiles.dank module
Files:
- Create:
modules/environments/dank/default.nix - Modify:
modules/environments/default.nix(add./danktoimports)
Interfaces:
-
Consumes:
my.profiles.home-manager.enable(Task 2);inputs.dank.nixosModules.dank-material-shell,inputs.dank.homeModules.dank-material-shell,inputs.dank.homeModules.niri,inputs.niri.homeModules.niri(Task 1);pkgs.unstable.quickshell. -
Produces: option
my.profiles.dank.enable. -
Step 1: Create the module
Create modules/environments/dank/default.nix. Use the exact homeModules/nixosModules output names confirmed in Task 1 Step 3 — the block below assumes dank-material-shell and niri:
{
config,
lib,
pkgs,
inputs,
...
}:
let
cfg = config.my.profiles.dank;
in
{
imports = [ inputs.dank.nixosModules.dank-material-shell ];
options.my.profiles.dank.enable = lib.mkEnableOption "DankMaterialShell on niri";
config = lib.mkIf cfg.enable {
# Dependency: declarative user config comes from home-manager.
my.profiles.home-manager.enable = true;
# System side: niri Wayland session + DMS daemons/packages.
programs.niri.enable = true;
programs.dank-material-shell = {
enable = true;
systemd.enable = true;
quickshell.package = pkgs.unstable.quickshell;
};
# Home side: DMS shell + niri keybinds/spawn for finn.
home-manager.users.finn = {
imports = [
inputs.niri.homeModules.niri
inputs.dank.homeModules.dank-material-shell
inputs.dank.homeModules.niri
];
programs.dank-material-shell = {
enable = true;
systemd.enable = true;
quickshell.package = pkgs.unstable.quickshell;
niri.enableKeybinds = true;
niri.enableSpawn = true;
};
home.stateVersion = "26.05";
};
};
}
- Step 2: Register the module
In modules/environments/default.nix, add ./dank to the imports list (after ./home-manager):
./home-manager
./dank
- Step 3: Verify it evaluates disabled
Run: nix eval '.#nixosConfigurations.mibook.config.my.profiles.dank.enable'
Expected: false
Run: nix build '.#nixosConfigurations.mibook.config.system.build.toplevel' --dry-run
Expected: evaluates without error (dank disabled → no behavior change yet).
- Step 4: Format and commit
nixfmt-rfc-style modules/environments/dank/default.nix modules/environments/default.nix
git add modules/environments/dank/default.nix modules/environments/default.nix
git commit -m "feat(dank): add DankMaterialShell (niri) profile
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN"
Task 4: Enable on mibook and build the full toplevel
Files:
- Modify:
machines/mibook/environments.nix:7-17(themy.profiles = { ... }block)
Interfaces:
-
Consumes:
my.profiles.dank.enable(Task 3). -
Step 1: Enable the profile
In machines/mibook/environments.nix, inside the my.profiles = { ... } block, add:
dank.enable = true;
- Step 2: Build the full toplevel (the real test)
Run: nix build '.#nixosConfigurations.mibook.config.system.build.toplevel'
Expected: builds successfully. This exercises the DMS package, quickshell from unstable, niri, and the home-manager generation for finn.
If it fails on a quickshell/Qt6 version mismatch (see spec risks): drop quickshell.package = pkgs.unstable.quickshell; from both the system and HM programs.dank-material-shell blocks in modules/environments/dank/default.nix and rebuild, letting DMS's module pick its own default quickshell. If it fails on an unknown HM option (e.g. niri.enableKeybinds), run nix eval '.#nixosConfigurations.mibook.config.home-manager.users.finn.programs.dank-material-shell' --apply builtins.attrNames 2>&1 | head to list the real option names and adjust. Re-run the build until it passes.
- Step 3: Run flake check
Run: nix flake check
Expected: passes (all nixosConfigurations evaluate). If nix flake check is slow or pulls DMS's own checks, nix build '.#nixosConfigurations.mibook.config.system.build.toplevel' from Step 2 passing is the authoritative gate.
- Step 4: Format and commit
nixfmt-rfc-style machines/mibook/environments.nix
git add machines/mibook/environments.nix modules/environments/dank/default.nix
git commit -m "feat(mibook): enable DankMaterialShell (niri) session
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN"
- Step 5: Manual acceptance (human, on hardware)
Run: sudo nixos-rebuild test --flake '.#mibook'
Then log out, pick the niri session at SDDM, log in as finn.
Expected: DMS bar/shell appears; Mod+Space opens the launcher; Mod+V opens the clipboard; the KDE session is still selectable and works. Note this step cannot be automated — it requires the physical machine.
Notes for the implementer
- Order matters: Task 1 must land first (inputs must resolve before any module can import them). Tasks 2→3→4 are strictly sequential.
- Output-name drift is the top risk. The DMS flake has renamed outputs over time (there are deprecated aliases like
dankMaterialShell.niri). Task 1 Step 3 pins down the real names against the locked revision; use those, not the names in this plan, if they differ. - No unit-test framework here. Nix evaluation + a successful
toplevelbuild is the test. Do not fabricate a test harness. - Do not touch
machines/configuration.nix,machines/jupiter/*, or the KDE profile.