fix: code review fixes

- Fix hardcoded user path in webapps.nix (use homeDirectory)
- Normalize wallpapers option to use .enable suffix
- Remove duplicate FZF keybind declaration
- Update comments to match actual implementation
This commit is contained in:
m3tm3re
2026-04-26 10:48:52 +02:00
parent b1eb50a350
commit 06b430e067
10 changed files with 809 additions and 41 deletions

View File

@@ -0,0 +1,727 @@
# Home Profile Restructuring 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:** Restructure nixos-config/home/ from host-based to profile-based organization with clear separation between base, coding, profiles, desktop, and server layers.
**Architecture:** Three-layer model: Base (always loaded) → Coding (profile-independent) → Profiles/Context (freely combinable with constraints). Desktop and Server contexts are mutually exclusive.
**Tech Stack:** NixOS, Home Manager, Nix flakes
---
## File Structure
```
home/
├── base/ # IMMER geladen
│ ├── default.nix
│ ├── shell/
│ │ ├── default.nix
│ │ ├── nushell.nix # PRIMARY Shell
│ │ └── starship.nix
│ ├── cli-tools/
│ │ ├── default.nix
│ │ ├── fzf.nix
│ │ ├── zellij.nix
│ │ ├── nitch.nix
│ │ └── television.nix
│ └── secrets/
│ └── secrets.nix
├── coding/ # Profil-unabhängig
│ ├── default.nix
│ ├── editor/
│ │ ├── default.nix
│ │ └── neovim.nix # Basis NeoVim (aus nixpkgs referenziert)
│ ├── lsp/
│ │ ├── default.nix
│ │ └── servers.nix
│ ├── git/
│ │ └── git.nix
│ └── agents/
│ └── agents.nix # Agent-System (aus nixpkgs referenziert)
├── profiles/ # FREI KOMBINIERBAR
│ ├── gaming/
│ │ ├── default.nix
│ │ ├── steam.nix
│ │ └── gamescope.nix
│ │
│ └── media/
│ ├── default.nix
│ ├── obs.nix
│ ├── ffmpeg.nix
│ ├── yt-dlp.nix
│ ├── kdenlive.nix
│ └── handbrake.nix
├── desktop/ # NUR wenn context=desktop
│ ├── default.nix
│ ├── wm/
│ │ ├── default.nix
│ │ ├── hyprland.nix
│ │ ├── wayland.nix
│ │ └── rofi.nix
│ ├── apps/
│ │ ├── default.nix
│ │ ├── obsidian.nix
│ │ ├── office.nix
│ │ ├── webapps.nix
│ │ └── crypto.nix
│ └── theme/
│ ├── default.nix
│ ├── fonts.nix
│ ├── theme.nix
│ └── wallpapers.nix
└── server/
└── default.nix
```
**Key Integration Points:**
| Component | Source | Notes |
|-----------|--------|-------|
| NeoVim Config | `inputs.m3ta-nixpkgs.pkgs.neovim-config` | Custom package in nixpkgs |
| OpenCode Desktop | `inputs.m3ta-nixpkgs.pkgs.opencode-desktop` | Custom package |
| Agent-System | `inputs.m3ta-nixpkgs.homeModules.coding.agents` | OpenCode, Claude Code, Pi |
| Zed Editor | `inputs.m3ta-nixpkgs.homeModules.coding.editors` | Desktop-only via Zed Remote |
| Editor Module | `inputs.m3ta-nixpkgs.homeModules.coding.editors` | NeoVim (base) + Zed (desktop) |
---
## Phase 1: Create New Structure
### Task 1: Create Directory Structure
**Files:**
- Create: `home/base/default.nix`
- Create: `home/base/shell/default.nix`
- Create: `home/base/shell/nushell.nix`
- Create: `home/base/shell/starship.nix`
- Create: `home/base/cli-tools/default.nix`
- Create: `home/base/cli-tools/fzf.nix`
- Create: `home/base/cli-tools/zellij.nix`
- Create: `home/base/cli-tools/nitch.nix`
- Create: `home/base/cli-tools/television.nix`
- Create: `home/base/secrets/secrets.nix`
- Create: `home/coding/default.nix`
- Create: `home/coding/editor/default.nix`
- Create: `home/coding/editor/neovim.nix`
- Create: `home/coding/lsp/default.nix`
- Create: `home/coding/lsp/servers.nix`
- Create: `home/coding/git/git.nix`
- Create: `home/coding/agents/agents.nix`
- Create: `home/profiles/gaming/default.nix`
- Create: `home/profiles/gaming/steam.nix`
- Create: `home/profiles/gaming/gamescope.nix`
- Create: `home/profiles/media/default.nix`
- Create: `home/profiles/media/obs.nix`
- Create: `home/profiles/media/ffmpeg.nix`
- Create: `home/profiles/media/yt-dlp.nix`
- Create: `home/profiles/media/kdenlive.nix`
- Create: `home/profiles/media/handbrake.nix`
- Create: `home/desktop/default.nix`
- Create: `home/desktop/wm/default.nix`
- Create: `home/desktop/wm/hyprland.nix`
- Create: `home/desktop/wm/wayland.nix`
- Create: `home/desktop/wm/rofi.nix`
- Create: `home/desktop/apps/default.nix`
- Create: `home/desktop/apps/obsidian.nix`
- Create: `home/desktop/apps/office.nix`
- Create: `home/desktop/apps/webapps.nix`
- Create: `home/desktop/apps/crypto.nix`
- Create: `home/desktop/theme/default.nix`
- Create: `home/desktop/theme/fonts.nix`
- Create: `home/desktop/theme/theme.nix`
- Create: `home/desktop/theme/wallpapers.nix`
- Create: `home/server/default.nix`
- Modify: `home/default.nix` (Hauptaggregator)
- [ ] **Step 1: Create home/base/default.nix**
```nix
# home/base/default.nix
# Basis-Konfiguration: Shell + CLI-Tools + Secrets
# Wird IMMER geladen (kein enable-Flag)
{ inputs, lib, pkgs, ... }:
{
imports = [
./shell
./cli-tools
./secrets
];
}
```
- [ ] **Step 2: Create home/base/shell/default.nix**
```nix
# home/base/shell/default.nix
{ inputs, lib, pkgs, ... }:
{
imports = [
./nushell.nix
./starship.nix
];
}
```
- [ ] **Step 3: Create home/base/shell/nushell.nix**
Migrated from: `home/features/cli/nushell.nix`
```nix
# home/base/shell/nushell.nix
# Primary shell - Nushell
{ lib, pkgs, ... }:
{
programs.nushell = {
enable = true;
configFile = ...;
};
home.packages = with pkgs; [
nushell
];
}
```
- [ ] **Step 4: Create home/base/shell/starship.nix**
Migrated from: `home/features/cli/starship.nix`
- [ ] **Step 5: Create home/base/cli-tools/default.nix**
```nix
# home/base/cli-tools/default.nix
{ ... }:
{
imports = [
./fzf.nix
./zellij.nix
./nitch.nix
./television.nix
];
}
```
- [ ] **Step 6: Create CLI tool modules**
Migrate from `home/features/cli/`:
- `fzf.nix``home/base/cli-tools/fzf.nix`
- `zellij.nix``home/base/cli-tools/zellij.nix`
- `nitch.nix``home/base/cli-tools/nitch.nix`
- `television.nix``home/base/cli-tools/television.nix`
- [ ] **Step 7: Create home/base/secrets/secrets.nix**
Migrated from: `home/features/cli/secrets.nix`
- [ ] **Step 8: Create home/coding/default.nix**
```nix
# home/coding/default.nix
# Coding-Konfiguration: Editor + LSP + Git + Agents
# Wird geladen wenn coding Profil aktiviert
{ inputs, lib, pkgs, ... }:
{
imports = [
./editor
./lsp
./git
./agents
];
}
```
- [ ] **Step 9: Create home/coding/editor/default.nix**
References: `inputs.m3ta-nixpkgs.homeModules.coding.editors`
```nix
# home/coding/editor/default.nix
{ inputs, lib, pkgs, ... }:
{
# Importiert NeoVim (immer) + Zed (desktop)
imports = [
inputs.m3ta-nixpkgs.homeModules.coding.editors
];
# NeoVim Config Package
home.packages = [ inputs.m3ta-nixpkgs.packages.${pkgs.system}.neovim-config ];
}
```
- [ ] **Step 10: Create home/coding/lsp/default.nix + servers.nix**
Migrate LSP configuration from existing setup
- [ ] **Step 11: Create home/coding/git/git.nix**
```nix
# home/coding/git/git.nix
{ lib, pkgs, ... }:
{
programs.git = {
enable = true;
# Git configuration
};
}
```
- [ ] **Step 12: Create home/coding/agents/agents.nix**
References: `inputs.m3ta-nixpkgs.homeModules.coding.agents`
```nix
# home/coding/agents/agents.nix
{ inputs, lib, pkgs, ... }:
{
imports = [
inputs.m3ta-nixpkgs.homeModules.coding.agents
];
# Agent-Konfiguration
coding.agents.opencode = {
enable = true;
agentsInput = inputs.agents;
# modelOverrides...
};
}
```
- [ ] **Step 13: Create home/profiles/gaming/default.nix**
```nix
# home/profiles/gaming/default.nix
# Gaming Profile - frei kombinierbar
{ lib, pkgs, ... }:
{
imports = [
./steam.nix
./gamescope.nix
];
}
```
- [ ] **Step 14: Create gaming profile modules**
- `steam.nix` - Steam + Steam Deck Tools
- `gamescope.nix` - Gamescope Session
- [ ] **Step 15: Create home/profiles/media/default.nix**
```nix
# home/profiles/media/default.nix
# Media Profile - Content Creation / Streaming
{ lib, pkgs, ... }:
{
imports = [
./obs.nix
./ffmpeg.nix
./yt-dlp.nix
./kdenlive.nix
./handbrake.nix
];
}
```
- [ ] **Step 16: Create media profile modules**
Migrate from `home/features/desktop/media.nix`:
- `obs.nix` - OBS Studio
- `ffmpeg.nix` - FFmpeg + Tools
- `yt-dlp.nix` - YouTube Downloader
- `kdenlive.nix` - Kdenlive Video Editor
- `handbrake.nix` - HandBrake
- [ ] **Step 17: Create home/desktop/default.nix**
```nix
# home/desktop/default.nix
# Desktop-Konfiguration - nur wenn context=desktop
{ lib, pkgs, ... }:
{
# Zed Remote: Server-Zugriff via SSH
programs.zed-editor = {
enable = true;
# Remote Connections Config
};
imports = [
./wm
./apps
./theme
];
}
```
- [ ] **Step 18: Create home/desktop/wm modules**
Migrate from `home/features/desktop/`:
- `hyprland.nix``home/desktop/wm/hyprland.nix`
- `wayland.nix``home/desktop/wm/wayland.nix`
- `rofi.nix``home/desktop/wm/rofi.nix`
- [ ] **Step 19: Create home/desktop/apps modules**
Migrate from `home/features/desktop/`:
- `obsidian.nix``home/desktop/apps/obsidian.nix`
- `office.nix``home/desktop/apps/office.nix`
- `webapps.nix``home/desktop/apps/webapps.nix`
- `crypto.nix``home/desktop/apps/crypto.nix`
- [ ] **Step 20: Create home/desktop/theme modules**
Migrate from `home/features/desktop/`:
- `fonts.nix``home/desktop/theme/fonts.nix`
- `theme.nix``home/desktop/theme/theme.nix`
- `wallpapers.nix``home/desktop/theme/wallpapers.nix`
- [ ] **Step 21: Create home/server/default.nix**
```nix
# home/server/default.nix
# Server-Konfiguration - nur wenn context=server
# Minimal da primär via Zed Remote gearbeitet wird
{ lib, pkgs, ... }:
{
# Server-spezifische Konfiguration falls nötig
}
```
- [ ] **Step 22: Commit Phase 1**
```bash
git add home/
git commit -m "feat(home): create new directory structure
- Add base/ with shell, cli-tools, secrets
- Add coding/ with editor, lsp, git, agents
- Add profiles/ with gaming, media
- Add desktop/ with wm, apps, theme
- Add server/ minimal config
- Reference m3ta-nixpkgs modules where appropriate"
```
---
## Phase 2: Create Profile System with Constraints
### Task 2: Implement Profile Loader with Mutual Exclusion
**Files:**
- Create: `home/lib/default.nix` (Profile loading utilities)
- Modify: `flake.nix` (Host-spezifische Home-Config)
- Modify: `hosts/common/users/home.nix`
- [ ] **Step 1: Create home/lib/default.nix**
```nix
# home/lib/default.nix
# Profile loading utilities
{ lib }:
{
# Generiert Home-Manager Konfiguration basierend auf Profilen
mkHomeConfig = {
profiles ? [],
context ? null, # "desktop" | "server" | null
}: let
inherit (lib) optionalAttrs mkIf;
# Profile die immer geladen werden
baseModules = [ ./base ];
# Profile die optional geladen werden
profileModules = optionalAttrs (builtins.elem "coding" profiles) [ ./coding ];
# Context-spezifische Module
contextModules = {
desktop = [ ./desktop ];
server = [ ./server ];
};
# Profile-spezifische Module
profileSpecific = {
gaming = [ ./profiles/gaming ];
media = [ ./profiles/media ];
};
in {
imports = baseModules ++ profileModules
++ (contextModules.${context} or [])
++ (builtins.map (p: ./profiles.${p})
(builtins.filter (p: builtins.hasAttr p profileSpecific) profiles));
};
# Assertion: desktop und server schließen sich aus
mutualExclusiveContexts = builtins.hasAttr "desktop" && builtins.hasAttr "server";
}
```
- [ ] **Step 2: Update flake.nix for m3-ares (Desktop)**
```nix
# hosts/m3-ares/ (Desktop Beispiel)
{ inputs, lib, pkgs, ... }:
{
# Home-Manager für m3tam3re auf m3-ares
home-manager.users.m3tam3re = { config, ... }: {
# NEU: Profile-System
m3ta.profiles = [ "coding" "gaming" "media" ]; # Freie Kombination
m3ta.context = "desktop"; # Schließt "server" aus
# Alternativ: Legacy-Kompatibilität
# imports = [ ./home ];
};
}
```
- [ ] **Step 3: Update flake.nix for m3-atlas (Server)**
```nix
# hosts/m3-atlas/ (Server Beispiel)
{ inputs, lib, pkgs, ... }:
{
home-manager.users.m3tam3re = { config, ... }: {
m3ta.profiles = [ "coding" ]; # Nur Coding auf Server
m3ta.context = "server"; # Schließt "desktop" aus
};
}
```
- [ ] **Step 4: Add assertions in flake.nix**
```nix
# Validation: Context constraints
assertion = hostConfig.m3ta.context != "desktop" || hostConfig.m3ta.context != "server"
|| (hostConfig.m3ta.context == null); # Mutually exclusive
```
- [ ] **Step 5: Commit Phase 2**
```bash
git add flake.nix hosts/
git commit -m "feat: implement profile system with constraints
- Add home/lib for profile loading utilities
- Add m3ta.profiles option (list of profiles)
- Add m3ta.context option (desktop|server|null)
- Add mutual exclusion assertion
- Update m3-ares and m3-atlas as examples"
```
---
## Phase 3: Migrate Existing Configuration
### Task 3: Migrate home/features to new Structure
**Files:**
- Modify: Multiple files in `home/features/` (move content, update paths)
- [ ] **Step 1: Map existing features to new structure**
| Old Location | New Location | Notes |
|--------------|--------------|-------|
| `home/features/cli/nushell.nix` | `home/base/shell/nushell.nix` | ✓ Done in Task 1 |
| `home/features/cli/starship.nix` | `home/base/shell/starship.nix` | ✓ Done in Task 1 |
| `home/features/cli/fzf.nix` | `home/base/cli-tools/fzf.nix` | ✓ Done in Task 1 |
| `home/features/cli/zellij.nix` | `home/base/cli-tools/zellij.nix` | ✓ Done in Task 1 |
| `home/features/cli/nitch.nix` | `home/base/cli-tools/nitch.nix` | ✓ Done in Task 1 |
| `home/features/cli/television.nix` | `home/base/cli-tools/television.nix` | ✓ Done in Task 1 |
| `home/features/cli/secrets.nix` | `home/base/secrets/secrets.nix` | ✓ Done in Task 1 |
| `home/features/coding/opencode.nix` | Reference via `m3ta-nixpkgs` | Update import |
| `home/features/coding/pi.nix` | Reference via `m3ta-nixpkgs` | Update import |
| `home/features/desktop/hyprland.nix` | `home/desktop/wm/hyprland.nix` | ✓ Done in Task 1 |
| `home/features/desktop/wayland.nix` | `home/desktop/wm/wayland.nix` | ✓ Done in Task 1 |
| `home/features/desktop/rofi.nix` | `home/desktop/wm/rofi.nix` | ✓ Done in Task 1 |
| `home/features/desktop/obsidian.nix` | `home/desktop/apps/obsidian.nix` | ✓ Done in Task 1 |
| `home/features/desktop/office.nix` | `home/desktop/apps/office.nix` | ✓ Done in Task 1 |
| `home/features/desktop/webapps.nix` | `home/desktop/apps/webapps.nix` | ✓ Done in Task 1 |
| `home/features/desktop/crypto.nix` | `home/desktop/apps/crypto.nix` | ✓ Done in Task 1 |
| `home/features/desktop/fonts.nix` | `home/desktop/theme/fonts.nix` | ✓ Done in Task 1 |
| `home/features/desktop/theme.nix` | `home/desktop/theme/theme.nix` | ✓ Done in Task 1 |
| `home/features/desktop/wallpapers.nix` | `home/desktop/theme/wallpapers.nix` | ✓ Done in Task 1 |
| `home/features/desktop/media.nix` | `home/profiles/media/*.nix` | Split into modules |
| `home/features/desktop/gaming.nix` | `home/profiles/gaming/*.nix` | Split into modules |
- [ ] **Step 2: Archive old structure**
```bash
# After migration, archive old features/
git mv home/features home/features.old
```
- [ ] **Step 3: Verify all configurations are imported**
```bash
# Check that all features are accessible in new structure
nix flake check
home-manager dry-activate
```
- [ ] **Step 4: Commit Phase 3**
```bash
git add -A
git commit -m "chore: migrate features to profile structure
- Move all cli features to base/shell and base/cli-tools
- Move desktop features to desktop/* subdirectories
- Split media into individual profile modules
- Split gaming into individual profile modules
- Archive old features/ directory"
```
---
## Phase 4: Test and Validate
### Task 4: Test Profile Combinations
**Files:**
- Test: Manual testing on m3-ares (Desktop)
- Test: Manual testing on m3-atlas (Server)
- [ ] **Step 1: Test m3-ares (Desktop with all profiles)**
```bash
# Build and test on m3-ares
nixos-rebuild dry-build --flake .#m3-ares
home-manager dry-activate --flake .#m3tam3re@m3-ares
```
Expected: Loads base + coding + desktop + gaming + media
- [ ] **Step 2: Test m3-atlas (Server with coding only)**
```bash
# Build and test on m3-atlas
nixos-rebuild dry-build --flake .#m3-atlas
home-manager dry-activate --flake .#m3tam3re@m3-atlas
```
Expected: Loads base + coding + server (no desktop modules)
- [ ] **Step 3: Test assertion (should fail)**
```nix
# This SHOULD fail - desktop and server together
m3ta.context = "desktop";
m3ta.profiles = [ "coding" ];
# Nix should throw assertion error
```
- [ ] **Step 4: Commit Phase 4**
```bash
git commit -m "test: validate profile combinations on all hosts
- m3-ares: base + coding + desktop + gaming + media ✓
- m3-atlas: base + coding + server ✓
- Constraint assertion working ✓"
```
---
## Phase 5: Cleanup
### Task 5: Remove Old Structure
**Files:**
- Delete: `home/features.old/` (after verification)
- [ ] **Step 1: Verify no broken imports**
```bash
# Search for any references to old paths
grep -r "home/features" --include="*.nix"
```
Expected: No results
- [ ] **Step 2: Delete old directory**
```bash
git rm -rf home/features.old
```
- [ ] **Step 3: Final format and check**
```bash
nix fmt
nix flake check
```
- [ ] **Step 4: Final commit**
```bash
git commit -m "chore: remove old features directory
Cleanup complete. New structure:
- home/base/ (always loaded)
- home/coding/ (profile-independent)
- home/profiles/ (gaming, media)
- home/desktop/ (context=desktop)
- home/server/ (context=server)"
```
---
## Summary
| Phase | Tasks | Description |
|-------|-------|-------------|
| 1 | 1 | Create new directory structure |
| 2 | 2 | Implement profile system with constraints |
| 3 | 3 | Migrate existing features |
| 4 | 4 | Test profile combinations |
| 5 | 5 | Remove old structure |
**Total:** 5 tasks, ~22 steps
**Expected Duration:** 2-4 hours (depending on migration complexity)
---
## Migration Notes
1. **NeoVim Config**: Already in nixpkgs, reference via `inputs.m3ta-nixpkgs.packages.neovim-config`
2. **Agent-System**: Already in nixpkgs, reference via `inputs.m3ta-nixpkgs.homeModules.coding.agents`
3. **Zed Remote**: Desktop-only feature, works via SSH. No server-side installation needed.
4. **Fish Shell**: Removed from base (Nushell is primary). Can be added as optional profile if needed.
5. **Feature Flags**: Old `features.*.enable` options → New profile lists `m3ta.profiles = [ "gaming" "media" ]`