- 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
19 KiB
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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)
# 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)
# 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
# Validation: Context constraints
assertion = hostConfig.m3ta.context != "desktop" || hostConfig.m3ta.context != "server"
|| (hostConfig.m3ta.context == null); # Mutually exclusive
- Step 5: Commit Phase 2
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
# After migration, archive old features/
git mv home/features home/features.old
- Step 3: Verify all configurations are imported
# Check that all features are accessible in new structure
nix flake check
home-manager dry-activate
- Step 4: Commit Phase 3
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)
# 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)
# 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)
# This SHOULD fail - desktop and server together
m3ta.context = "desktop";
m3ta.profiles = [ "coding" ];
# Nix should throw assertion error
- Step 4: Commit Phase 4
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
# Search for any references to old paths
grep -r "home/features" --include="*.nix"
Expected: No results
- Step 2: Delete old directory
git rm -rf home/features.old
- Step 3: Final format and check
nix fmt
nix flake check
- Step 4: Final commit
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
-
NeoVim Config: Already in nixpkgs, reference via
inputs.m3ta-nixpkgs.packages.neovim-config -
Agent-System: Already in nixpkgs, reference via
inputs.m3ta-nixpkgs.homeModules.coding.agents -
Zed Remote: Desktop-only feature, works via SSH. No server-side installation needed.
-
Fish Shell: Removed from base (Nushell is primary). Can be added as optional profile if needed.
-
Feature Flags: Old
features.*.enableoptions → New profile listsm3ta.profiles = [ "gaming" "media" ]