From 826a612d9d30ee1e6e9b399d713676c8643d4de9 Mon Sep 17 00:00:00 2001 From: "Finn@MiBook" Date: Fri, 24 Jul 2026 12:19:05 +0200 Subject: [PATCH] docs: implementation plan for DankMaterialShell (niri) profile Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN --- .../plans/2026-07-24-dank-material-shell.md | 285 ++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-24-dank-material-shell.md diff --git a/docs/superpowers/plans/2026-07-24-dank-material-shell.md b/docs/superpowers/plans/2026-07-24-dank-material-shell.md new file mode 100644 index 0000000..e714434 --- /dev/null +++ b/docs/superpowers/plans/2026-07-24-dank-material-shell.md @@ -0,0 +1,285 @@ +# 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`. `inputs` and `self` are already threaded into every module via `_module.args`; consume them as module arguments. +- Base channel is pinned `nixpkgs/nixos-26.05`; `pkgs.unstable` overlay is available everywhere. quickshell must come from `pkgs.unstable.quickshell` (needs ≥ 0.3.0). +- home-manager scoped to user `finn` only; `home.stateVersion = "26.05"`. +- Follow the existing profile pattern exactly: `let cfg = config.my.profiles.; in { options.my.profiles..enable = lib.mkEnableOption "..."; config = lib.mkIf cfg.enable { ... }; }`. +- Format every new/edited `.nix` file with `nixfmt-rfc-style` before 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` (the `inputs = { ... }` 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 consume `inputs.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: + +```nix + 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** + +```bash +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 +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-manager` to `imports`) + +**Interfaces:** +- Consumes: `inputs.home-manager.nixosModules.home-manager` (Task 1). +- Produces: option `my.profiles.home-manager.enable`. When enabled, sets `home-manager.useGlobalPkgs = true`, `home-manager.useUserPackages = true`, `home-manager.extraSpecialArgs = { inherit inputs self; }`. Also makes the `home-manager.users.` option available (from the unconditional import) so Task 3 can populate `home-manager.users.finn`. + +- [ ] **Step 1: Create the module** + +Create `modules/environments/home-manager/default.nix`: + +```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`): + +```nix + ./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** + +```bash +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 +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 `./dank` to `imports`) + +**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`: + +```nix +{ + 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`): + +```nix + ./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** + +```bash +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 +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` (the `my.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: + +```nix + 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** + +```bash +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 +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 `toplevel` build *is* the test. Do not fabricate a test harness. +- Do not touch `machines/configuration.nix`, `machines/jupiter/*`, or the KDE profile.