Feat/dank material shell #5

Open
finn.markwitz wants to merge 9 commits from feat/dank-material-shell into main
Showing only changes of commit 826a612d9d - Show all commits
@@ -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.