diff --git a/docs/plans/2026-04-27-missing-packages.md b/docs/plans/2026-04-27-missing-packages.md
new file mode 100644
index 0000000..303aff9
--- /dev/null
+++ b/docs/plans/2026-04-27-missing-packages.md
@@ -0,0 +1,259 @@
+# Missing Packages Implementation Plan
+
+> **Goal:** Restore missing packages from old configuration to new profile-based structure
+
+**Context:** The home profile restructuring (Task 1-5) moved files but left many packages unaccounted for. This plan categorizes and assigns each package to the appropriate location.
+
+---
+
+## Package Categorization
+
+### Base Layer (`home/base/`) — Always Available
+
+These are CLI tools that work on any system (server or desktop):
+
+| Package | Source | Module | Option |
+|---------|--------|--------|--------|
+| `jq` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `ripgrep` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `fd` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `coreutils` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `htop` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `httpie` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `just` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `lazygit` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `lf` | old cli | `home/base/cli-tools/default.nix` | `home/packages` |
+| `tldr` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `trash-cli` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `unzip` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `zip` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `yazi` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `gcc` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `go` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `sqlite` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `sqlite-vec` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `nix-index` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `nix-update` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `progress` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `devenv` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `libnotify` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `basecamp` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `comma` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `fabric-ai` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `llm` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+| `hyprpaper-random` | old cli | `home/base/cli-tools/default.nix` | `home.packages` |
+
+**Note:** `hyprpaper-random` is in base despite being Hyprland-specific. Alternative: move to `desktop/wm/` if it causes issues on non-Hyprland systems.
+
+### Base Programs (CLI Integration)
+
+These are programs with shell integration, placed in `home/base/cli-tools/`:
+
+| Program | Source | Module | Option |
+|---------|--------|--------|--------|
+| `carapace` | old cli | `home/base/cli-tools/default.nix` | `programs.carapace` |
+| `zoxide` | old cli | `home/base/cli-tools/default.nix` | `programs.zoxide` |
+| `bat` | old cli | `home/base/cli-tools/default.nix` | `programs.bat` |
+| `direnv` | old cli | `home/base/cli-tools/default.nix` | `programs.direnv` |
+| `eza` | old cli | `home/base/cli-tools/default.nix` | `programs.eza` |
+| `lf` | old cli | `home/base/cli-tools/default.nix` | `programs.lf` |
+| `zellij-ps` | old cli | `home/base/cli-tools/default.nix` | `cli.zellij-ps` |
+
+### Coding Layer (`home/coding/`) — Developer Tools
+
+| Package | Source | Module | Option |
+|---------|--------|--------|--------|
+| `bruno` | old desktop/coding | `home/coding/packages.nix` | `home.packages` |
+| `insomnia` | old desktop/coding | `home/coding/packages.nix` | `home.packages` |
+| `vim` | - | `home/coding/packages.nix` | `home.packages` |
+
+**New module:** `home/coding/packages.nix` (or inline into `coding/default.nix`)
+
+### Desktop Layer (`home/desktop/`) — Desktop-Specific
+
+| Package | Source | Module | Option |
+|---------|--------|--------|--------|
+| `vibetyper` | old desktop | `home/desktop/apps/default.nix` | `home.packages` |
+| `pomodoro-timer` | old cli | `home/desktop/apps/default.nix` | `home.packages` |
+| `launch-timer` | - | `home/desktop/apps/default.nix` | `home.packages` |
+
+**Note:** `launch-timer` needs investigation - is it a custom script or nixpkgs package?
+
+### Gaming Profile (`home/profiles/gaming/`) — Gaming Only
+
+| Package | Source | Module | Option |
+|---------|--------|--------|--------|
+| `rocmPackages.rocm-smi` | old cli | `home/profiles/gaming/default.nix` | `home.packages` |
+| `rocmPackages.rocminfo` | old cli | `home/profiles/gaming/default.nix` | `home.packages` |
+| `rocmPackages.rocm-runtime` | old cli | `home/profiles/gaming/default.nix` | `home.packages` |
+| `vulkan-tools` | old cli | `home/profiles/gaming/default.nix` | `home.packages` |
+
+**Rationale:** ROCm is for AMD GPUs used in gaming (e.g., ROG Ally, gaming laptops with AMD dGPUs). This keeps server configs clean.
+
+### Media Profile (`home/profiles/media/`) — Media Creation
+
+| Package | Source | Module | Option |
+|---------|--------|--------|--------|
+| `plexamp` | old desktop/media | `home/profiles/media/default.nix` | `home.packages` |
+| `webcord` | old desktop/media | `home/profiles/media/default.nix` | `home.packages` |
+| `unimatrix` | old cli | `home/profiles/media/default.nix` | `home.packages` |
+| `mpv` (config) | old desktop/media | `home/profiles/media/default.nix` | `programs.mpv` |
+
+**Note:** `unimatrix` is a terminal screensaver - fits well with media profile.
+
+---
+
+## NOT Needed (Explicitly Removed)
+
+These packages should NOT be added:
+
+| Package | Reason |
+|---------|--------|
+| `wireguard-tools` | No longer needed |
+| `wttrbar` | No longer needed |
+| `nushellPlugins.skim` | No longer needed |
+
+---
+
+## Tasks
+
+### Task 1: Update `home/base/cli-tools/default.nix`
+
+Add missing packages to the CLI tools aggregator:
+
+```nix
+home.packages = with pkgs; [
+ # Core utilities
+ jq ripgrep fd coreutils htop
+ # Dev tools
+ just lazylib lf tldr devenv
+ gcc go sqlite sqlite-vec
+ nix-index nix-update progress
+ # AI tools
+ comma fabric-ai llm
+ # Misc
+ libnotify basecamp hyprpaper-random
+ trash-cli unzip zip yazi
+];
+```
+
+Also add programs: carapace, zoxide, bat, direnv, eza, lf, zellij-ps
+
+### Task 2: Create `home/coding/packages.nix`
+
+New module for coding-specific packages:
+
+```nix
+{ lib, pkgs, ... }:
+
+{
+ options.coding.packages = {
+ enable = mkEnableOption "additional coding packages";
+ };
+
+ config = mkIf config.coding.packages.enable {
+ home.packages = with pkgs; [
+ bruno
+ insomnia
+ ];
+ };
+}
+```
+
+### Task 3: Update `home/profiles/gaming/default.nix`
+
+Add GPU monitoring tools:
+
+```nix
+home.packages = with pkgs; [
+ # Gaming utilities
+ gamescope gamemode goverlay mangohud protonplus
+ # AMD GPU monitoring (ROCm)
+ rocmPackages.rocm-smi
+ rocmPackages.rocminfo
+ rocmPackages.rocm-runtime
+ vulkan-tools
+];
+```
+
+### Task 4: Update `home/profiles/media/default.nix`
+
+Add missing media packages:
+
+```nix
+home.packages = with pkgs; [
+ # Already present: ffmpeg_6-full, gimp, handbrake, etc.
+ # Add missing:
+ plexamp
+ webcord
+ unimatrix
+];
+
+programs.mpv = {
+ enable = true;
+ bindings = {
+ WHEEL_UP = "seek 10";
+ WHEEL_DOWN = "seek -10";
+ };
+ config = {
+ profile = "gpu-hq";
+ ytdl-format = "bestvideo+bestaudio";
+ };
+};
+```
+
+### Task 5: Update Desktop Apps
+
+Add desktop-specific packages to `home/desktop/apps/default.nix`:
+
+```nix
+home.packages = with pkgs; [
+ # Already present
+ # Add missing:
+ pomodoro-timer
+ # launch-timer - needs investigation
+];
+```
+
+### Task 6: Update Host Configs
+
+Ensure all desktop hosts import the new modules:
+
+- `home/m3tam3re/m3-ares.nix` - Should have `coding.packages.enable = true`
+- `home/m3tam3re/m3-kratos.nix` - Should have `coding.packages.enable = true`
+
+---
+
+## Implementation Order
+
+1. **Task 1** - Base CLI tools (largest impact, affects all hosts)
+2. **Task 2** - Coding packages (small, new module)
+3. **Task 3** - Gaming profile (ROCm)
+4. **Task 4** - Media profile (plexamp, webcord, unimatrix, mpv)
+5. **Task 5** - Desktop apps (vibetyper already present, add pomodoro-timer)
+6. **Task 6** - Host config updates (if needed)
+
+---
+
+## Verification
+
+```bash
+nix flake check
+# Should pass with no new errors
+```
+
+---
+
+## Summary
+
+| Layer | New Files | Modified Files |
+|-------|-----------|----------------|
+| base/cli-tools | - | `default.nix` |
+| coding | `packages.nix` | `default.nix` |
+| profiles/gaming | - | `default.nix` |
+| profiles/media | - | `default.nix` |
+| desktop/apps | - | `default.nix` |
+
+**Total packages to restore:** ~30
+**Programs to restore:** 7
+**Packages excluded:** 3 (wireguard, wttrbar, nushellPlugins.skim)
diff --git a/home/base/cli-tools/bat.nix b/home/base/cli-tools/bat.nix
index 473ae69..9a0e213 100644
--- a/home/base/cli-tools/bat.nix
+++ b/home/base/cli-tools/bat.nix
@@ -9,7 +9,8 @@ with lib; let
cfg = config.base.cliTools.bat;
palette = config.colorScheme.palette;
in {
- options.base.cliTools.bat.enable = mkEnableOption "enable bat with nix-colors theme";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.bat.enable = (mkEnableOption "enable bat with nix-colors theme") // {default = true;};
config = mkIf cfg.enable {
programs.bat = {
diff --git a/home/base/cli-tools/carapace.nix b/home/base/cli-tools/carapace.nix
index 5fbb595..ea9194e 100644
--- a/home/base/cli-tools/carapace.nix
+++ b/home/base/cli-tools/carapace.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.carapace;
in {
- options.base.cliTools.carapace.enable = mkEnableOption "enable carapace completion engine";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.carapace.enable = (mkEnableOption "enable carapace completion engine") // {default = true;};
config = mkIf cfg.enable {
programs.carapace = {
diff --git a/home/base/cli-tools/direnv.nix b/home/base/cli-tools/direnv.nix
index d7f7c7e..4ca206a 100644
--- a/home/base/cli-tools/direnv.nix
+++ b/home/base/cli-tools/direnv.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.direnv;
in {
- options.base.cliTools.direnv.enable = mkEnableOption "enable direnv with nix-direnv";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.direnv.enable = (mkEnableOption "enable direnv with nix-direnv") // {default = true;};
config = mkIf cfg.enable {
programs.direnv = {
diff --git a/home/base/cli-tools/eza.nix b/home/base/cli-tools/eza.nix
index 9d2df93..2e432a8 100644
--- a/home/base/cli-tools/eza.nix
+++ b/home/base/cli-tools/eza.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.eza;
in {
- options.base.cliTools.eza.enable = mkEnableOption "enable eza modern ls replacement";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.eza.enable = (mkEnableOption "enable eza modern ls replacement") // {default = true;};
config = mkIf cfg.enable {
programs.eza = {
diff --git a/home/base/cli-tools/fzf.nix b/home/base/cli-tools/fzf.nix
index f4ef6af..4093298 100644
--- a/home/base/cli-tools/fzf.nix
+++ b/home/base/cli-tools/fzf.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.fzf;
in {
- options.base.cliTools.fzf.enable = mkEnableOption "enable fuzzy finder";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.fzf.enable = (mkEnableOption "enable fuzzy finder") // {default = true;};
config = mkIf cfg.enable {
programs.fzf = {
diff --git a/home/base/cli-tools/lf.nix b/home/base/cli-tools/lf.nix
index 67bc50a..50ff740 100644
--- a/home/base/cli-tools/lf.nix
+++ b/home/base/cli-tools/lf.nix
@@ -8,7 +8,8 @@
with lib; let
cfg = config.base.cliTools.lf;
in {
- options.base.cliTools.lf.enable = mkEnableOption "enable lf terminal file manager";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.lf.enable = (mkEnableOption "enable lf terminal file manager") // {default = true;};
config = mkIf cfg.enable {
home.packages = [pkgs.lf];
diff --git a/home/base/cli-tools/nitch.nix b/home/base/cli-tools/nitch.nix
index dc2147d..eac4d62 100644
--- a/home/base/cli-tools/nitch.nix
+++ b/home/base/cli-tools/nitch.nix
@@ -8,7 +8,8 @@
with lib; let
cfg = config.base.cliTools.nitch;
in {
- options.base.cliTools.nitch.enable = mkEnableOption "enable nitch";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.nitch.enable = (mkEnableOption "enable nitch") // {default = true;};
config = mkIf cfg.enable {
home.packages = [pkgs.nitch];
diff --git a/home/base/cli-tools/packages.nix b/home/base/cli-tools/packages.nix
index fcfec2a..aee3c41 100644
--- a/home/base/cli-tools/packages.nix
+++ b/home/base/cli-tools/packages.nix
@@ -1,4 +1,6 @@
# Essential CLI packages — core utilities always available on every host.
+# NOTE: `lazylib` does not exist in nixpkgs. `lazygit` is the correct package
+# (Git TUI) and is intentionally used here instead.
{
config,
lib,
@@ -8,7 +10,8 @@
with lib; let
cfg = config.base.cliTools.essentials;
in {
- options.base.cliTools.essentials.enable = mkEnableOption "enable essential CLI packages";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.essentials.enable = (mkEnableOption "enable essential CLI packages") // {default = true;};
config = mkIf cfg.enable {
home.packages = with pkgs; [
@@ -19,22 +22,30 @@ in {
jq
ripgrep
+ # Nix
+ alejandra
+ comma
+ nixd
+ nix-diff
+ nix-index
+ nix-update
+
# Dev tools
+ bc
+ cmake
devenv
gcc
+ gnumake
go
httpie
just
lazygit
- nix-index
- nix-update
progress
sqlite
sqlite-vec
tldr
# AI tools
- comma
fabric-ai
llm
diff --git a/home/base/cli-tools/television.nix b/home/base/cli-tools/television.nix
index 3c6aa67..3a74203 100644
--- a/home/base/cli-tools/television.nix
+++ b/home/base/cli-tools/television.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.television;
in {
- options.base.cliTools.television.enable = mkEnableOption "enable television";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.television.enable = (mkEnableOption "enable television") // {default = true;};
config = mkIf cfg.enable {
programs.television = {
diff --git a/home/base/cli-tools/zellij-ps.nix b/home/base/cli-tools/zellij-ps.nix
index c2f8c72..8dac702 100644
--- a/home/base/cli-tools/zellij-ps.nix
+++ b/home/base/cli-tools/zellij-ps.nix
@@ -1,5 +1,7 @@
# Zellij-ps — project-aware Zellij session manager from m3ta-nixpkgs.
-# Delegates to the cli.zellij-ps module provided by inputs.m3ta-nixpkgs.
+# Delegates to `cli.zellij-ps` — the home-manager module namespace provided by
+# m3ta-nixpkgs (inputs.m3ta-nixpkgs.nixosModules.default). This is intentional;
+# `cli.*` is the convention used by m3ta-nixpkgs home-manager modules.
{
config,
lib,
@@ -9,7 +11,8 @@ with lib; let
cfg = config.base.cliTools.zellijPs;
in {
options.base.cliTools.zellijPs = {
- enable = mkEnableOption "enable zellij-ps project session manager";
+ # Enabled by default — base modules are always-on.
+ enable = (mkEnableOption "enable zellij-ps project session manager") // {default = true;};
projectFolders = mkOption {
type = types.listOf types.path;
diff --git a/home/base/cli-tools/zellij.nix b/home/base/cli-tools/zellij.nix
index 38e5c40..efe2c6c 100644
--- a/home/base/cli-tools/zellij.nix
+++ b/home/base/cli-tools/zellij.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.zellij;
in {
- options.base.cliTools.zellij.enable = mkEnableOption "enable zellij multiplexer";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.zellij.enable = (mkEnableOption "enable zellij multiplexer") // {default = true;};
config = mkIf cfg.enable {
programs.zellij = {
diff --git a/home/base/cli-tools/zoxide.nix b/home/base/cli-tools/zoxide.nix
index 8c27c6f..bc3e80e 100644
--- a/home/base/cli-tools/zoxide.nix
+++ b/home/base/cli-tools/zoxide.nix
@@ -7,7 +7,8 @@
with lib; let
cfg = config.base.cliTools.zoxide;
in {
- options.base.cliTools.zoxide.enable = mkEnableOption "enable zoxide smarter cd";
+ # Enabled by default — base modules are always-on.
+ options.base.cliTools.zoxide.enable = (mkEnableOption "enable zoxide smarter cd") // {default = true;};
config = mkIf cfg.enable {
programs.zoxide = {
diff --git a/home/base/default.nix b/home/base/default.nix
new file mode 100644
index 0000000..daa5afb
--- /dev/null
+++ b/home/base/default.nix
@@ -0,0 +1,9 @@
+# Base home-manager configuration — always loaded on every host.
+# Includes shell, CLI tools, and secrets modules.
+{...}: {
+ imports = [
+ ./shell
+ ./cli-tools
+ ./secrets/secrets.nix
+ ];
+}
diff --git a/home/features/cli/secrets.nix b/home/base/secrets/secrets.nix
similarity index 51%
rename from home/features/cli/secrets.nix
rename to home/base/secrets/secrets.nix
index c1848f3..324546b 100644
--- a/home/features/cli/secrets.nix
+++ b/home/base/secrets/secrets.nix
@@ -1,3 +1,4 @@
+# Password store and secrets management via pass-wayland with OTP and import extensions.
{
config,
lib,
@@ -5,9 +6,10 @@
...
}:
with lib; let
- cfg = config.features.cli.secrets;
+ cfg = config.base.secrets;
in {
- options.features.cli.secrets.enable = mkEnableOption "enable secrets";
+ # Enabled by default — base modules are always-on.
+ options.base.secrets.enable = (mkEnableOption "enable secrets management") // {default = true;};
config = mkIf cfg.enable {
programs.password-store = {
@@ -17,6 +19,6 @@ in {
(exts: [exts.pass-otp exts.pass-import]);
settings = {PASSWORD_STORE_DIR = "$XDG_DATA_HOME/password-store";};
};
- home.packages = with pkgs; [pinentry-gnome3];
+ home.packages = [pkgs.pinentry-gnome3];
};
}
diff --git a/home/base/shell/default.nix b/home/base/shell/default.nix
new file mode 100644
index 0000000..0b02d43
--- /dev/null
+++ b/home/base/shell/default.nix
@@ -0,0 +1,8 @@
+# Shell aggregator — imports Nushell (primary), Fish, and Starship prompt.
+{...}: {
+ imports = [
+ ./nushell.nix
+ ./fish.nix
+ ./starship.nix
+ ];
+}
diff --git a/home/features/cli/fish.nix b/home/base/shell/fish.nix
similarity index 95%
rename from home/features/cli/fish.nix
rename to home/base/shell/fish.nix
index 7d80aea..6c6e3ad 100644
--- a/home/features/cli/fish.nix
+++ b/home/base/shell/fish.nix
@@ -1,12 +1,14 @@
+# Fish shell configuration exposed under the new base namespace.
{
config,
lib,
...
}:
with lib; let
- cfg = config.features.cli.fish;
+ cfg = config.base.shell.fish;
in {
- options.features.cli.fish.enable = mkEnableOption "enable fish shell";
+ # Enabled by default — base modules are always-on.
+ options.base.shell.fish.enable = (mkEnableOption "enable fish shell") // {default = true;};
config = mkIf cfg.enable {
programs.fish = {
diff --git a/home/features/cli/nushell.nix b/home/base/shell/nushell.nix
similarity index 78%
rename from home/features/cli/nushell.nix
rename to home/base/shell/nushell.nix
index 16d1cba..fccb7f0 100644
--- a/home/features/cli/nushell.nix
+++ b/home/base/shell/nushell.nix
@@ -1,12 +1,14 @@
+# Primary shell configuration — Nushell with environment, aliases, and integrations.
{
config,
lib,
...
}:
with lib; let
- cfg = config.features.cli.nushell;
+ cfg = config.base.shell.nushell;
in {
- options.features.cli.nushell.enable = mkEnableOption "enable nushell";
+ # Enabled by default — base modules are always-on.
+ options.base.shell.nushell.enable = (mkEnableOption "enable nushell") // {default = true;};
config = mkIf cfg.enable {
programs.nushell = {
@@ -20,9 +22,8 @@ in {
$env.EDITOR = "nvim"
$env.VISUAL = "zeditor"
$env.FZF_DEFAULT_COMMAND = "fd --type f --exclude .git --follow --hidden"
- $env.FZF_DEFAULT_OPTS = "--preview='bat --color=always -n {}' --bind 'ctrl-/:toggle-preview' --header 'Press CTRL-Y to copy command into clipboard' --bind 'ctrl-/:toggle-preview' --bind 'ctrl-y:execute-silent(echo -n {2..} | wl-copy)+abort' --color bg:#282a36,bg+:#44475a,fg:#f8f8f2,fg+:#f8f8f2,header:#6272a4,hl:#bd93f9,hl+:#bd93f9,info:#ffb86c,marker:#ff79c6,pointer:#ff79c6,prompt:#50fa7b,spinner:#ffb86c"
+ $env.FZF_DEFAULT_OPTS = "--preview='bat --color=always -n {}' --bind 'ctrl-/:toggle-preview' --header 'Press CTRL-Y to copy command into clipboard' --bind 'ctrl-y:execute-silent(echo -n {2..} | wl-copy)+abort' --color bg:#282a36,bg+:#44475a,fg:#f8f8f2,fg+:#f8f8f2,header:#6272a4,hl:#bd93f9,hl+:#bd93f9,info:#ffb86c,marker:#ff79c6,pointer:#ff79c6,prompt:#50fa7b,spinner:#ffb86c"
$env.XDG_DATA_HOME = $"($env.HOME)/.local/share"
- $env.FZF_DEFAULT_COMMAND = "fd --type f --exclude .git --follow --hidden"
$env.SSH_AUTH_SOCK = "/run/user/1000/gnupg/S.gpg-agent.ssh"
$env.PATH = ($env.PATH | split row (char esep) | append $"($env.HOME)/.cache/.bun/bin" | append $"($env.HOME)/.npm-global/bin" | uniq)
$env.NPM_CONFIG_PREFIX = $"($env.HOME)/.npm-global"
@@ -40,12 +41,6 @@ in {
}
'';
- # if (tty) == "/dev/tty1" {
- # exec uwsm start -S -F /run/current-system/sw/bin/Hyprland
- # }
- # if (tty) == "/dev/tty2" {
- # exec gamescope -O HDMI-A-1 -W 1920 -H 1080 --adaptive-sync --hdr-enabled --rt --steam -- steam -pipewire-dmabuf -tenfoot
- # }
configFile.text = ''
# Aliases
alias .. = cd ..
diff --git a/home/features/cli/starship.nix b/home/base/shell/starship.nix
similarity index 86%
rename from home/features/cli/starship.nix
rename to home/base/shell/starship.nix
index 0861293..5d467d6 100644
--- a/home/features/cli/starship.nix
+++ b/home/base/shell/starship.nix
@@ -1,12 +1,14 @@
+# Starship cross-shell prompt with nix-colors theming.
{
config,
lib,
...
}:
with lib; let
- cfg = config.features.cli.starship;
+ cfg = config.base.shell.starship;
in {
- options.features.cli.starship.enable = mkEnableOption "enable starship prompt";
+ # Enabled by default — base modules are always-on.
+ options.base.shell.starship.enable = (mkEnableOption "enable starship prompt") // {default = true;};
config = mkIf cfg.enable {
programs.starship = {
diff --git a/home/features/coding/default.nix b/home/coding/agents/agents.nix
similarity index 71%
rename from home/features/coding/default.nix
rename to home/coding/agents/agents.nix
index d8ba37b..e710d06 100644
--- a/home/features/coding/default.nix
+++ b/home/coding/agents/agents.nix
@@ -1,17 +1,16 @@
+# AI agent system — OpenCode, Pi, and MCP server configuration.
+# Relies on coding.agents options provided by home/common/default.nix
+# (inputs.m3ta-nixpkgs.homeManagerModules.default).
{
config,
inputs,
+ lib,
pkgs,
- videoDrivers,
+ videoDrivers ? [],
...
-}: let
- npmGlobalPrefix = "${config.home.homeDirectory}/.npm-global";
-in {
- home.file.".npmrc".text = ''
- prefix=${npmGlobalPrefix}
- '';
- home.sessionVariables.NPM_CONFIG_PREFIX = npmGlobalPrefix;
+}: {
imports = [
+ # OpenCode and Pi agent configurations
./opencode.nix
./pi.nix
];
@@ -64,39 +63,12 @@ in {
home.packages = with pkgs; [
agenix-cli
agent-browser
- alejandra
- bc
- bun
- devpod
- #devpod-desktop
- gnumake
- cmake
- (python3.withPackages (ps:
- with ps; [
- pip
- uv
- # Scientific packages
- numba
- numpy
- torch
- srt
- ]))
pyrefly
- nixd
- nix-update
- nodejs
- # opencode-desktop
(qmd.override {
vulkanSupport = videoDrivers == ["amdgpu"];
cudaSupport = videoDrivers == ["nvidia"];
})
openshell
openspec
- pi-coding-agent
- alejandra
- sidecar
- tailwindcss
- tailwindcss-language-server
- td
];
}
diff --git a/home/features/coding/opencode.nix b/home/coding/agents/opencode.nix
similarity index 100%
rename from home/features/coding/opencode.nix
rename to home/coding/agents/opencode.nix
diff --git a/home/features/coding/pi.nix b/home/coding/agents/pi.nix
similarity index 98%
rename from home/features/coding/pi.nix
rename to home/coding/agents/pi.nix
index 9de9b26..2f431ea 100644
--- a/home/features/coding/pi.nix
+++ b/home/coding/agents/pi.nix
@@ -41,7 +41,6 @@
"npm:@plannotator/pi-extension"
"npm:pi-powerline-footer"
"npm:pi-markdown-preview"
- "npm:pi-gsd"
"npm:pi-tool-display"
"npm:pi-agent-browser-native"
"git:github.com/hk-vk/pi-connect"
diff --git a/home/coding/default.nix b/home/coding/default.nix
new file mode 100644
index 0000000..7420578
--- /dev/null
+++ b/home/coding/default.nix
@@ -0,0 +1,12 @@
+# Coding environment aggregator — profile-independent development tooling.
+# Imports editors, LSP servers, git configuration, the agent system, language runtimes, and optional packages.
+{...}: {
+ imports = [
+ ./editor
+ ./lsp
+ ./git/git.nix
+ ./agents/agents.nix
+ ./languages
+ ./packages.nix
+ ];
+}
diff --git a/home/coding/editor/default.nix b/home/coding/editor/default.nix
new file mode 100644
index 0000000..2f18bca
--- /dev/null
+++ b/home/coding/editor/default.nix
@@ -0,0 +1,6 @@
+# Editor aggregator — delegates to m3ta-nixpkgs editor modules.
+{...}: {
+ imports = [
+ ./neovim.nix
+ ];
+}
diff --git a/home/coding/editor/neovim.nix b/home/coding/editor/neovim.nix
new file mode 100644
index 0000000..79c101e
--- /dev/null
+++ b/home/coding/editor/neovim.nix
@@ -0,0 +1,7 @@
+# NeoVim base configuration via m3ta-nixpkgs coding.editors module.
+# The option `coding.editors.neovim.enable` is declared by
+# inputs.m3ta-nixpkgs.homeManagerModules.default — no re-declaration here.
+{...}: {
+ # Placeholder for host-agnostic NeoVim overrides.
+ # Set coding.editors.neovim.enable = true in per-host files to activate.
+}
diff --git a/home/coding/git/git.nix b/home/coding/git/git.nix
new file mode 100644
index 0000000..4d91287
--- /dev/null
+++ b/home/coding/git/git.nix
@@ -0,0 +1,41 @@
+# Git configuration with signing, aliases, and global ignore.
+# Identity and host-specific SSH keys are set per-host in home/m3tam3re/.
+{
+ lib,
+ pkgs,
+ ...
+}:
+with lib; {
+ programs.git = {
+ enable = true;
+ signing.format = null;
+ settings = {
+ user = {
+ name = lib.mkDefault "m3tam3re";
+ email = lib.mkDefault "p@m3ta.dev";
+ };
+ core.excludesfile = "~/.gitignore_global";
+ init.defaultBranch = "master";
+ alias = {
+ st = "status";
+ logd = "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
+ };
+ };
+ };
+
+ programs.difftastic.enable = true;
+
+ programs.jujutsu = {
+ enable = true;
+ settings = {
+ user = {
+ email = "m@m3tam3re.com";
+ name = "Sascha Koenig";
+ };
+ };
+ };
+
+ home.packages = with pkgs; [
+ lazygit
+ ];
+}
diff --git a/home/coding/languages/default.nix b/home/coding/languages/default.nix
new file mode 100644
index 0000000..586848d
--- /dev/null
+++ b/home/coding/languages/default.nix
@@ -0,0 +1,10 @@
+# Language runtimes — Python, JavaScript, Rust, Go, TypeScript.
+{...}: {
+ imports = [
+ ./python.nix
+ ./javascript.nix
+ ./rust-toolchain.nix
+ ./go.nix
+ ./typescript.nix
+ ];
+}
diff --git a/home/coding/languages/go.nix b/home/coding/languages/go.nix
new file mode 100644
index 0000000..c373f59
--- /dev/null
+++ b/home/coding/languages/go.nix
@@ -0,0 +1,19 @@
+# Go toolchain — compiler and language server.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.languages.go;
+in {
+ options.coding.languages.go.enable = mkEnableOption "Go toolchain";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ go
+ gopls
+ ];
+ };
+}
diff --git a/home/coding/languages/javascript.nix b/home/coding/languages/javascript.nix
new file mode 100644
index 0000000..86ccf2e
--- /dev/null
+++ b/home/coding/languages/javascript.nix
@@ -0,0 +1,25 @@
+# JavaScript/TypeScript runtime — Node.js and Bun.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.languages.javascript;
+ npmGlobalPrefix = "${config.home.homeDirectory}/.npm-global";
+in {
+ options.coding.languages.javascript.enable = mkEnableOption "JavaScript runtime (Node.js + Bun)";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ nodejs
+ bun
+ ];
+
+ home.file.".npmrc".text = ''
+ prefix=${npmGlobalPrefix}
+ '';
+ home.sessionVariables.NPM_CONFIG_PREFIX = npmGlobalPrefix;
+ };
+}
diff --git a/home/coding/languages/python.nix b/home/coding/languages/python.nix
new file mode 100644
index 0000000..11bb67f
--- /dev/null
+++ b/home/coding/languages/python.nix
@@ -0,0 +1,30 @@
+# Python runtime with pip and uv.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.languages.python;
+in {
+ options.coding.languages.python = {
+ enable = mkEnableOption "Python runtime with pip and uv";
+ extraPackages = mkOption {
+ type = types.listOf types.package;
+ default = [];
+ example = literalExpression "[ pkgs.python3Packages.numpy ]";
+ description = "Additional Python packages to include";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ home.packages = [
+ (pkgs.python3.withPackages (ps:
+ with ps; [
+ pip
+ uv
+ ] ++ cfg.extraPackages))
+ ];
+ };
+}
diff --git a/home/coding/languages/rust-toolchain.nix b/home/coding/languages/rust-toolchain.nix
new file mode 100644
index 0000000..823a28c
--- /dev/null
+++ b/home/coding/languages/rust-toolchain.nix
@@ -0,0 +1,20 @@
+# Rust toolchain — compiler, package manager, and language server.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.languages.rustToolchain;
+in {
+ options.coding.languages.rustToolchain.enable = mkEnableOption "Rust toolchain";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ rustc
+ cargo
+ rust-analyzer
+ ];
+ };
+}
diff --git a/home/coding/languages/typescript.nix b/home/coding/languages/typescript.nix
new file mode 100644
index 0000000..58a791e
--- /dev/null
+++ b/home/coding/languages/typescript.nix
@@ -0,0 +1,19 @@
+# TypeScript support — language server and type checking tools.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.languages.typescript;
+in {
+ options.coding.languages.typescript.enable = mkEnableOption "TypeScript support";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ typescript
+ typescript-language-server
+ ];
+ };
+}
diff --git a/home/coding/lsp/default.nix b/home/coding/lsp/default.nix
new file mode 100644
index 0000000..c8e11b0
--- /dev/null
+++ b/home/coding/lsp/default.nix
@@ -0,0 +1,6 @@
+# LSP aggregator — language server protocol tooling.
+{...}: {
+ imports = [
+ ./servers.nix
+ ];
+}
diff --git a/home/coding/lsp/servers.nix b/home/coding/lsp/servers.nix
new file mode 100644
index 0000000..77bc732
--- /dev/null
+++ b/home/coding/lsp/servers.nix
@@ -0,0 +1,23 @@
+# LSP server configuration — language servers for the development environment.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.lsp;
+in {
+ options.coding.lsp.enable = mkEnableOption "enable LSP servers";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ # Nix
+ nixd
+ # General
+ typescript-language-server
+ tailwindcss-language-server
+ pyrefly
+ ];
+ };
+}
diff --git a/home/coding/packages.nix b/home/coding/packages.nix
new file mode 100644
index 0000000..2501cd6
--- /dev/null
+++ b/home/coding/packages.nix
@@ -0,0 +1,20 @@
+# Additional coding packages — API clients and GUI development tools.
+# Opt-in since not all coding hosts need these desktop-oriented tools.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.coding.packages;
+in {
+ options.coding.packages.enable = mkEnableOption "additional coding packages (bruno, insomnia)";
+
+ config = mkIf cfg.enable {
+ home.packages = [
+ pkgs.bruno
+ pkgs.insomnia
+ ];
+ };
+}
diff --git a/home/desktop/apps/crypto.nix b/home/desktop/apps/crypto.nix
new file mode 100644
index 0000000..56b0ad8
--- /dev/null
+++ b/home/desktop/apps/crypto.nix
@@ -0,0 +1,16 @@
+# Cryptocurrency applications — Bisq, Monero GUI, and Trezor Suite.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.desktop.apps.crypto;
+in {
+ options.desktop.apps.crypto.enable = mkEnableOption "enable crypto applications";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [bisq2 monero-gui trezor-suite];
+ };
+}
diff --git a/home/desktop/apps/default.nix b/home/desktop/apps/default.nix
new file mode 100644
index 0000000..0888cfc
--- /dev/null
+++ b/home/desktop/apps/default.nix
@@ -0,0 +1,10 @@
+# Desktop apps aggregator — Obsidian, Office, web apps, crypto tools, and productivity.
+{...}: {
+ imports = [
+ ./obsidian.nix
+ ./office.nix
+ ./webapps.nix
+ ./crypto.nix
+ ./productivity.nix
+ ];
+}
diff --git a/home/features/desktop/obsidian.nix b/home/desktop/apps/obsidian.nix
similarity index 64%
rename from home/features/desktop/obsidian.nix
rename to home/desktop/apps/obsidian.nix
index c03b766..588cb98 100644
--- a/home/features/desktop/obsidian.nix
+++ b/home/desktop/apps/obsidian.nix
@@ -1,13 +1,13 @@
+# Obsidian knowledge base with markdown MIME association.
{
config,
lib,
...
}:
with lib; let
- cfg = config.features.desktop.obsidian;
+ cfg = config.desktop.apps.obsidian;
in {
- options.features.desktop.obsidian.enable =
- mkEnableOption "enable Obsidian knowledge base";
+ options.desktop.apps.obsidian.enable = mkEnableOption "enable Obsidian knowledge base";
config = mkIf cfg.enable {
programs.obsidian.enable = true;
diff --git a/home/desktop/apps/office.nix b/home/desktop/apps/office.nix
new file mode 100644
index 0000000..3d9c062
--- /dev/null
+++ b/home/desktop/apps/office.nix
@@ -0,0 +1,16 @@
+# Office and productivity applications — LibreOffice and document tools.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.desktop.apps.office;
+in {
+ options.desktop.apps.office.enable = mkEnableOption "install office and paperwork apps";
+
+ config = mkIf cfg.enable {
+ home.packages = [pkgs.libreoffice-fresh];
+ };
+}
diff --git a/home/desktop/apps/productivity.nix b/home/desktop/apps/productivity.nix
new file mode 100644
index 0000000..dd0c134
--- /dev/null
+++ b/home/desktop/apps/productivity.nix
@@ -0,0 +1,18 @@
+# Productivity tools — Pomodoro timer and focus utilities.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.desktop.apps.productivity;
+in {
+ options.desktop.apps.productivity.enable = mkEnableOption "enable productivity tools";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ pomodoro-timer
+ ];
+ };
+}
diff --git a/home/features/desktop/webapps.nix b/home/desktop/apps/webapps.nix
similarity index 90%
rename from home/features/desktop/webapps.nix
rename to home/desktop/apps/webapps.nix
index 57ed3fc..8c34b96 100644
--- a/home/features/desktop/webapps.nix
+++ b/home/desktop/apps/webapps.nix
@@ -1,6 +1,7 @@
+# Web application desktop entries — Teams, Outlook, Basecamp, and OpenCode launchers.
{
+ config,
pkgs,
- lib,
...
}: let
icons = {
@@ -41,7 +42,7 @@ in {
comment = "Open Basecamp as a Desktop App";
categories = ["Application" "Network"];
terminal = false;
- icon = "/home/sascha.koenig/.local/share/icons/basecamp-logo.png";
+ icon = "${config.home.homeDirectory}/.local/share/icons/basecamp-logo.png";
};
opencode = {
name = "Opencode";
diff --git a/home/features/desktop/default.nix b/home/desktop/default.nix
similarity index 77%
rename from home/features/desktop/default.nix
rename to home/desktop/default.nix
index 33c3780..ac73f43 100644
--- a/home/features/desktop/default.nix
+++ b/home/desktop/default.nix
@@ -1,22 +1,14 @@
+# Desktop environment aggregator — only loaded when context=desktop.
+# Includes window manager, applications, theming, and desktop session config.
{
config,
pkgs,
...
}: {
imports = [
- ./coding.nix
- ./crypto.nix
- ./fonts.nix
- ./gaming.nix
- ./hyprland.nix
- ./media.nix
- ./obsidian.nix
- ./office.nix
- ./rofi.nix
- ./theme.nix
- ./wallpapers.nix
- ./wayland.nix
- ./webapps.nix
+ ./wm
+ ./apps
+ ./theme
];
xdg = {
@@ -55,7 +47,13 @@
XDG_SESSION_TYPE = "wayland";
XDG_SESSION_DESKTOP = "Hyprland";
};
- home.sessionPath = ["\${XDG_BIN_HOME}" "\${HOME}/.cargo/bin" "$HOME/.npm-global/bin" "$HOME/.cache/.bun/bin"];
+
+ home.sessionPath = [
+ "\${XDG_BIN_HOME}"
+ "\${HOME}/.cargo/bin"
+ "$HOME/.npm-global/bin"
+ "$HOME/.cache/.bun/bin"
+ ];
fonts.fontconfig.enable = true;
@@ -66,17 +64,11 @@
settings = {
font-family = "Fira Code";
copy-on-select = true;
-
- # Base colors from nix-colors
foreground = "#${config.colorScheme.palette.base05}";
background = "#${config.colorScheme.palette.base00}";
selection-foreground = "#${config.colorScheme.palette.base07}";
selection-background = "#${config.colorScheme.palette.base02}";
-
- # Cursor
cursor-color = "#${config.colorScheme.palette.base05}";
-
- # Palette (16 colors)
palette = [
"0=#${config.colorScheme.palette.base01}"
"1=#${config.colorScheme.palette.base08}"
@@ -107,56 +99,27 @@
home.packages = with pkgs; [
appimage-run
- # blueberry
bemoji
brave
- # brightnessctl
- # clipman
distrobox
eigent
(element-desktop.override {
commandLineArgs = "--password-store=gnome-libsecret";
})
launch-webapp
- # eww
- # firefox-devedition
file-roller
hyprpanel
seahorse
sushi
- # glib
- # google-chrome
- # gsettings-desktop-schemas
- # graphviz
ksnip
msty-studio
nwg-look
- # opencode-desktop
- # pamixer
- # pavucontrol
- # libsForQt5.qtstyleplugins
- # stable.nyxt
- # pcmanfm
rose-pine-hyprcursor
- # qt5ct
- # qt6.qtwayland
- #rustdesk
- # socat
- # unrar
- # unzip
- # usbutils
- # v4l-utils
remmina
slack
telegram-desktop
vivaldi
vivaldi-ffmpeg-codecs
vibetyper
- # wl-clipboard
- # wlogout
- # wtype
- # xdg-utils
- # ydotool
- # zip
];
}
diff --git a/home/desktop/theme/default.nix b/home/desktop/theme/default.nix
new file mode 100644
index 0000000..8445fe5
--- /dev/null
+++ b/home/desktop/theme/default.nix
@@ -0,0 +1,8 @@
+# Theme aggregator — fonts, GTK/Qt theming, and wallpapers.
+{...}: {
+ imports = [
+ ./fonts.nix
+ ./theme.nix
+ ./wallpapers.nix
+ ];
+}
diff --git a/home/features/desktop/fonts.nix b/home/desktop/theme/fonts.nix
similarity index 59%
rename from home/features/desktop/fonts.nix
rename to home/desktop/theme/fonts.nix
index cb69db2..95eb69c 100644
--- a/home/features/desktop/fonts.nix
+++ b/home/desktop/theme/fonts.nix
@@ -1,3 +1,4 @@
+# Font packages — Fira Code, JetBrains Mono Nerd Font, and supporting icon fonts.
{
config,
lib,
@@ -5,10 +6,9 @@
...
}:
with lib; let
- cfg = config.features.desktop.fonts;
+ cfg = config.desktop.theme.fonts;
in {
- options.features.desktop.fonts.enable =
- mkEnableOption "install additional fonts for desktop apps";
+ options.desktop.theme.fonts.enable = mkEnableOption "install desktop fonts";
config = mkIf cfg.enable {
home.packages = with pkgs; [
diff --git a/home/features/desktop/theme.nix b/home/desktop/theme/theme.nix
similarity index 82%
rename from home/features/desktop/theme.nix
rename to home/desktop/theme/theme.nix
index ee2aa17..c78c598 100644
--- a/home/features/desktop/theme.nix
+++ b/home/desktop/theme/theme.nix
@@ -1,12 +1,14 @@
+# GTK and Qt theming — Dracula theme with matching icons and cursor.
{
- config,
pkgs,
+ config,
...
}: {
qt = {
enable = true;
platformTheme.name = "gtk";
};
+
gtk = {
enable = true;
theme = {
diff --git a/home/desktop/theme/wallpapers.nix b/home/desktop/theme/wallpapers.nix
new file mode 100644
index 0000000..bcf6c34
--- /dev/null
+++ b/home/desktop/theme/wallpapers.nix
@@ -0,0 +1,19 @@
+# Wallpaper collection — copies wallpapers to Hyprland config directory.
+{
+ config,
+ lib,
+ ...
+}:
+with lib; let
+ cfg = config.desktop.theme.wallpapers.enable;
+in {
+ options.desktop.theme.wallpapers.enable = mkEnableOption "wallpapers for Hyprland";
+
+ config = mkIf cfg {
+ xdg.configFile."hypr/wallpapers" = {
+ # Wallpapers are stored relative to the home/m3tam3re directory.
+ source = ../../m3tam3re/wallpapers;
+ recursive = true;
+ };
+ };
+}
diff --git a/home/desktop/wm/default.nix b/home/desktop/wm/default.nix
new file mode 100644
index 0000000..796b018
--- /dev/null
+++ b/home/desktop/wm/default.nix
@@ -0,0 +1,8 @@
+# Window manager aggregator — Hyprland, Wayland tools, and Rofi launcher.
+{...}: {
+ imports = [
+ ./hyprland.nix
+ ./wayland.nix
+ ./rofi.nix
+ ];
+}
diff --git a/home/features/desktop/hyprland.nix b/home/desktop/wm/hyprland.nix
similarity index 93%
rename from home/features/desktop/hyprland.nix
rename to home/desktop/wm/hyprland.nix
index 090c809..75e3cd8 100644
--- a/home/features/desktop/hyprland.nix
+++ b/home/desktop/wm/hyprland.nix
@@ -1,13 +1,13 @@
+# Hyprland window manager with keybindings, window rules, idle/lock, and hyprpaper.
{
config,
lib,
...
}:
with lib; let
- cfg = config.features.desktop.hyprland;
+ cfg = config.desktop.wm.hyprland;
in {
- options.features.desktop.hyprland.enable =
- mkEnableOption "Hyprland related stuff";
+ options.desktop.wm.hyprland.enable = mkEnableOption "Hyprland window manager";
config = mkIf cfg.enable {
wayland.windowManager.hyprland = {
@@ -19,8 +19,8 @@ in {
exec-once = [
"hyprpanel"
"while ! hyprpaper-random; do sleep 0.5; done"
- "wl-paste --type text --watch cliphist store" # Stores only text data
- "wl-paste --type image --watch cliphist store" # Stores only image data "wl-paste -p -t text --watch clipman store -P --histpath=\"~/.local/share/clipman-primary.json\""
+ "wl-paste --type text --watch cliphist store"
+ "wl-paste --type image --watch cliphist store"
"vibetyper"
];
@@ -49,7 +49,6 @@ in {
gaps_in = 5;
gaps_out = 5;
border_size = 1;
- # Keeping the existing active border as requested
"col.active_border" = "rgba(9742b5ee) rgba(9742b5ee) 45deg";
"col.inactive_border" = "rgba(${config.colorScheme.palette.base03}aa)";
layout = "dwindle";
@@ -110,8 +109,8 @@ in {
kb_layout = "us";
}
];
+
windowrule = [
- # Floating dialogs
"match:class file_progress, float on"
"match:class confirm, float on"
"match:class dialog, float on"
@@ -125,24 +124,19 @@ in {
"match:class pavucontrol-qt, float on"
"match:class pavucontrol, float on"
"match:class class:^(espanso)$, float on"
- # wlogout
"match:class wlogout, fullscreen on"
"match:title wlogout, float on"
"match:title wlogout, fullscreen on"
- # mpv
"match:class mpv, float on"
"match:class mpv, idle_inhibit focus"
"match:class mpv, opacity 1.0 override"
- # Media/Volume/PiP
"match:title ^(Media viewer)$, float on"
"match:title ^(Volume Control)$, float on"
"match:title ^(Picture-in-Picture)$, float on"
- # Pomodoro timer
"match:title ^(floating-pomodoro)$, float on"
"match:title ^(floating-pomodoro)$, size 250 50"
"match:title ^(floating-pomodoro)$, move 12 (monitor_h-150)"
"match:title ^(floating-pomodoro)$, pin on"
- # Streamlabs overlays
"match:initial_title .*streamlabs.com.*, float on"
"match:initial_title .*streamlabs.com.*, pin on"
"match:initial_title .*streamlabs.com.*, size 800 400"
@@ -154,16 +148,15 @@ in {
"match:initial_title .*streamlabs.com.*, decorate off"
"match:initial_title .*streamlabs.com.*, no_shadow on"
"match:initial_title .*streamlabs.com.*, no_blur on"
- # Vibetyper recording indicator
"match:class ^vibe-typer$, match:title ^Recording Indicator$, no_blur on"
"border_color rgb(ffffff), match:xwayland 1"
];
+
"$mainMod" = "SUPER";
"$terminal" = "ghostty";
bind = [
"$mainMod, return, exec, $terminal nu -c zellij-ps"
- # "$mainMod, t, exec, warp-terminal"
"$mainMod, t, exec, $terminal -e nu -c 'nitch; exec nu'"
"$mainMod SHIFT, t, exec, launch-timer"
"$mainMod, n, exec, $terminal -e nvim"
@@ -214,16 +207,19 @@ in {
"$mainMod, mouse_down, workspace, e+1"
"$mainMod, mouse_up, workspace, e-1"
];
+
bindr = [
"$mainMod, R, exec, stt-ptt stop"
"$mainMod, S, exec, stt-ptt format-stop"
];
+
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
];
};
};
+
services.hypridle = {
enable = true;
settings = {
@@ -232,14 +228,13 @@ in {
after_sleep_cmd = "hyprctl dispatch dpms on";
inhibit_sleep = 3;
};
-
listener = [
{
- timeout = 300; # 5 min
+ timeout = 300;
on-timeout = "hyprlock";
}
{
- timeout = 420; # 5.5 min
+ timeout = 420;
on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on";
}
diff --git a/home/features/desktop/rofi.nix b/home/desktop/wm/rofi.nix
similarity index 92%
rename from home/features/desktop/rofi.nix
rename to home/desktop/wm/rofi.nix
index e17c9a6..d3c3a76 100644
--- a/home/features/desktop/rofi.nix
+++ b/home/desktop/wm/rofi.nix
@@ -1,3 +1,4 @@
+# Rofi application launcher with nix-colors theme, pass integration, and project opener.
{
config,
pkgs,
@@ -5,23 +6,23 @@
...
}:
with lib; let
- cfg = config.features.desktop.rofi;
+ cfg = config.desktop.wm.rofi;
in {
- options.features.desktop.rofi.enable = mkEnableOption "enable rofi";
+ options.desktop.wm.rofi.enable = mkEnableOption "enable rofi";
config = mkIf cfg.enable {
- programs.rofi = with pkgs; {
+ programs.rofi = {
enable = true;
- package = rofi.override {
+ package = pkgs.rofi.override {
plugins = [
- rofi-calc
- rofi-emoji
- stable.rofi-file-browser
+ pkgs.rofi-calc
+ pkgs.rofi-emoji
+ pkgs.stable.rofi-file-browser
];
};
pass = {
enable = true;
- package = rofi-pass-wayland;
+ package = pkgs.rofi-pass-wayland;
};
terminal = "${pkgs.ghostty}/bin/ghostty";
font = "Fira Code";
@@ -169,7 +170,6 @@ in {
text-color: @background;
}
- /* Scrollbar */
scrollbar {
width: 4px;
border: 0;
@@ -179,6 +179,7 @@ in {
}
'');
};
+
cli.rofi-project-opener = {
enable = true;
projectDirs = {
diff --git a/home/features/desktop/wayland.nix b/home/desktop/wm/wayland.nix
similarity index 61%
rename from home/features/desktop/wayland.nix
rename to home/desktop/wm/wayland.nix
index 506b182..1429d35 100644
--- a/home/features/desktop/wayland.nix
+++ b/home/desktop/wm/wayland.nix
@@ -1,3 +1,4 @@
+# Wayland extra tooling — screenshot, clipboard, cursor, and display utilities.
{
config,
lib,
@@ -5,9 +6,9 @@
...
}:
with lib; let
- cfg = config.features.desktop.wayland;
+ cfg = config.desktop.wm.wayland;
in {
- options.features.desktop.wayland.enable = mkEnableOption "wayland extra tools and config";
+ options.desktop.wm.wayland.enable = mkEnableOption "wayland extra tools and config";
config = mkIf cfg.enable {
home.packages = with pkgs; [
diff --git a/home/features/cli/AGENTS.md b/home/features/cli/AGENTS.md
deleted file mode 100644
index 24f1920..0000000
--- a/home/features/cli/AGENTS.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# CLI FEATURES (home-manager)
-
-**Shell and terminal tooling with Fish + Nushell dual configuration**
-
-## OVERVIEW
-8 CLI modules with integrated tooling across Fish and Nushell shells.
-
-## STRUCTURE
-```
-cli/
-├── default.nix # Imports + shared tools (bat, eza, direnv)
-├── fish.nix # Fish shell + aliases
-├── fzf.nix # Fuzzy finder
-├── nitch.nix # System info tool
-├── nushell.nix # Nushell + aliases
-├── secrets.nix # Password-store integration
-├── starship.nix # Shell prompt
-└── zellij.nix # Terminal multiplexer
-```
-
-## WHERE TO LOOK
-
-| Task | Location | Notes |
-|------|----------|-------|
-| Add CLI tool | default.nix home.packages | Check if shell integration needed |
-| Shell aliases | fish.nix or nushell.nix | Kept in sync between shells |
-| Prompt config | starship.nix | Uses nerd-fonts symbols |
-| Secret access | secrets.nix | Agenix integration |
-
-## CONVENTIONS
-
-### Shell Integration Pattern
-Tools with shell hooks enabled in both Fish and Nushell:
-- **carapace**: Completions
-- **zoxide**: Smart cd
-- **eza**: ls replacement
-- **direnv**: Directory environments
-- **fzf**: Fuzzy finding
-
-### NixOS Rebuild Aliases (both shells)
-```
-nr/nrs - nixos-rebuild [switch]
-snr/snrs - sudo nixos-rebuild [switch]
-hms - home-manager switch
-```
-
-### Bat Theme
-Custom `universal` theme generated from nix-colors palette in default.nix (lines 34-157).
-
-### Secrets Integration
-Fish/Nushell source `$HOME/.secrets` if `secrets.enable = true` (CLI secrets feature).
-
-## ANTI-PATTERNS
-
-- **DON'T** add aliases to only one shell - keep Fish/Nushell in sync
-- **DON'T** use `programs.bash` - Nushell is default shell
-- **DON'T** bypass carapace for completions - integrated by default
-
-## NOTES
-
-- zellij-ps custom package for project session management
-- Default shell set to Nushell in hosts/common/default.nix
-- Bat theme dynamically generated (no external theme files)
-- lf file manager uses bat for previews
-- Agenix CLI (agenix-cli) included for secret management
diff --git a/home/features/cli/default.nix b/home/features/cli/default.nix
deleted file mode 100644
index 3ab556e..0000000
--- a/home/features/cli/default.nix
+++ /dev/null
@@ -1,230 +0,0 @@
-{
- config,
- pkgs,
- videoDrivers,
- ...
-}: {
- imports = [
- ./fish.nix
- ./fzf.nix
- ./nitch.nix
- ./nushell.nix
- ./secrets.nix
- ./starship.nix
- ./television.nix
- ./zellij.nix
- ];
-
- programs.carapace = {
- enable = true;
- enableFishIntegration = true;
- enableNushellIntegration = true;
- enableBashIntegration = true;
- };
-
- programs.zoxide = {
- enable = true;
- enableFishIntegration = true;
- enableNushellIntegration = true;
- };
-
- programs.bat = {
- enable = true;
- config = {theme = "universal";};
- themes = {
- universal = {
- src = pkgs.writeText "universal.tmTheme" ''
-
-
-
-
- name
- Universal (nix-colors)
- settings
-
-
- settings
-
- background
- #${config.colorScheme.palette.base00}
- foreground
- #${config.colorScheme.palette.base05}
- caret
- #${config.colorScheme.palette.base05}
- selection
- #${config.colorScheme.palette.base02}
- selectionForeground
- #${config.colorScheme.palette.base05}
- lineHighlight
- #${config.colorScheme.palette.base01}
-
-
-
- name
- Comment
- scope
- comment
- settings
-
- foreground
- #${config.colorScheme.palette.base03}
- fontStyle
- italic
-
-
-
- name
- String
- scope
- string
- settings
-
- foreground
- #${config.colorScheme.palette.base0A}
-
-
-
- name
- Number
- scope
- constant.numeric
- settings
-
- foreground
- #${config.colorScheme.palette.base0E}
-
-
-
- name
- Keyword
- scope
- keyword
- settings
-
- foreground
- #${config.colorScheme.palette.base08}
-
-
-
- name
- Function
- scope
- entity.name.function
- settings
-
- foreground
- #${config.colorScheme.palette.base0B}
-
-
-
- name
- Type
- scope
- entity.name.type, storage.type
- settings
-
- foreground
- #${config.colorScheme.palette.base0D}
-
-
-
- name
- Variable
- scope
- variable
- settings
-
- foreground
- #${config.colorScheme.palette.base05}
-
-
-
- name
- Constant
- scope
- constant
- settings
-
- foreground
- #${config.colorScheme.palette.base0E}
-
-
-
-
-
- '';
- };
- };
- };
-
- programs.direnv = {
- enable = true;
- enableNushellIntegration = true;
- nix-direnv.enable = true;
- };
-
- programs.eza = {
- enable = true;
- enableFishIntegration = true;
- enableBashIntegration = true;
- extraOptions = ["-l" "--icons" "--git" "-a"];
- };
-
- programs.lf = {
- enable = true;
- settings = {
- preview = true;
- drawbox = true;
- hidden = true;
- icons = true;
- theme = "Dracula";
- previewer = "bat";
- };
- };
-
- cli.zellij-ps = {
- enable = true;
- projectFolders = ["/home/m3tam3re/p"];
- };
-
- home.packages = with pkgs; [
- basecamp
- comma
- coreutils
- devenv
- fabric-ai
- fd
- gcc
- go
- htop
- httpie
- hyprpaper-random
- jq
- just
- lazygit
- llm
- lf
- nix-index
- nix-update
- libnotify
- nushellPlugins.skim
- progress
- ripgrep
- rocmPackages.rocm-smi
- rocmPackages.rocminfo
- rocmPackages.rocm-runtime
- sqlite
- sqlite-vec
- tldr
- pomodoro-timer
- trash-cli
- unimatrix
- unzip
- vulkan-tools
- wttrbar
- wireguard-tools
- yazi
- zellij-ps
- zip
- ];
-}
diff --git a/home/features/cli/fzf.nix b/home/features/cli/fzf.nix
deleted file mode 100644
index ce65606..0000000
--- a/home/features/cli/fzf.nix
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- config,
- lib,
- ...
-}:
-with lib; let
- cfg = config.features.cli.fzf;
-in {
- options.features.cli.fzf.enable = mkEnableOption "enable fuzzy finder";
-
- config = mkIf cfg.enable {
- programs.fzf = {
- enable = true;
- enableFishIntegration = true;
- colors = {
- "fg" = "#${config.colorScheme.palette.base05}";
- "bg" = "#${config.colorScheme.palette.base00}";
- "hl" = "#${config.colorScheme.palette.base0E}";
- "fg+" = "#${config.colorScheme.palette.base05}";
- "bg+" = "#${config.colorScheme.palette.base02}";
- "hl+" = "#${config.colorScheme.palette.base0E}";
- "info" = "#${config.colorScheme.palette.base09}";
- "prompt" = "#${config.colorScheme.palette.base0B}";
- "pointer" = "#${config.colorScheme.palette.base08}";
- "marker" = "#${config.colorScheme.palette.base08}";
- "spinner" = "#${config.colorScheme.palette.base09}";
- "header" = "#${config.colorScheme.palette.base03}";
- };
- defaultOptions = [
- "--preview='bat --color=always -n {}'"
- "--bind 'ctrl-/:toggle-preview'"
- "--header 'Press CTRL-Y to copy command into clipboard'"
- "--bind 'ctrl-/:toggle-preview'"
- "--bind 'ctrl-y:execute-silent(echo -n {2..} | wl-copy)+abort'"
- ];
- defaultCommand = "fd --type f --exclude .git --follow --hidden";
- changeDirWidgetCommand = "fd --type d --exclude .git --follow --hidden";
- };
- };
-}
diff --git a/home/features/cli/nitch.nix b/home/features/cli/nitch.nix
deleted file mode 100644
index 1177299..0000000
--- a/home/features/cli/nitch.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.cli.nitch;
-in {
- options.features.cli.nitch.enable = mkEnableOption "enable nitch";
-
- config = mkIf cfg.enable {
- home.packages = with pkgs; [nitch];
- };
-}
diff --git a/home/features/cli/television.nix b/home/features/cli/television.nix
deleted file mode 100644
index bc1b036..0000000
--- a/home/features/cli/television.nix
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- config,
- lib,
- ...
-}:
-with lib; let
- cfg = config.features.cli.television;
-in {
- options.features.cli.television.enable = mkEnableOption "enable nitch";
-
- config = mkIf cfg.enable {
- programs.television = {
- enable = true;
- channels = {
- tldr = {
- metadata = {
- description = "Browse TLDR pages";
- name = "tldr";
- requirements = [
- "tldr"
- ];
- };
- preview = {
- command = "tldr '{}'";
- };
- source = {
- command = "tldr --list";
- };
- };
- git-diff = {
- metadata = {
- description = "A channel to select files from git diff commands";
- name = "git-diff";
- requirements = [
- "git"
- ];
- };
- preview = {
- command = "git diff HEAD --color=always -- '{}'";
- };
- source = {
- command = "git diff --name-only HEAD";
- };
- };
- git-log = {
- metadata = {
- description = "A channel to select from git log entries";
- name = "git-log";
- requirements = [
- "git"
- ];
- };
- preview = {
- command = "git show -p --stat --pretty=fuller --color=always '{0}'";
- };
- source = {
- command = "git log --oneline --date=short --pretty=\"format:%h %s %an %cd\" \"$@\"";
- output = "{split: :0}";
- };
- };
- };
- };
- };
-}
diff --git a/home/features/cli/zellij.nix b/home/features/cli/zellij.nix
deleted file mode 100644
index bd38e5b..0000000
--- a/home/features/cli/zellij.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- config,
- lib,
- ...
-}:
-with lib; let
- cfg = config.features.cli.zellij;
-in {
- options.features.cli.zellij.enable = mkEnableOption "enable tmux";
-
- config = mkIf cfg.enable {
- programs.zellij = {
- enable = true;
- settings = {
- theme = "universal";
- themes.universal = {
- bg = "#${config.colorScheme.palette.base00}";
- fg = "#${config.colorScheme.palette.base05}";
- black = "#${config.colorScheme.palette.base01}";
- red = "#${config.colorScheme.palette.base08}";
- green = "#${config.colorScheme.palette.base0B}";
- yellow = "#${config.colorScheme.palette.base0A}";
- blue = "#${config.colorScheme.palette.base0D}";
- magenta = "#${config.colorScheme.palette.base0E}";
- cyan = "#${config.colorScheme.palette.base0C}";
- white = "#${config.colorScheme.palette.base07}";
- orange = "#${config.colorScheme.palette.base09}";
- };
- };
- };
- };
-}
diff --git a/home/features/desktop/AGENTS.md b/home/features/desktop/AGENTS.md
deleted file mode 100644
index 1c9fbb7..0000000
--- a/home/features/desktop/AGENTS.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# DESKTOP FEATURES (home-manager)
-
-**Wayland/Hyprland environment with color-coordinated tooling**
-
-## OVERVIEW
-12 modular desktop features with nix-colors (Dracula) integration across all components.
-
-## STRUCTURE
-```
-desktop/
-├── default.nix # Imports + XDG + Kitty config
-├── coding.nix # Development tools (VSCode, etc.)
-├── crypto.nix # Crypto wallets/tools
-├── fonts.nix # Font packages
-├── gaming.nix # Gaming tools/Steam
-├── hyprland.nix # Hyprland WM configuration
-├── media.nix # Media players/editors
-├── office.nix # LibreOffice, document tools
-├── rofi.nix # Application launcher
-├── theme.nix # GTK/Qt theming
-├── wayland.nix # Wayland utilities
-└── webapps.nix # Browser-based apps
-```
-
-## WHERE TO LOOK
-
-| Task | Location | Notes |
-|------|----------|-------|
-| Add desktop app | Relevant feature .nix | Update home.packages |
-| Configure Hyprland | hyprland.nix | Window manager settings |
-| Fix colors | Check colorScheme references | Uses config.colorScheme.palette.base* |
-| Add font | fonts.nix | Increases system closure size |
-
-## CONVENTIONS
-
-### Color Scheme Integration
-All color-aware tools reference `config.colorScheme.palette.base00` through `base0F`:
-- **base00-07**: Grayscale (dark to light)
-- **base08**: Red/errors
-- **base09**: Orange
-- **base0A**: Yellow/strings
-- **base0B**: Green/functions
-- **base0C**: Cyan
-- **base0D**: Blue/types
-- **base0E**: Purple/constants
-- **base0F**: Brown
-
-Template:
-```nix
-foreground = "#${config.colorScheme.palette.base05}";
-background = "#${config.colorScheme.palette.base00}";
-```
-
-### Session Variables
-Set in default.nix for Wayland/Hyprland:
-```nix
-NIXOS_OZONE_WL = "1";
-QT_QPA_PLATFORM = "wayland";
-XDG_CURRENT_DESKTOP = "Hyprland";
-```
-
-### XDG Defaults
-- **PDF**: okular
-- **Text**: nvim
-- **Browser**: Zen (io.github.zen_browser.zen)
-- **Archive**: file-roller
-
-## ANTI-PATTERNS
-
-- **DON'T** hardcode hex colors - use colorScheme palette
-- **DON'T** install fonts globally - keep in user packages
-- **DON'T** bypass XDG defaults - set in mimeApps
-
-## NOTES
-
-- Kitty terminal configured in default.nix (not separate file)
-- Bibata-Modern-Ice cursor theme hardcoded
-- Session path includes cargo, npm-global, bun
-- Desktop features are always-enabled (no feature flags in this dir)
diff --git a/home/features/desktop/coding.nix b/home/features/desktop/coding.nix
deleted file mode 100644
index b6a12bf..0000000
--- a/home/features/desktop/coding.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.desktop.coding;
-in {
- options.features.desktop.coding.enable =
- mkEnableOption "install coding related stuff";
-
- config = mkIf cfg.enable {
- home.packages = with pkgs; [
- bruno
- insomnia
- ];
- coding.editors = {
- neovim.enable = true;
- zed.enable = true;
- };
- };
-}
diff --git a/home/features/desktop/crypto.nix b/home/features/desktop/crypto.nix
deleted file mode 100644
index f8132b5..0000000
--- a/home/features/desktop/crypto.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.desktop.crypto;
-in {
- options.features.desktop.crypto.enable = mkEnableOption "Enable Crypto";
-
- config = mkIf cfg.enable {
- home.packages = with pkgs; [bisq2 monero-gui trezor-suite];
- };
-}
diff --git a/home/features/desktop/gaming.nix b/home/features/desktop/gaming.nix
deleted file mode 100644
index 6cc7414..0000000
--- a/home/features/desktop/gaming.nix
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.desktop.gaming;
-in {
- options.features.desktop.gaming.enable =
- mkEnableOption "install gaming related stuff";
-
- config = mkIf cfg.enable {
- home.packages = with pkgs; [
- gamescope
- gamemode
- goverlay
- mangohud
- protonplus
- ];
- };
-}
diff --git a/home/features/desktop/media.nix b/home/features/desktop/media.nix
deleted file mode 100644
index 39f4d01..0000000
--- a/home/features/desktop/media.nix
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.desktop.media;
-in {
- options.features.desktop.media.enable =
- mkEnableOption "enable media features";
-
- config = mkIf cfg.enable {
- home.packages = with pkgs; [
- # handbrake
- # kdePackages.kdenlive
- # makemkv
- # mediainfo
- amf
- ffmpeg_6-full
- gimp
- gst_all_1.gstreamer
- gst_all_1.gst-vaapi
- handbrake
- inkscape
- kdePackages.kdenlive
- libation
- #makemkv
- pamixer
- pavucontrol
- qpwgraph
- v4l-utils
- plexamp
- # uxplay
- # vlc
- webcord
- # yt-dlp
- unimatrix
- ];
-
- programs = {
- mpv = {
- enable = true;
- bindings = {
- WHEEL_UP = "seek 10";
- WHEEL_DOWN = "seek -10";
- };
- config = {
- profile = "gpu-hq";
- ytdl-format = "bestvideo+bestaudio";
- };
- };
- };
- };
-}
diff --git a/home/features/desktop/office.nix b/home/features/desktop/office.nix
deleted file mode 100644
index 0eddd32..0000000
--- a/home/features/desktop/office.nix
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.desktop.office;
-in {
- options.features.desktop.office.enable =
- mkEnableOption "install office and paperwork stuff";
-
- config = mkIf cfg.enable {
- home.packages = with pkgs; [
- libreoffice-fresh
- ];
- };
-}
diff --git a/home/features/desktop/wallpapers.nix b/home/features/desktop/wallpapers.nix
deleted file mode 100644
index fbc6a27..0000000
--- a/home/features/desktop/wallpapers.nix
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- cfg = config.features.desktop.wallpapers;
-in {
- options.features.desktop.wallpapers = mkEnableOption "Wallpapers for Hyprland";
-
- config = mkIf cfg {
- xdg.configFile."hypr/wallpapers" = {
- source = ../../m3tam3re/wallpapers;
- recursive = true;
- };
- };
-}
diff --git a/home/lib/default.nix b/home/lib/default.nix
new file mode 100644
index 0000000..6fb9798
--- /dev/null
+++ b/home/lib/default.nix
@@ -0,0 +1,95 @@
+# home/lib/default.nix
+# Profile loading utilities for home-manager configurations.
+#
+# Usage:
+# let homeLib = import ../lib { inherit lib; };
+# in {
+# imports = [
+# (homeLib.mkHomeConfig { profiles = ["coding" "gaming"]; context = "desktop"; })
+# ];
+# }
+{lib}: let
+ # Infrastructure layer — nixpkgs overlays, nix-colors, m3ta-nixpkgs modules.
+ # Always loaded on every host.
+ commonModule = ../common;
+
+ # Base user environment — shell (nushell, starship), CLI tools, secrets.
+ # Always loaded on every host.
+ baseModule = ../base;
+
+ # Context-specific modules — desktop and server are mutually exclusive.
+ contextModuleMap = {
+ desktop = ../desktop;
+ server = ../server;
+ };
+
+ # Profile modules — freely combinable additions on top of base + context.
+ profileModuleMap = {
+ coding = ../coding;
+ gaming = ../profiles/gaming;
+ media = ../profiles/media;
+ };
+in {
+ # Generate a home-manager module with imports based on profiles and context.
+ #
+ # Args:
+ # profiles: list of profile names (e.g. ["coding" "gaming" "media"])
+ # context: host context, one of "desktop" | "server" | null
+ #
+ # Returns: a home-manager module attrset with imports and assertions.
+ # Desktop and server contexts are mutually exclusive by design — passing
+ # any value other than "desktop", "server", or null causes an assertion
+ # failure at evaluation time.
+ mkHomeConfig = {
+ profiles ? [],
+ context ? null,
+ }: let
+ contextImport =
+ if context == "desktop"
+ then [contextModuleMap.desktop]
+ else if context == "server"
+ then [contextModuleMap.server]
+ else [];
+
+ # Partition profiles into known and unknown for assertion + safe import.
+ unknownProfiles =
+ builtins.filter
+ (profileName: ! builtins.hasAttr profileName profileModuleMap)
+ profiles;
+
+ # Only import known profiles; the assertion below catches unknowns.
+ activeProfiles =
+ builtins.filter
+ (profileName: builtins.hasAttr profileName profileModuleMap)
+ profiles;
+
+ profileImports = map (profileName: profileModuleMap.${profileName}) activeProfiles;
+
+ contextStr =
+ if context == null
+ then "null"
+ else context;
+ in {
+ imports =
+ [commonModule baseModule]
+ ++ contextImport
+ ++ profileImports;
+
+ assertions = [
+ {
+ assertion = builtins.elem context ["desktop" "server" null];
+ message =
+ "m3ta home: context must be 'desktop', 'server', or null"
+ + " (got: '${contextStr}')";
+ }
+ {
+ assertion = unknownProfiles == [];
+ message =
+ "m3ta home: unknown profiles requested:"
+ + " [ ${builtins.concatStringsSep " " unknownProfiles} ]."
+ + " Valid profiles are:"
+ + " [ ${builtins.concatStringsSep " " (builtins.attrNames profileModuleMap)} ]";
+ }
+ ];
+ };
+}
diff --git a/home/m3tam3re/m3-aether.nix b/home/m3tam3re/m3-aether.nix
index 0f6c41d..fac6499 100644
--- a/home/m3tam3re/m3-aether.nix
+++ b/home/m3tam3re/m3-aether.nix
@@ -1,17 +1,25 @@
-{
+# m3-aether — cloud VM.
+# Context: server | Profiles: (none)
+{lib, ...}: let
+ homeLib = import ../lib {inherit lib;};
+in {
imports = [
- ../common
- ../features/cli
+ (homeLib.mkHomeConfig {
+ profiles = [];
+ context = "server";
+ })
./home-server.nix
];
- features = {
- cli = {
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
fish.enable = true;
+ starship.enable = true;
+ };
+ cliTools = {
fzf.enable = true;
nitch.enable = true;
- secrets.enable = false;
- starship.enable = true;
};
};
}
diff --git a/home/m3tam3re/m3-ares.nix b/home/m3tam3re/m3-ares.nix
index 43f03dd..a1d1cfe 100644
--- a/home/m3tam3re/m3-ares.nix
+++ b/home/m3tam3re/m3-ares.nix
@@ -1,98 +1,142 @@
+# m3-ares — TUXEDO laptop desktop workstation.
+# Context: desktop | Profiles: coding, gaming, media
{
config,
lib,
...
-}:
-with lib; {
- imports = [
- ../common
- ./home.nix
- ../features/cli
- ../features/coding
- ../features/desktop
- ];
+}: let
+ homeLib = import ../lib {inherit lib;};
+in
+ with lib; {
+ imports = [
+ (homeLib.mkHomeConfig {
+ profiles = ["coding" "gaming" "media"];
+ context = "desktop";
+ })
+ ./home.nix
+ ];
- config = mkMerge [
- {
- xdg = {
- # TODO: better structure
- enable = true;
- configFile."mimeapps.list".force = true;
- mimeApps = {
- enable = true;
- associations.added = {
- "application/zip" = ["org.gnome.FileRoller.desktop"];
- "application/csv" = ["calc.desktop"];
- "application/pdf" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ config = mkMerge [
+ {
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
+ fish.enable = true;
+ nushell.enable = true;
+ starship.enable = true;
};
- defaultApplications = {
- "application/zip" = ["org.gnome.FileRoller.desktop"];
- "application/csv" = ["calc.desktop"];
- "application/pdf" = ["vivaldi-stable.desktop"];
- "application/md" = ["dev.zed.Zed.desktop"];
- "application/text" = ["dev.zed.Zed.desktop"];
- "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ cliTools = {
+ fzf.enable = true;
+ nitch.enable = true;
+ television.enable = true;
};
- };
- };
- features = {
- cli = {
- fish.enable = true;
- nushell.enable = true;
- fzf.enable = true;
- nitch.enable = true;
secrets.enable = true;
- starship.enable = true;
- television.enable = true;
};
- desktop = {
- coding.enable = true;
- crypto.enable = true;
- gaming.enable = true;
- hyprland.enable = true;
- media.enable = true;
- obsidian.enable = true;
- office.enable = true;
- rofi.enable = true;
- fonts.enable = true;
- wayland.enable = true;
- wallpapers = true;
- };
- };
- }
- (mkIf config.features.desktop.hyprland.enable {
- wayland.windowManager.hyprland = {
- enable = true;
- settings = {
- exec-once = ["tuxedo-backlight"];
- monitor = [
- "eDP-1,preferred,0x0,1.25"
- "HDMI-A-1,1920x1080@120,2560x0,1"
- ];
- workspace = [
- "1, monitor:eDP-1, default:true"
- "2, monitor:eDP-1"
- "3, monitor:eDP-1"
- "4, monitor:HDMI-A-1,"
- "5, monitor:HDMI-A-1,border:false,rounding:false"
- "6, monitor:HDMI-A-1"
- ];
- windowrule = [
- "match:class dev.zed.Zed, workspace 1"
- "match:class Msty, workspace 1"
- "match:class ^(com.obsproject.Studio)$, workspace 2"
- "match:class ^(brave-browser)$, workspace 4, opacity 1.0"
- "match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
- "match:class ^steam_app_\\d+$, fullscreen on"
- "match:class ^steam_app_\\d+$, workspace 5"
- "match:class ^steam_app_\\d+$, idle_inhibit focus"
- ];
+ # Desktop features (new namespace)
+ desktop = {
+ wm = {
+ hyprland.enable = true;
+ rofi.enable = true;
+ wayland.enable = true;
+ };
+ apps = {
+ crypto.enable = true;
+ obsidian.enable = true;
+ office.enable = true;
+ };
+ theme = {
+ fonts.enable = true;
+ wallpapers.enable = true;
+ };
};
- };
- })
- ];
-}
+
+ # Coding environment
+ coding = {
+ editors = {
+ neovim.enable = true;
+ zed.enable = true;
+ };
+ lsp.enable = true;
+ packages.enable = true;
+ languages = {
+ python.enable = true;
+ javascript.enable = true;
+ rustToolchain.enable = true;
+ go.enable = true;
+ typescript.enable = true;
+ };
+ };
+
+ # Gaming profile features
+ profiles.gaming = {
+ steam.enable = true;
+ gamescope.enable = true;
+ };
+
+ # Media profile features
+ profiles.media = {
+ obs.enable = true;
+ ffmpeg.enable = true;
+ kdenlive.enable = true;
+ ytDlp.enable = true;
+ };
+
+ xdg = {
+ enable = true;
+ configFile."mimeapps.list".force = true;
+ mimeApps = {
+ enable = true;
+ associations.added = {
+ "application/zip" = ["org.gnome.FileRoller.desktop"];
+ "application/csv" = ["calc.desktop"];
+ "application/pdf" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ };
+ defaultApplications = {
+ "application/zip" = ["org.gnome.FileRoller.desktop"];
+ "application/csv" = ["calc.desktop"];
+ "application/pdf" = ["vivaldi-stable.desktop"];
+ "application/md" = ["dev.zed.Zed.desktop"];
+ "application/text" = ["dev.zed.Zed.desktop"];
+ "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ };
+ };
+ };
+ }
+
+ # Host-specific Hyprland monitor and workspace layout
+ (mkIf config.desktop.wm.hyprland.enable {
+ wayland.windowManager.hyprland = {
+ enable = true;
+ settings = {
+ exec-once = ["tuxedo-backlight"];
+ monitor = [
+ "eDP-1,preferred,0x0,1.25"
+ "HDMI-A-1,1920x1080@120,2560x0,1"
+ ];
+ workspace = [
+ "1, monitor:eDP-1, default:true"
+ "2, monitor:eDP-1"
+ "3, monitor:eDP-1"
+ "4, monitor:HDMI-A-1,"
+ "5, monitor:HDMI-A-1,border:false,rounding:false"
+ "6, monitor:HDMI-A-1"
+ ];
+ windowrule = [
+ "match:class dev.zed.Zed, workspace 1"
+ "match:class Msty, workspace 1"
+ "match:class ^(com.obsproject.Studio)$, workspace 2"
+ "match:class ^(brave-browser)$, workspace 4, opacity 1.0"
+ "match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
+ "match:class ^steam_app_\\d+$, fullscreen on"
+ "match:class ^steam_app_\\d+$, workspace 5"
+ "match:class ^steam_app_\\d+$, idle_inhibit focus"
+ ];
+ };
+ };
+ })
+ ];
+ }
diff --git a/home/m3tam3re/m3-atlas.nix b/home/m3tam3re/m3-atlas.nix
index 1738953..248fe23 100644
--- a/home/m3tam3re/m3-atlas.nix
+++ b/home/m3tam3re/m3-atlas.nix
@@ -1,19 +1,29 @@
-{
+# m3-atlas — primary server, Traefik hub and container host.
+# Context: server | Profiles: coding
+{lib, ...}: let
+ homeLib = import ../lib {inherit lib;};
+in {
imports = [
- ../common
- ../features/cli
- ../features/coding/opencode.nix
+ (homeLib.mkHomeConfig {
+ profiles = ["coding"];
+ context = "server";
+ })
./home-server.nix
];
- coding.editors.neovim.enable = true;
- features = {
- cli = {
+
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
nushell.enable = true;
+ starship.enable = true;
+ };
+ cliTools = {
fzf.enable = true;
nitch.enable = true;
- secrets.enable = false;
- starship.enable = true;
zellij.enable = true;
};
};
+
+ # Coding environment
+ coding.editors.neovim.enable = true;
}
diff --git a/home/m3tam3re/m3-daedalus.nix b/home/m3tam3re/m3-daedalus.nix
index 370ca5d..124dc4a 100644
--- a/home/m3tam3re/m3-daedalus.nix
+++ b/home/m3tam3re/m3-daedalus.nix
@@ -1,101 +1,127 @@
+# m3-daedalus — portable laptop (standalone home-manager).
+# Context: desktop | Profiles: coding, media
{
config,
lib,
...
-}:
-with lib; let
- cfg = config.features.desktop.hyprland;
-in {
- imports = [
- ../common
- ./home.nix
- ../features/cli
- ../features/coding
- ../features/desktop
- #./services/librechat.nix
- ];
+}: let
+ homeLib = import ../lib {inherit lib;};
+in
+ with lib; {
+ imports = [
+ (homeLib.mkHomeConfig {
+ profiles = ["coding" "media"];
+ context = "desktop";
+ })
+ ./home.nix
+ ];
- options.features.desktop.hyprland.enable =
- mkEnableOption "enable Hyprland";
-
- config = mkMerge [
- # Base configuration
- {
- xdg = {
- # TODO: better structure
- enable = true;
- configFile."mimeapps.list".force = true;
- mimeApps = {
- enable = true;
- associations.added = {
- "application/zip" = ["org.gnome.FileRoller.desktop"];
- "application/csv" = ["calc.desktop"];
- "application/pdf" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ config = mkMerge [
+ {
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
+ fish.enable = true;
+ nushell.enable = true;
+ starship.enable = true;
};
- defaultApplications = {
- "application/zip" = ["org.gnome.FileRoller.desktop"];
- "application/csv" = ["calc.desktop"];
- "application/pdf" = ["vivaldi-stable.desktop"];
- "application/md" = ["dev.zed.Zed.desktop"];
- "application/text" = ["dev.zed.Zed.desktop"];
- "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ cliTools = {
+ fzf.enable = true;
+ nitch.enable = true;
+ television.enable = true;
};
- };
- };
- features = {
- cli = {
- fish.enable = true;
- nushell.enable = true;
- fzf.enable = true;
- nitch.enable = true;
secrets.enable = true;
- starship.enable = true;
};
- desktop = {
- coding.enable = true;
- crypto.enable = false;
- gaming.enable = false;
- hyprland.enable = false;
- media.enable = true;
- office.enable = false;
- rofi.enable = true;
- fonts.enable = true;
- wayland.enable = false;
- };
- };
- }
- (mkIf cfg.enable {
- wayland.windowManager.hyprland = {
- enable = true;
- settings = {
- monitor = [
- "eDP-1,preferred,0x0,1.25"
- "HDMI-A-1,preferred,2560x0,1"
- ];
- workspace = [
- "1, monitor:eDP-1, default:true"
- "2, monitor:eDP-1"
- "3, monitor:eDP-1"
- "4, monitor:HDMI-A-1"
- "5, monitor:HDMI-A-1,border:false,rounding:false"
- "6, monitor:HDMI-A-1"
- ];
- windowrule = [
- "match:class dev.zed.Zed, workspace 1"
- "match:class Msty, workspace 1"
- "match:class ^(com.obsproject.Studio)$, workspace 2"
- "match:class ^(brave-browser)$, workspace 4, opacity 1.0"
- "match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
- "match:class ^steam_app_\\d+$, fullscreen on"
- "match:class ^steam_app_\\d+$, workspace 5"
- "match:class ^steam_app_\\d+$, idle_inhibit focus"
- ];
+ # Desktop features (new namespace)
+ desktop = {
+ wm = {
+ hyprland.enable = false;
+ rofi.enable = true;
+ wayland.enable = false;
+ };
+ apps = {
+ obsidian.enable = true;
+ office.enable = false;
+ crypto.enable = false;
+ };
+ theme = {
+ fonts.enable = true;
+ wallpapers.enable = false;
+ };
};
- };
- })
- ];
-}
+
+ # Coding environment
+ coding = {
+ editors = {
+ neovim.enable = true;
+ zed.enable = true;
+ };
+ lsp.enable = true;
+ };
+
+ # Media profile features
+ profiles.media = {
+ obs.enable = false;
+ ffmpeg.enable = false;
+ kdenlive.enable = false;
+ ytDlp.enable = true;
+ };
+
+ xdg = {
+ enable = true;
+ configFile."mimeapps.list".force = true;
+ mimeApps = {
+ enable = true;
+ associations.added = {
+ "application/zip" = ["org.gnome.FileRoller.desktop"];
+ "application/csv" = ["calc.desktop"];
+ "application/pdf" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ };
+ defaultApplications = {
+ "application/zip" = ["org.gnome.FileRoller.desktop"];
+ "application/csv" = ["calc.desktop"];
+ "application/pdf" = ["vivaldi-stable.desktop"];
+ "application/md" = ["dev.zed.Zed.desktop"];
+ "application/text" = ["dev.zed.Zed.desktop"];
+ "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ };
+ };
+ };
+ }
+
+ # Host-specific Hyprland layout — only applies when hyprland is enabled
+ (mkIf config.desktop.wm.hyprland.enable {
+ wayland.windowManager.hyprland = {
+ enable = true;
+ settings = {
+ monitor = [
+ "eDP-1,preferred,0x0,1.25"
+ "HDMI-A-1,preferred,2560x0,1"
+ ];
+ workspace = [
+ "1, monitor:eDP-1, default:true"
+ "2, monitor:eDP-1"
+ "3, monitor:eDP-1"
+ "4, monitor:HDMI-A-1"
+ "5, monitor:HDMI-A-1,border:false,rounding:false"
+ "6, monitor:HDMI-A-1"
+ ];
+ windowrule = [
+ "match:class dev.zed.Zed, workspace 1"
+ "match:class Msty, workspace 1"
+ "match:class ^(com.obsproject.Studio)$, workspace 2"
+ "match:class ^(brave-browser)$, workspace 4, opacity 1.0"
+ "match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
+ "match:class ^steam_app_\\d+$, fullscreen on"
+ "match:class ^steam_app_\\d+$, workspace 5"
+ "match:class ^steam_app_\\d+$, idle_inhibit focus"
+ ];
+ };
+ };
+ })
+ ];
+ }
diff --git a/home/m3tam3re/m3-helios.nix b/home/m3tam3re/m3-helios.nix
index 0f6c41d..12fb021 100644
--- a/home/m3tam3re/m3-helios.nix
+++ b/home/m3tam3re/m3-helios.nix
@@ -1,17 +1,25 @@
-{
+# m3-helios — AdGuard DNS and internal routing server.
+# Context: server | Profiles: (none)
+{lib, ...}: let
+ homeLib = import ../lib {inherit lib;};
+in {
imports = [
- ../common
- ../features/cli
+ (homeLib.mkHomeConfig {
+ profiles = [];
+ context = "server";
+ })
./home-server.nix
];
- features = {
- cli = {
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
fish.enable = true;
+ starship.enable = true;
+ };
+ cliTools = {
fzf.enable = true;
nitch.enable = true;
- secrets.enable = false;
- starship.enable = true;
};
};
}
diff --git a/home/m3tam3re/m3-hermes.nix b/home/m3tam3re/m3-hermes.nix
index 0f6c41d..fe8d193 100644
--- a/home/m3tam3re/m3-hermes.nix
+++ b/home/m3tam3re/m3-hermes.nix
@@ -1,17 +1,25 @@
-{
+# m3-hermes — secondary server.
+# Context: server | Profiles: (none)
+{lib, ...}: let
+ homeLib = import ../lib {inherit lib;};
+in {
imports = [
- ../common
- ../features/cli
+ (homeLib.mkHomeConfig {
+ profiles = [];
+ context = "server";
+ })
./home-server.nix
];
- features = {
- cli = {
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
fish.enable = true;
+ starship.enable = true;
+ };
+ cliTools = {
fzf.enable = true;
nitch.enable = true;
- secrets.enable = false;
- starship.enable = true;
};
};
}
diff --git a/home/m3tam3re/m3-kratos.nix b/home/m3tam3re/m3-kratos.nix
index 70c5824..5f01fbf 100644
--- a/home/m3tam3re/m3-kratos.nix
+++ b/home/m3tam3re/m3-kratos.nix
@@ -1,96 +1,138 @@
+# m3-kratos — AMD desktop workstation.
+# Context: desktop | Profiles: coding, gaming, media
{
config,
lib,
...
-}:
-with lib; {
- imports = [
- ../common
- ./home.nix
- ../features/cli
- ../features/coding
- ../features/desktop
- ];
+}: let
+ homeLib = import ../lib {inherit lib;};
+in
+ with lib; {
+ imports = [
+ (homeLib.mkHomeConfig {
+ profiles = ["coding" "gaming" "media"];
+ context = "desktop";
+ })
+ ./home.nix
+ ];
- config = mkMerge [
- {
- xdg = {
- # TODO: better structure
- enable = true;
- configFile."mimeapps.list".force = true;
- mimeApps = {
- enable = true;
- associations.added = {
- "application/zip" = ["org.gnome.FileRoller.desktop"];
- "application/csv" = ["calc.desktop"];
- "application/pdf" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ config = mkMerge [
+ {
+ # Base CLI tools (new namespace)
+ base = {
+ shell = {
+ nushell.enable = true;
+ starship.enable = true;
};
- defaultApplications = {
- "application/zip" = ["org.gnome.FileRoller.desktop"];
- "application/csv" = ["calc.desktop"];
- "application/pdf" = ["vivaldi-stable.desktop"];
- "application/md" = ["dev.zed.Zed.desktop"];
- "application/text" = ["dev.zed.Zed.desktop"];
- "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
- "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ cliTools = {
+ fzf.enable = true;
+ nitch.enable = true;
+ television.enable = true;
};
- };
- };
- features = {
- cli = {
- nushell.enable = true;
- fzf.enable = true;
- nitch.enable = true;
secrets.enable = true;
- starship.enable = true;
- television.enable = true;
};
+
+ # Desktop features (new namespace)
desktop = {
- crypto.enable = true;
- coding.enable = true;
- gaming.enable = true;
- hyprland.enable = true;
- media.enable = true;
- obsidian.enable = true;
- office.enable = true;
- rofi.enable = true;
- fonts.enable = true;
- wayland.enable = true;
- wallpapers = true;
+ wm = {
+ hyprland.enable = true;
+ rofi.enable = true;
+ wayland.enable = true;
+ };
+ apps = {
+ crypto.enable = true;
+ obsidian.enable = true;
+ office.enable = true;
+ };
+ theme = {
+ fonts.enable = true;
+ wallpapers.enable = true;
+ };
};
- };
- }
- (mkIf config.features.desktop.hyprland.enable {
- wayland.windowManager.hyprland = {
- enable = true;
- settings = {
- monitor = [
- "DP-1,2560x1440@144,0x0,1"
- "DP-2,2560x1440@144,2560x0,1"
- ];
- workspace = [
- "1, monitor:DP-1, default:true"
- "2, monitor:DP-1"
- "3, monitor:DP-1"
- "4, monitor:DP-2"
- "5, monitor:DP-2"
- "6, monitor:DP-2"
- "7, monitor:DP-2"
- ];
-
- windowrule = [
- "match:class dev.zed.Zed, workspace 1"
- "match:class Msty, workspace 1"
- "match:class ^(com.obsproject.Studio)$, workspace 2"
- "match:class ^(brave-browser)$, workspace 4, opacity 1.0"
- "match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
- "match:class ^steam_app_\\d+$, idle_inhibit focus"
- ];
+ # Coding environment
+ coding = {
+ editors = {
+ neovim.enable = true;
+ zed.enable = true;
+ };
+ lsp.enable = true;
+ languages = {
+ python.enable = true;
+ javascript.enable = true;
+ rustToolchain.enable = true;
+ go.enable = true;
+ typescript.enable = true;
+ };
};
- };
- })
- ];
-}
+
+ # Gaming profile features
+ profiles.gaming = {
+ steam.enable = true;
+ gamescope.enable = true;
+ };
+
+ # Media profile features
+ profiles.media = {
+ obs.enable = true;
+ ffmpeg.enable = true;
+ kdenlive.enable = true;
+ ytDlp.enable = true;
+ };
+
+ xdg = {
+ enable = true;
+ configFile."mimeapps.list".force = true;
+ mimeApps = {
+ enable = true;
+ associations.added = {
+ "application/zip" = ["org.gnome.FileRoller.desktop"];
+ "application/csv" = ["calc.desktop"];
+ "application/pdf" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ };
+ defaultApplications = {
+ "application/zip" = ["org.gnome.FileRoller.desktop"];
+ "application/csv" = ["calc.desktop"];
+ "application/pdf" = ["vivaldi-stable.desktop"];
+ "application/md" = ["dev.zed.Zed.desktop"];
+ "application/text" = ["dev.zed.Zed.desktop"];
+ "x-scheme-handler/http" = ["vivaldi-stable.desktop"];
+ "x-scheme-handler/https" = ["vivaldi-stable.desktop"];
+ };
+ };
+ };
+ }
+
+ # Host-specific Hyprland monitor and workspace layout (dual 1440p monitors)
+ (mkIf config.desktop.wm.hyprland.enable {
+ wayland.windowManager.hyprland = {
+ enable = true;
+ settings = {
+ monitor = [
+ "DP-1,2560x1440@144,0x0,1"
+ "DP-2,2560x1440@144,2560x0,1"
+ ];
+ workspace = [
+ "1, monitor:DP-1, default:true"
+ "2, monitor:DP-1"
+ "3, monitor:DP-1"
+ "4, monitor:DP-2"
+ "5, monitor:DP-2"
+ "6, monitor:DP-2"
+ "7, monitor:DP-2"
+ ];
+ windowrule = [
+ "match:class dev.zed.Zed, workspace 1"
+ "match:class Msty, workspace 1"
+ "match:class ^(com.obsproject.Studio)$, workspace 2"
+ "match:class ^(brave-browser)$, workspace 4, opacity 1.0"
+ "match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
+ "match:class ^steam_app_\\d+$, idle_inhibit focus"
+ ];
+ };
+ };
+ })
+ ];
+ }
diff --git a/home/profiles/gaming/default.nix b/home/profiles/gaming/default.nix
new file mode 100644
index 0000000..7b1f663
--- /dev/null
+++ b/home/profiles/gaming/default.nix
@@ -0,0 +1,8 @@
+# Gaming profile aggregator — Steam platform, Gamescope session, and AMD GPU tools.
+{...}: {
+ imports = [
+ ./steam.nix
+ ./gamescope.nix
+ ./gpu.nix
+ ];
+}
diff --git a/home/profiles/gaming/gamescope.nix b/home/profiles/gaming/gamescope.nix
new file mode 100644
index 0000000..6f975cd
--- /dev/null
+++ b/home/profiles/gaming/gamescope.nix
@@ -0,0 +1,16 @@
+# Gamescope — Valve's micro-compositor for Steam gaming sessions.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.gaming.gamescope;
+in {
+ options.profiles.gaming.gamescope.enable = mkEnableOption "enable Gamescope session";
+
+ config = mkIf cfg.enable {
+ home.packages = [pkgs.gamescope];
+ };
+}
diff --git a/home/profiles/gaming/gpu.nix b/home/profiles/gaming/gpu.nix
new file mode 100644
index 0000000..ad8c85c
--- /dev/null
+++ b/home/profiles/gaming/gpu.nix
@@ -0,0 +1,21 @@
+# AMD GPU tools — ROCm runtime, monitoring, and Vulkan utilities for gaming.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.gaming.gpu;
+in {
+ options.profiles.gaming.gpu.enable = mkEnableOption "enable AMD GPU tools";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ rocmPackages.rocm-runtime
+ rocmPackages.rocm-smi
+ rocmPackages.rocminfo
+ vulkan-tools
+ ];
+ };
+}
diff --git a/home/profiles/gaming/steam.nix b/home/profiles/gaming/steam.nix
new file mode 100644
index 0000000..92a24c1
--- /dev/null
+++ b/home/profiles/gaming/steam.nix
@@ -0,0 +1,21 @@
+# Steam gaming platform with Steam Deck compatibility tools and gaming utilities.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.gaming.steam;
+in {
+ options.profiles.gaming.steam.enable = mkEnableOption "enable Steam gaming";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ gamemode
+ goverlay
+ mangohud
+ protonplus
+ ];
+ };
+}
diff --git a/home/profiles/media/default.nix b/home/profiles/media/default.nix
new file mode 100644
index 0000000..0f453a5
--- /dev/null
+++ b/home/profiles/media/default.nix
@@ -0,0 +1,10 @@
+# Media profile aggregator — OBS, FFmpeg, yt-dlp, Kdenlive, and HandBrake.
+{...}: {
+ imports = [
+ ./obs.nix
+ ./ffmpeg.nix
+ ./yt-dlp.nix
+ ./kdenlive.nix
+ ./handbrake.nix
+ ];
+}
diff --git a/home/profiles/media/ffmpeg.nix b/home/profiles/media/ffmpeg.nix
new file mode 100644
index 0000000..287e32c
--- /dev/null
+++ b/home/profiles/media/ffmpeg.nix
@@ -0,0 +1,24 @@
+# FFmpeg — full-featured multimedia processing toolchain.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.media.ffmpeg;
+in {
+ options.profiles.media.ffmpeg.enable = mkEnableOption "enable FFmpeg tools";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ amf
+ ffmpeg_6-full
+ gst_all_1.gstreamer
+ gst_all_1.gst-vaapi
+ pamixer
+ pavucontrol
+ qpwgraph
+ ];
+ };
+}
diff --git a/home/profiles/media/handbrake.nix b/home/profiles/media/handbrake.nix
new file mode 100644
index 0000000..f14ff5d
--- /dev/null
+++ b/home/profiles/media/handbrake.nix
@@ -0,0 +1,21 @@
+# HandBrake — open-source video transcoder.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.media.handbrake;
+in {
+ options.profiles.media.handbrake.enable = mkEnableOption "enable HandBrake transcoder";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ handbrake
+ gimp
+ inkscape
+ libation
+ ];
+ };
+}
diff --git a/home/profiles/media/kdenlive.nix b/home/profiles/media/kdenlive.nix
new file mode 100644
index 0000000..f3a4dbd
--- /dev/null
+++ b/home/profiles/media/kdenlive.nix
@@ -0,0 +1,16 @@
+# Kdenlive — KDE non-linear video editor.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.media.kdenlive;
+in {
+ options.profiles.media.kdenlive.enable = mkEnableOption "enable Kdenlive video editor";
+
+ config = mkIf cfg.enable {
+ home.packages = [pkgs.kdePackages.kdenlive];
+ };
+}
diff --git a/home/profiles/media/obs.nix b/home/profiles/media/obs.nix
new file mode 100644
index 0000000..2a6f22c
--- /dev/null
+++ b/home/profiles/media/obs.nix
@@ -0,0 +1,21 @@
+# OBS Studio — open broadcaster software for streaming and recording.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.media.obs;
+in {
+ options.profiles.media.obs.enable = mkEnableOption "enable OBS Studio";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ v4l-utils
+ ];
+
+ # OBS is managed via NixOS programs.obs-studio at the system level.
+ # Home-manager only installs supporting tools.
+ };
+}
diff --git a/home/profiles/media/yt-dlp.nix b/home/profiles/media/yt-dlp.nix
new file mode 100644
index 0000000..5c9e088
--- /dev/null
+++ b/home/profiles/media/yt-dlp.nix
@@ -0,0 +1,32 @@
+# yt-dlp and media playback — YouTube downloader with MPV integration.
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.profiles.media.ytDlp;
+in {
+ options.profiles.media.ytDlp.enable = mkEnableOption "enable yt-dlp and media playback";
+
+ config = mkIf cfg.enable {
+ home.packages = with pkgs; [
+ plexamp
+ unimatrix
+ webcord
+ ];
+
+ programs.mpv = {
+ enable = true;
+ bindings = {
+ WHEEL_UP = "seek 10";
+ WHEEL_DOWN = "seek -10";
+ };
+ config = {
+ profile = "gpu-hq";
+ ytdl-format = "bestvideo+bestaudio";
+ };
+ };
+ };
+}
diff --git a/home/server/default.nix b/home/server/default.nix
new file mode 100644
index 0000000..2c6d8ea
--- /dev/null
+++ b/home/server/default.nix
@@ -0,0 +1,6 @@
+# Server context home-manager configuration — minimal headless setup.
+# Loaded on server hosts: m3-atlas, m3-helios, m3-aether.
+{...}: {
+ # Server hosts use the base and coding modules directly.
+ # No desktop environment or GUI applications.
+}
diff --git a/hosts/m3-aether/hardware-configuration.nix b/hosts/m3-aether/hardware-configuration.nix
index 4e571c8..7caa8fe 100644
--- a/hosts/m3-aether/hardware-configuration.nix
+++ b/hosts/m3-aether/hardware-configuration.nix
@@ -1,24 +1,28 @@
-# Do not modify this file! It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations. Please make changes
-# to /etc/nixos/configuration.nix instead.
-{ config, lib, pkgs, modulesPath, ... }:
-
-{
- imports =
- [ (modulesPath + "/profiles/qemu-guest.nix")
- ];
-
- boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
- boot.initrd.kernelModules = [ ];
- boot.kernelModules = [ ];
- boot.extraModulePackages = [ ];
-
- # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
- # (the default) this is the recommended approach. When using systemd-networkd it's
- # still possible to use this option, but it's recommended to use it in conjunction
- # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
- networking.useDHCP = lib.mkDefault true;
- # networking.interfaces.ens18.useDHCP = lib.mkDefault true;
-
- nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-}
+# Do not modify this file! It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations. Please make changes
+# to /etc/nixos/configuration.nix instead.
+{
+ config,
+ lib,
+ pkgs,
+ modulesPath,
+ ...
+}: {
+ imports = [
+ (modulesPath + "/profiles/qemu-guest.nix")
+ ];
+
+ boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
+ boot.initrd.kernelModules = [];
+ boot.kernelModules = [];
+ boot.extraModulePackages = [];
+
+ # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+ # (the default) this is the recommended approach. When using systemd-networkd it's
+ # still possible to use this option, but it's recommended to use it in conjunction
+ # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
+ networking.useDHCP = lib.mkDefault true;
+ # networking.interfaces.ens18.useDHCP = lib.mkDefault true;
+
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+}
diff --git a/hosts/m3-ares/services/postgres.nix b/hosts/m3-ares/services/postgres.nix
index 4b8feec..eb46ca8 100644
--- a/hosts/m3-ares/services/postgres.nix
+++ b/hosts/m3-ares/services/postgres.nix
@@ -1,7 +1,4 @@
-{
- pkgs,
- ...
-}: {
+{pkgs, ...}: {
services.postgresql = {
enable = true;
package = pkgs.postgresql_17;
diff --git a/hosts/m3-atlas/services/containers/kestra.nix b/hosts/m3-atlas/services/containers/kestra.nix
index 87ceb79..8882d8c 100644
--- a/hosts/m3-atlas/services/containers/kestra.nix
+++ b/hosts/m3-atlas/services/containers/kestra.nix
@@ -1,9 +1,9 @@
-{ config, ... }: {
+{config, ...}: {
virtualisation.oci-containers.containers."kestra" = {
image = "docker.io/kestra/kestra:latest";
- environmentFiles = [ config.age.secrets.kestra-env.path ];
- cmd = [ "server" "standalone" "--config" "/etc/config/application.yaml"];
- ports = [ "127.0.0.1:3018:8080" ];
+ environmentFiles = [config.age.secrets.kestra-env.path];
+ cmd = ["server" "standalone" "--config" "/etc/config/application.yaml"];
+ ports = ["127.0.0.1:3018:8080"];
user = "root";
volumes = [
"/var/run/docker.sock:/var/run/docker.sock"
@@ -11,8 +11,7 @@
"kestra_data:/app/storage"
"/tmp/kestra-wd:/tmp/kestra-wd"
];
- extraOptions =
- [ "--add-host=postgres:10.89.0.1" "--ip=10.89.0.18" "--network=web" ];
+ extraOptions = ["--add-host=postgres:10.89.0.1" "--ip=10.89.0.18" "--network=web"];
};
systemd.tmpfiles.rules = [
@@ -21,12 +20,11 @@
# Traefik configuration specific to littlelink
services.traefik.dynamicConfigOptions.http = {
- services.kestra.loadBalancer.servers =
- [{ url = "http://localhost:3018/"; }];
+ services.kestra.loadBalancer.servers = [{url = "http://localhost:3018/";}];
routers.kestra = {
rule = "Host(`k.m3ta.dev`)";
- tls = { certResolver = "godaddy"; };
+ tls = {certResolver = "godaddy";};
service = "kestra";
entrypoints = "websecure";
};
diff --git a/hosts/m3-helios/hardware-configuration.nix b/hosts/m3-helios/hardware-configuration.nix
index 4e571c8..7caa8fe 100644
--- a/hosts/m3-helios/hardware-configuration.nix
+++ b/hosts/m3-helios/hardware-configuration.nix
@@ -1,24 +1,28 @@
-# Do not modify this file! It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations. Please make changes
-# to /etc/nixos/configuration.nix instead.
-{ config, lib, pkgs, modulesPath, ... }:
-
-{
- imports =
- [ (modulesPath + "/profiles/qemu-guest.nix")
- ];
-
- boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
- boot.initrd.kernelModules = [ ];
- boot.kernelModules = [ ];
- boot.extraModulePackages = [ ];
-
- # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
- # (the default) this is the recommended approach. When using systemd-networkd it's
- # still possible to use this option, but it's recommended to use it in conjunction
- # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
- networking.useDHCP = lib.mkDefault true;
- # networking.interfaces.ens18.useDHCP = lib.mkDefault true;
-
- nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-}
+# Do not modify this file! It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations. Please make changes
+# to /etc/nixos/configuration.nix instead.
+{
+ config,
+ lib,
+ pkgs,
+ modulesPath,
+ ...
+}: {
+ imports = [
+ (modulesPath + "/profiles/qemu-guest.nix")
+ ];
+
+ boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
+ boot.initrd.kernelModules = [];
+ boot.kernelModules = [];
+ boot.extraModulePackages = [];
+
+ # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+ # (the default) this is the recommended approach. When using systemd-networkd it's
+ # still possible to use this option, but it's recommended to use it in conjunction
+ # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
+ networking.useDHCP = lib.mkDefault true;
+ # networking.interfaces.ens18.useDHCP = lib.mkDefault true;
+
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+}
diff --git a/hosts/m3-hermes/hardware-configuration.nix b/hosts/m3-hermes/hardware-configuration.nix
index 419024b..d52e1a3 100644
--- a/hosts/m3-hermes/hardware-configuration.nix
+++ b/hosts/m3-hermes/hardware-configuration.nix
@@ -1,7 +1,13 @@
# Do not modify this file! It was generated by 'nixos-generate-config'
# and may be overwritten by future invocations. Please make changes
# to configuration.nix instead.
-{config, lib, pkgs, modulesPath, ...}: {
+{
+ config,
+ lib,
+ pkgs,
+ modulesPath,
+ ...
+}: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];