docs: implementation plan for DankMaterialShell (niri) profile
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN
This commit is contained in:
@@ -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.<name>; in { options.my.profiles.<name>.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 <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-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.<name>` 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 <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 `./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 <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` (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 <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 `toplevel` build *is* the test. Do not fabricate a test harness.
|
||||||
|
- Do not touch `machines/configuration.nix`, `machines/jupiter/*`, or the KDE profile.
|
||||||
Reference in New Issue
Block a user